1 /* 2 * Copyright (c) 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_BUILTINS_BUILTINS_SHARED_ARRAY_H 17 #define ECMASCRIPT_BUILTINS_BUILTINS_SHARED_ARRAY_H 18 19 #include "ecmascript/base/builtins_base.h" 20 21 // List of functions in Shared Array, excluding the '@@' properties. 22 // V(name, func, length, stubIndex) 23 // where BuiltinsSharedArray::func refers to the native implementation of SharedArray[name]. 24 // kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available. 25 #define BUILTIN_SHARED_ARRAY_FUNCTIONS(V) \ 26 /* SharedArray.from ( items [ , mapfn [ , thisArg ] ] ) */ \ 27 V("from", From, 1, INVALID) \ 28 V("create", Create, 2, INVALID) \ 29 /* SendableArray.isArray ( arg ) */ \ 30 V("isArray", IsArray, 1, INVALID) \ 31 // fixme(hzzhouzebin) Support later. 32 // /* SharedArray.of ( ...items ) */ \ 33 // V("of", Of, 0, INVALID) 34 35 // List of functions in SharedArray.prototype, excluding the constructor and '@@' properties. 36 // V(name, func, length, stubIndex) 37 // where BuiltinsSharedArray::func refers to the native implementation of SharedArray.prototype[name]. 38 #define BUILTIN_SHARED_ARRAY_PROTOTYPE_FUNCTIONS(V) \ 39 /* SharedArray.prototype.at ( index ) */ \ 40 V("at", At, 1, INVALID) \ 41 /* SharedArray.prototype.concat ( ...items ) */ \ 42 V("concat", Concat, 1, INVALID) \ 43 /* SharedArray.prototype.entries ( ) */ \ 44 V("entries", Entries, 0, INVALID) \ 45 /* SharedArray.prototype.fill ( value [ , start [ , end ] ] ) */ \ 46 V("fill", Fill, 1, INVALID) \ 47 /* SharedArray.prototype.filter ( callbackfn [ , thisArg ] ) */ \ 48 V("filter", Filter, 1, INVALID) \ 49 /* SharedArray.prototype.find ( predicate [ , thisArg ] ) */ \ 50 V("find", Find, 1, INVALID) \ 51 /* SharedArray.prototype.findIndex ( predicate [ , thisArg ] ) */ \ 52 V("findIndex", FindIndex, 1, INVALID) \ 53 /* SharedArray.prototype.forEach ( callbackfn [ , thisArg ] ) */ \ 54 V("forEach", ForEach, 1, INVALID) \ 55 /* SharedArray.prototype.includes ( searchElement [ , fromIndex ] ) */ \ 56 V("includes", Includes, 1, INVALID) \ 57 /* SharedArray.prototype.indexOf ( searchElement [ , fromIndex ] ) */ \ 58 V("indexOf", IndexOf, 1, INVALID) \ 59 /* SharedArray.prototype.join ( separator ) */ \ 60 V("join", Join, 1, INVALID) \ 61 /* SharedArray.prototype.keys ( ) */ \ 62 V("keys", Keys, 0, INVALID) \ 63 /* SharedArray.prototype.map ( callbackfn [ , thisArg ] ) */ \ 64 V("map", Map, 1, INVALID) \ 65 /* SharedArray.prototype.pop ( ) */ \ 66 V("pop", Pop, 0, INVALID) \ 67 /* SharedArray.prototype.push ( ...items ) */ \ 68 V("push", Push, 1, INVALID) \ 69 /* SharedArray.prototype.reduce ( callbackfn [ , initialValue ] ) */ \ 70 V("reduce", Reduce, 1, INVALID) \ 71 /* SharedArray.prototype.shift ( ) */ \ 72 V("shift", Shift, 0, INVALID) \ 73 /* SharedArray.prototype.slice ( start, end ) */ \ 74 V("slice", Slice, 2, INVALID) \ 75 /* SharedArray.prototype.sort ( comparefn ) */ \ 76 V("sort", Sort, 1, INVALID) \ 77 /* SharedArray.prototype.toString ( ) */ \ 78 V("toString", ToString, 0, INVALID) \ 79 /* SharedArray.prototype.values ( ) */ \ 80 /* SharedArray.prototype.unshift ( ...items ) */ \ 81 V("unshift", Unshift, 1, INVALID) \ 82 V("values", Values, 0, INVALID) \ 83 V("shrinkTo", ShrinkTo, 0, INVALID) \ 84 V("extendTo", ExtendTo, 0, INVALID) \ 85 /* SharedArray.prototype.splice ( start, deleteCount, ...items ) */ \ 86 V("splice", Splice, 2, INVALID) \ 87 /* SharedArray.prototype.every ( callbackfn [ , thisArg ] ) */ \ 88 V("every", Every, 1, INVALID) \ 89 /* SharedArray.prototype.some ( callbackfn [ , thisArg ] ) */ \ 90 V("some", Some, 1, INVALID) \ 91 /* SendableArray.prototype.lastIndexOf ( searchElement [ , fromIndex ] ) */ \ 92 V("lastIndexOf", LastIndexOf, 1, INVALID) 93 // fixme(hzzhouzebin) Support later. 94 // /* SharedArray.prototype.with ( index, value ) */ \ 95 // V("with", With, 2, INVALID) \ 96 // /* SharedArray.prototype.reduceRight ( callbackfn [ , initialValue ] ) */ \ 97 // V("reduceRight", ReduceRight, 1, INVALID) \ 98 // /* SharedArray.prototype.reverse ( ) */ \ 99 // V("reverse", Reverse, 0, INVALID) \ 100 // /* SharedArray.prototype.copyWithin ( target, start [ , end ] ) */ \ 101 // V("copyWithin", CopyWithin, 2, INVALID) \ 102 // /* SharedArray.prototype.findLast ( predicate [ , thisArg ] ) */ \ 103 // V("findLast", FindLast, 1, INVALID) \ 104 // /* SharedArray.prototype.findLastIndex ( predicate [ , thisArg ] ) */ \ 105 // V("findLastIndex", FindLastIndex, 1, INVALID) \ 106 // /* SharedArray.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ) */ \ 107 // V("toLocaleString", ToLocaleString, 0, INVALID) \ 108 // /* SharedArray.prototype.toReversed ( ) */ \ 109 // V("toReversed", ToReversed, 0, INVALID) \ 110 // /* SharedArray.prototype.toSorted ( comparefn ) */ \ 111 // V("toSorted", ToSorted, 1, INVALID) \ 112 // /* SharedArray.prototype.toSpliced ( start, skipCount, ...items ) */ \ 113 // V("toSpliced", ToSpliced, 2, INVALID) 114 115 namespace panda::ecmascript::builtins { 116 class BuiltinsSharedArray : public base::BuiltinsBase { 117 public: 118 static JSTaggedValue ArrayConstructor(EcmaRuntimeCallInfo *argv); 119 static JSTaggedValue From(EcmaRuntimeCallInfo *argv); 120 static JSTaggedValue Create(EcmaRuntimeCallInfo *argv); 121 static JSTaggedValue IsArray(EcmaRuntimeCallInfo *argv); 122 static JSTaggedValue Species(EcmaRuntimeCallInfo *argv); 123 124 // prototype 125 static JSTaggedValue Concat(EcmaRuntimeCallInfo *argv); 126 static JSTaggedValue Entries(EcmaRuntimeCallInfo *argv); 127 static JSTaggedValue Fill(EcmaRuntimeCallInfo *argv); 128 static JSTaggedValue Filter(EcmaRuntimeCallInfo *argv); 129 static JSTaggedValue Find(EcmaRuntimeCallInfo *argv); 130 static JSTaggedValue FindIndex(EcmaRuntimeCallInfo *argv); 131 static JSTaggedValue ForEach(EcmaRuntimeCallInfo *argv); 132 static JSTaggedValue IndexOf(EcmaRuntimeCallInfo *argv); 133 static JSTaggedValue Join(EcmaRuntimeCallInfo *argv); 134 static JSTaggedValue Keys(EcmaRuntimeCallInfo *argv); 135 static JSTaggedValue Map(EcmaRuntimeCallInfo *argv); 136 static JSTaggedValue Pop(EcmaRuntimeCallInfo *argv); 137 static JSTaggedValue Push(EcmaRuntimeCallInfo *argv); 138 static JSTaggedValue Reduce(EcmaRuntimeCallInfo *argv); 139 static JSTaggedValue Shift(EcmaRuntimeCallInfo *argv); 140 static JSTaggedValue Slice(EcmaRuntimeCallInfo *argv); 141 static JSTaggedValue Splice(EcmaRuntimeCallInfo *argv); 142 static JSTaggedValue Sort(EcmaRuntimeCallInfo *argv); 143 static JSTaggedValue ToString(EcmaRuntimeCallInfo *argv); 144 static JSTaggedValue Unshift(EcmaRuntimeCallInfo *argv); 145 static JSTaggedValue Values(EcmaRuntimeCallInfo *argv); 146 static JSTaggedValue Unscopables(EcmaRuntimeCallInfo *argv); 147 static JSTaggedValue Includes(EcmaRuntimeCallInfo *argv); 148 static JSTaggedValue At(EcmaRuntimeCallInfo *argv); 149 static JSTaggedValue ShrinkTo(EcmaRuntimeCallInfo *argv); 150 static JSTaggedValue ExtendTo(EcmaRuntimeCallInfo *argv); 151 static JSTaggedValue Every(EcmaRuntimeCallInfo *argv); 152 static JSTaggedValue Some(EcmaRuntimeCallInfo *argv); 153 static JSTaggedValue LastIndexOf(EcmaRuntimeCallInfo *argv); 154 155 // Excluding the '@@' internal properties GetSharedArrayFunctions()156 static Span<const base::BuiltinFunctionEntry> GetSharedArrayFunctions() 157 { 158 return Span<const base::BuiltinFunctionEntry>(SENDABLE_ARRAY_FUNCTIONS); 159 } 160 161 // Excluding the constructor and '@@' internal properties. GetSharedArrayPrototypeFunctions()162 static Span<const base::BuiltinFunctionEntry> GetSharedArrayPrototypeFunctions() 163 { 164 return Span<const base::BuiltinFunctionEntry>(SENDABLE_ARRAY_PROTOTYPE_FUNCTIONS); 165 } 166 GetNumPrototypeInlinedProperties()167 static size_t GetNumPrototypeInlinedProperties() 168 { 169 // 4 : 4 More inlined entries in SharedArray.prototype for the following functions/accessors: 170 // (1) 'length' accessor 171 // (2) SharedArray.prototype.constructor, i.e. Array() 172 // (3) SharedArray.prototype[@@iterator]() 173 // (4) SharedArray.prototype[@@unscopables]() 174 return GetSharedArrayPrototypeFunctions().Size() + 4; 175 } 176 static JSTaggedValue ReduceUnStableJSArray(JSThread *thread, JSHandle<JSTaggedValue> &thisHandle, 177 JSHandle<JSTaggedValue> &thisObjVal, int64_t k, int64_t len, JSMutableHandle<JSTaggedValue> &accumulator, 178 JSHandle<JSTaggedValue> &callbackFnHandle); 179 180 static JSTaggedValue FilterUnStableJSArray(JSThread *thread, JSHandle<JSTaggedValue> &thisArgHandle, 181 JSHandle<JSTaggedValue> &thisObjVal, int64_t k, int64_t len, uint32_t toIndex, 182 JSHandle<JSObject> newArrayHandle, JSHandle<JSTaggedValue> &callbackFnHandle); 183 GetPrototypeProperties()184 static Span<const std::pair<std::string_view, bool>> GetPrototypeProperties() 185 { 186 return Span<const std::pair<std::string_view, bool>>(ARRAY_PROTOTYPE_PROPERTIES); 187 } GetFunctionProperties()188 static Span<const std::pair<std::string_view, bool>> GetFunctionProperties() 189 { 190 return Span<const std::pair<std::string_view, bool>>(ARRAY_FUNCTION_PROPERTIES); 191 } 192 private: 193 static JSTaggedValue PopInner(EcmaRuntimeCallInfo *argv, JSHandle<JSTaggedValue> &thisHandle, 194 JSHandle<JSObject> &thisObjHandle); 195 #define BUILTIN_SENDABLE_ARRAY_FUNCTION_ENTRY(name, method, length, id) \ 196 base::BuiltinFunctionEntry::Create(name, BuiltinsSharedArray::method, length, kungfu::BuiltinsStubCSigns::id), 197 198 static constexpr std::array SENDABLE_ARRAY_FUNCTIONS = { 199 BUILTIN_SHARED_ARRAY_FUNCTIONS(BUILTIN_SENDABLE_ARRAY_FUNCTION_ENTRY) 200 }; 201 static constexpr std::array SENDABLE_ARRAY_PROTOTYPE_FUNCTIONS = { 202 BUILTIN_SHARED_ARRAY_PROTOTYPE_FUNCTIONS(BUILTIN_SENDABLE_ARRAY_FUNCTION_ENTRY) 203 }; 204 #undef BUILTIN_SENDABLE_ARRAY_FUNCTION_ENTRY 205 206 static JSTaggedValue IndexOfSlowPath( 207 EcmaRuntimeCallInfo *argv, JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle); 208 209 static JSTaggedValue IndexOfSlowPath( 210 EcmaRuntimeCallInfo *argv, JSThread *thread, const JSHandle<JSTaggedValue> &thisObjVal, 211 int64_t length, int64_t fromIndex); 212 213 static JSTaggedValue LastIndexOfSlowPath(EcmaRuntimeCallInfo *argv, JSThread *thread, 214 const JSHandle<JSTaggedValue> &thisHandle); 215 static JSTaggedValue LastIndexOfSlowPath(EcmaRuntimeCallInfo *argv, JSThread *thread, 216 const JSHandle<JSTaggedValue> &thisObjVal, int64_t fromIndex); 217 218 #define ARRAY_PROPERTIES_PAIR(name, func, length, id) \ 219 std::pair<std::string_view, bool>(name, false), 220 221 static constexpr std::array ARRAY_PROTOTYPE_PROPERTIES = { 222 std::pair<std::string_view, bool>("length", false), 223 std::pair<std::string_view, bool>("constructor", false), 224 BUILTIN_SHARED_ARRAY_PROTOTYPE_FUNCTIONS(ARRAY_PROPERTIES_PAIR) 225 std::pair<std::string_view, bool>("[Symbol.iterator]", false), 226 std::pair<std::string_view, bool>("[Symbol.unscopables]", false) 227 }; 228 static constexpr std::array ARRAY_FUNCTION_PROPERTIES = { 229 std::pair<std::string_view, bool>("length", false), 230 std::pair<std::string_view, bool>("name", false), 231 std::pair<std::string_view, bool>("prototype", false), 232 BUILTIN_SHARED_ARRAY_FUNCTIONS(ARRAY_PROPERTIES_PAIR) 233 std::pair<std::string_view, bool>("[Symbol.species]", true), 234 }; 235 static JSTaggedValue CheckElementForEvery(JSThread *thread, 236 JSHandle<JSTaggedValue> &thisObjVal, 237 JSHandle<JSTaggedValue> &callbackFnHandle, 238 JSHandle<JSTaggedValue> &thisArgHandle, 239 uint32_t &k); 240 #undef ARRAY_PROPERTIES_PAIR 241 }; 242 } // namespace panda::ecmascript::builtins 243 244 #endif // ECMASCRIPT_BUILTINS_BUILTINS_SHARED_ARRAY_H 245