Home | History | Annotate | Download | only in builtins
      1 // Copyright 2017 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_BUILTINS_BUILTINS_STRING_GEN_H_
      6 #define V8_BUILTINS_BUILTINS_STRING_GEN_H_
      7 
      8 #include "src/code-stub-assembler.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 class StringBuiltinsAssembler : public CodeStubAssembler {
     14  public:
     15   explicit StringBuiltinsAssembler(compiler::CodeAssemblerState* state)
     16       : CodeStubAssembler(state) {}
     17 
     18   // ES#sec-getsubstitution
     19   Node* GetSubstitution(Node* context, Node* subject_string,
     20                         Node* match_start_index, Node* match_end_index,
     21                         Node* replace_string);
     22   void StringEqual_Core(Node* context, Node* lhs, Node* lhs_instance_type,
     23                         Node* rhs, Node* rhs_instance_type,
     24                         TNode<IntPtrT> length, Label* if_equal,
     25                         Label* if_not_equal, Label* if_indirect);
     26 
     27  protected:
     28   void StringEqual_Loop(Node* lhs, Node* lhs_instance_type,
     29                         MachineType lhs_type, Node* rhs,
     30                         Node* rhs_instance_type, MachineType rhs_type,
     31                         TNode<IntPtrT> length, Label* if_equal,
     32                         Label* if_not_equal);
     33   Node* DirectStringData(Node* string, Node* string_instance_type);
     34 
     35   void DispatchOnStringEncodings(Node* const lhs_instance_type,
     36                                  Node* const rhs_instance_type,
     37                                  Label* if_one_one, Label* if_one_two,
     38                                  Label* if_two_one, Label* if_two_two);
     39 
     40   template <typename SubjectChar, typename PatternChar>
     41   Node* CallSearchStringRaw(Node* const subject_ptr, Node* const subject_length,
     42                             Node* const search_ptr, Node* const search_length,
     43                             Node* const start_position);
     44 
     45   Node* PointerToStringDataAtIndex(Node* const string_data, Node* const index,
     46                                    String::Encoding encoding);
     47 
     48   // substr and slice have a common way of handling the {start} argument.
     49   void ConvertAndBoundsCheckStartArgument(Node* context, Variable* var_start,
     50                                           Node* start, Node* string_length);
     51 
     52   void GenerateStringEqual(Node* context, Node* left, Node* right);
     53   void GenerateStringRelationalComparison(Node* context, Node* left,
     54                                           Node* right, Operation op);
     55 
     56   TNode<Smi> ToSmiBetweenZeroAnd(SloppyTNode<Context> context,
     57                                  SloppyTNode<Object> value,
     58                                  SloppyTNode<Smi> limit);
     59 
     60   typedef std::function<TNode<Object>(
     61       TNode<String> receiver, TNode<IntPtrT> length, TNode<IntPtrT> index)>
     62       StringAtAccessor;
     63 
     64   void GenerateStringAt(const char* method_name, TNode<Context> context,
     65                         Node* receiver, TNode<Object> maybe_position,
     66                         TNode<Object> default_return,
     67                         StringAtAccessor accessor);
     68 
     69   TNode<Int32T> LoadSurrogatePairAt(SloppyTNode<String> string,
     70                                     SloppyTNode<IntPtrT> length,
     71                                     SloppyTNode<IntPtrT> index,
     72                                     UnicodeEncoding encoding);
     73 
     74   void StringIndexOf(Node* const subject_string, Node* const search_string,
     75                      Node* const position, std::function<void(Node*)> f_return);
     76 
     77   TNode<Smi> IndexOfDollarChar(Node* const context, Node* const string);
     78 
     79   TNode<JSArray> StringToArray(TNode<Context> context,
     80                                TNode<String> subject_string,
     81                                TNode<Smi> subject_length,
     82                                TNode<Number> limit_number);
     83 
     84   void RequireObjectCoercible(Node* const context, Node* const value,
     85                               const char* method_name);
     86 
     87   TNode<BoolT> SmiIsNegative(TNode<Smi> value) {
     88     return SmiLessThan(value, SmiConstant(0));
     89   }
     90 
     91   // Implements boilerplate logic for {match, split, replace, search} of the
     92   // form:
     93   //
     94   //  if (!IS_NULL_OR_UNDEFINED(object)) {
     95   //    var maybe_function = object[symbol];
     96   //    if (!IS_UNDEFINED(maybe_function)) {
     97   //      return %_Call(maybe_function, ...);
     98   //    }
     99   //  }
    100   //
    101   // Contains fast paths for Smi and RegExp objects.
    102   // Important: {regexp_call} may not contain any code that can call into JS.
    103   typedef std::function<void()> NodeFunction0;
    104   typedef std::function<void(Node* fn)> NodeFunction1;
    105   void MaybeCallFunctionAtSymbol(Node* const context, Node* const object,
    106                                  Node* const maybe_string,
    107                                  Handle<Symbol> symbol,
    108                                  const NodeFunction0& regexp_call,
    109                                  const NodeFunction1& generic_call);
    110 
    111   void Generate_StringAdd(StringAddFlags flags, PretenureFlag pretenure_flag,
    112                           Node* context, Node* left, Node* right);
    113 };
    114 
    115 class StringIncludesIndexOfAssembler : public StringBuiltinsAssembler {
    116  public:
    117   explicit StringIncludesIndexOfAssembler(compiler::CodeAssemblerState* state)
    118       : StringBuiltinsAssembler(state) {}
    119 
    120  protected:
    121   enum SearchVariant { kIncludes, kIndexOf };
    122 
    123   void Generate(SearchVariant variant, TNode<IntPtrT> argc,
    124                 TNode<Context> context);
    125 };
    126 
    127 class StringTrimAssembler : public StringBuiltinsAssembler {
    128  public:
    129   explicit StringTrimAssembler(compiler::CodeAssemblerState* state)
    130       : StringBuiltinsAssembler(state) {}
    131 
    132   void GotoIfNotWhiteSpaceOrLineTerminator(Node* const char_code,
    133                                            Label* const if_not_whitespace);
    134 
    135  protected:
    136   void Generate(String::TrimMode mode, const char* method, TNode<IntPtrT> argc,
    137                 TNode<Context> context);
    138 
    139   void ScanForNonWhiteSpaceOrLineTerminator(Node* const string_data,
    140                                             Node* const string_data_offset,
    141                                             Node* const is_stringonebyte,
    142                                             Variable* const var_index,
    143                                             Node* const end, int increment,
    144                                             Label* const if_none_found);
    145 
    146   void BuildLoop(Variable* const var_index, Node* const end, int increment,
    147                  Label* const if_none_found, Label* const out,
    148                  std::function<Node*(Node*)> get_character);
    149 };
    150 
    151 }  // namespace internal
    152 }  // namespace v8
    153 
    154 #endif  // V8_BUILTINS_BUILTINS_STRING_GEN_H_
    155