1 /* 2 * Copyright (c) 2023-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_ARRAY_STUB_BUILDER_H 17 #define ECMASCRIPT_COMPILER_BUILTINS_ARRAY_STUB_BUILDER_H 18 #include "ecmascript/compiler/circuit_builder.h" 19 #include "ecmascript/compiler/gate.h" 20 #include "ecmascript/compiler/share_gate_meta_data.h" 21 #include "ecmascript/compiler/stub_builder-inl.h" 22 #include "ecmascript/compiler/builtins/builtins_stubs.h" 23 #include "ecmascript/js_stable_array.h" 24 25 namespace panda::ecmascript::kungfu { 26 class BuiltinsArrayStubBuilder : public BuiltinsStubBuilder { 27 public: BuiltinsArrayStubBuilder(StubBuilder * parent,GateRef globalEnv)28 explicit BuiltinsArrayStubBuilder(StubBuilder *parent, GateRef globalEnv) 29 : BuiltinsStubBuilder(parent, globalEnv) {} BuiltinsArrayStubBuilder(Environment * env,GateRef globalEnv)30 explicit BuiltinsArrayStubBuilder(Environment* env, GateRef globalEnv): BuiltinsStubBuilder(env, globalEnv) {} 31 ~BuiltinsArrayStubBuilder() override = default; 32 NO_MOVE_SEMANTIC(BuiltinsArrayStubBuilder); 33 NO_COPY_SEMANTIC(BuiltinsArrayStubBuilder); GenerateCircuit()34 void GenerateCircuit() override {} 35 36 #define DECLARE_BUILTINS_ARRAY_STUB_BUILDER(method, ...) \ 37 void method(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, Label *slowPath); 38 BUILTINS_WITH_ARRAY_STUB_BUILDER(DECLARE_BUILTINS_ARRAY_STUB_BUILDER) 39 #undef DECLARE_BUILTINS_ARRAY_STUB_BUILDER 40 41 void Sort(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, Label *slowPath); 42 43 void ArrayIteratorNext(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 44 Label *slowPath); 45 46 void SortAfterArgs(GateRef glue, GateRef thisValue, GateRef callbackFnHandle, 47 Variable *result, Label *exit, Label *slowPath, GateRef hir = Circuit::NullGate()); 48 49 void GenArrayConstructor(GateRef glue, GateRef nativeCode, GateRef func, 50 GateRef newTarget, GateRef thisValue, GateRef numArgs); 51 52 void FastCreateArrayWithArgv(GateRef glue, Variable *res, GateRef argc, GateRef hclass, Label *exit); 53 54 void ElementsKindHclassCompare(GateRef glue, GateRef arrayCls, Label *matchCls, Label *slowPath); 55 56 GateRef IsConcatSpreadable(GateRef glue, GateRef obj); 57 58 void InitializeArray(GateRef glue, GateRef count, Variable *result); 59 60 GateRef NewArray(GateRef glue, GateRef count); 61 62 GateRef NewArrayWithHClass(GateRef glue, GateRef hclass, GateRef newArrayLen); 63 64 GateRef CalculatePositionWithLength(GateRef position, GateRef length); 65 66 GateRef DoSort(GateRef glue, GateRef receiver, bool isToSorted, 67 Variable *result, Label *exit, Label *slowPath, GateRef hir = Circuit::NullGate()); 68 69 void FastReverse(GateRef glue, GateRef thisValue, GateRef len, 70 ElementsKind kind, Variable *result, Label *exit); 71 72 using ComparisonType = JSStableArray::ComparisonType; 73 using IndexOfReturnType = JSStableArray::IndexOfReturnType; 74 using IndexOfOptions = JSStableArray::IndexOfOptions; 75 76 enum class StringElementsCondition { 77 MUST_BE_STRING, 78 MAY_BE_HOLE, 79 MAY_BE_ANY, 80 }; 81 82 static IndexOfOptions MakeIndexOfOptions(BuiltinsStubCSigns::ID id, bool resultIsTagged); 83 Variable MakeResultVariableDefaultNotFound(IndexOfOptions options); 84 // Result is int64 which falls in range 85 // [ 0, len] when reversedOrder == false (i.e. indexOf, includes) 86 // or [-1, len - 1] when reversedOrder == true (i.e. lastIndexOf) 87 GateRef MakeFromIndex(GateRef input, GateRef len, bool reversedOrder); 88 // For all the IndexOf* members below: fromIndex is int64; len is int32. 89 GateRef IndexOfTaggedUndefined( 90 GateRef glue, GateRef elements, GateRef fromIndex, GateRef len, IndexOfOptions options); 91 GateRef IndexOfTaggedZero( 92 GateRef glue, GateRef elements, GateRef fromIndex, GateRef len, IndexOfOptions options); 93 GateRef IndexOfTaggedIntElements( 94 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, IndexOfOptions options); 95 GateRef IndexOfTaggedIntTarget( 96 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, IndexOfOptions options); 97 GateRef IndexOfTaggedNumber( 98 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, 99 IndexOfOptions options, bool targetIsAlwaysDouble); 100 GateRef IndexOfStringElements( 101 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, 102 IndexOfOptions options, StringElementsCondition condition); 103 GateRef IndexOfStringTarget( 104 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, IndexOfOptions options); 105 GateRef IndexOfBigInt( 106 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, IndexOfOptions options); 107 // Including true, false, null. 108 GateRef IndexOfObject( 109 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, IndexOfOptions options); 110 GateRef IndexOfBigIntOrObjectElements( 111 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, IndexOfOptions options); 112 GateRef IndexOfBigIntOrObjectTarget( 113 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, IndexOfOptions options); 114 GateRef IndexOfGeneric( 115 GateRef glue, GateRef elements, GateRef target, GateRef fromIndex, GateRef len, IndexOfOptions options); 116 117 private: 118 static constexpr uint32_t MAX_LENGTH_ZERO = 0; 119 static constexpr uint32_t MAX_LENGTH_ONE = 1; 120 static constexpr uint32_t ONE_ARGS = 1; 121 static constexpr uint32_t TWO_ARGS = 2; 122 static constexpr uint32_t THREE_ARGS = 3; 123 static constexpr uint32_t Index0 = 0; 124 static constexpr uint32_t Index1 = 1; 125 static constexpr uint32_t Index2 = 2; 126 struct JsArrayRequirements { 127 bool stable = false; 128 bool defaultConstructor = false; 129 }; 130 131 GateRef IsJsArrayWithLengthLimit(GateRef glue, GateRef object, 132 uint32_t maxLength, JsArrayRequirements requirements); 133 GateRef CreateSpliceDeletedArray(GateRef glue, GateRef thisValue, GateRef actualDeleteCount, GateRef start); 134 void DoReverse(GateRef glue, GateRef fromArray, GateRef toArray, bool holeToUndefined, bool getWithKind, 135 MemoryAttribute mAttr); 136 GateRef DoReverse(GateRef glue, GateRef thisValue, GateRef receiver, GateRef receiverState, Variable *result, 137 Label *exit); 138 void FastToSpliced(GateRef glue, GateRef thisValue, GateRef newArray, GateRef actualStart, 139 GateRef actualDeleteCount, GateRef insertCount, GateRef insertValue); 140 void ToSplicedOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 141 Label *slowPath); 142 void UnshiftOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 143 Label *slowPath); 144 void SliceOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 145 Label *slowPath); 146 GateRef DoSortOptimised(GateRef glue, GateRef receiver, GateRef receiverState, Variable *result, Label *exit, 147 Label *slowPath, GateRef hir); 148 GateRef DoSortOptimisedFast(GateRef glue, GateRef receiver, Variable *result, Label *exit, 149 Label *slowPath, GateRef hir); 150 void ToReversedOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 151 Label *slowPath); 152 153 void FindOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 154 Label *slowPath); 155 156 void FindIndexOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 157 Label *slowPath); 158 159 struct Option { 160 enum MethodKind { 161 MethodFind, 162 MethodFindIndex, 163 MethodSome, 164 MethodEvery, 165 MethodForEach, 166 }; 167 enum CompatibleMode { 168 Standard, 169 Compatible5_0_0, 170 }; 171 MethodKind kind; 172 CompatibleMode mode; 173 }; 174 175 void FindOrFindIndex(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 176 Label *slowPath, const Option option); 177 178 void EveryOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 179 Label *slowPath); 180 181 void ForEachOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 182 Label *slowPath); 183 184 void SomeOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 185 Label *slowPath); 186 187 void VisitAll(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 188 Label *slowPath, const Option option); 189 void ConcatOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 190 Label *slowPath); 191 void DoConcat(GateRef glue, GateRef thisValue, GateRef arg0, Variable *result, Label *exit, GateRef thisLen, 192 GateRef argLen, GateRef sumArrayLen); 193 void FillOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 194 Label *slowPath); 195 void FastFill(GateRef glue, GateRef element, GateRef start, GateRef count, GateRef value, bool needBarrier); 196 void PopOptimised(GateRef glue, GateRef thisValue, 197 GateRef numArgs, Variable *result, Label *exit, Label *slowPath); 198 void ReverseOptimised(GateRef glue, GateRef thisValue, GateRef thisLen, Variable *result, Label *exit); 199 void ShiftOptimised(GateRef glue, GateRef thisValue, 200 GateRef numArgs, Variable *result, Label *exit, Label *slowPath); 201 void IndexOfOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, 202 Label *exit, Label *slowPath, IndexOfOptions options); 203 void CopyWithinOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 204 Label *slowPath); 205 GateRef CalEleKindForNewArrayNoHole(GateRef glue, GateRef thisValue, GateRef thisLen, GateRef actualIndex, 206 GateRef insertVal); 207 void FastArrayWith(GateRef glue, GateRef thisValue, GateRef newArray, GateRef actualIndex, GateRef insertValue, 208 GateRef newArrEleKind); 209 void WithOptimised(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *result, Label *exit, 210 Label *slowPath); 211 212 // Helpers of includes, indexOf and lastIndexOf 213 GateRef MakeFromIndexWithInt(GateRef intValue, GateRef length, bool reversedOrder); 214 GateRef MakeFromIndexWithDouble(GateRef doubleValue, GateRef length, bool reversedOrder); 215 template <class Predicate> 216 GateRef IndexOfElements(GateRef glue, GateRef elements, Predicate predicate, GateRef fromIndex, GateRef len, 217 IndexOfOptions options); 218 GateRef StringEqual(GateRef glue, GateRef left, GateRef right, StringElementsCondition rightCondition); 219 GateRef BigIntEqual(GateRef glue, GateRef left, GateRef right); 220 }; 221 } // namespace panda::ecmascript::kungfu 222 #endif // ECMASCRIPT_COMPILER_BUILTINS_ARRAY_STUB_BUILDER_H 223