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#include "ecmascript/builtins/builtins_shared_array.h"
17
18#include <cmath>
19
20#include "ecmascript/builtins/builtins_array.h"
21#include "ecmascript/builtins/builtins_string.h"
22#include "ecmascript/interpreter/interpreter.h"
23#include "ecmascript/js_map_iterator.h"
24#include "ecmascript/js_stable_array.h"
25#include "ecmascript/object_fast_operator-inl.h"
26
27namespace panda::ecmascript::builtins {
28namespace {
29    constexpr int32_t COUNT_LENGTH_AND_INIT = 2;
30} // namespace
31using ArrayHelper = base::ArrayHelper;
32using TypedArrayHelper = base::TypedArrayHelper;
33using ContainerError = containers::ContainerError;
34
35// 22.1.1
36JSTaggedValue BuiltinsSharedArray::ArrayConstructor(EcmaRuntimeCallInfo *argv)
37{
38    BUILTINS_ENTRY_DEBUG_LOG();
39    ASSERT(argv);
40    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Constructor);
41    JSThread *thread = argv->GetThread();
42    [[maybe_unused]] EcmaHandleScope handleScope(thread);
43
44    // 1. Let numberOfArgs be the number of arguments passed to this function call.
45    uint32_t argc = argv->GetArgsNumber();
46
47    // 3. If NewTarget is undefined, throw exception
48    JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv);
49    if (newTarget->IsUndefined()) {
50        JSTaggedValue error = containers::ContainerError::BusinessError(
51            thread, containers::ErrorFlag::IS_NULL_ERROR, "The ArkTS Array's constructor cannot be directly invoked.");
52        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
53    }
54
55    // 4. Let proto be GetPrototypeFromConstructor(newTarget, "%ArrayPrototype%").
56    // In NewJSObjectByConstructor(), will get prototype.
57    // 5. ReturnIfAbrupt(proto).
58
59    // 22.1.1.1 Array ( )
60    if (argc == 0) {
61        // 6. Return ArrayCreate(0, proto).
62        return JSSharedArray::ArrayCreate(thread, JSTaggedNumber(0), newTarget).GetTaggedValue();
63    }
64
65    // 22.1.1.3 Array(...items )
66    JSTaggedValue newArray = JSSharedArray::ArrayCreate(thread, JSTaggedNumber(argc), newTarget).GetTaggedValue();
67    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
68    if (!newArray.IsJSSharedArray()) {
69        THROW_TYPE_ERROR_AND_RETURN(thread, "Failed to create array.", JSTaggedValue::Exception());
70    }
71    JSHandle<JSObject> newArrayHandle(thread, newArray);
72    // 8. Let k be 0.
73    // 9. Let items be a zero-origined List containing the argument items in order.
74    // 10. Repeat, while k < numberOfArgs
75    //   a. Let Pk be ToString(k).
76    //   b. Let itemK be items[k].
77    //   c. Let defineStatus be CreateDataProperty(array, Pk, itemK).
78    //   d. Assert: defineStatus is true.
79    //   e. Increase k by 1.
80    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
81    JSMutableHandle<JSTaggedValue> itemK(thread, JSTaggedValue::Undefined());
82    for (uint32_t k = 0; k < argc; k++) {
83        key.Update(JSTaggedValue(k));
84        itemK.Update(GetCallArg(argv, k));
85        if (!itemK->IsSharedType()) {
86            auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
87            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
88        }
89        JSObject::CreateDataProperty(thread, newArrayHandle, key, itemK);
90    }
91    // 11. Assert: the value of array’s length property is numberOfArgs.
92    // 12. Return array.
93    JSSharedArray::Cast(*newArrayHandle)->SetArrayLength(thread, argc);
94    newArrayHandle->GetJSHClass()->SetExtensible(false);
95    return newArrayHandle.GetTaggedValue();
96}
97
98// 22.1.2.1 Array.from ( items [ , mapfn [ , thisArg ] ] )
99// NOLINTNEXTLINE(readability-function-size)
100JSTaggedValue BuiltinsSharedArray::From(EcmaRuntimeCallInfo *argv)
101{
102    ASSERT(argv);
103    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, From);
104    JSThread *thread = argv->GetThread();
105    [[maybe_unused]] EcmaHandleScope handleScope(thread);
106    // 1. Let C be the this value.
107    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
108    // 2. If mapfn is undefined, let mapping be false.
109    bool mapping = false;
110    // 3. else
111    //   a. If IsCallable(mapfn) is false, throw a TypeError exception.
112    //   b. If thisArg was supplied, let T be thisArg; else let T be undefined.
113    //   c. Let mapping be true
114    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, INDEX_TWO);
115    JSHandle<JSTaggedValue> mapfn = GetCallArg(argv, 1);
116    if (!mapfn->IsUndefined()) {
117        if (!mapfn->IsCallable()) {
118            THROW_TYPE_ERROR_AND_RETURN(thread, "the mapfn is not callable.", JSTaggedValue::Exception());
119        }
120        mapping = true;
121    }
122    // 4. Let usingIterator be GetMethod(items, @@iterator).
123    JSHandle<JSTaggedValue> items = GetCallArg(argv, 0);
124    if (items->IsNull()) {
125        THROW_TYPE_ERROR_AND_RETURN(thread, "The items is null.", JSTaggedValue::Exception());
126    }
127    if (!mapping && items->IsString()) {
128        JSHandle<EcmaString> strItems(items);
129        return BuiltinsString::StringToSList(thread, strItems);
130    }
131    // Fast path for TypedArray
132    if (!mapping && (items->IsTypedArray() || items->IsSharedTypedArray())) {
133        auto error = ContainerError::ParamError(thread, "Parameter error.TypedArray not support yet.");
134        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
135    }
136
137    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
138    JSHandle<JSTaggedValue> iteratorSymbol = env->GetIteratorSymbol();
139    JSHandle<JSTaggedValue> usingIterator = JSObject::GetMethod(thread, items, iteratorSymbol);
140    // 5. ReturnIfAbrupt(usingIterator).
141    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
142    // 6. If usingIterator is not undefined, then
143    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
144    if (!usingIterator->IsUndefined()) {
145        // Fast path for MapIterator
146        JSHandle<JSTaggedValue> iterator(thread, JSTaggedValue::Hole());
147        if (!mapping && items->IsJSMapIterator()) {
148            iterator = JSIterator::GetIterator(thread, items, usingIterator);
149            if (iterator->IsJSMapIterator()) {
150                return JSMapIterator::MapIteratorToList(thread, iterator);
151            }
152        }
153
154        //   a. If IsConstructor(C) is true, then
155        //     i. Let A be Construct(C).
156        //   b. Else,
157        //     i. Let A be ArrayCreate(0).
158        //   c. ReturnIfAbrupt(A).
159        JSTaggedValue newArray;
160        if (thisHandle->IsConstructor()) {
161            EcmaRuntimeCallInfo *info =
162                EcmaInterpreter::NewRuntimeCallInfo(thread, thisHandle, undefined, undefined, 0);
163            newArray = JSFunction::Construct(info);
164            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
165        } else {
166            newArray = JSSharedArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue();
167            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
168        }
169        if (!newArray.IsJSSharedArray()) {
170            THROW_TYPE_ERROR_AND_RETURN(thread, "Failed to construct the array.", JSTaggedValue::Exception());
171        }
172        JSHandle<JSObject> newArrayHandle(thread, newArray);
173        //   d. Let iterator be GetIterator(items, usingIterator).
174        if (iterator->IsHole()) {
175            iterator = JSIterator::GetIterator(thread, items, usingIterator);
176            //   e. ReturnIfAbrupt(iterator).
177            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
178        }
179        //   f. Let k be 0.
180        int k = 0;
181        //   g. Repeat
182        JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
183        JSMutableHandle<JSTaggedValue> mapValue(thread, JSTaggedValue::Undefined());
184        while (true) {
185            key.Update(JSTaggedValue(k));
186            //     i. Let Pk be ToString(k).
187            //     ii. Let next be IteratorStep(iterator).
188            JSHandle<JSTaggedValue> next = JSIterator::IteratorStep(thread, iterator);
189            //     iii. ReturnIfAbrupt(next).
190            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
191            //     iv. If next is false, then
192            //       1. Let setStatus be Set(A, "length", k, true).
193            //       2. ReturnIfAbrupt(setStatus).
194            //       3. Return A.
195            if (next->IsFalse()) {
196                JSSharedArray::LengthSetter(thread, newArrayHandle, key, true);
197                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
198                newArrayHandle->GetJSHClass()->SetExtensible(false);
199                return newArrayHandle.GetTaggedValue();
200            }
201            //     v. Let nextValue be IteratorValue(next).
202            JSHandle<JSTaggedValue> nextValue = JSIterator::IteratorValue(thread, next);
203            //     vi. ReturnIfAbrupt(nextValue).
204            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
205            //     vii. If mapping is true, then
206            //       1. Let mappedValue be Call(mapfn, T, «nextValue, k»).
207            //       2. If mappedValue is an abrupt completion, return IteratorClose(iterator, mappedValue).
208            //       3. Let mappedValue be mappedValue.[[value]].
209            //     viii. Else, let mappedValue be nextValue.
210            if (mapping) {
211                const uint32_t argsLength = 2; // 2: «nextValue, k»
212                EcmaRuntimeCallInfo *info =
213                    EcmaInterpreter::NewRuntimeCallInfo(thread, mapfn, thisArgHandle, undefined, argsLength);
214                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
215                info->SetCallArg(nextValue.GetTaggedValue(), key.GetTaggedValue());
216                JSTaggedValue callResult = JSFunction::Call(info);
217                RETURN_VALUE_IF_ABRUPT_COMPLETION(thread,
218                    JSIterator::IteratorClose(thread, iterator, mapValue).GetTaggedValue());
219                mapValue.Update(callResult);
220            } else {
221                mapValue.Update(nextValue.GetTaggedValue());
222            }
223            if (!mapValue->IsSharedType()) {
224                auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
225                THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
226            }
227            //     ix. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, mappedValue).
228            //     x. If defineStatus is an abrupt completion, return IteratorClose(iterator, defineStatus).
229            //     xi. Increase k by 1.
230            JSHandle<JSTaggedValue> defineStatus(thread, JSTaggedValue(JSObject::CreateDataPropertyOrThrow(
231                thread, newArrayHandle, key, mapValue, SCheckMode::SKIP)));
232            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread,
233                JSIterator::IteratorClose(thread, iterator, defineStatus).GetTaggedValue());
234            k++;
235        }
236    }
237    // 7. Assert: items is not an Iterable so assume it is an array-like object.
238    // 8. Let arrayLike be ToObject(items).
239    JSHandle<JSObject> arrayLikeObj = JSTaggedValue::ToObject(thread, items);
240    // 9. ReturnIfAbrupt(arrayLike).
241    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
242    JSHandle<JSTaggedValue> arrayLike(arrayLikeObj);
243    // 10. Let len be ToLength(Get(arrayLike, "length")).
244    int64_t len = ArrayHelper::GetArrayLength(thread, arrayLike);
245    // 11. ReturnIfAbrupt(len).
246    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
247    // 12. If IsConstructor(C) is true, then
248    //   a. Let A be Construct(C, «len»).
249    // 13. Else,
250    //   a. Let A be ArrayCreate(len).
251    // 14. ReturnIfAbrupt(A).
252    JSTaggedValue newArray;
253    if (thisHandle->IsConstructor()) {
254        EcmaRuntimeCallInfo *info =
255            EcmaInterpreter::NewRuntimeCallInfo(thread, thisHandle, undefined, undefined, 1);
256        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
257        info->SetCallArg(JSTaggedValue(len));
258        newArray = JSFunction::Construct(info);
259        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
260    } else {
261        newArray = JSSharedArray::ArrayCreate(thread, JSTaggedNumber(static_cast<double>(len))).GetTaggedValue();
262        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
263    }
264    if (!newArray.IsJSSharedArray()) {
265        THROW_TYPE_ERROR_AND_RETURN(thread, "Failed to construct the array.", JSTaggedValue::Exception());
266    }
267    JSHandle<JSObject> newArrayHandle(thread, newArray);
268    // 15. Let k be 0.
269    // 16. Repeat, while k < len
270    //   a. Let Pk be ToString(k).
271    //   b. Let kValue be Get(arrayLike, Pk).
272    //   d. If mapping is true, then
273    //     i. Let mappedValue be Call(mapfn, T, «kValue, k»).
274    //   e. Else, let mappedValue be kValue.
275    //   f. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, mappedValue).
276    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
277    JSMutableHandle<JSTaggedValue> mapValue(thread, JSTaggedValue::Undefined());
278    int64_t k = 0;
279    while (k < len) {
280        JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, arrayLike, k);
281        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
282        if (mapping) {
283            key.Update(JSTaggedValue(k));
284            const uint32_t argsLength = 2; // 2: «kValue, k»
285            EcmaRuntimeCallInfo *info =
286                EcmaInterpreter::NewRuntimeCallInfo(thread, mapfn, thisArgHandle, undefined, argsLength);
287            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
288            info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue());
289            JSTaggedValue callResult = JSFunction::Call(info);
290            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
291            mapValue.Update(callResult);
292        } else {
293            mapValue.Update(kValue.GetTaggedValue());
294        }
295        if (!mapValue->IsSharedType()) {
296            auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
297            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
298        }
299        JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapValue, SCheckMode::SKIP);
300        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
301        k++;
302    }
303    // 17. Let setStatus be Set(A, "length", len, true).
304    JSHandle<JSTaggedValue> lenHandle(thread, JSTaggedValue(len));
305    JSSharedArray::LengthSetter(thread, newArrayHandle, lenHandle, true);
306    newArrayHandle->GetJSHClass()->SetExtensible(false);
307    // 18. ReturnIfAbrupt(setStatus).
308    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
309    // 19. Return A.
310    return newArrayHandle.GetTaggedValue();
311}
312
313// Array.create ( arrayLength, initialValue )
314JSTaggedValue BuiltinsSharedArray::Create(EcmaRuntimeCallInfo *argv)
315{
316    ASSERT(argv);
317    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, From);
318    JSThread *thread = argv->GetThread();
319    [[maybe_unused]] EcmaHandleScope handleScope(thread);
320    if (argv->GetArgsNumber() < COUNT_LENGTH_AND_INIT) {
321        auto error = ContainerError::ParamError(thread, "Parameter error.Not enough parameters.");
322        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
323    }
324    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
325    JSHandle<JSTaggedValue> arrayLengthValue = GetCallArg(argv, 0);
326    if (!arrayLengthValue->IsNumber()) {
327        auto error = ContainerError::ParamError(thread, "Parameter error.Invalid array length.");
328        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
329    }
330    auto arrayLength = JSTaggedValue::ToUint32(thread, arrayLengthValue);
331    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
332    if (JSTaggedNumber(arrayLengthValue.GetTaggedValue()).GetNumber() != arrayLength) {
333        auto error = ContainerError::ParamError(thread, "Parameter error.Invalid array length.");
334        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
335    }
336    JSHandle<JSTaggedValue> initValue = GetCallArg(argv, 1);
337    if (!initValue->IsSharedType()) {
338        auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
339        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
340    }
341    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
342    JSTaggedValue newArray;
343    if (thisHandle->IsConstructor()) {
344        EcmaRuntimeCallInfo *info =
345            EcmaInterpreter::NewRuntimeCallInfo(thread, thisHandle, undefined, undefined, 0);
346        newArray = JSFunction::Construct(info);
347        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
348    } else {
349        newArray = JSSharedArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue();
350        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
351    }
352    if (!newArray.IsJSSharedArray()) {
353        THROW_TYPE_ERROR_AND_RETURN(thread, "Failed to construct the array.", JSTaggedValue::Exception());
354    }
355    JSHandle<JSObject> newArrayHandle(thread, newArray);
356    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
357    auto elements = factory->NewSOldSpaceTaggedArray(arrayLength, JSTaggedValue::Hole());
358    for (uint32_t k = 0; k < arrayLength; k++) {
359        elements->Set(thread, k, initValue);
360    }
361    newArrayHandle->SetElements(thread, elements);
362    auto len = JSHandle<JSTaggedValue>(thread, JSTaggedValue(arrayLength));
363    JSSharedArray::LengthSetter(thread, newArrayHandle, len, true);
364    newArrayHandle->GetJSHClass()->SetExtensible(false);
365    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
366    // Return A.
367    return newArrayHandle.GetTaggedValue();
368}
369
370// Array.isArray ( arg )
371JSTaggedValue BuiltinsSharedArray::IsArray(EcmaRuntimeCallInfo *argv)
372{
373    ASSERT(argv);
374    JSThread *thread = argv->GetThread();
375    BUILTINS_API_TRACE(thread, SharedArray, IsArray);
376    [[maybe_unused]] EcmaHandleScope handleScope(thread);
377    if (GetCallArg(argv, 0)->IsJSSharedArray()) {
378        return GetTaggedBoolean(true);
379    }
380    return GetTaggedBoolean(false);
381}
382
383// 22.1.2.5 get Array [ @@species ]
384JSTaggedValue BuiltinsSharedArray::Species(EcmaRuntimeCallInfo *argv)
385{
386    ASSERT(argv);
387    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Species);
388    return BuiltinsArray::Species(argv);
389}
390
391// 22.1.3.1 Array.prototype.concat ( ...arguments )
392JSTaggedValue BuiltinsSharedArray::Concat(EcmaRuntimeCallInfo *argv)
393{
394    ASSERT(argv);
395    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Concat);
396    JSThread *thread = argv->GetThread();
397    [[maybe_unused]] EcmaHandleScope handleScope(thread);
398    int argc = static_cast<int>(argv->GetArgsNumber());
399
400    // 1. Let O be ToObject(this value).
401    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
402    if (!thisHandle->IsJSSharedArray()) {
403        auto error = ContainerError::BindError(thread, "The concat method cannot be bound.");
404        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
405    }
406    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
407    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
408    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
409    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
410
411    // 2. Let A be ArraySpeciesCreate(O, 0).
412    uint32_t arrayLen = 0;
413    JSTaggedValue newArray = JSSharedArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(arrayLen));
414    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
415    if (!(newArray.IsECMAObject() || newArray.IsUndefined())) {
416        THROW_TYPE_ERROR_AND_RETURN(thread, "array must be object or undefined.", JSTaggedValue::Exception());
417    }
418    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
419    JSHandle<JSObject> newArrayHandle(thread, newArray);
420
421    // 3. Let n be 0.
422    int64_t n = 0;
423    JSMutableHandle<JSTaggedValue> ele(thread, JSTaggedValue::Undefined());
424    JSMutableHandle<JSTaggedValue> fromKey(thread, JSTaggedValue::Undefined());
425    JSMutableHandle<JSTaggedValue> toKey(thread, JSTaggedValue::Undefined());
426    // 4. Prepend O to items.
427    // 5. For each element E of items, do
428    for (int i = -1; i < argc; i++) {
429        if (i < 0) {
430            ele.Update(thisObjHandle.GetTaggedValue());
431        } else {
432            ele.Update(GetCallArg(argv, i));
433        }
434        if (!ele->IsSharedType()) {
435            auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
436            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
437        }
438        // a. Let spreadable be ? IsConcatSpreadable(E).
439        bool isSpreadable = ArrayHelper::IsConcatSpreadable(thread, ele);
440        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
441        // b. If spreadable is true, then
442        if (isSpreadable) {
443            // i. Let k be 0.
444            // ii. Let len be ? LengthOfArrayLike(E).
445            // iii. If n + len > 253 - 1, throw a TypeError exception.
446            int64_t len = ArrayHelper::GetArrayLength(thread, ele);
447            int64_t k = 0;
448            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
449            if (n + len > base::MAX_SAFE_INTEGER) {
450                THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
451            }
452
453            if (ele->IsStableJSArray(thread)) {
454                JSStableArray::Concat(thread, newArrayHandle, JSHandle<JSObject>::Cast(ele), k, n);
455                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
456            }
457            // iv. Repeat, while k < len,
458            while (k < len) {
459                // 1. Let P be ToString(k).
460                // 2. Let exists be HasProperty(E, P).
461                // 3. If exists is true, then
462                fromKey.Update(JSTaggedValue::ToString(thread, JSTaggedValue(k)));
463                toKey.Update(JSTaggedValue(n));
464                bool exists = JSTaggedValue::HasProperty(thread, ele, fromKey);
465                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
466                if (exists) {
467                    // a. Let subElement be Get(E, P).
468                    JSHandle<JSTaggedValue> fromValHandle =
469                        JSSharedArray::FastGetPropertyByValue(thread, ele, fromKey);
470                    if (!fromValHandle->IsSharedType()) {
471                        auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
472                        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
473                    }
474                    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
475                    // b. Perform ? CreateDataPropertyOrThrow(A, ! ToString(�(n)), subElement).
476                    JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toKey, fromValHandle, SCheckMode::SKIP);
477                    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
478                }
479                // 4. Set n to n + 1.
480                // 5. Set k to k + 1.
481                n++;
482                k++;
483            }
484        //c. Else
485        } else {
486            // ii. If n ≥ 253 - 1, throw a TypeError exception.
487            if (n >= base::MAX_SAFE_INTEGER) {
488                THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
489            }
490            // iii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(�(n)), E).
491            // iv. Set n to n + 1.
492            JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, n, ele, SCheckMode::SKIP);
493            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
494            n++;
495        }
496    }
497    // 6. Perform ? Set(A, "length", �(n), true).
498    JSHandle<JSTaggedValue> lenHandle(thread, JSTaggedValue(n));
499    JSSharedArray::LengthSetter(thread, newArrayHandle, lenHandle, true);
500    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
501
502    // 7. Return A.
503    return newArrayHandle.GetTaggedValue();
504}
505
506// 22.1.3.4 Array.prototype.entries ( )
507JSTaggedValue BuiltinsSharedArray::Entries(EcmaRuntimeCallInfo *argv)
508{
509    ASSERT(argv);
510    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Entries);
511    JSThread *thread = argv->GetThread();
512    [[maybe_unused]] EcmaHandleScope handleScope(thread);
513    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
514    if (!thisHandle->IsJSSharedArray()) {
515        auto error = ContainerError::BindError(thread, "The entries method cannot be bound.");
516        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
517    }
518    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
519    // 1. Let O be ToObject(this value).
520    // 2. ReturnIfAbrupt(O).
521    JSHandle<JSObject> self = JSTaggedValue::ToObject(thread, GetThis(argv));
522    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
523    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
524    // 3. Return CreateArrayIterator(O, "key+value").
525    JSHandle<JSSharedArrayIterator> iter(factory->NewJSSharedArrayIterator(self, IterationKind::KEY_AND_VALUE));
526    return iter.GetTaggedValue();
527}
528JSTaggedValue BuiltinsSharedArray::CheckElementForEvery(JSThread *thread,
529                                                        JSHandle<JSTaggedValue> &thisObjVal,
530                                                        JSHandle<JSTaggedValue> &callbackFnHandle,
531                                                        JSHandle<JSTaggedValue> &thisArgHandle,
532                                                        uint32_t &k)
533{
534    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
535    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
536    const uint32_t argsLength = 3; // 3: «kValue, k, O»
537    JSTaggedValue callResult = GetTaggedBoolean(true);
538    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
539    // Let len be ToLength(Get(O, "length")).
540    uint64_t len = static_cast<uint64_t>(ArrayHelper::GetArrayLength(thread, thisObjVal));
541    // ReturnIfAbrupt(len).
542    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
543    while (k < len) {
544        bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
545        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
546        if (exists) {
547            JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
548            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
549            key.Update(JSTaggedValue(k));
550            EcmaRuntimeCallInfo *info =
551                EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
552            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
553            info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
554            callResult = JSFunction::Call(info);
555            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
556            if (!callResult.ToBoolean()) {
557                return GetTaggedBoolean(false);
558            }
559        }
560        k++;
561        thread->CheckSafepointIfSuspended();
562    }
563    return GetTaggedBoolean(true);
564}
565
566// Array.prototype.every ( callbackfn [ , thisArg] )
567JSTaggedValue BuiltinsSharedArray::Every(EcmaRuntimeCallInfo *argv)
568{
569    ASSERT(argv);
570    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Every);
571    JSThread *thread = argv->GetThread();
572    [[maybe_unused]] EcmaHandleScope handleScope(thread);
573
574    // 1. Let O be ToObject(this value).
575    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
576    if (!thisHandle->IsJSSharedArray()) {
577        auto error = ContainerError::BindError(thread, "The every method cannot be bound.");
578        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
579    }
580    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
581    // 2. ReturnIfAbrupt(O).
582    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
583    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
584    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
585
586    // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
587    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
588    if (!callbackFnHandle->IsCallable()) {
589        THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception());
590    }
591
592    // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
593    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
594
595    // 5. Let k be 0.
596    // 6. Repeat, while k < len
597    //   a. Let Pk be ToString(k).
598    //   b. Let kPresent be HasProperty(O, Pk).
599    //   c. ReturnIfAbrupt(kPresent).
600    //   d. If kPresent is true, then
601    //     i. Let kValue be Get(O, Pk).
602    //     ii. ReturnIfAbrupt(kValue).
603    //     iii. Let testResult be ToBoolean(Call(callbackfn, T, «kValue, k, O»)).
604    //     iv. ReturnIfAbrupt(testResult).
605    //     v. If testResult is false, return false.
606    //   e. Increase k by 1.
607    uint32_t k = 0;
608    JSTaggedValue callResult = GetTaggedBoolean(true);
609    if (thisObjVal->IsStableJSArray(thread)) {
610        callResult = JSStableArray::HandleEveryOfStable(thread, thisObjHandle, callbackFnHandle, thisArgHandle, k);
611        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
612        if (!callResult.ToBoolean()) {
613            return GetTaggedBoolean(false);
614        }
615    }
616    return CheckElementForEvery(thread, thisObjVal, callbackFnHandle, thisArgHandle, k);
617}
618
619// Array.prototype.some ( callbackfn [ , thisArg ] )
620JSTaggedValue BuiltinsSharedArray::Some(EcmaRuntimeCallInfo *argv)
621{
622    ASSERT(argv);
623    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Some);
624    JSThread *thread = argv->GetThread();
625    [[maybe_unused]] EcmaHandleScope handleScope(thread);
626
627    // 1. Let O be ToObject(this value).
628    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
629    if (!thisHandle->IsJSSharedArray()) {
630        auto error = ContainerError::BindError(thread, "The some method cannot be bound.");
631        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
632    }
633    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
634    // 2. ReturnIfAbrupt(O).
635    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
636    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
637
638    // 3. Let len be ToLength(Get(O, "length")).
639    int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
640    // 4. ReturnIfAbrupt(len).
641    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
642
643    // 5. If IsCallable(callbackfn) is false, throw a TypeError exception.
644    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
645    if (!callbackFnHandle->IsCallable()) {
646        THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception());
647    }
648
649    // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
650    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
651
652    // 7. Let k be 0.
653    // 8. Repeat, while k < len
654    //   a. Let Pk be ToString(k).
655    //   b. Let kPresent be HasProperty(O, Pk).
656    //   c. ReturnIfAbrupt(kPresent).
657    //   d. If kPresent is true, then
658    //     i. Let kValue be Get(O, Pk).
659    //     ii. ReturnIfAbrupt(kValue).
660    //     iii. Let testResult be ToBoolean(Call(callbackfn, T, «kValue, k, and O»)).
661    //     iv. ReturnIfAbrupt(testResult).
662    //     v. If testResult is true, return true.
663    //   e. Increase k by 1.
664    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
665    JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
666    uint32_t k = 0;
667    JSTaggedValue callResult = GetTaggedBoolean(false);
668    if (thisObjVal->IsStableJSArray(thread)) {
669        callResult = JSStableArray::HandleSomeOfStable(thread, thisObjHandle, callbackFnHandle, thisArgHandle, k);
670        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
671        if (callResult.ToBoolean()) {
672            return GetTaggedBoolean(true);
673        }
674    }
675    while (k < len) {
676        bool exists = (thisHandle->IsTypedArray() || thisHandle->IsSharedTypedArray() ||
677            JSTaggedValue::HasProperty(thread, thisObjVal, k));
678        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
679        if (exists) {
680            key.Update(JSTaggedValue(k));
681            kValue.Update(JSArray::FastGetPropertyByValue(thread, thisObjVal, key));
682            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
683            const uint32_t argsLength = 3; // 3: «kValue, k, O»
684            JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
685            EcmaRuntimeCallInfo *info =
686                EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
687            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
688            info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
689            callResult = JSFunction::Call(info);
690            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
691            if (callResult.ToBoolean()) {
692                return GetTaggedBoolean(true);
693            }
694        }
695        k++;
696        thread->CheckSafepointIfSuspended();
697    }
698
699    // 9. Return false.
700    return GetTaggedBoolean(false);
701}
702
703// 22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
704JSTaggedValue BuiltinsSharedArray::Fill(EcmaRuntimeCallInfo *argv)
705{
706    ASSERT(argv);
707    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Fill);
708    JSThread *thread = argv->GetThread();
709    [[maybe_unused]] EcmaHandleScope handleScope(thread);
710
711    // 1. Let O be ToObject(this value).
712    JSHandle<JSTaggedValue> thisObjVal = GetThis(argv);
713    if (!thisObjVal->IsJSSharedArray()) {
714        auto error = ContainerError::BindError(thread, "The fill method cannot be bound.");
715        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
716    }
717    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisObjVal);
718    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisObjVal);
719    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
720    if (thisObjVal->IsJSSharedArray()) {
721        bool isDictionary = thisObjHandle->GetJSHClass()->IsDictionaryElement();
722        if (isDictionary) {
723            uint32_t length = JSSharedArray::Cast(*thisObjHandle)->GetLength();
724            uint32_t size = thisObjHandle->GetNumberOfElements();
725            if (length - size > JSObject::MAX_GAP) {
726                JSObject::TryOptimizeAsFastElements(thread, thisObjHandle);
727            }
728        }
729    }
730
731    // 2. ReturnIfAbrupt(O).
732    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
733
734    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
735    if (!value->IsSharedType()) {
736        auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
737        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
738    }
739    if (thisObjVal->IsTypedArray() || thisObjVal->IsSharedTypedArray()) {
740        ContentType contentType = JSHandle<JSTypedArray>::Cast(thisObjVal)->GetContentType();
741        if (contentType == ContentType::BigInt) {
742            value = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, value));
743        } else {
744            value = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToNumber(thread, value));
745        }
746        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
747    }
748
749    // 3. Let len be ToLength(Get(O, "length")).
750    int64_t len = ArrayHelper::GetLength(thread, thisObjVal);
751    // 4. ReturnIfAbrupt(len).
752    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
753
754    // 5. Let relativeStart be ToInteger(start).
755    JSHandle<JSTaggedValue> startArg = GetCallArg(argv, 1);
756    JSTaggedNumber argStartTemp = JSTaggedValue::ToInteger(thread, startArg);
757    // 6. ReturnIfAbrupt(relativeStart).
758    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
759    double argStart = argStartTemp.GetNumber();
760    // 7. If relativeStart < 0, let k be max((len + relativeStart),0); else let k be min(relativeStart, len).
761    int64_t start = 0;
762    if (argStart < 0) {
763        double tempStart = argStart + len;
764        start = tempStart > 0 ? tempStart : 0;
765    } else {
766        start = argStart < len ? argStart : len;
767    }
768
769    // 8. If end is undefined, let relativeEnd be len; else let relativeEnd be ToInteger(end).
770    double argEnd = len;
771    JSHandle<JSTaggedValue> endArg = GetCallArg(argv, INDEX_TWO);
772    if (!endArg->IsUndefined()) {
773        JSTaggedNumber argEndTemp = JSTaggedValue::ToInteger(thread, endArg);
774        // 9. ReturnIfAbrupt(relativeEnd).
775        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
776        argEnd = argEndTemp.GetNumber();
777    }
778
779    // 10. If relativeEnd < 0, let final be max((len + relativeEnd),0); else let final be min(relativeEnd, len).
780    int64_t end = len;
781    if (argEnd < 0) {
782        double tempEnd = argEnd + len;
783        end = tempEnd > 0 ? tempEnd : 0;
784    } else {
785        end = argEnd < len ? argEnd : len;
786    }
787    // 11. Repeat, while k < final
788    //   a. Let Pk be ToString(k).
789    //   b. Let setStatus be Set(O, Pk, value, true).
790    //   c. ReturnIfAbrupt(setStatus).
791    //   d. Increase k by 1.
792
793    if (thisObjVal->IsStableJSArray(thread) && !startArg->IsJSObject() && !endArg->IsJSObject()) {
794        auto opResult = JSStableArray::Fill(thread, thisObjHandle, value, start, end, len);
795        return opResult;
796    }
797
798    if (thisObjVal->IsTypedArray() || thisObjVal->IsSharedTypedArray()) {
799        bool result = JSTypedArray::FastTypedArrayFill(thread, thisObjVal, value, start, end);
800        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
801        if (result) {
802            return thisObjHandle.GetTaggedValue();
803        }
804    }
805
806    int64_t k = start;
807    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
808    while (k < end) {
809        key.Update(JSTaggedValue(k));
810        JSSharedArray::FastSetPropertyByValue(thread, thisObjVal, key, value);
811        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
812        k++;
813    }
814
815    // 12. Return O.
816    return thisObjHandle.GetTaggedValue();
817}
818
819JSTaggedValue BuiltinsSharedArray::FilterUnStableJSArray(JSThread *thread, JSHandle<JSTaggedValue> &thisArgHandle,
820    JSHandle<JSTaggedValue> &thisObjVal, int64_t k, int64_t len, uint32_t toIndex, JSHandle<JSObject> newArrayHandle,
821    JSHandle<JSTaggedValue> &callbackFnHandle)
822{
823    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
824    const uint32_t argsLength = 3; // 3: «kValue, k, O»
825    JSTaggedValue callResult = GetTaggedBoolean(true);
826    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
827    JSMutableHandle<JSTaggedValue> toIndexHandle(thread, JSTaggedValue::Undefined());
828    while (k < len) {
829        bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
830        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
831        if (exists) {
832            JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
833            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
834            key.Update(JSTaggedValue(k));
835            EcmaRuntimeCallInfo *info =
836                EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
837            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
838            info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
839            callResult = JSFunction::Call(info);
840            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
841            if (callResult.ToBoolean()) {
842                toIndexHandle.Update(JSTaggedValue(toIndex));
843                JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toIndexHandle, kValue, SCheckMode::SKIP);
844                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
845                toIndex++;
846            }
847        }
848        k++;
849    }
850    return newArrayHandle.GetTaggedValue();
851}
852
853// 22.1.3.7 Array.prototype.filter ( callbackfn [ , thisArg ] )
854JSTaggedValue BuiltinsSharedArray::Filter(EcmaRuntimeCallInfo *argv)
855{
856    ASSERT(argv);
857    JSThread *thread = argv->GetThread();
858    BUILTINS_API_TRACE(thread, SharedArray, Filter);
859    [[maybe_unused]] EcmaHandleScope handleScope(thread);
860
861    // 1. Let O be ToObject(this value).
862    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
863    if (!thisHandle->IsJSSharedArray()) {
864        auto error = ContainerError::BindError(thread, "The filter method cannot be bound.");
865        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
866    }
867    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
868    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
869    // 2. ReturnIfAbrupt(O).
870    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
871    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
872
873    // 3. Let len be ToLength(Get(O, "length")).
874    uint64_t len = static_cast<uint64_t>(ArrayHelper::GetArrayLength(thread, thisObjVal));
875    // 4. ReturnIfAbrupt(len).
876    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
877
878    // 5. If IsCallable(callbackfn) is false, throw a TypeError exception.
879    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
880    if (!callbackFnHandle->IsCallable()) {
881        THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception());
882    }
883
884    // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
885    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
886
887    // 7. Let A be ArraySpeciesCreate(O, 0).
888    int32_t arrayLen = 0;
889    JSTaggedValue newArray = JSSharedArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(arrayLen));
890    // 8. ReturnIfAbrupt(A).
891    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
892    JSHandle<JSObject> newArrayHandle(thread, newArray);
893
894    // 9. Let k be 0.
895    // 10. Let to be 0.
896    // 11. Repeat, while k < len
897    //   a. Let Pk be ToString(k).
898    //   b. Let kPresent be HasProperty(O, Pk).
899    //   c. ReturnIfAbrupt(kPresent).
900    //   d. If kPresent is true, then
901    //     i. Let kValue be Get(O, Pk).
902    //     ii. ReturnIfAbrupt(kValue).
903    //     iii. Let selected be ToBoolean(Call(callbackfn, T, «kValue, k, O»)).
904    //     iv. ReturnIfAbrupt(selected).
905    //     v. If selected is true, then
906    //       1. Let status be CreateDataPropertyOrThrow (A, ToString(to), kValue).
907    //       2. ReturnIfAbrupt(status).
908    //       3. Increase to by 1.
909    //   e. Increase k by 1.
910    uint32_t toIndex = 0;
911    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
912    JSMutableHandle<JSTaggedValue> toIndexHandle(thread, JSTaggedValue::Undefined());
913    uint32_t k = 0;
914    if (thisObjVal->IsStableJSArray(thread)) {
915        JSStableArray::Filter(newArrayHandle, thisObjHandle, argv, k, toIndex);
916        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
917    }
918    auto opResult =
919        FilterUnStableJSArray(thread, thisArgHandle, thisObjVal, k, len, toIndex, newArrayHandle, callbackFnHandle);
920
921    return opResult;
922}
923
924// 22.1.3.8 Array.prototype.find ( predicate [ , thisArg ] )
925JSTaggedValue BuiltinsSharedArray::Find(EcmaRuntimeCallInfo *argv)
926{
927    ASSERT(argv);
928    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Find);
929    JSThread *thread = argv->GetThread();
930    [[maybe_unused]] EcmaHandleScope handleScope(thread);
931
932    // 1. Let O be ToObject(this value).
933    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
934    if (!thisHandle->IsJSSharedArray()) {
935        auto error = ContainerError::BindError(thread, "The find method cannot be bound.");
936        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
937    }
938    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
939    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
940    // 2. ReturnIfAbrupt(O).
941    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
942    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
943
944    // 3. Let len be ToLength(Get(O, "length")).
945    int64_t len = ArrayHelper::GetLength(thread, thisObjVal);
946    // 4. ReturnIfAbrupt(len).
947    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
948
949    // 5. If IsCallable(predicate) is false, throw a TypeError exception.
950    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
951    if (!callbackFnHandle->IsCallable()) {
952        THROW_TYPE_ERROR_AND_RETURN(thread, "the predicate is not callable.", JSTaggedValue::Exception());
953    }
954
955    // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
956    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
957
958    // 7. Let k be 0.
959    // 8. Repeat, while k < len
960    //   a. Let Pk be ToString(k).
961    //   b. Let kValue be Get(O, Pk).
962    //   c. ReturnIfAbrupt(kValue).
963    //   d. Let testResult be ToBoolean(Call(predicate, T, «kValue, k, O»)).
964    //   e. ReturnIfAbrupt(testResult).
965    //   f. If testResult is true, return kValue.
966    //   g. Increase k by 1.
967    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
968    int64_t k = 0;
969    while (k < len) {
970        JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
971        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
972        key.Update(JSTaggedValue(k));
973        const uint32_t argsLength = 3; // 3: «kValue, k, O»
974        JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
975        EcmaRuntimeCallInfo *info =
976            EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
977        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
978        info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
979        JSTaggedValue callResult = JSFunction::Call(info);
980        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
981        if (callResult.ToBoolean()) {
982            return kValue.GetTaggedValue();
983        }
984        k++;
985    }
986
987    // 9. Return undefined.
988    return JSTaggedValue::Undefined();
989}
990
991// 22.1.3.9 Array.prototype.findIndex ( predicate [ , thisArg ] )
992JSTaggedValue BuiltinsSharedArray::FindIndex(EcmaRuntimeCallInfo *argv)
993{
994    ASSERT(argv);
995    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, FindIndex);
996    JSThread *thread = argv->GetThread();
997    [[maybe_unused]] EcmaHandleScope handleScope(thread);
998
999    // 1. Let O be ToObject(this value).
1000    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1001    if (!thisHandle->IsJSSharedArray()) {
1002        auto error = ContainerError::BindError(thread, "The findIndex method cannot be bound.");
1003        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1004    }
1005    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1006    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
1007    // 2. ReturnIfAbrupt(O).
1008    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1009    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1010
1011    // 3. Let len be ToLength(Get(O, "length")).
1012    uint64_t len = static_cast<uint64_t>(ArrayHelper::GetLength(thread, thisObjVal));
1013    // 4. ReturnIfAbrupt(len).
1014    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1015
1016    // 5. If IsCallable(predicate) is false, throw a TypeError exception.
1017    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
1018    if (!callbackFnHandle->IsCallable()) {
1019        THROW_TYPE_ERROR_AND_RETURN(thread, "the predicate is not callable.", JSTaggedValue::Exception());
1020    }
1021
1022    // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
1023    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
1024
1025    // 7. Let k be 0.
1026    // 8. Repeat, while k < len
1027    //   a. Let Pk be ToString(k).
1028    //   b. Let kValue be Get(O, Pk).
1029    //   c. ReturnIfAbrupt(kValue).
1030    //   d. Let testResult be ToBoolean(Call(predicate, T, «kValue, k, O»)).
1031    //   e. ReturnIfAbrupt(testResult).
1032    //   f. If testResult is true, return k.
1033    //   g. Increase k by 1.
1034    uint32_t k = 0;
1035    JSTaggedValue callResult = GetTaggedBoolean(true);
1036    if (thisObjVal->IsStableJSArray(thread)) {
1037        callResult = JSStableArray::HandleFindIndexOfStable(thread, thisObjHandle, callbackFnHandle, thisArgHandle, k);
1038        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1039        if (callResult.ToBoolean()) {
1040            return GetTaggedDouble(k);
1041        }
1042    }
1043    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1044    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1045    const uint32_t argsLength = 3; // 3: «kValue, k, O»
1046    while (k < len) {
1047        JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
1048        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1049        key.Update(JSTaggedValue(k));
1050        EcmaRuntimeCallInfo *info =
1051            EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
1052        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1053        info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
1054        callResult = JSFunction::Call(info);
1055        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1056        if (callResult.ToBoolean()) {
1057            return GetTaggedDouble(k);
1058        }
1059        k++;
1060    }
1061
1062    // 9. Return -1.
1063    return GetTaggedDouble(-1);
1064}
1065
1066// 22.1.3.10 Array.prototype.forEach ( callbackfn [ , thisArg ] )
1067JSTaggedValue BuiltinsSharedArray::ForEach(EcmaRuntimeCallInfo *argv)
1068{
1069    ASSERT(argv);
1070    JSThread *thread = argv->GetThread();
1071    BUILTINS_API_TRACE(thread, SharedArray, ForEach);
1072    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1073
1074    // 1. Let O be ToObject(this value).
1075    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1076    if (!thisHandle->IsJSSharedArray()) {
1077        auto error = ContainerError::BindError(thread, "The forEach method cannot be bound.");
1078        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1079    }
1080    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1081    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
1082    // 2. ReturnIfAbrupt(O).
1083    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1084    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1085
1086    // 3. Let len be ToLength(Get(O, "length")).
1087    uint64_t len = static_cast<uint64_t>(ArrayHelper::GetArrayLength(thread, thisObjVal));
1088    // 4. ReturnIfAbrupt(len).
1089    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1090
1091    // 5. If IsCallable(callbackfn) is false, throw a TypeError exception.
1092    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
1093    if (!callbackFnHandle->IsCallable()) {
1094        THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception());
1095    }
1096
1097    // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
1098    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
1099
1100    // 7. Let k be 0.
1101    // 8. Repeat, while k < len
1102    //   a. Let Pk be ToString(k).
1103    //   b. Let kPresent be HasProperty(O, Pk).
1104    //   c. ReturnIfAbrupt(kPresent).
1105    //   d. If kPresent is true, then
1106    //     i. Let kValue be Get(O, Pk).
1107    //     ii. ReturnIfAbrupt(kValue).
1108    //     iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»).
1109    //     iv. ReturnIfAbrupt(funcResult).
1110    //   e. Increase k by 1.
1111    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1112    uint32_t k = 0;
1113    if (thisObjVal->IsStableJSArray(thread)) {
1114        JSStableArray::HandleforEachOfStable(thread, thisObjHandle, callbackFnHandle, thisArgHandle, len, k);
1115        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1116    }
1117    const uint32_t argsLength = 3; // 3: «kValue, k, O»
1118    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1119    while (k < len) {
1120        bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
1121        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1122        if (exists) {
1123            JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
1124            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1125            key.Update(JSTaggedValue(k));
1126            EcmaRuntimeCallInfo *info =
1127                EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
1128            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1129            info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
1130            JSTaggedValue funcResult = JSFunction::Call(info);
1131            RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
1132        }
1133        k++;
1134    }
1135
1136    // 9. Return undefined.
1137    return JSTaggedValue::Undefined();
1138}
1139
1140JSTaggedValue BuiltinsSharedArray::IndexOfSlowPath(
1141    EcmaRuntimeCallInfo *argv, JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle)
1142{
1143    // 1. Let O be ToObject(this value).
1144    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1145    // 2. ReturnIfAbrupt(O).
1146    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1147    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1148    // 3. Let len be ToLength(Get(O, "length")).
1149    int64_t length = ArrayHelper::GetLength(thread, thisObjVal);
1150    // 4. ReturnIfAbrupt(len).
1151    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1152    // 5. If len is 0, return −1.
1153    if (length == 0) {
1154        return JSTaggedValue(-1);
1155    }
1156    // 6. If argument fromIndex was passed let n be ToInteger(fromIndex); else let n be 0.
1157    int64_t fromIndex = ArrayHelper::GetStartIndexFromArgs(thread, argv, 1, length);
1158    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1159    return IndexOfSlowPath(argv, thread, thisObjVal, length, fromIndex);
1160}
1161
1162JSTaggedValue BuiltinsSharedArray::IndexOfSlowPath(
1163    EcmaRuntimeCallInfo *argv, JSThread *thread, const JSHandle<JSTaggedValue> &thisObjVal,
1164    int64_t length, int64_t fromIndex)
1165{
1166    if (fromIndex >= length) {
1167        return JSTaggedValue(-1);
1168    }
1169    JSMutableHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue::Undefined());
1170    JSHandle<JSTaggedValue> target = GetCallArg(argv, 0);
1171    // 11. Repeat, while k < len
1172    for (int64_t curIndex = fromIndex; curIndex < length; ++curIndex) {
1173        keyHandle.Update(JSTaggedValue(curIndex));
1174        bool found = ArrayHelper::ElementIsStrictEqualTo(thread, thisObjVal, keyHandle, target);
1175        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1176        if (UNLIKELY(found)) {
1177            return JSTaggedValue(curIndex);
1178        }
1179    }
1180    // 12. Return -1.
1181    return JSTaggedValue(-1);
1182}
1183
1184// 22.1.3.11 Array.prototype.indexOf ( searchElement [ , fromIndex ] )
1185JSTaggedValue BuiltinsSharedArray::IndexOf(EcmaRuntimeCallInfo *argv)
1186{
1187    ASSERT(argv);
1188    JSThread *thread = argv->GetThread();
1189    BUILTINS_API_TRACE(thread, SharedArray, IndexOf);
1190    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1191
1192    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1193    if (!thisHandle->IsJSSharedArray()) {
1194        auto error = ContainerError::BindError(thread, "The indexOf method cannot be bound.");
1195        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1196    }
1197    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
1198    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1199
1200    JSTaggedValue opResult;
1201    if (thisHandle->IsStableJSArray(thread)) {
1202        auto error = ContainerError::BindError(thread, "The indexOf method not support stable array.");
1203        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1204    } else {
1205        opResult = IndexOfSlowPath(argv, thread, thisHandle);
1206    }
1207
1208    return opResult;
1209}
1210
1211// 22.1.3.12 Array.prototype.join (separator)
1212JSTaggedValue BuiltinsSharedArray::Join(EcmaRuntimeCallInfo *argv)
1213{
1214    ASSERT(argv);
1215    JSThread *thread = argv->GetThread();
1216    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Join);
1217    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1218    if (!thisHandle->IsJSSharedArray()) {
1219        auto error = ContainerError::BindError(thread, "The join method cannot be bound.");
1220        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1221    }
1222    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
1223    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1224    auto opResult = BuiltinsArray::Join(argv);
1225    return opResult;
1226}
1227
1228// 22.1.3.13 Array.prototype.keys ( )
1229JSTaggedValue BuiltinsSharedArray::Keys(EcmaRuntimeCallInfo *argv)
1230{
1231    ASSERT(argv);
1232    JSThread *thread = argv->GetThread();
1233    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Keys);
1234    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1235    if (!thisHandle->IsJSSharedArray()) {
1236        auto error = ContainerError::BindError(thread, "The keys method cannot be bound.");
1237        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1238    }
1239    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
1240    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1241    auto opResult = BuiltinsArray::Keys(argv);
1242    return opResult;
1243}
1244
1245// 22.1.3.15 Array.prototype.map ( callbackfn [ , thisArg ] )
1246JSTaggedValue BuiltinsSharedArray::Map(EcmaRuntimeCallInfo *argv)
1247{
1248    ASSERT(argv);
1249    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Map);
1250    JSThread *thread = argv->GetThread();
1251    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1252
1253    // 1. Let O be ToObject(this value).
1254    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1255    if (!thisHandle->IsJSSharedArray()) {
1256        auto error = ContainerError::BindError(thread, "The map method cannot be bound.");
1257        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1258    }
1259    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1260    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
1261    // 2. ReturnIfAbrupt(O).
1262    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1263    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1264
1265    // 3. Let len be ToLength(Get(O, "length")).
1266    int64_t rawLen = ArrayHelper::GetArrayLength(thread, thisObjVal);
1267    // 4. ReturnIfAbrupt(len).
1268    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1269
1270    // 5. If IsCallable(callbackfn) is false, throw a TypeError exception.
1271    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
1272    if (!callbackFnHandle->IsCallable()) {
1273        THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception());
1274    }
1275
1276    // 6. If thisArg was supplied, let T be thisArg; else let T be undefined.
1277    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
1278
1279    // 7. Let A be ArraySpeciesCreate(O, len).
1280    JSTaggedValue newArray =
1281        JSSharedArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(static_cast<double>(rawLen)));
1282    // 8. ReturnIfAbrupt(A).
1283    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1284    if (!newArray.IsECMAObject()) {
1285        THROW_TYPE_ERROR_AND_RETURN(thread, "Failed to create Object.", JSTaggedValue::Exception());
1286    }
1287    JSHandle<JSObject> newArrayHandle(thread, newArray);
1288
1289    // 9. Let k be 0.
1290    // 10. Repeat, while k < len
1291    //   a. Let Pk be ToString(k).
1292    //   b. Let kPresent be HasProperty(O, Pk).
1293    //   c. ReturnIfAbrupt(kPresent).
1294    //   d. If kPresent is true, then
1295    //     i. Let kValue be Get(O, Pk).
1296    //     ii. ReturnIfAbrupt(kValue).
1297    //     iii. Let mappedValue be Call(callbackfn, T, «kValue, k, O»).
1298    //     iv. ReturnIfAbrupt(mappedValue).
1299    //     v. Let status be CreateDataPropertyOrThrow (A, Pk, mappedValue).
1300    //     vi. ReturnIfAbrupt(status).
1301    //   e. Increase k by 1.
1302    uint32_t k = 0;
1303    uint32_t len = static_cast<uint32_t>(rawLen);
1304    if (thisObjVal->IsStableJSArray(thread)) {
1305        JSStableArray::Map(newArrayHandle, thisObjHandle, argv, k, len);
1306        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1307    }
1308    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1309    JSMutableHandle<JSTaggedValue> mapResultHandle(thread, JSTaggedValue::Undefined());
1310    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1311    const uint32_t argsLength = 3; // 3: «kValue, k, O»
1312    while (k < len) {
1313        bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
1314        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1315        if (exists) {
1316            JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
1317            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1318            key.Update(JSTaggedValue(k));
1319            EcmaRuntimeCallInfo *info =
1320                EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
1321            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1322            info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
1323            JSTaggedValue mapResult = JSFunction::Call(info);
1324            if (!mapResult.IsSharedType()) {
1325                auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
1326                THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1327            }
1328            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1329            mapResultHandle.Update(mapResult);
1330            JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapResultHandle, SCheckMode::SKIP);
1331            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1332        }
1333        k++;
1334    }
1335
1336    // 11. Return A.
1337    return newArrayHandle.GetTaggedValue();
1338}
1339
1340// 22.1.3.16 Array.prototype.pop ( )
1341JSTaggedValue BuiltinsSharedArray::Pop(EcmaRuntimeCallInfo *argv)
1342{
1343    ASSERT(argv);
1344    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Pop);
1345
1346    JSThread *thread = argv->GetThread();
1347    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1348
1349    // 1. Let O be ToObject(this value).
1350    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1351    if (!thisHandle->IsJSSharedArray()) {
1352        auto error = ContainerError::BindError(thread, "The pop method cannot be bound.");
1353        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1354    }
1355    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1356    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisHandle);
1357    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1358
1359    JSTaggedValue opResult = PopInner(argv, thisHandle, thisObjHandle);
1360    return opResult;
1361}
1362
1363JSTaggedValue BuiltinsSharedArray::PopInner(EcmaRuntimeCallInfo *argv, JSHandle<JSTaggedValue> &thisHandle,
1364                                            JSHandle<JSObject> &thisObjHandle)
1365{
1366    JSThread *thread = argv->GetThread();
1367    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1368
1369    // 1. Let O be ToObject(this value).
1370    if (thisHandle->IsStableJSArray(thread) && JSObject::IsArrayLengthWritable(thread, thisObjHandle)) {
1371        return JSStableArray::Pop(JSHandle<JSSharedArray>::Cast(thisHandle), argv);
1372    }
1373
1374    // 2. ReturnIfAbrupt(O).
1375    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1376    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1377
1378    // 3. Let len be ToLength(Get(O, "length")).
1379    int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
1380    // 4. ReturnIfAbrupt(len).
1381    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1382    // 5. If len is zero,
1383    //   a. Let setStatus be Set(O, "length", 0, true).
1384    //   b. ReturnIfAbrupt(setStatus).
1385    //   c. Return undefined.
1386    if (len == 0) {
1387        JSHandle<JSTaggedValue> lengthValue(thread, JSTaggedValue(0));
1388        JSSharedArray::LengthSetter(thread, thisObjHandle, lengthValue, true);
1389        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1390        return JSTaggedValue::Undefined();
1391    }
1392
1393    // 6. Else len > 0,
1394    //   a. Let newLen be len–1.
1395    //   b. Let indx be ToString(newLen).
1396    //   c. Let element be Get(O, indx).
1397    //   d. ReturnIfAbrupt(element).
1398    //   e. Let deleteStatus be DeletePropertyOrThrow(O, indx).
1399    //   f. ReturnIfAbrupt(deleteStatus).
1400    //   g. Let setStatus be Set(O, "length", newLen, true).
1401    //   h. ReturnIfAbrupt(setStatus).
1402    //   i. Return element.
1403    int64_t newLen = len - 1;
1404    JSHandle<JSTaggedValue> indexHandle(thread, JSTaggedValue(newLen));
1405    JSHandle<JSTaggedValue> element =
1406        JSTaggedValue::GetProperty(thread, thisObjVal, indexHandle, SCheckMode::SKIP).GetValue();
1407    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1408    JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, indexHandle);
1409    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1410    JSSharedArray::LengthSetter(thread, thisObjHandle, indexHandle, true);
1411    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1412
1413    return element.GetTaggedValue();
1414}
1415
1416// 22.1.3.17 Array.prototype.push ( ...items )
1417JSTaggedValue BuiltinsSharedArray::Push(EcmaRuntimeCallInfo *argv)
1418{
1419    ASSERT(argv);
1420    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Push);
1421    JSThread *thread = argv->GetThread();
1422    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1423    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1424    if (!thisHandle->IsJSSharedArray()) {
1425        auto error = ContainerError::BindError(thread, "The push method cannot be bound.");
1426        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1427    }
1428    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisHandle);
1429    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1430    if (thisHandle->IsStableJSArray(thread)) {
1431        auto opResult = JSStableArray::Push(JSHandle<JSSharedArray>::Cast(thisHandle), argv);
1432        return opResult;
1433    }
1434    // 6. Let argCount be the number of elements in items.
1435    uint32_t argc = argv->GetArgsNumber();
1436
1437    // 1. Let O be ToObject(this value).
1438    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1439    // 2. ReturnIfAbrupt(O).
1440    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1441    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1442
1443    // 3. Let len be ToLength(Get(O, "length")).
1444    int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
1445    // 4. ReturnIfAbrupt(len).
1446    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1447    // 7. If len + argCount > 253-1, throw a TypeError exception.
1448    if ((len + static_cast<int64_t>(argc)) > base::MAX_SAFE_INTEGER) {
1449        THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
1450    }
1451
1452    // 8. Repeat, while items is not empty
1453    //   a. Remove the first element from items and let E be the value of the element.
1454    //   b. Let setStatus be Set(O, ToString(len), E, true).
1455    //   c. ReturnIfAbrupt(setStatus).
1456    //   d. Let len be len+1.
1457    uint32_t k = 0;
1458    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1459    while (k < argc) {
1460        key.Update(JSTaggedValue(len));
1461        JSHandle<JSTaggedValue> kValue = GetCallArg(argv, k);
1462        if (!kValue->IsSharedType()) {
1463            auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
1464            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1465        }
1466        JSSharedArray::FastSetPropertyByValue(thread, thisObjVal, key, kValue);
1467        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1468        k++;
1469        len++;
1470    }
1471
1472    // 9. Let setStatus be Set(O, "length", len, true).
1473    key.Update(JSTaggedValue(len));
1474    JSSharedArray::LengthSetter(thread, thisObjHandle, key, true);
1475    // 10. ReturnIfAbrupt(setStatus).
1476    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1477
1478    // 11. Return len.
1479    return GetTaggedDouble(len);
1480}
1481
1482JSTaggedValue BuiltinsSharedArray::ReduceUnStableJSArray(JSThread *thread, JSHandle<JSTaggedValue> &thisHandle,
1483    JSHandle<JSTaggedValue> &thisObjVal, int64_t k, int64_t len, JSMutableHandle<JSTaggedValue> &accumulator,
1484    JSHandle<JSTaggedValue> &callbackFnHandle)
1485{
1486    const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1487    JSTaggedValue callResult = JSTaggedValue::Undefined();
1488    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1489    while (k < len) {
1490        bool exists = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, k));
1491        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1492        if (exists) {
1493            JSHandle<JSTaggedValue> kValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
1494            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1495            key.Update(JSTaggedValue(k));
1496            JSHandle<JSTaggedValue> thisArgHandle = globalConst->GetHandledUndefined();
1497            const uint32_t argsLength = 4; // 4: «accumulator, kValue, k, O»
1498            JSHandle<JSTaggedValue> undefined = globalConst->GetHandledUndefined();
1499            EcmaRuntimeCallInfo *info =
1500                EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
1501            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1502            info->SetCallArg(accumulator.GetTaggedValue(), kValue.GetTaggedValue(), key.GetTaggedValue(),
1503                thisObjVal.GetTaggedValue());
1504            callResult = JSFunction::Call(info);
1505            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1506            accumulator.Update(callResult);
1507        }
1508        k++;
1509    }
1510    return accumulator.GetTaggedValue();
1511}
1512
1513// 22.1.3.18 Array.prototype.reduce ( callbackfn [ , initialValue ] )
1514JSTaggedValue BuiltinsSharedArray::Reduce(EcmaRuntimeCallInfo *argv)
1515{
1516    ASSERT(argv);
1517    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Reduce);
1518    JSThread *thread = argv->GetThread();
1519    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1520
1521    uint32_t argc = argv->GetArgsNumber();
1522    // 1. Let O be ToObject(this value).
1523    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1524    if (!thisHandle->IsJSSharedArray()) {
1525        auto error = ContainerError::BindError(thread, "The reduce method cannot be bound.");
1526        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1527    }
1528    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1529    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
1530    // 2. ReturnIfAbrupt(O).
1531    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1532    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1533
1534    // 3. Let len be ToLength(Get(O, "length")).
1535    int64_t len = ArrayHelper::GetLength(thread, thisObjVal);
1536    // 4. ReturnIfAbrupt(len).
1537    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1538
1539    // 5. If IsCallable(callbackfn) is false, throw a TypeError exception.
1540    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
1541    if (!callbackFnHandle->IsCallable()) {
1542        THROW_TYPE_ERROR_AND_RETURN(thread, "the callbackfun is not callable.", JSTaggedValue::Exception());
1543    }
1544
1545    // 6. If len is 0 and initialValue is not present, throw a TypeError exception.
1546    if (len == 0 && argc < 2) {  // 2:2 means the number of parameters
1547        THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
1548    }
1549
1550    // 7. Let k be 0.
1551    // 8. If initialValue is present, then
1552    //   a. Set accumulator to initialValue.
1553    // 9. Else initialValue is not present,
1554    //   a. Let kPresent be false.
1555    //   b. Repeat, while kPresent is false and k < len
1556    //     i. Let Pk be ToString(k).
1557    //     ii. Let kPresent be HasProperty(O, Pk).
1558    //     iii. ReturnIfAbrupt(kPresent).
1559    //     iv. If kPresent is true, then
1560    //       1. Let accumulator be Get(O, Pk).
1561    //       2. ReturnIfAbrupt(accumulator).
1562    //     v. Increase k by 1.
1563    //   c. If kPresent is false, throw a TypeError exception.
1564    int64_t k = 0;
1565    JSMutableHandle<JSTaggedValue> accumulator(thread, JSTaggedValue::Undefined());
1566    if (argc == 2) {  // 2:2 means the number of parameters
1567        accumulator.Update(GetCallArg(argv, 1).GetTaggedValue());
1568    } else {
1569        bool kPresent = false;
1570        while (!kPresent && k < len) {
1571            kPresent = (thisHandle->IsTypedArray() || thisHandle->IsSharedTypedArray() ||
1572               JSTaggedValue::HasProperty(thread, thisObjVal, k));
1573            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1574            if (kPresent) {
1575                accumulator.Update(JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k).GetTaggedValue());
1576                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1577            }
1578            k++;
1579        }
1580        if (!kPresent) {
1581            THROW_TYPE_ERROR_AND_RETURN(thread, "accumulator can't be initialized.", JSTaggedValue::Exception());
1582        }
1583    }
1584
1585    if (thisObjVal->IsStableJSArray(thread)) {
1586        JSStableArray::Reduce(thread, thisObjHandle, callbackFnHandle, accumulator, k, len);
1587        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1588    }
1589    auto opResult = ReduceUnStableJSArray(thread, thisHandle, thisObjVal, k, len, accumulator, callbackFnHandle);
1590    return opResult;
1591}
1592
1593// 22.1.3.21 Array.prototype.shift ( )
1594JSTaggedValue BuiltinsSharedArray::Shift(EcmaRuntimeCallInfo *argv)
1595{
1596    ASSERT(argv);
1597    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Shift);
1598    JSThread *thread = argv->GetThread();
1599    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1600
1601    // 1. Let O be ToObject(this value).
1602    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1603    if (!thisHandle->IsJSSharedArray()) {
1604        auto error = ContainerError::BindError(thread, "The shift method cannot be bound.");
1605        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1606    }
1607    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1608    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisHandle);
1609    // 2. ReturnIfAbrupt(O).
1610    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1611    if (thisHandle->IsStableJSArray(thread) && JSObject::IsArrayLengthWritable(thread, thisObjHandle)) {
1612        auto opResult = JSStableArray::Shift(JSHandle<JSSharedArray>::Cast(thisHandle), argv);
1613        return opResult;
1614    }
1615    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1616
1617    // 3. Let len be ToLength(Get(O, "length")).
1618    int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
1619    // 4. ReturnIfAbrupt(len).
1620    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1621    // 5. If len is zero, then
1622    //   a. Let setStatus be Set(O, "length", 0, true).
1623    //   b. ReturnIfAbrupt(setStatus).
1624    //   c. Return undefined.
1625    if (len == 0) {
1626        JSHandle<JSTaggedValue> zeroLenHandle(thread, JSTaggedValue(len));
1627        JSSharedArray::LengthSetter(thread, thisObjHandle, zeroLenHandle, false);
1628        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1629        return JSTaggedValue::Undefined();
1630    }
1631
1632    // 6. Let first be Get(O, "0").
1633    JSHandle<JSTaggedValue> firstKey(thread, JSTaggedValue(0));
1634    JSHandle<JSTaggedValue> firstValue =
1635        JSTaggedValue::GetProperty(thread, thisObjVal, firstKey, SCheckMode::SKIP).GetValue();
1636    // 7. ReturnIfAbrupt(first).
1637    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1638
1639    // 8. Let k be 1.
1640    // 9. Repeat, while k < len
1641    //   a. Let from be ToString(k).
1642    //   b. Let to be ToString(k–1).
1643    //   c. Let fromPresent be HasProperty(O, from).
1644    //   d. ReturnIfAbrupt(fromPresent).
1645    //   e. If fromPresent is true, then
1646    //     i. Let fromVal be Get(O, from).
1647    //     ii. ReturnIfAbrupt(fromVal).
1648    //     iii. Let setStatus be Set(O, to, fromVal, true).
1649    //     iv. ReturnIfAbrupt(setStatus).
1650    //   f. Else fromPresent is false,
1651    //     i. Let deleteStatus be DeletePropertyOrThrow(O, to).
1652    //     ii. ReturnIfAbrupt(deleteStatus).
1653    //   g. Increase k by 1.
1654    JSMutableHandle<JSTaggedValue> toKey(thread, JSTaggedValue::Undefined());
1655    int64_t k = 1;
1656    while (k < len) {
1657        bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
1658        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1659        if (exists) {
1660            JSHandle<JSTaggedValue> fromValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
1661            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1662            JSSharedArray::FastSetPropertyByValue(thread, thisObjVal, k - 1, fromValue);
1663            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1664        } else {
1665            toKey.Update(JSTaggedValue(k - 1));
1666            JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, toKey);
1667            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1668        }
1669        k++;
1670    }
1671    // 10. Let deleteStatus be DeletePropertyOrThrow(O, ToString(len–1)).
1672    JSHandle<JSTaggedValue> deleteKey(thread, JSTaggedValue(len - 1));
1673    JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, deleteKey);
1674    // 11. ReturnIfAbrupt(deleteStatus).
1675    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1676
1677    // 12. Let setStatus be Set(O, "length", len–1, true).
1678    JSHandle<JSTaggedValue> newLenHandle(thread, JSTaggedValue(len - 1));
1679    JSSharedArray::LengthSetter(thread, thisObjHandle, newLenHandle, true);
1680    // 13. ReturnIfAbrupt(setStatus).
1681    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1682
1683    // 14. Return first.
1684    return firstValue.GetTaggedValue();
1685}
1686
1687// 22.1.3.22 Array.prototype.slice (start, end)
1688JSTaggedValue BuiltinsSharedArray::Slice(EcmaRuntimeCallInfo *argv)
1689{
1690    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Slice);
1691    ASSERT(argv);
1692    JSThread *thread = argv->GetThread();
1693    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1694
1695    // 1. Let O be ToObject(this value).
1696    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1697    if (!thisHandle->IsJSSharedArray()) {
1698        auto error = ContainerError::BindError(thread, "The slice method cannot be bound.");
1699        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1700    }
1701    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1702    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
1703    // 2. ReturnIfAbrupt(O).
1704    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1705    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1706
1707    // 3. Let len be ToLength(Get(O, "length")).
1708    int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
1709    // 4. ReturnIfAbrupt(len).
1710    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1711
1712    JSHandle<JSTaggedValue> msg0 = GetCallArg(argv, 0);
1713    double argStart;
1714    if (msg0->IsInt()) {
1715        argStart = msg0->GetInt();
1716    } else {
1717        // 5. Let relativeStart be ToInteger(start).
1718        JSTaggedNumber argStartTemp = JSTaggedValue::ToInteger(thread, msg0);
1719        // 6. ReturnIfAbrupt(relativeStart).
1720        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1721        argStart = argStartTemp.GetNumber();
1722    }
1723
1724    // 7. If relativeStart < 0, let k be max((len + relativeStart),0); else let k be min(relativeStart, len).
1725    int64_t k = 0;
1726    if (argStart < 0) {
1727        double tempStart = len + argStart;
1728        k = tempStart > 0 ? tempStart : 0;
1729    } else {
1730        k = argStart < len ? argStart : len;
1731    }
1732
1733    // 8. If end is undefined, let relativeEnd be len; else let relativeEnd be ToInteger(end).
1734    // 9. ReturnIfAbrupt(relativeEnd).
1735    // 10. If relativeEnd < 0, let final be max((len + relativeEnd),0); else let final be min(relativeEnd, len).
1736    JSHandle<JSTaggedValue> msg1 = GetCallArg(argv, 1);
1737    double argEnd = len;
1738    if (!msg1->IsUndefined()) {
1739        if (msg1->IsInt()) {
1740            argEnd = msg1->GetInt();
1741        } else {
1742            JSTaggedNumber argEndTemp = JSTaggedValue::ToInteger(thread, msg1);
1743            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1744            argEnd = argEndTemp.GetNumber();
1745        }
1746    }
1747    int64_t final = 0;
1748    if (argEnd < 0) {
1749        double tempFinal = len + argEnd;
1750        final = tempFinal > 0 ? tempFinal : 0;
1751    } else {
1752        final = argEnd < len ? argEnd : len;
1753    }
1754    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1755
1756    // 11. Let count be max(final – k, 0).
1757    int64_t count = final > k ? (final - k) : 0;
1758
1759    if (thisHandle->IsStableJSArray(thread) && !thisObjHandle->GetJSHClass()->HasConstructor()
1760        && JSObject::GetPrototype(thisObjHandle).IsJSArray()) {
1761        auto opResult = JSStableArray::Slice(thread, thisObjHandle, k, count);
1762        return opResult;
1763    }
1764
1765    // 12. Let A be ArraySpeciesCreate(O, count).
1766    JSTaggedValue newArray =
1767        JSSharedArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(static_cast<double>(count)));
1768    // 13. ReturnIfAbrupt(A).
1769    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1770    if (count == 0) {
1771        return newArray;
1772    }
1773    JSHandle<JSObject> newArrayHandle(thread, newArray);
1774
1775    // 14. Let n be 0.
1776    // 15. Repeat, while k < final
1777    //   a. Let Pk be ToString(k).
1778    //   b. Let kPresent be HasProperty(O, Pk).
1779    //   c. ReturnIfAbrupt(kPresent).
1780    //   d. If kPresent is true, then
1781    //     i. Let kValue be Get(O, Pk).
1782    //     ii. ReturnIfAbrupt(kValue).
1783    //     iii. Let status be CreateDataPropertyOrThrow(A, ToString(n), kValue ).
1784    //     iv. ReturnIfAbrupt(status).
1785    //   e. Increase k by 1.
1786    //   f. Increase n by 1.
1787    int64_t n = 0;
1788    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
1789    JSMutableHandle<JSTaggedValue> nKey(thread, JSTaggedValue::Undefined());
1790    while (k < final) {
1791        key.Update(JSTaggedValue(k));
1792        bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, key);
1793        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1794        if (exists) {
1795            nKey.Update(JSTaggedValue(n));
1796            JSHandle<JSTaggedValue> kValueHandle = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, key);
1797            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1798            JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, nKey, kValueHandle, SCheckMode::SKIP);
1799            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1800        }
1801        k++;
1802        n++;
1803    }
1804
1805    // 16. Let setStatus be Set(A, "length", n, true).
1806    JSHandle<JSTaggedValue> newLenHandle(thread, JSTaggedValue(n));
1807    JSSharedArray::LengthSetter(thread, newArrayHandle, newLenHandle, true);
1808    // 17. ReturnIfAbrupt(setStatus).
1809    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1810
1811    // 18. Return A.
1812    return newArrayHandle.GetTaggedValue();
1813}
1814
1815// 22.1.3.24 Array.prototype.sort (comparefn)
1816JSTaggedValue BuiltinsSharedArray::Sort(EcmaRuntimeCallInfo *argv)
1817{
1818    ASSERT(argv);
1819    JSThread *thread = argv->GetThread();
1820    BUILTINS_API_TRACE(thread, SharedArray, Sort);
1821    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1822
1823    // 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
1824    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
1825    if (!callbackFnHandle->IsUndefined() && !callbackFnHandle->IsCallable()) {
1826        THROW_TYPE_ERROR_AND_RETURN(thread, "Callable is false", JSTaggedValue::Exception());
1827    }
1828
1829    // 2. Let obj be ToObject(this value).
1830    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1831    if (!thisHandle->IsJSSharedArray()) {
1832        auto error = ContainerError::BindError(thread, "The sort method cannot be bound.");
1833        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1834    }
1835    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1836    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisHandle);
1837    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1838
1839    // Array sort
1840    if (thisHandle->IsStableJSArray(thread) && callbackFnHandle->IsUndefined()) {
1841        JSStableArray::Sort(thread, thisObjHandle, callbackFnHandle);
1842    } else {
1843        JSSharedArray::Sort(thread, JSHandle<JSTaggedValue>::Cast(thisObjHandle), callbackFnHandle);
1844        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1845    }
1846    return thisObjHandle.GetTaggedValue();
1847}
1848
1849// 22.1.3.25 Array.prototype.splice (start, deleteCount , ...items )
1850// NOLINTNEXTLINE(readability-function-size)
1851JSTaggedValue BuiltinsSharedArray::Splice(EcmaRuntimeCallInfo *argv)
1852{
1853    ASSERT(argv);
1854    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Splice);
1855    JSThread *thread = argv->GetThread();
1856    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1857    uint32_t argc = argv->GetArgsNumber();
1858    // 1. Let O be ToObject(this value).
1859    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
1860    if (!thisHandle->IsJSSharedArray()) {
1861        auto error = ContainerError::BindError(thread, "The splice method cannot be bound.");
1862        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1863    }
1864    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
1865    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(
1866        thread, thisHandle);
1867    // 2. ReturnIfAbrupt(O).
1868    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1869    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
1870    // 3. Let len be ToLength(Get(O, "length")).
1871    int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
1872    // 4. ReturnIfAbrupt(len).
1873    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1874    // 5. Let relativeStart be ToInteger(start).
1875    int64_t start = 0;
1876    int64_t insertCount = 0;
1877    int64_t actualDeleteCount = 0;
1878    int64_t end = len;
1879    double argStart = 0;
1880    if (argc > 0) {
1881        JSHandle<JSTaggedValue> msg0 = GetCallArg(argv, 0);
1882        JSTaggedNumber argStartTemp = JSTaggedValue::ToInteger(thread, msg0);
1883        // 6. ReturnIfAbrupt(relativeStart).
1884        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1885        argStart = argStartTemp.GetNumber();
1886        // 7. If relativeStart < 0, let actualStart be max((len + relativeStart),0); else let actualStart be
1887        // min(relativeStart, len).
1888        if (argStart < 0) {
1889            double tempStart = argStart + len;
1890            start = tempStart > 0 ? tempStart : 0;
1891        } else {
1892            start = argStart < end ? argStart : end;
1893        }
1894        actualDeleteCount = len - start;
1895    }
1896    // 8. If the number of actual arguments is 0, then
1897    //   a. Let insertCount be 0.
1898    //   b. Let actualDeleteCount be 0.
1899    // 9. Else if the number of actual arguments is 1, then
1900    //   a. Let insertCount be 0.
1901    //   b. Let actualDeleteCount be len – actualStart.
1902    // 10. Else,
1903    //   a. Let insertCount be the number of actual arguments minus 2.
1904    //   b. Let dc be ToInteger(deleteCount).
1905    //   c. ReturnIfAbrupt(dc).
1906    //   d. Let actualDeleteCount be min(max(dc,0), len – actualStart).
1907    if (argc > 1) {
1908        insertCount = argc - 2;  // 2:2 means there are two arguments before the insert items.
1909        JSHandle<JSTaggedValue> msg1 = GetCallArg(argv, 1);
1910        JSTaggedNumber argDeleteCount = JSTaggedValue::ToInteger(thread, msg1);
1911        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1912        double deleteCount = argDeleteCount.GetNumber();
1913        deleteCount = deleteCount > 0 ? deleteCount : 0;
1914        actualDeleteCount = deleteCount < (len - start) ? deleteCount : len - start;
1915    }
1916    // 11. If len+insertCount−actualDeleteCount > 253-1, throw a TypeError exception.
1917    if (len + insertCount - actualDeleteCount > base::MAX_SAFE_INTEGER) {
1918        THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
1919    }
1920    // 12. Let A be ArraySpeciesCreate(O, actualDeleteCount).
1921    JSTaggedValue newArray = JSSharedArray::ArraySpeciesCreate(
1922        thread, thisObjHandle, JSTaggedNumber(static_cast<double>(actualDeleteCount)));
1923    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1924    JSHandle<JSObject> newArrayHandle(thread, newArray);
1925    if (thisHandle->IsStableJSArray(thread)) {
1926        return JSStableArray::Splice(JSHandle<JSSharedArray>::Cast(thisHandle), argv, start, insertCount,
1927            actualDeleteCount, newArrayHandle, len);
1928    }
1929    // 14. Let k be 0.
1930    // 15. Repeat, while k < actualDeleteCount
1931    //   a. Let from be ToString(actualStart+k).
1932    //   b. Let fromPresent be HasProperty(O, from).
1933    //   d. If fromPresent is true, then
1934    //     i. Let fromValue be Get(O, from).
1935    //     iii. Let status be CreateDataPropertyOrThrow(A, ToString(k), fromValue).
1936    //   e. Increase k by 1.
1937    JSMutableHandle<JSTaggedValue> fromKey(thread, JSTaggedValue::Undefined());
1938    JSMutableHandle<JSTaggedValue> toKey(thread, JSTaggedValue::Undefined());
1939    int64_t k = 0;
1940    while (k < actualDeleteCount) {
1941        int64_t from = start + k;
1942        fromKey.Update(JSTaggedValue(from));
1943        bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, fromKey);
1944        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1945        if (exists) {
1946            JSHandle<JSTaggedValue> fromValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, fromKey);
1947            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1948            toKey.Update(JSTaggedValue(k));
1949            if (newArrayHandle->IsJSProxy()) {
1950                toKey.Update(JSTaggedValue::ToString(thread, toKey).GetTaggedValue());
1951                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1952            }
1953            JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toKey, fromValue);
1954            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1955        }
1956        k++;
1957    }
1958    // 16. Let setStatus be Set(A, "length", actualDeleteCount, true).
1959    JSHandle<JSTaggedValue> deleteCountHandle(thread, JSTaggedValue(actualDeleteCount));
1960    JSSharedArray::LengthSetter(thread, newArrayHandle, deleteCountHandle, true);
1961    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1962    // 19. Let itemCount be the number of elements in items.
1963    // 20. If itemCount < actualDeleteCount, then
1964    //   a. Let k be actualStart.
1965    //   b. Repeat, while k < (len – actualDeleteCount)
1966    //     i. Let from be ToString(k+actualDeleteCount).
1967    //     ii. Let to be ToString(k+itemCount).
1968    //     iii. Let fromPresent be HasProperty(O, from).
1969    //     v. If fromPresent is true, then
1970    //       1. Let fromValue be Get(O, from).
1971    //       3. Let setStatus be Set(O, to, fromValue, true).
1972    //     vi. Else fromPresent is false,
1973    //       1. Let deleteStatus be DeletePropertyOrThrow(O, to).
1974    //     vii. Increase k by 1.
1975    //   c. Let k be len.
1976    //   d. Repeat, while k > (len – actualDeleteCount + itemCount)
1977    //     i. Let deleteStatus be DeletePropertyOrThrow(O, ToString(k–1)).
1978    //     iii. Decrease k by 1.
1979    if (insertCount < actualDeleteCount) {
1980        k = start;
1981        while (k < len - actualDeleteCount) {
1982            fromKey.Update(JSTaggedValue(k + actualDeleteCount));
1983            toKey.Update(JSTaggedValue(k + insertCount));
1984            bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, fromKey);
1985            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1986            if (exists) {
1987                JSHandle<JSTaggedValue> fromValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, fromKey);
1988                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1989                JSSharedArray::FastSetPropertyByValue(thread, thisObjVal, toKey, fromValue);
1990                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1991            } else {
1992                JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, toKey);
1993                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1994            }
1995            k++;
1996        }
1997        k = len;
1998        JSMutableHandle<JSTaggedValue> deleteKey(thread, JSTaggedValue::Undefined());
1999        while (k > len - actualDeleteCount + insertCount) {
2000            deleteKey.Update(JSTaggedValue(k - 1));
2001            JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, deleteKey);
2002            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2003            k--;
2004        }
2005    } else if (insertCount > actualDeleteCount) {
2006        // 21. Else if itemCount > actualDeleteCount, then
2007        //   a. Let k be (len – actualDeleteCount).
2008        //   b. Repeat, while k > actualStart
2009        //     i. Let from be ToString(k + actualDeleteCount – 1).
2010        //     ii. Let to be ToString(k + itemCount – 1)
2011        //     iii. Let fromPresent be HasProperty(O, from).
2012        //     iv. ReturnIfAbrupt(fromPresent).
2013        //     v. If fromPresent is true, then
2014        //       1. Let fromValue be Get(O, from).
2015        //       2. ReturnIfAbrupt(fromValue).
2016        //       3. Let setStatus be Set(O, to, fromValue, true).
2017        //       4. ReturnIfAbrupt(setStatus).
2018        //     vi. Else fromPresent is false,
2019        //       1. Let deleteStatus be DeletePropertyOrThrow(O, to).
2020        //       2. ReturnIfAbrupt(deleteStatus).
2021        //     vii. Decrease k by 1.
2022        k = len - actualDeleteCount;
2023        while (k > start) {
2024            fromKey.Update(JSTaggedValue(k + actualDeleteCount - 1));
2025            toKey.Update(JSTaggedValue(k + insertCount - 1));
2026            bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, fromKey);
2027            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2028            if (exists) {
2029                JSHandle<JSTaggedValue> fromValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, fromKey);
2030                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2031                JSSharedArray::FastSetPropertyByValue(thread, thisObjVal, toKey, fromValue);
2032                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2033            } else {
2034                JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, toKey);
2035                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2036            }
2037            k--;
2038        }
2039    }
2040    // 22. Let k be actualStart.
2041    k = start;
2042    // 23. Repeat, while items is not empty
2043    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
2044    for (uint32_t i = 2; i < argc; i++) {
2045        JSHandle<JSTaggedValue> itemValue = GetCallArg(argv, i);
2046        if (!itemValue->IsSharedType()) {
2047            auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
2048            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2049        }
2050        key.Update(JSTaggedValue(k));
2051        JSSharedArray::FastSetPropertyByValue(thread, thisObjVal, key, itemValue);
2052        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2053        k++;
2054    }
2055    // 24. Let setStatus be Set(O, "length", len – actualDeleteCount + itemCount, true).
2056    int64_t newLen = len - actualDeleteCount + insertCount;
2057    JSHandle<JSTaggedValue> newLenHandle(thread, JSTaggedValue(newLen));
2058    JSSharedArray::LengthSetter(thread, thisObjHandle, newLenHandle, true);
2059    // 25. ReturnIfAbrupt(setStatus).
2060    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2061    // 26. Return A.
2062    return newArrayHandle.GetTaggedValue();
2063}
2064
2065// 22.1.3.27 Array.prototype.toString ( )
2066JSTaggedValue BuiltinsSharedArray::ToString(EcmaRuntimeCallInfo *argv)
2067{
2068    ASSERT(argv);
2069    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, ToString);
2070    JSThread *thread = argv->GetThread();
2071    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2072    auto ecmaVm = thread->GetEcmaVM();
2073
2074    // 1. Let array be ToObject(this value).
2075    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
2076    if (!thisHandle->IsJSSharedArray()) {
2077        auto error = ContainerError::BindError(thread, "The toString method cannot be bound.");
2078        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2079    }
2080    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
2081    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
2082    // 2. ReturnIfAbrupt(array).
2083    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2084    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
2085
2086    // 3. Let func be Get(array, "join").
2087    JSHandle<JSTaggedValue> joinKey = thread->GlobalConstants()->GetHandledJoinString();
2088    JSHandle<JSTaggedValue> callbackFnHandle = JSTaggedValue::GetProperty(thread, thisObjVal, joinKey).GetValue();
2089
2090    // 4. ReturnIfAbrupt(func).
2091    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2092
2093    // 5. If IsCallable(func) is false, let func be the intrinsic function %ObjProto_toString% (19.1.3.6).
2094    if (!callbackFnHandle->IsCallable()) {
2095        JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv();
2096        JSHandle<JSTaggedValue> objectPrototype = env->GetObjectFunctionPrototype();
2097        JSHandle<JSTaggedValue> toStringKey = thread->GlobalConstants()->GetHandledToStringString();
2098        callbackFnHandle = JSTaggedValue::GetProperty(thread, objectPrototype, toStringKey).GetValue();
2099        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2100    }
2101    const uint32_t argsLength = argv->GetArgsNumber();
2102    JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
2103    EcmaRuntimeCallInfo *info =
2104        EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisObjVal, undefined, argsLength);
2105    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2106    info->SetCallArg(argsLength, 0, argv, 0);
2107    auto opResult = JSFunction::Call(info);
2108    return opResult;
2109}
2110
2111// 22.1.3.28 Array.prototype.unshift ( ...items )
2112JSTaggedValue BuiltinsSharedArray::Unshift(EcmaRuntimeCallInfo *argv)
2113{
2114    ASSERT(argv);
2115    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Unshift);
2116    JSThread *thread = argv->GetThread();
2117    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2118
2119    // 5. Let argCount be the number of actual arguments.
2120    int64_t argc = argv->GetArgsNumber();
2121
2122    // 1. Let O be ToObject(this value).
2123    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
2124    if (!thisHandle->IsJSSharedArray()) {
2125        auto error = ContainerError::BindError(thread, "The unshift method cannot be bound.");
2126        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2127    }
2128    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
2129    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisHandle);
2130    // 2. ReturnIfAbrupt(O).
2131    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2132    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
2133
2134    // 3. Let len be ToLength(Get(O, "length")).
2135    int64_t len = ArrayHelper::GetArrayLength(thread, thisObjVal);
2136    // 4. ReturnIfAbrupt(len).
2137    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2138
2139    // 6. If argCount > 0, then
2140    //   a. If len+ argCount > 253-1, throw a TypeError exception.
2141    //   b. Let k be len.
2142    //   c. Repeat, while k > 0,
2143    //     i. Let from be ToString(k–1).
2144    //     ii. Let to be ToString(k+argCount –1).
2145    //     iii. Let fromPresent be HasProperty(O, from).
2146    //     iv. ReturnIfAbrupt(fromPresent).
2147    //     v. If fromPresent is true, then
2148    //       1. Let fromValue be Get(O, from).
2149    //       2. ReturnIfAbrupt(fromValue).
2150    //       3. Let setStatus be Set(O, to, fromValue, true).
2151    //       4. ReturnIfAbrupt(setStatus).
2152    //     vi. Else fromPresent is false,
2153    //       1. Let deleteStatus be DeletePropertyOrThrow(O, to).
2154    //       2. ReturnIfAbrupt(deleteStatus).
2155    //     vii. Decrease k by 1.
2156    if (argc > 0) {
2157        if (len + argc > base::MAX_SAFE_INTEGER) {
2158            THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
2159        }
2160        JSMutableHandle<JSTaggedValue> fromKey(thread, JSTaggedValue::Undefined());
2161        JSMutableHandle<JSTaggedValue> toKey(thread, JSTaggedValue::Undefined());
2162        int64_t k = len;
2163        while (k > 0) {
2164            fromKey.Update(JSTaggedValue(k - 1));
2165            toKey.Update(JSTaggedValue(k + argc - 1));
2166            bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, fromKey);
2167            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2168            if (exists) {
2169                JSHandle<JSTaggedValue> fromValue = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, fromKey);
2170                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2171                JSSharedArray::FastSetPropertyByValue(thread, thisObjVal, toKey, fromValue);
2172                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2173            } else {
2174                JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, toKey);
2175                RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2176            }
2177            k--;
2178        }
2179        //   d. Let j be 0.
2180        //   e. Let items be a List whose elements are, in left to right order, the arguments that were passed to this
2181        //   function invocation.
2182        //   f. Repeat, while items is not empty
2183        //     i. Remove the first element from items and let E be the value of that element.
2184        //     ii. Let setStatus be Set(O, ToString(j), E, true).
2185        //     iii. ReturnIfAbrupt(setStatus).
2186        //     iv. Increase j by 1.
2187        int64_t j = 0;
2188        while (j < argc) {
2189            toKey.Update(JSTaggedValue(j));
2190            JSHandle<JSTaggedValue> toValue = GetCallArg(argv, j);
2191            if (!toValue->IsSharedType()) {
2192                auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
2193                THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2194            }
2195            JSSharedArray::FastSetPropertyByValue(thread, thisObjVal, toKey, toValue);
2196            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2197            j++;
2198        }
2199    }
2200
2201    // 7. Let setStatus be Set(O, "length", len+argCount, true).
2202    int64_t newLen = len + argc;
2203    JSHandle<JSTaggedValue> newLenHandle(thread, JSTaggedValue(newLen));
2204    JSSharedArray::LengthSetter(thread, thisObjHandle, newLenHandle, true);
2205    // 8. ReturnIfAbrupt(setStatus).
2206    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2207
2208    // 9. Return len+argCount.
2209    return GetTaggedDouble(newLen);
2210}
2211
2212// 22.1.3.29 Array.prototype.values ( )
2213JSTaggedValue BuiltinsSharedArray::Values(EcmaRuntimeCallInfo *argv)
2214{
2215    ASSERT(argv);
2216    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Values);
2217    JSThread *thread = argv->GetThread();
2218    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2219    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
2220    if (!thisHandle->IsJSSharedArray()) {
2221        auto error = ContainerError::BindError(thread, "The values method cannot be bound.");
2222        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2223    }
2224    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2225    // 1. Let O be ToObject(this value).
2226    // 2. ReturnIfAbrupt(O).
2227    JSHandle<JSObject> self = JSTaggedValue::ToObject(thread, GetThis(argv));
2228    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
2229    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2230    // 3. Return CreateArrayIterator(O, "value").
2231    JSHandle<JSSharedArrayIterator> iter(factory->NewJSSharedArrayIterator(self, IterationKind::VALUE));
2232    return iter.GetTaggedValue();
2233}
2234// 22.1.3.31 Array.prototype [ @@unscopables ]
2235JSTaggedValue BuiltinsSharedArray::Unscopables(EcmaRuntimeCallInfo *argv)
2236{
2237    JSThread *thread = argv->GetThread();
2238    BUILTINS_API_TRACE(thread, SharedArray, Unscopables);
2239    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2240    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2241    const GlobalEnvConstants *globalConst = thread->GlobalConstants();
2242
2243    JSHandle<JSObject> unscopableList = factory->CreateNullJSObject();
2244
2245    JSHandle<JSTaggedValue> trueVal(thread, JSTaggedValue::True());
2246
2247    JSHandle<JSTaggedValue> atKey((factory->NewFromASCII("at")));
2248    JSObject::CreateDataProperty(thread, unscopableList, atKey, trueVal);
2249
2250    JSHandle<JSTaggedValue> copyWithKey = globalConst->GetHandledCopyWithinString();
2251    JSObject::CreateDataProperty(thread, unscopableList, copyWithKey, trueVal);
2252
2253    JSHandle<JSTaggedValue> entriesKey = globalConst->GetHandledEntriesString();
2254    JSObject::CreateDataProperty(thread, unscopableList, entriesKey, trueVal);
2255
2256    JSHandle<JSTaggedValue> fillKey = globalConst->GetHandledFillString();
2257    JSObject::CreateDataProperty(thread, unscopableList, fillKey, trueVal);
2258
2259    JSHandle<JSTaggedValue> findKey = globalConst->GetHandledFindString();
2260    JSObject::CreateDataProperty(thread, unscopableList, findKey, trueVal);
2261
2262    JSHandle<JSTaggedValue> findIndexKey = globalConst->GetHandledFindIndexString();
2263    JSObject::CreateDataProperty(thread, unscopableList, findIndexKey, trueVal);
2264
2265    JSHandle<JSTaggedValue> findLastKey((factory->NewFromASCII("findLast")));
2266    JSObject::CreateDataProperty(thread, unscopableList, findLastKey, trueVal);
2267
2268    JSHandle<JSTaggedValue> findLastIndexKey((factory->NewFromASCII("findLastIndex")));
2269    JSObject::CreateDataProperty(thread, unscopableList, findLastIndexKey, trueVal);
2270
2271    JSHandle<JSTaggedValue> flatKey = globalConst->GetHandledFlatString();
2272    JSObject::CreateDataProperty(thread, unscopableList, flatKey, trueVal);
2273
2274    JSHandle<JSTaggedValue> flatMapKey = globalConst->GetHandledFlatMapString();
2275    JSObject::CreateDataProperty(thread, unscopableList, flatMapKey, trueVal);
2276
2277    JSHandle<JSTaggedValue> includesKey = globalConst->GetHandledIncludesString();
2278    JSObject::CreateDataProperty(thread, unscopableList, includesKey, trueVal);
2279
2280    JSHandle<JSTaggedValue> keysKey = globalConst->GetHandledKeysString();
2281    JSObject::CreateDataProperty(thread, unscopableList, keysKey, trueVal);
2282
2283    JSHandle<JSTaggedValue> valuesKey = globalConst->GetHandledValuesString();
2284    JSObject::CreateDataProperty(thread, unscopableList, valuesKey, trueVal);
2285
2286    JSHandle<JSTaggedValue> toReversedKey((factory->NewFromASCII("toReversed")));
2287    JSObject::CreateDataProperty(thread, unscopableList, toReversedKey, trueVal);
2288
2289    JSHandle<JSTaggedValue> toSortedKey((factory->NewFromASCII("toSorted")));
2290    JSObject::CreateDataProperty(thread, unscopableList, toSortedKey, trueVal);
2291
2292    JSHandle<JSTaggedValue> toSplicedKey((factory->NewFromASCII("toSpliced")));
2293    JSObject::CreateDataProperty(thread, unscopableList, toSplicedKey, trueVal);
2294    return unscopableList.GetTaggedValue();
2295}
2296
2297// 23.1.3.13 Array.prototype.includes ( searchElement [ , fromIndex ] )
2298JSTaggedValue BuiltinsSharedArray::Includes(EcmaRuntimeCallInfo *argv)
2299{
2300    ASSERT(argv);
2301    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, Includes);
2302    JSThread *thread = argv->GetThread();
2303    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2304    // 1. Let O be ? ToObject(this value).
2305    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
2306    if (!thisHandle->IsJSSharedArray()) {
2307        auto error = ContainerError::BindError(thread, "The includes method cannot be bound.");
2308        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2309    }
2310    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
2311    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
2312    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2313
2314    uint32_t argc = argv->GetArgsNumber();
2315    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
2316    JSHandle<JSTaggedValue> searchElement = GetCallArg(argv, 0);
2317
2318    // 2. Let len be ? LengthOfArrayLike(O).
2319    int64_t len = ArrayHelper::GetLength(thread, thisObjVal);
2320    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2321    // 3. If len is 0, return false.
2322    if (len == 0) {
2323        return GetTaggedBoolean(false);
2324    }
2325    // 4. Let n be ? ToIntegerOrInfinity(fromIndex).
2326    // 5. Assert: If fromIndex is undefined, then n is 0.
2327    double fromIndex = 0;
2328    if (argc > 1) {
2329        JSHandle<JSTaggedValue> msg1 = GetCallArg(argv, 1);
2330        JSTaggedNumber fromIndexTemp = JSTaggedValue::ToNumber(thread, msg1);
2331        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2332        fromIndex = base::NumberHelper::TruncateDouble(fromIndexTemp.GetNumber());
2333    }
2334
2335    // 6. If n is +∞, return false.
2336    // 7. Else if n is -∞, set n to 0.
2337    if (fromIndex >= len) {
2338        return GetTaggedBoolean(false);
2339    } else if (fromIndex < -len) {
2340        fromIndex = 0;
2341    }
2342    // 8. If n ≥ 0, then
2343    //     a. Let k be n.
2344    // 9. Else,
2345    //     a. Let k be len + n.
2346    //     b. If k < 0, let k be 0.
2347    int64_t from = (fromIndex >= 0) ? fromIndex : ((len + fromIndex) >= 0 ? len + fromIndex : 0);
2348
2349    // 10. Repeat, while k < len,
2350    //     a. Let elementK be ? Get(O, ! ToString(!(k))).
2351    //     b. If SameValueZero(searchElement, elementK) is true, return true.
2352    //     c. Set k to k + 1.
2353    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
2354    JSMutableHandle<JSTaggedValue> kValueHandle(thread, JSTaggedValue::Undefined());
2355    JSHandle<EcmaString> fromStr;
2356    while (from < len) {
2357        JSHandle<JSTaggedValue> handledFrom(thread, JSTaggedValue(from));
2358        fromStr = JSTaggedValue::ToString(thread, handledFrom);
2359        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2360        key.Update(fromStr.GetTaggedValue());
2361        kValueHandle.Update(JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, key).GetTaggedValue());
2362        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2363        if (JSTaggedValue::SameValueZero(searchElement.GetTaggedValue(), kValueHandle.GetTaggedValue())) {
2364            return GetTaggedBoolean(true);
2365        }
2366        from++;
2367    }
2368    // 11. Return false.
2369    return GetTaggedBoolean(false);
2370}
2371
2372// 23.1.3.1 Array.prototype.at ( index )
2373JSTaggedValue BuiltinsSharedArray::At(EcmaRuntimeCallInfo *argv)
2374{
2375    ASSERT(argv);
2376    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, At);
2377    JSThread *thread = argv->GetThread();
2378    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2379
2380    // 1. Let O be ToObject(this value).
2381    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
2382    if (!thisHandle->IsJSSharedArray()) {
2383        auto error = ContainerError::BindError(thread, "The at method cannot be bound.");
2384        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2385    }
2386    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
2387    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2388    if (thisHandle->IsStableJSArray(thread)) {
2389        auto opResult = JSStableArray::At(JSHandle<JSSharedArray>::Cast(thisHandle), argv);
2390        return opResult;
2391    }
2392    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
2393    // ReturnIfAbrupt(O).
2394    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2395    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
2396
2397    // 2. Let len be ? LengthOfArrayLike(O).
2398    int64_t len = ArrayHelper::GetLength(thread, thisObjVal);
2399    // ReturnIfAbrupt(len).
2400    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2401
2402    // 3. Let index be ? ToIntegerOrInfinity(index).
2403    JSTaggedNumber index = JSTaggedValue::ToInteger(thread, GetCallArg(argv, 0));
2404    // ReturnIfAbrupt(index).
2405    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2406
2407    // 4. If relativeIndex ≥ 0, then
2408    //     a. Let k be relativeIndex.
2409    // 5. Else,
2410    //     a. Let k be len + relativeIndex.
2411    int64_t relativeIndex = index.GetNumber();
2412    int64_t k = 0;
2413    if (relativeIndex >= 0) {
2414        k = relativeIndex;
2415    } else {
2416        k = len + relativeIndex;
2417    }
2418
2419    // 6. If k < 0 or k ≥ len, return undefined.
2420    if (k < 0 || k >= len) {
2421        // Return undefined.
2422        return JSTaggedValue::Undefined();
2423    }
2424    // 7. Return ? Get(O, ! ToString(�(k))).
2425    JSHandle<JSTaggedValue> element = JSSharedArray::FastGetPropertyByValue(thread, thisObjVal, k);
2426    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2427    return element.GetTaggedValue();
2428}
2429
2430// Array.prototype.shrinkTo ( arrayLength )
2431JSTaggedValue BuiltinsSharedArray::ShrinkTo(EcmaRuntimeCallInfo *argv)
2432{
2433    ASSERT(argv);
2434    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, ShrinkTo);
2435    JSThread *thread = argv->GetThread();
2436    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2437    if (argv->GetArgsNumber() != 1) {
2438        auto error = ContainerError::ParamError(thread, "Parameter error.Not enough parameter.");
2439        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2440    }
2441    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
2442    if (!thisHandle->IsJSSharedArray()) {
2443        auto error = ContainerError::BindError(thread, "The ShrinkTo method cannot be bound.");
2444        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2445    }
2446    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
2447    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisHandle);
2448    JSHandle<JSTaggedValue> newLengthValue = GetCallArg(argv, 0);
2449    if (!newLengthValue->IsNumber()) {
2450        auto error = ContainerError::ParamError(thread, "Parameter error.Invalid array length.");
2451        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2452    }
2453    auto newLength = JSTaggedValue::ToUint32(thread, newLengthValue);
2454    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2455    if (JSTaggedNumber(newLengthValue.GetTaggedValue()).GetNumber() != newLength) {
2456        auto error = ContainerError::ParamError(thread, "Parameter error.Invalid array length.");
2457        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2458    }
2459    int64_t len = ArrayHelper::GetLength(thread, thisHandle);
2460    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2461    if (newLength >= len) {
2462        return JSTaggedValue::Undefined();
2463    }
2464    JSSharedArray::LengthSetter(thread, thisObjHandle, newLengthValue, true);
2465    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2466    return JSTaggedValue::Undefined();
2467}
2468
2469// Array.prototype.ExtendTo ( arrayLength, initialValue )
2470JSTaggedValue BuiltinsSharedArray::ExtendTo(EcmaRuntimeCallInfo *argv)
2471{
2472    ASSERT(argv);
2473    BUILTINS_API_TRACE(argv->GetThread(), SharedArray, ShrinkTo);
2474    JSThread *thread = argv->GetThread();
2475    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2476    if (argv->GetArgsNumber() < COUNT_LENGTH_AND_INIT) {
2477        auto error = ContainerError::ParamError(thread, "Parameter error.Not enough parameters.");
2478        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2479    }
2480    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
2481    if (!thisHandle->IsJSSharedArray()) {
2482        auto error = ContainerError::BindError(thread, "The ExtendTo method cannot be bound.");
2483        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2484    }
2485    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
2486    [[maybe_unused]] ConcurrentApiScope<JSSharedArray, ModType::WRITE> scope(thread, thisHandle);
2487    JSHandle<JSTaggedValue> newLengthValue = GetCallArg(argv, 0);
2488    if (!newLengthValue->IsNumber()) {
2489        auto error = ContainerError::ParamError(thread, "Parameter error.Invalid array length.");
2490        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2491    }
2492    auto newLength = JSTaggedValue::ToUint32(thread, newLengthValue);
2493    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2494    if (JSTaggedNumber(newLengthValue.GetTaggedValue()).GetNumber() != newLength) {
2495        auto error = ContainerError::ParamError(thread, "Parameter error.Invalid array length.");
2496        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2497    }
2498
2499    int64_t length = ArrayHelper::GetLength(thread, thisHandle);
2500    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2501    if (newLength <= length) {
2502        return JSTaggedValue::Undefined();
2503    }
2504
2505    JSHandle<JSTaggedValue> initValue = GetCallArg(argv, 1);
2506    if (!initValue->IsSharedType()) {
2507        auto error = ContainerError::ParamError(thread, "Parameter error.Only accept sendable value.");
2508        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2509    }
2510    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
2511    for (uint32_t k = static_cast<uint32_t>(length); k < newLength; k++) {
2512        key.Update(JSTaggedValue(k));
2513        JSObject::CreateDataPropertyOrThrow(thread, thisObjHandle, key, initValue, SCheckMode::SKIP);
2514    }
2515    key.Update(JSTaggedValue(newLength));
2516    JSSharedArray::LengthSetter(thread, thisObjHandle, key, true);
2517    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2518    return JSTaggedValue::Undefined();
2519}
2520
2521JSTaggedValue BuiltinsSharedArray::LastIndexOfSlowPath(EcmaRuntimeCallInfo *argv, JSThread *thread,
2522                                                       const JSHandle<JSTaggedValue> &thisHandle)
2523{
2524    // 1. Let O be ToObject(this value).
2525    JSHandle<JSObject> thisObjHandle = JSTaggedValue::ToObject(thread, thisHandle);
2526    // 2. ReturnIfAbrupt(O).
2527    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2528    JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
2529    // 3. Let len be ToLength(Get(O, "length")).
2530    int64_t length = ArrayHelper::GetLength(thread, thisObjVal);
2531    // 4. ReturnIfAbrupt(len).
2532    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2533    // 5. If len is 0, return −1.
2534    if (length == 0) {
2535        return JSTaggedValue(-1);
2536    }
2537    // 6. If argument fromIndex was passed let n be ToInteger(fromIndex); else let n be 0.
2538    int64_t fromIndex = ArrayHelper::GetLastStartIndexFromArgs(thread, argv, 1, length);
2539    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2540    return LastIndexOfSlowPath(argv, thread, thisObjVal, fromIndex);
2541}
2542
2543JSTaggedValue BuiltinsSharedArray::LastIndexOfSlowPath(EcmaRuntimeCallInfo *argv, JSThread *thread,
2544                                                       const JSHandle<JSTaggedValue> &thisObjVal, int64_t fromIndex)
2545{
2546    if (fromIndex < 0) {
2547        return JSTaggedValue(-1);
2548    }
2549    JSMutableHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue::Undefined());
2550    JSHandle<JSTaggedValue> target = base::BuiltinsBase::GetCallArg(argv, 0);
2551    // 11. Repeat, while k < len
2552    for (int64_t curIndex = fromIndex; curIndex >= 0; --curIndex) {
2553        keyHandle.Update(JSTaggedValue(curIndex));
2554        bool found = ArrayHelper::ElementIsStrictEqualTo(thread, thisObjVal, keyHandle, target);
2555        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2556        if (UNLIKELY(found)) {
2557            return JSTaggedValue(curIndex);
2558        }
2559    }
2560    // 12. Return -1.
2561    return JSTaggedValue(-1);
2562}
2563
2564// Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )
2565JSTaggedValue BuiltinsSharedArray::LastIndexOf(EcmaRuntimeCallInfo *argv)
2566{
2567    ASSERT(argv);
2568    JSThread *thread = argv->GetThread();
2569    BUILTINS_API_TRACE(thread, SharedArray, LastIndexOf);
2570    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2571
2572    JSHandle<JSTaggedValue> thisHandle = GetThis(argv);
2573    if (UNLIKELY(!thisHandle->IsJSSharedArray())) {
2574        auto error = ContainerError::BindError(thread, "The lastIndexOf method cannot be bound.");
2575        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2576    }
2577    [[maybe_unused]] ConcurrentApiScope<JSSharedArray> scope(thread, thisHandle);
2578    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2579
2580    if (thisHandle->IsStableJSArray(thread)) {
2581        auto error = ContainerError::BindError(thread, "The lastIndexOf method not support stable array.");
2582        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2583    }
2584    return LastIndexOfSlowPath(argv, thread, thisHandle);
2585}
2586
2587}  // namespace panda::ecmascript::builtins
2588