builtins-string-gen.h 9.23 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_BUILTINS_BUILTINS_STRING_GEN_H_
#define V8_BUILTINS_BUILTINS_STRING_GEN_H_

8
#include "src/codegen/code-stub-assembler.h"
9 10 11 12 13 14 15 16 17 18

namespace v8 {
namespace internal {

class StringBuiltinsAssembler : public CodeStubAssembler {
 public:
  explicit StringBuiltinsAssembler(compiler::CodeAssemblerState* state)
      : CodeStubAssembler(state) {}

  // ES#sec-getsubstitution
19 20 21 22 23
  TNode<String> GetSubstitution(TNode<Context> context,
                                TNode<String> subject_string,
                                TNode<Smi> match_start_index,
                                TNode<Smi> match_end_index,
                                TNode<String> replace_string);
24 25
  void StringEqual_Core(TNode<String> lhs, TNode<Word32T> lhs_instance_type,
                        TNode<String> rhs, TNode<Word32T> rhs_instance_type,
26 27
                        TNode<IntPtrT> length, Label* if_equal,
                        Label* if_not_equal, Label* if_indirect);
28 29 30 31
  void BranchIfStringPrimitiveWithNoCustomIteration(TNode<Object> object,
                                                    TNode<Context> context,
                                                    Label* if_true,
                                                    Label* if_false);
32

33 34
  TNode<Int32T> LoadSurrogatePairAt(TNode<String> string, TNode<IntPtrT> length,
                                    TNode<IntPtrT> index,
35 36
                                    UnicodeEncoding encoding);

37 38
  TNode<String> StringFromSingleUTF16EncodedCodePoint(TNode<Int32T> codepoint);

39 40
  // Return a new string object which holds a substring containing the range
  // [from,to[ of string.
41 42
  // TODO(v8:9880): Fix implementation to use UintPtrT arguments and drop
  // IntPtrT version once all callers use UintPtrT version.
43 44
  TNode<String> SubString(TNode<String> string, TNode<IntPtrT> from,
                          TNode<IntPtrT> to);
45 46 47 48
  TNode<String> SubString(TNode<String> string, TNode<UintPtrT> from,
                          TNode<UintPtrT> to) {
    return SubString(string, Signed(from), Signed(to));
  }
49 50 51 52 53 54 55 56

  // Copies |character_count| elements from |from_string| to |to_string|
  // starting at the |from_index|'th character. |from_string| and |to_string|
  // can either be one-byte strings or two-byte strings, although if
  // |from_string| is two-byte, then |to_string| must be two-byte.
  // |from_index|, |to_index| and |character_count| must be intptr_ts s.t. 0 <=
  // |from_index| <= |from_index| + |character_count| <= from_string.length and
  // 0 <= |to_index| <= |to_index| + |character_count| <= to_string.length.
57 58 59 60 61 62
  template <typename T>
  void CopyStringCharacters(TNode<T> from_string, TNode<String> to_string,
                            TNode<IntPtrT> from_index, TNode<IntPtrT> to_index,
                            TNode<IntPtrT> character_count,
                            String::Encoding from_encoding,
                            String::Encoding to_encoding);
63

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  // Torque wrapper methods for CallSearchStringRaw for each combination of
  // search and subject character widths (char8/char16). This is a workaround
  // for Torque's current lack of support for extern macros with generics.
  TNode<IntPtrT> SearchOneByteStringInTwoByteString(
      const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
      const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length,
      const TNode<IntPtrT> start_position);
  TNode<IntPtrT> SearchOneByteStringInOneByteString(
      const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
      const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length,
      const TNode<IntPtrT> start_position);
  TNode<IntPtrT> SearchTwoByteStringInTwoByteString(
      const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
      const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length,
      const TNode<IntPtrT> start_position);
  TNode<IntPtrT> SearchTwoByteStringInOneByteString(
      const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
      const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> search_length,
      const TNode<IntPtrT> start_position);
  TNode<IntPtrT> SearchOneByteInOneByteString(
      const TNode<RawPtrT> subject_ptr, const TNode<IntPtrT> subject_length,
      const TNode<RawPtrT> search_ptr, const TNode<IntPtrT> start_position);

87
 protected:
88 89 90
  void StringEqual_Loop(TNode<String> lhs, TNode<Word32T> lhs_instance_type,
                        MachineType lhs_type, TNode<String> rhs,
                        TNode<Word32T> rhs_instance_type, MachineType rhs_type,
91 92
                        TNode<IntPtrT> length, Label* if_equal,
                        Label* if_not_equal);
93
  TNode<RawPtrT> DirectStringData(TNode<String> string,
94
                                  TNode<Word32T> string_instance_type);
95 96

  template <typename SubjectChar, typename PatternChar>
97 98 99 100 101
  TNode<IntPtrT> CallSearchStringRaw(const TNode<RawPtrT> subject_ptr,
                                     const TNode<IntPtrT> subject_length,
                                     const TNode<RawPtrT> search_ptr,
                                     const TNode<IntPtrT> search_length,
                                     const TNode<IntPtrT> start_position);
102

103 104 105
  void GenerateStringEqual(TNode<String> left, TNode<String> right);
  void GenerateStringRelationalComparison(TNode<String> left,
                                          TNode<String> right, Operation op);
106

107 108
  using StringAtAccessor = std::function<TNode<Object>(
      TNode<String> receiver, TNode<IntPtrT> length, TNode<IntPtrT> index)>;
109

110 111
  const TNode<Smi> IndexOfDollarChar(const TNode<Context> context,
                                     const TNode<String> string);
112

113
  TNode<JSArray> StringToArray(TNode<NativeContext> context,
114 115 116 117
                               TNode<String> subject_string,
                               TNode<Smi> subject_length,
                               TNode<Number> limit_number);

118
  TNode<BoolT> SmiIsNegative(TNode<Smi> value) {
119 120 121
    return SmiLessThan(value, SmiConstant(0));
  }

122 123 124
  TNode<String> AllocateConsString(TNode<Uint32T> length, TNode<String> left,
                                   TNode<String> right);

125 126
  TNode<String> StringAdd(TNode<ContextOrEmptyContext> context,
                          TNode<String> left, TNode<String> right);
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153

  // Check if |string| is an indirect (thin or flat cons) string type that can
  // be dereferenced by DerefIndirectString.
  void BranchIfCanDerefIndirectString(TNode<String> string,
                                      TNode<Int32T> instance_type,
                                      Label* can_deref, Label* cannot_deref);
  // Allocate an appropriate one- or two-byte ConsString with the first and
  // second parts specified by |left| and |right|.
  // Unpack an indirect (thin or flat cons) string type.
  void DerefIndirectString(TVariable<String>* var_string,
                           TNode<Int32T> instance_type);
  // Check if |var_string| has an indirect (thin or flat cons) string type, and
  // unpack it if so.
  void MaybeDerefIndirectString(TVariable<String>* var_string,
                                TNode<Int32T> instance_type, Label* did_deref,
                                Label* cannot_deref);
  // Check if |var_left| or |var_right| has an indirect (thin or flat cons)
  // string type, and unpack it/them if so. Fall through if nothing was done.
  void MaybeDerefIndirectStrings(TVariable<String>* var_left,
                                 TNode<Int32T> left_instance_type,
                                 TVariable<String>* var_right,
                                 TNode<Int32T> right_instance_type,
                                 Label* did_something);
  TNode<String> DerefIndirectString(TNode<String> string,
                                    TNode<Int32T> instance_type,
                                    Label* cannot_deref);

154 155 156 157 158 159 160 161 162 163 164
  // Implements boilerplate logic for {match, split, replace, search} of the
  // form:
  //
  //  if (!IS_NULL_OR_UNDEFINED(object)) {
  //    var maybe_function = object[symbol];
  //    if (!IS_UNDEFINED(maybe_function)) {
  //      return %_Call(maybe_function, ...);
  //    }
  //  }
  //
  // Contains fast paths for Smi and RegExp objects.
165
  // Important: {regexp_call} may not contain any code that can call into JS.
166
  using NodeFunction0 = std::function<void()>;
167
  using NodeFunction1 = std::function<void(TNode<Object> fn)>;
168 169 170
  using DescriptorIndexNameValue =
      PrototypeCheckAssembler::DescriptorIndexNameValue;
  void MaybeCallFunctionAtSymbol(
171 172
      const TNode<Context> context, const TNode<Object> object,
      const TNode<Object> maybe_string, Handle<Symbol> symbol,
173 174
      DescriptorIndexNameValue additional_property_to_check,
      const NodeFunction0& regexp_call, const NodeFunction1& generic_call);
175 176

 private:
177 178 179
  template <typename T>
  TNode<String> AllocAndCopyStringCharacters(TNode<T> from,
                                             TNode<Int32T> from_instance_type,
180 181
                                             TNode<IntPtrT> from_index,
                                             TNode<IntPtrT> character_count);
182 183 184 185 186 187
};

}  // namespace internal
}  // namespace v8

#endif  // V8_BUILTINS_BUILTINS_STRING_GEN_H_