1 /* 2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_COMPILER_BUILTINS_STRING_STUB_BUILDER_H 17 #define ECMASCRIPT_COMPILER_BUILTINS_STRING_STUB_BUILDER_H 18 #include "ecmascript/compiler/gate.h" 19 #include "ecmascript/compiler/stub_builder-inl.h" 20 #include "ecmascript/compiler/builtins/builtins_stubs.h" 21 22 namespace panda::ecmascript::kungfu { 23 class FlatStringStubBuilder; 24 struct StringInfoGateRef; 25 26 class BuiltinsStringStubBuilder : public BuiltinsStubBuilder { 27 public: BuiltinsStringStubBuilder(StubBuilder * parent,GateRef globalEnv)28 explicit BuiltinsStringStubBuilder(StubBuilder *parent, GateRef globalEnv) 29 : BuiltinsStubBuilder(parent, globalEnv) {} BuiltinsStringStubBuilder(CallSignature * callSignature,Environment * env,GateRef globalEnv)30 BuiltinsStringStubBuilder(CallSignature *callSignature, Environment *env, GateRef globalEnv) 31 : BuiltinsStubBuilder(callSignature, env, globalEnv) {} BuiltinsStringStubBuilder(Environment * env,GateRef globalEnv)32 explicit BuiltinsStringStubBuilder(Environment* env, GateRef globalEnv): BuiltinsStubBuilder(env, globalEnv) {} 33 ~BuiltinsStringStubBuilder() override = default; 34 NO_MOVE_SEMANTIC(BuiltinsStringStubBuilder); 35 NO_COPY_SEMANTIC(BuiltinsStringStubBuilder); GenerateCircuit()36 void GenerateCircuit() override {} 37 38 #define DECLARE_BUILTINS_SRRING_STUB_BUILDER(method, ...) \ 39 void method(GateRef glue, GateRef thisValue, GateRef numArgs, Variable* res, Label *exit, Label *slowPath); 40 BUILTINS_WITH_STRING_STUB_BUILDER(DECLARE_BUILTINS_SRRING_STUB_BUILDER) 41 #undef DECLARE_BUILTINS_SRRING_STUB_BUILDER 42 43 void LocaleCompare(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *res, Label *exit, Label *slowPath); 44 void StringIteratorNext(GateRef glue, GateRef thisValue, GateRef numArgs, 45 Variable *res, Label *exit, Label *slowPath); 46 47 GateRef ConvertAndClampRelativeIndex(GateRef index, GateRef length); 48 GateRef StringAt(GateRef glue, const StringInfoGateRef &stringInfoGate, GateRef index); 49 GateRef FastSubString(GateRef glue, GateRef thisValue, GateRef from, GateRef len, 50 const StringInfoGateRef &stringInfoGate); 51 GateRef FastSubUtf8String(GateRef glue, GateRef from, GateRef len, const StringInfoGateRef &stringInfoGate); 52 GateRef FastSubUtf16String(GateRef glue, GateRef from, GateRef len, const StringInfoGateRef &stringInfoGate); 53 GateRef FastStringCharCodeAt(GateRef glue, GateRef thisValue, GateRef pos); 54 GateRef GetSubstitution(GateRef glue, GateRef searchString, GateRef thisString, 55 GateRef pos, GateRef replaceString); 56 void CopyChars(GateRef glue, GateRef dst, GateRef source, GateRef sourceLength, GateRef size, VariableType type); 57 void CopyUtf16AsUtf8(GateRef glue, GateRef dst, GateRef src, GateRef sourceLength); 58 void CopyUtf8AsUtf16(GateRef glue, GateRef dst, GateRef src, GateRef sourceLength); 59 GateRef StringIndexOf(GateRef lhsData, bool lhsIsUtf8, GateRef rhsData, bool rhsIsUtf8, 60 GateRef pos, GateRef max, GateRef rhsCount); 61 GateRef StringIndexOf(GateRef glue, const StringInfoGateRef &lStringInfoGate, 62 const StringInfoGateRef &rStringInfoGate, GateRef pos); 63 GateRef GetSingleCharCodeByIndex(GateRef glue, GateRef str, GateRef index); 64 GateRef CreateStringBySingleCharCode(GateRef glue, GateRef charCode); 65 GateRef CreateFromEcmaString(GateRef glue, GateRef index, const StringInfoGateRef &stringInfoGate); 66 GateRef IsFirstConcatInStringAdd(GateRef init, GateRef status); 67 GateRef ConcatIsInStringAdd(GateRef init, GateRef status); 68 GateRef StringAdd(GateRef glue, GateRef leftString, GateRef rightString, GateRef status); 69 GateRef AllocateLineString(GateRef glue, GateRef length, GateRef canBeCompressed); 70 GateRef AllocateSlicedString(GateRef glue, GateRef flatString, GateRef length, GateRef canBeCompressed); 71 GateRef IsSpecialSlicedString(GateRef glue, GateRef obj); 72 GateRef StringConcat(GateRef glue, GateRef leftString, GateRef rightString); 73 GateRef EcmaStringTrim(GateRef glue, GateRef srcString, GateRef trimMode); 74 GateRef EcmaStringTrimBody(GateRef glue, GateRef thisValue, StringInfoGateRef srcStringInfoGate, 75 GateRef trimMode, GateRef isUtf8); 76 void StoreParent(GateRef glue, GateRef object, GateRef parent); 77 void StoreStartIndexAndBackingStore(GateRef glue, GateRef object, GateRef startIndex, GateRef hasBackingStore); 78 GateRef LoadStartIndex(GateRef object); 79 GateRef LoadHasBackingStore(GateRef object); 80 GateRef IsSubStringAt(GateRef lhsData, bool lhsIsUtf8, GateRef rhsData, bool rhsIsUtf8, 81 GateRef pos, GateRef rhsCount); 82 GateRef IsSubStringAt(GateRef glue, const StringInfoGateRef &lStringInfoGate, 83 const StringInfoGateRef &rStringInfoGate, GateRef pos); 84 GateRef GetSubString(GateRef glue, GateRef thisValue, GateRef from, GateRef len); 85 GateRef GetFastSubString(GateRef glue, GateRef thisValue, GateRef start, GateRef len); 86 GateRef StringToUint(GateRef glue, GateRef string, uint64_t maxValue); 87 GateRef StringDataToUint(GateRef dataUtf8, GateRef len, uint64_t maxValue); 88 private: ChangeStringTaggedPointerToInt64(GateRef x)89 GateRef ChangeStringTaggedPointerToInt64(GateRef x) 90 { 91 return GetEnvironment()->GetBuilder()->ChangeTaggedPointerToInt64(x); 92 } 93 GateRef CanBeCompressed(GateRef utf16Data, GateRef utf16Len, bool isUtf16); 94 GateRef GetUtf16Data(GateRef stringData, GateRef index); 95 GateRef IsASCIICharacter(GateRef data); 96 GateRef GetUtf8Data(GateRef stringData, GateRef index); 97 GateRef GetSingleCharCodeFromLineString(GateRef str, GateRef index); 98 GateRef GetSingleCharCodeFromSlicedString(GateRef glue, GateRef str, GateRef index); 99 void CheckParamsAndGetPosition(GateRef glue, GateRef thisValue, GateRef numArgs, 100 Variable* pos, Label *exit, Label *slowPath, Label *posIsValid); 101 }; 102 103 class FlatStringStubBuilder : public StubBuilder { 104 public: FlatStringStubBuilder(StubBuilder * parent)105 explicit FlatStringStubBuilder(StubBuilder *parent) 106 : StubBuilder(parent) {} 107 ~FlatStringStubBuilder() override = default; 108 NO_MOVE_SEMANTIC(FlatStringStubBuilder); 109 NO_COPY_SEMANTIC(FlatStringStubBuilder); GenerateCircuit()110 void GenerateCircuit() override {} 111 112 void FlattenString(GateRef glue, GateRef str, Label *exit); 113 void FlattenStringWithIndex(GateRef glue, GateRef str, Variable *index, Label *exit); GetParentFromSlicedString(GateRef glue,GateRef string)114 GateRef GetParentFromSlicedString(GateRef glue, GateRef string) 115 { 116 GateRef offset = IntPtr(SlicedString::PARENT_OFFSET); 117 return Load(VariableType::JS_POINTER(), glue, string, offset); 118 } 119 GetStartIndexFromSlicedString(GateRef string)120 GateRef GetStartIndexFromSlicedString(GateRef string) { 121 GateRef offset = IntPtr(SlicedString::STARTINDEX_AND_FLAGS_OFFSET); 122 GateRef mixStartIndex = LoadPrimitive(VariableType::INT32(), string, offset); 123 return Int32LSR(mixStartIndex, Int32(SlicedString::StartIndexBits::START_BIT)); 124 } 125 GetHasBackingStoreFromSlicedString(GateRef string)126 GateRef GetHasBackingStoreFromSlicedString(GateRef string) { 127 GateRef offset = IntPtr(SlicedString::STARTINDEX_AND_FLAGS_OFFSET); 128 GateRef mixStartIndex = LoadPrimitive(VariableType::INT32(), string, offset); 129 return TruncInt32ToInt1(Int32And(mixStartIndex, Int32((1 << SlicedString::HasBackingStoreBit::SIZE) - 1))); 130 } 131 GetFlatString()132 GateRef GetFlatString() 133 { 134 return flatString_.ReadVariable(); 135 } 136 GetStartIndex()137 GateRef GetStartIndex() 138 { 139 return startIndex_.ReadVariable(); 140 } 141 GetLength()142 GateRef GetLength() 143 { 144 return length_; 145 } 146 147 private: 148 void FlattenStringImpl(GateRef glue, GateRef str, Label *handleSlicedString, Label *exit); 149 Variable flatString_ { GetEnvironment(), VariableType::JS_POINTER(), NextVariableId(), Undefined() }; 150 Variable startIndex_ { GetEnvironment(), VariableType::INT32(), NextVariableId(), Int32(0) }; 151 GateRef length_ { Circuit::NullGate() }; 152 }; 153 154 struct StringInfoGateRef { 155 GateRef string_ { Circuit::NullGate() }; 156 GateRef startIndex_ { Circuit::NullGate() }; 157 GateRef length_ { Circuit::NullGate() }; StringInfoGateRefStringInfoGateRef158 explicit StringInfoGateRef(FlatStringStubBuilder* flatString) : string_(flatString->GetFlatString()), 159 startIndex_(flatString->GetStartIndex()), 160 length_(flatString->GetLength()) {} GetStringStringInfoGateRef161 GateRef GetString() const 162 { 163 return string_; 164 } 165 GetStartIndexStringInfoGateRef166 GateRef GetStartIndex() const 167 { 168 return startIndex_; 169 } 170 GetLengthStringInfoGateRef171 GateRef GetLength() const 172 { 173 return length_; 174 } 175 }; 176 } // namespace panda::ecmascript::kungfu 177 #endif // ECMASCRIPT_COMPILER_BUILTINS_STRING_STUB_BUILDER_H 178