14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/containers/containers_arraylist.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/containers/containers_errors.h"
194514f5e3Sopenharmony_ci#include "ecmascript/base/array_helper.h"
204514f5e3Sopenharmony_ci#include "ecmascript/js_api/js_api_arraylist.h"
214514f5e3Sopenharmony_ci#include "ecmascript/js_array.h"
224514f5e3Sopenharmony_ci#include "ecmascript/tagged_array-inl.h"
234514f5e3Sopenharmony_ci
244514f5e3Sopenharmony_cinamespace panda::ecmascript::containers {
254514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::ArrayListConstructor(EcmaRuntimeCallInfo *argv)
264514f5e3Sopenharmony_ci{
274514f5e3Sopenharmony_ci    ASSERT(argv);
284514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Constructor);
294514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
304514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
314514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
324514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv);
334514f5e3Sopenharmony_ci    if (newTarget->IsUndefined()) {
344514f5e3Sopenharmony_ci        JSTaggedValue error =
354514f5e3Sopenharmony_ci            ContainerError::BusinessError(thread, ErrorFlag::IS_NULL_ERROR,
364514f5e3Sopenharmony_ci                                          "The ArrayList's constructor cannot be directly invoked.");
374514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
384514f5e3Sopenharmony_ci    }
394514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> constructor = GetConstructor(argv);
404514f5e3Sopenharmony_ci    JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), newTarget);
414514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
424514f5e3Sopenharmony_ci    JSHandle<TaggedArray> newTaggedArray = factory->NewTaggedArray(JSAPIArrayList::DEFAULT_CAPACITY_LENGTH);
434514f5e3Sopenharmony_ci    obj->SetElements(thread, newTaggedArray);
444514f5e3Sopenharmony_ci    return obj.GetTaggedValue();
454514f5e3Sopenharmony_ci}
464514f5e3Sopenharmony_ci
474514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Add(EcmaRuntimeCallInfo *argv)
484514f5e3Sopenharmony_ci{
494514f5e3Sopenharmony_ci    ASSERT(argv);
504514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Add);
514514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
524514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
534514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
544514f5e3Sopenharmony_ci
554514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
564514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
574514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
584514f5e3Sopenharmony_ci        } else {
594514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
604514f5e3Sopenharmony_ci                                                                "The add method cannot be bound");
614514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
624514f5e3Sopenharmony_ci        }
634514f5e3Sopenharmony_ci    }
644514f5e3Sopenharmony_ci
654514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
664514f5e3Sopenharmony_ci    return GetTaggedBoolean(JSAPIArrayList::Add(thread, JSHandle<JSAPIArrayList>::Cast(self), value));
674514f5e3Sopenharmony_ci}
684514f5e3Sopenharmony_ci
694514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Insert(EcmaRuntimeCallInfo *argv)
704514f5e3Sopenharmony_ci{
714514f5e3Sopenharmony_ci    ASSERT(argv);
724514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Insert);
734514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
744514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
754514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
764514f5e3Sopenharmony_ci
774514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
784514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
794514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
804514f5e3Sopenharmony_ci        } else {
814514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
824514f5e3Sopenharmony_ci                                                                "The insert method cannot be bound");
834514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
844514f5e3Sopenharmony_ci        }
854514f5e3Sopenharmony_ci    }
864514f5e3Sopenharmony_ci
874514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
884514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> index = GetCallArg(argv, 1);
894514f5e3Sopenharmony_ci    if (index->IsDouble()) {
904514f5e3Sopenharmony_ci        // Math.floor(1) will produce TaggedDouble, we need to cast into TaggedInt
914514f5e3Sopenharmony_ci        // For integer which is greater than INT32_MAX, it will remain TaggedDouble
924514f5e3Sopenharmony_ci        index = JSHandle<JSTaggedValue>(thread, JSTaggedValue::TryCastDoubleToInt32(index->GetDouble()));
934514f5e3Sopenharmony_ci    }
944514f5e3Sopenharmony_ci    if (!index->IsInt()) {
954514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, index);
964514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
974514f5e3Sopenharmony_ci        CString errorMsg =
984514f5e3Sopenharmony_ci            "The type of \"index\" must be small integer. Received value is: " + ConvertToString(*result);
994514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
1004514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1014514f5e3Sopenharmony_ci    }
1024514f5e3Sopenharmony_ci    JSAPIArrayList::Insert(thread, JSHandle<JSAPIArrayList>::Cast(self), value, JSTaggedValue::ToUint32(thread, index));
1034514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1044514f5e3Sopenharmony_ci
1054514f5e3Sopenharmony_ci    return JSTaggedValue::Undefined();
1064514f5e3Sopenharmony_ci}
1074514f5e3Sopenharmony_ci
1084514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Clear(EcmaRuntimeCallInfo *argv)
1094514f5e3Sopenharmony_ci{
1104514f5e3Sopenharmony_ci    ASSERT(argv);
1114514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Clear);
1124514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1134514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1144514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
1154514f5e3Sopenharmony_ci
1164514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
1174514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
1184514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
1194514f5e3Sopenharmony_ci        } else {
1204514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
1214514f5e3Sopenharmony_ci                                                                "The clear method cannot be bound");
1224514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1234514f5e3Sopenharmony_ci        }
1244514f5e3Sopenharmony_ci    }
1254514f5e3Sopenharmony_ci
1264514f5e3Sopenharmony_ci    JSAPIArrayList::Clear(thread, JSHandle<JSAPIArrayList>::Cast(self));
1274514f5e3Sopenharmony_ci
1284514f5e3Sopenharmony_ci    return JSTaggedValue::True();
1294514f5e3Sopenharmony_ci}
1304514f5e3Sopenharmony_ci
1314514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Clone(EcmaRuntimeCallInfo *argv)
1324514f5e3Sopenharmony_ci{
1334514f5e3Sopenharmony_ci    ASSERT(argv);
1344514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Clone);
1354514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1364514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1374514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
1384514f5e3Sopenharmony_ci
1394514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
1404514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
1414514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
1424514f5e3Sopenharmony_ci        } else {
1434514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR,
1444514f5e3Sopenharmony_ci                                                                "The clone method cannot be bound");
1454514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1464514f5e3Sopenharmony_ci        }
1474514f5e3Sopenharmony_ci    }
1484514f5e3Sopenharmony_ci
1494514f5e3Sopenharmony_ci    JSHandle<JSAPIArrayList> newArrayList = JSAPIArrayList::Clone(thread, JSHandle<JSAPIArrayList>::Cast(self));
1504514f5e3Sopenharmony_ci
1514514f5e3Sopenharmony_ci    return newArrayList.GetTaggedValue();
1524514f5e3Sopenharmony_ci}
1534514f5e3Sopenharmony_ci
1544514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Has(EcmaRuntimeCallInfo *argv)
1554514f5e3Sopenharmony_ci{
1564514f5e3Sopenharmony_ci    ASSERT(argv);
1574514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Has);
1584514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1594514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
1604514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
1614514f5e3Sopenharmony_ci
1624514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
1634514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
1644514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
1654514f5e3Sopenharmony_ci        } else {
1664514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR,
1674514f5e3Sopenharmony_ci                                                                "The has method cannot be bound");
1684514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1694514f5e3Sopenharmony_ci        }
1704514f5e3Sopenharmony_ci    }
1714514f5e3Sopenharmony_ci
1724514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
1734514f5e3Sopenharmony_ci    bool isHas = JSHandle<JSAPIArrayList>::Cast(self)->Has(value.GetTaggedValue());
1744514f5e3Sopenharmony_ci
1754514f5e3Sopenharmony_ci    return GetTaggedBoolean(isHas);
1764514f5e3Sopenharmony_ci}
1774514f5e3Sopenharmony_ci
1784514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::GetCapacity(EcmaRuntimeCallInfo *argv)
1794514f5e3Sopenharmony_ci{
1804514f5e3Sopenharmony_ci    ASSERT(argv);
1814514f5e3Sopenharmony_ci
1824514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetCapacity);
1834514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
1844514f5e3Sopenharmony_ci
1854514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
1864514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
1874514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
1884514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
1894514f5e3Sopenharmony_ci        } else {
1904514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
1914514f5e3Sopenharmony_ci                                                                "The getCapacity method cannot be bound");
1924514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
1934514f5e3Sopenharmony_ci        }
1944514f5e3Sopenharmony_ci    }
1954514f5e3Sopenharmony_ci
1964514f5e3Sopenharmony_ci    uint32_t capacity = JSAPIArrayList::GetCapacity(thread, JSHandle<JSAPIArrayList>::Cast(self));
1974514f5e3Sopenharmony_ci
1984514f5e3Sopenharmony_ci    return JSTaggedValue(capacity);
1994514f5e3Sopenharmony_ci}
2004514f5e3Sopenharmony_ci
2014514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::IncreaseCapacityTo(EcmaRuntimeCallInfo *argv)
2024514f5e3Sopenharmony_ci{
2034514f5e3Sopenharmony_ci    ASSERT(argv);
2044514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, IncreaseCapacityTo);
2054514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2064514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2074514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
2084514f5e3Sopenharmony_ci
2094514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
2104514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
2114514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
2124514f5e3Sopenharmony_ci        } else {
2134514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
2144514f5e3Sopenharmony_ci                                                                "The increaseCapacityTo method cannot be bound");
2154514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2164514f5e3Sopenharmony_ci        }
2174514f5e3Sopenharmony_ci    }
2184514f5e3Sopenharmony_ci
2194514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> newCapacity = GetCallArg(argv, 0);
2204514f5e3Sopenharmony_ci    if (!newCapacity->IsInteger()) {
2214514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, newCapacity);
2224514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
2234514f5e3Sopenharmony_ci        CString errorMsg =
2244514f5e3Sopenharmony_ci            "The type of \"newCapacity\" must be number. Received value is: " + ConvertToString(*result);
2254514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
2264514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2274514f5e3Sopenharmony_ci    }
2284514f5e3Sopenharmony_ci
2294514f5e3Sopenharmony_ci    JSAPIArrayList::IncreaseCapacityTo(thread, JSHandle<JSAPIArrayList>::Cast(self),
2304514f5e3Sopenharmony_ci                                       JSTaggedValue::ToUint32(thread, newCapacity));
2314514f5e3Sopenharmony_ci
2324514f5e3Sopenharmony_ci    return JSTaggedValue::True();
2334514f5e3Sopenharmony_ci}
2344514f5e3Sopenharmony_ci
2354514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::TrimToCurrentLength(EcmaRuntimeCallInfo *argv)
2364514f5e3Sopenharmony_ci{
2374514f5e3Sopenharmony_ci    ASSERT(argv);
2384514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, TrimToCurrentLength);
2394514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2404514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2414514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
2424514f5e3Sopenharmony_ci
2434514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
2444514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
2454514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
2464514f5e3Sopenharmony_ci        } else {
2474514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
2484514f5e3Sopenharmony_ci                                                                "The trimToCurrentLength method cannot be bound");
2494514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2504514f5e3Sopenharmony_ci        }
2514514f5e3Sopenharmony_ci    }
2524514f5e3Sopenharmony_ci
2534514f5e3Sopenharmony_ci    JSAPIArrayList::TrimToCurrentLength(thread, JSHandle<JSAPIArrayList>::Cast(self));
2544514f5e3Sopenharmony_ci
2554514f5e3Sopenharmony_ci    return JSTaggedValue::True();
2564514f5e3Sopenharmony_ci}
2574514f5e3Sopenharmony_ci
2584514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Get(EcmaRuntimeCallInfo *argv)
2594514f5e3Sopenharmony_ci{
2604514f5e3Sopenharmony_ci    ASSERT(argv);
2614514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Get);
2624514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2634514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2644514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
2654514f5e3Sopenharmony_ci
2664514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
2674514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
2684514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
2694514f5e3Sopenharmony_ci        } else {
2704514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
2714514f5e3Sopenharmony_ci                                                                "The get method cannot be bound");
2724514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2734514f5e3Sopenharmony_ci        }
2744514f5e3Sopenharmony_ci    }
2754514f5e3Sopenharmony_ci
2764514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
2774514f5e3Sopenharmony_ci
2784514f5e3Sopenharmony_ci    JSTaggedValue element = JSHandle<JSAPIArrayList>::Cast(self)->Get(thread, JSTaggedValue::ToUint32(thread, value));
2794514f5e3Sopenharmony_ci
2804514f5e3Sopenharmony_ci    return element;
2814514f5e3Sopenharmony_ci}
2824514f5e3Sopenharmony_ci
2834514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::GetIndexOf(EcmaRuntimeCallInfo *argv)
2844514f5e3Sopenharmony_ci{
2854514f5e3Sopenharmony_ci    ASSERT(argv);
2864514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetIndexOf);
2874514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
2884514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
2894514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
2904514f5e3Sopenharmony_ci
2914514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
2924514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
2934514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
2944514f5e3Sopenharmony_ci        } else {
2954514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
2964514f5e3Sopenharmony_ci                                                                "The getIndexOf method cannot be bound");
2974514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
2984514f5e3Sopenharmony_ci        }
2994514f5e3Sopenharmony_ci    }
3004514f5e3Sopenharmony_ci
3014514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
3024514f5e3Sopenharmony_ci
3034514f5e3Sopenharmony_ci    return JSTaggedValue(JSAPIArrayList::GetIndexOf(thread, JSHandle<JSAPIArrayList>::Cast(self), value));
3044514f5e3Sopenharmony_ci}
3054514f5e3Sopenharmony_ci
3064514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::IsEmpty(EcmaRuntimeCallInfo *argv)
3074514f5e3Sopenharmony_ci{
3084514f5e3Sopenharmony_ci    ASSERT(argv);
3094514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, IsEmpty);
3104514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3114514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3124514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
3134514f5e3Sopenharmony_ci
3144514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
3154514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
3164514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
3174514f5e3Sopenharmony_ci        } else {
3184514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
3194514f5e3Sopenharmony_ci                                                                "The isEmpty method cannot be bound");
3204514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
3214514f5e3Sopenharmony_ci        }
3224514f5e3Sopenharmony_ci    }
3234514f5e3Sopenharmony_ci
3244514f5e3Sopenharmony_ci    return JSTaggedValue(JSAPIArrayList::IsEmpty(JSHandle<JSAPIArrayList>::Cast(self)));
3254514f5e3Sopenharmony_ci}
3264514f5e3Sopenharmony_ci
3274514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::GetLastIndexOf(EcmaRuntimeCallInfo *argv)
3284514f5e3Sopenharmony_ci{
3294514f5e3Sopenharmony_ci    ASSERT(argv);
3304514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetLastIndexOf);
3314514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3324514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3334514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
3344514f5e3Sopenharmony_ci
3354514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
3364514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
3374514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
3384514f5e3Sopenharmony_ci        } else {
3394514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
3404514f5e3Sopenharmony_ci                                                                "The getLastIndexOf method cannot be bound");
3414514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
3424514f5e3Sopenharmony_ci        }
3434514f5e3Sopenharmony_ci    }
3444514f5e3Sopenharmony_ci
3454514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
3464514f5e3Sopenharmony_ci
3474514f5e3Sopenharmony_ci    return JSTaggedValue(JSAPIArrayList::GetLastIndexOf(thread, JSHandle<JSAPIArrayList>::Cast(self), value));
3484514f5e3Sopenharmony_ci}
3494514f5e3Sopenharmony_ci
3504514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::RemoveByIndex(EcmaRuntimeCallInfo *argv)
3514514f5e3Sopenharmony_ci{
3524514f5e3Sopenharmony_ci    ASSERT(argv);
3534514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, RemoveByIndex);
3544514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3554514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3564514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
3574514f5e3Sopenharmony_ci
3584514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
3594514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
3604514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
3614514f5e3Sopenharmony_ci        } else {
3624514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
3634514f5e3Sopenharmony_ci                                                                "The removeByIndex method cannot be bound");
3644514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
3654514f5e3Sopenharmony_ci        }
3664514f5e3Sopenharmony_ci    }
3674514f5e3Sopenharmony_ci
3684514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
3694514f5e3Sopenharmony_ci    if (value->IsDouble()) {
3704514f5e3Sopenharmony_ci        value = JSHandle<JSTaggedValue>(thread, JSTaggedValue::TryCastDoubleToInt32(value->GetDouble()));
3714514f5e3Sopenharmony_ci    }
3724514f5e3Sopenharmony_ci    if (!value->IsInt()) {
3734514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value.GetTaggedValue());
3744514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3754514f5e3Sopenharmony_ci        CString errorMsg =
3764514f5e3Sopenharmony_ci            "The type of \"index\" must be small integer. Received value is: " + ConvertToString(*result);
3774514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
3784514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
3794514f5e3Sopenharmony_ci    }
3804514f5e3Sopenharmony_ci
3814514f5e3Sopenharmony_ci    JSTaggedValue result =
3824514f5e3Sopenharmony_ci        JSAPIArrayList::RemoveByIndex(thread,
3834514f5e3Sopenharmony_ci                                      JSHandle<JSAPIArrayList>::Cast(self), JSTaggedValue::ToUint32(thread, value));
3844514f5e3Sopenharmony_ci
3854514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
3864514f5e3Sopenharmony_ci    return result;
3874514f5e3Sopenharmony_ci}
3884514f5e3Sopenharmony_ci
3894514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Remove(EcmaRuntimeCallInfo *argv)
3904514f5e3Sopenharmony_ci{
3914514f5e3Sopenharmony_ci    ASSERT(argv);
3924514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Remove);
3934514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
3944514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
3954514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
3964514f5e3Sopenharmony_ci
3974514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
3984514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
3994514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
4004514f5e3Sopenharmony_ci        } else {
4014514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
4024514f5e3Sopenharmony_ci                                                                "The remove method cannot be bound");
4034514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
4044514f5e3Sopenharmony_ci        }
4054514f5e3Sopenharmony_ci    }
4064514f5e3Sopenharmony_ci
4074514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
4084514f5e3Sopenharmony_ci
4094514f5e3Sopenharmony_ci    bool isRemove = JSAPIArrayList::Remove(thread, JSHandle<JSAPIArrayList>::Cast(self), value);
4104514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4114514f5e3Sopenharmony_ci
4124514f5e3Sopenharmony_ci    return GetTaggedBoolean(isRemove);
4134514f5e3Sopenharmony_ci}
4144514f5e3Sopenharmony_ci
4154514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::RemoveByRange(EcmaRuntimeCallInfo *argv)
4164514f5e3Sopenharmony_ci{
4174514f5e3Sopenharmony_ci    ASSERT(argv);
4184514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, RemoveByRange);
4194514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
4204514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
4214514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
4224514f5e3Sopenharmony_ci
4234514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
4244514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
4254514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
4264514f5e3Sopenharmony_ci        } else {
4274514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, BIND_ERROR,
4284514f5e3Sopenharmony_ci                                                                "The removeByRange method cannot be bound");
4294514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
4304514f5e3Sopenharmony_ci        }
4314514f5e3Sopenharmony_ci    }
4324514f5e3Sopenharmony_ci
4334514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> startIndex = GetCallArg(argv, 0);
4344514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> endIndex = GetCallArg(argv, 1);
4354514f5e3Sopenharmony_ci    if (!startIndex->IsInteger()) {
4364514f5e3Sopenharmony_ci        std::ostringstream oss;
4374514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, startIndex);
4384514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4394514f5e3Sopenharmony_ci        CString errorMsg =
4404514f5e3Sopenharmony_ci            "The type of \"fromIndex\" must be number. Received value is: " + ConvertToString(*result);
4414514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
4424514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
4434514f5e3Sopenharmony_ci    }
4444514f5e3Sopenharmony_ci    if (!endIndex->IsInteger()) {
4454514f5e3Sopenharmony_ci        std::ostringstream oss;
4464514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, endIndex);
4474514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4484514f5e3Sopenharmony_ci        CString errorMsg =
4494514f5e3Sopenharmony_ci            "The type of \"toIndex\" must be number. Received value is: " + ConvertToString(*result);
4504514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
4514514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
4524514f5e3Sopenharmony_ci    }
4534514f5e3Sopenharmony_ci    JSTaggedValue result =
4544514f5e3Sopenharmony_ci        JSAPIArrayList::RemoveByRange(thread, JSHandle<JSAPIArrayList>::Cast(self), startIndex, endIndex);
4554514f5e3Sopenharmony_ci
4564514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4574514f5e3Sopenharmony_ci    return result;
4584514f5e3Sopenharmony_ci}
4594514f5e3Sopenharmony_ci
4604514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::ReplaceAllElements(EcmaRuntimeCallInfo *argv)
4614514f5e3Sopenharmony_ci{
4624514f5e3Sopenharmony_ci    ASSERT(argv);
4634514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, ReplaceAllElements);
4644514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
4654514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
4664514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
4674514f5e3Sopenharmony_ci
4684514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
4694514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
4704514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
4714514f5e3Sopenharmony_ci        } else {
4724514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
4734514f5e3Sopenharmony_ci                                                                "The replaceAllElements method cannot be bound");
4744514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
4754514f5e3Sopenharmony_ci        }
4764514f5e3Sopenharmony_ci    }
4774514f5e3Sopenharmony_ci
4784514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
4794514f5e3Sopenharmony_ci    if (!callbackFnHandle->IsCallable()) {
4804514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, callbackFnHandle);
4814514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
4824514f5e3Sopenharmony_ci        CString errorMsg =
4834514f5e3Sopenharmony_ci            "The type of \"callbackfn\" must be callable. Received value is: " + ConvertToString(*result);
4844514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
4854514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
4864514f5e3Sopenharmony_ci    }
4874514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
4884514f5e3Sopenharmony_ci
4894514f5e3Sopenharmony_ci    return JSAPIArrayList::ReplaceAllElements(thread, self, callbackFnHandle, thisArgHandle);
4904514f5e3Sopenharmony_ci}
4914514f5e3Sopenharmony_ci
4924514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Set(EcmaRuntimeCallInfo *argv)
4934514f5e3Sopenharmony_ci{
4944514f5e3Sopenharmony_ci    ASSERT(argv);
4954514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, Set);
4964514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
4974514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
4984514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
4994514f5e3Sopenharmony_ci
5004514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
5014514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
5024514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
5034514f5e3Sopenharmony_ci        } else {
5044514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
5054514f5e3Sopenharmony_ci                                                                "The set method cannot be bound");
5064514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
5074514f5e3Sopenharmony_ci        }
5084514f5e3Sopenharmony_ci    }
5094514f5e3Sopenharmony_ci
5104514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> index = GetCallArg(argv, 0);
5114514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value = GetCallArg(argv, 1);
5124514f5e3Sopenharmony_ci    JSHandle<JSAPIArrayList>::Cast(self)->Set(thread, JSTaggedValue::ToUint32(thread, index), value.GetTaggedValue());
5134514f5e3Sopenharmony_ci
5144514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5154514f5e3Sopenharmony_ci    return JSTaggedValue::Undefined();
5164514f5e3Sopenharmony_ci}
5174514f5e3Sopenharmony_ci
5184514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::SubArrayList(EcmaRuntimeCallInfo *argv)
5194514f5e3Sopenharmony_ci{
5204514f5e3Sopenharmony_ci    ASSERT(argv);
5214514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, SubArrayList);
5224514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
5234514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
5244514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
5254514f5e3Sopenharmony_ci
5264514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
5274514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
5284514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
5294514f5e3Sopenharmony_ci        } else {
5304514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
5314514f5e3Sopenharmony_ci                                                                "The subArrayList method cannot be bound");
5324514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
5334514f5e3Sopenharmony_ci        }
5344514f5e3Sopenharmony_ci    }
5354514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value1 = GetCallArg(argv, 0);
5364514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> value2 = GetCallArg(argv, 1);
5374514f5e3Sopenharmony_ci    if (!value1->IsInteger()) {
5384514f5e3Sopenharmony_ci        std::ostringstream oss;
5394514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value1);
5404514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5414514f5e3Sopenharmony_ci        CString errorMsg =
5424514f5e3Sopenharmony_ci            "The type of \"fromIndex\" must be number. Received value is: " + ConvertToString(*result);
5434514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
5444514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
5454514f5e3Sopenharmony_ci    }
5464514f5e3Sopenharmony_ci    if (!value2->IsInteger()) {
5474514f5e3Sopenharmony_ci        std::ostringstream oss;
5484514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, value2);
5494514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5504514f5e3Sopenharmony_ci        CString errorMsg =
5514514f5e3Sopenharmony_ci            "The type of \"toIndex\" must be number. Received value is: " + ConvertToString(*result);
5524514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
5534514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
5544514f5e3Sopenharmony_ci    }
5554514f5e3Sopenharmony_ci    JSTaggedValue newArrayList =
5564514f5e3Sopenharmony_ci        JSAPIArrayList::SubArrayList(thread, JSHandle<JSAPIArrayList>::Cast(self), value1, value2);
5574514f5e3Sopenharmony_ci
5584514f5e3Sopenharmony_ci    RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5594514f5e3Sopenharmony_ci    return newArrayList;
5604514f5e3Sopenharmony_ci}
5614514f5e3Sopenharmony_ci
5624514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::Sort(EcmaRuntimeCallInfo *argv)
5634514f5e3Sopenharmony_ci{
5644514f5e3Sopenharmony_ci    ASSERT(argv);
5654514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), Array, Sort);
5664514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
5674514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
5684514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
5694514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
5704514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
5714514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
5724514f5e3Sopenharmony_ci        } else {
5734514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
5744514f5e3Sopenharmony_ci                                                                "The sort method cannot be bound");
5754514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
5764514f5e3Sopenharmony_ci        }
5774514f5e3Sopenharmony_ci    }
5784514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
5794514f5e3Sopenharmony_ci    if (!callbackFnHandle->IsUndefined() && !callbackFnHandle->IsCallable() && !callbackFnHandle->IsNull()) {
5804514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, callbackFnHandle);
5814514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
5824514f5e3Sopenharmony_ci        CString errorMsg =
5834514f5e3Sopenharmony_ci            "The type of \"comparator\" must be callable. Received value is: " + ConvertToString(*result);
5844514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
5854514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
5864514f5e3Sopenharmony_ci    }
5874514f5e3Sopenharmony_ci    JSHandle<TaggedArray> elements(thread, JSHandle<JSAPIArrayList>::Cast(self)->GetElements());
5884514f5e3Sopenharmony_ci    JSMutableHandle<JSTaggedValue> presentValue(thread, JSTaggedValue::Undefined());
5894514f5e3Sopenharmony_ci    JSMutableHandle<JSTaggedValue> middleValue(thread, JSTaggedValue::Undefined());
5904514f5e3Sopenharmony_ci    JSMutableHandle<JSTaggedValue> previousValue(thread, JSTaggedValue::Undefined());
5914514f5e3Sopenharmony_ci    uint32_t length = JSHandle<JSAPIArrayList>::Cast(self)->GetLength().GetArrayLength();
5924514f5e3Sopenharmony_ci    for (uint32_t i = 1; i < length; i++) {
5934514f5e3Sopenharmony_ci        uint32_t beginIndex = 0;
5944514f5e3Sopenharmony_ci        uint32_t endIndex = i;
5954514f5e3Sopenharmony_ci        presentValue.Update(elements->Get(i));
5964514f5e3Sopenharmony_ci        while (beginIndex < endIndex) {
5974514f5e3Sopenharmony_ci            uint32_t middleIndex = (beginIndex + endIndex) / 2; // 2 : half
5984514f5e3Sopenharmony_ci            middleValue.Update(elements->Get(middleIndex));
5994514f5e3Sopenharmony_ci            double compareResult = base::ArrayHelper::SortCompare(thread, callbackFnHandle,
6004514f5e3Sopenharmony_ci                                                                  middleValue, presentValue);
6014514f5e3Sopenharmony_ci            RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
6024514f5e3Sopenharmony_ci            if (compareResult > 0) {
6034514f5e3Sopenharmony_ci                endIndex = middleIndex;
6044514f5e3Sopenharmony_ci            } else {
6054514f5e3Sopenharmony_ci                beginIndex = middleIndex + 1;
6064514f5e3Sopenharmony_ci            }
6074514f5e3Sopenharmony_ci        }
6084514f5e3Sopenharmony_ci        if (endIndex >= 0 && endIndex < i) {
6094514f5e3Sopenharmony_ci            for (uint32_t j = i; j > endIndex; j--) {
6104514f5e3Sopenharmony_ci                previousValue.Update(elements->Get(j - 1));
6114514f5e3Sopenharmony_ci                elements->Set(thread, j, previousValue.GetTaggedValue());
6124514f5e3Sopenharmony_ci            }
6134514f5e3Sopenharmony_ci            elements->Set(thread, endIndex, presentValue.GetTaggedValue());
6144514f5e3Sopenharmony_ci        }
6154514f5e3Sopenharmony_ci    }
6164514f5e3Sopenharmony_ci    return JSTaggedValue::Undefined();
6174514f5e3Sopenharmony_ci}
6184514f5e3Sopenharmony_ci
6194514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::GetSize(EcmaRuntimeCallInfo *argv)
6204514f5e3Sopenharmony_ci{
6214514f5e3Sopenharmony_ci    ASSERT(argv);
6224514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetSize);
6234514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
6244514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
6254514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
6264514f5e3Sopenharmony_ci
6274514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
6284514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
6294514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
6304514f5e3Sopenharmony_ci        } else {
6314514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
6324514f5e3Sopenharmony_ci                                                                "The getLength method cannot be bound");
6334514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
6344514f5e3Sopenharmony_ci        }
6354514f5e3Sopenharmony_ci    }
6364514f5e3Sopenharmony_ci
6374514f5e3Sopenharmony_ci    return JSTaggedValue(JSHandle<JSAPIArrayList>::Cast(self)->GetSize());
6384514f5e3Sopenharmony_ci}
6394514f5e3Sopenharmony_ci
6404514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::ConvertToArray(EcmaRuntimeCallInfo *argv)
6414514f5e3Sopenharmony_ci{
6424514f5e3Sopenharmony_ci    ASSERT(argv);
6434514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, ConvertToArray);
6444514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
6454514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
6464514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
6474514f5e3Sopenharmony_ci
6484514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
6494514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
6504514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
6514514f5e3Sopenharmony_ci        } else {
6524514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
6534514f5e3Sopenharmony_ci                                                                "The convertToArray method cannot be bound");
6544514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
6554514f5e3Sopenharmony_ci        }
6564514f5e3Sopenharmony_ci    }
6574514f5e3Sopenharmony_ci
6584514f5e3Sopenharmony_ci    JSHandle<JSAPIArrayList> arrayList = JSHandle<JSAPIArrayList>::Cast(self);
6594514f5e3Sopenharmony_ci    auto factory = thread->GetEcmaVM()->GetFactory();
6604514f5e3Sopenharmony_ci    JSHandle<JSArray> array = factory->NewJSArray();
6614514f5e3Sopenharmony_ci
6624514f5e3Sopenharmony_ci    uint32_t length = arrayList->GetLength().GetArrayLength();
6634514f5e3Sopenharmony_ci    array->SetArrayLength(thread, length);
6644514f5e3Sopenharmony_ci
6654514f5e3Sopenharmony_ci    JSHandle<TaggedArray> srcElements(thread, arrayList->GetElements());
6664514f5e3Sopenharmony_ci    JSHandle<TaggedArray> dstElements = factory->NewAndCopyTaggedArray(srcElements, length, length);
6674514f5e3Sopenharmony_ci    array->SetElements(thread, dstElements);
6684514f5e3Sopenharmony_ci    return array.GetTaggedValue();
6694514f5e3Sopenharmony_ci}
6704514f5e3Sopenharmony_ci
6714514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::ForEach(EcmaRuntimeCallInfo *argv)
6724514f5e3Sopenharmony_ci{
6734514f5e3Sopenharmony_ci    ASSERT(argv);
6744514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, ForEach);
6754514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
6764514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
6774514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
6784514f5e3Sopenharmony_ci
6794514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
6804514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
6814514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
6824514f5e3Sopenharmony_ci        } else {
6834514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
6844514f5e3Sopenharmony_ci                                                                "The forEach method cannot be bound");
6854514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
6864514f5e3Sopenharmony_ci        }
6874514f5e3Sopenharmony_ci    }
6884514f5e3Sopenharmony_ci
6894514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> callbackFnHandle = GetCallArg(argv, 0);
6904514f5e3Sopenharmony_ci    if (!callbackFnHandle->IsCallable()) {
6914514f5e3Sopenharmony_ci        JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, callbackFnHandle);
6924514f5e3Sopenharmony_ci        RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
6934514f5e3Sopenharmony_ci        CString errorMsg =
6944514f5e3Sopenharmony_ci            "The type of \"callbackfn\" must be callable. Received value is: " + ConvertToString(*result);
6954514f5e3Sopenharmony_ci        JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
6964514f5e3Sopenharmony_ci        THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
6974514f5e3Sopenharmony_ci    }
6984514f5e3Sopenharmony_ci
6994514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> thisArgHandle = GetCallArg(argv, 1);
7004514f5e3Sopenharmony_ci
7014514f5e3Sopenharmony_ci    return JSAPIArrayList::ForEach(thread, self, callbackFnHandle, thisArgHandle);
7024514f5e3Sopenharmony_ci}
7034514f5e3Sopenharmony_ci
7044514f5e3Sopenharmony_ciJSTaggedValue ContainersArrayList::GetIteratorObj(EcmaRuntimeCallInfo *argv)
7054514f5e3Sopenharmony_ci{
7064514f5e3Sopenharmony_ci    ASSERT(argv);
7074514f5e3Sopenharmony_ci    BUILTINS_API_TRACE(argv->GetThread(), ArrayList, GetIteratorObj);
7084514f5e3Sopenharmony_ci    JSThread *thread = argv->GetThread();
7094514f5e3Sopenharmony_ci    [[maybe_unused]] EcmaHandleScope handleScope(thread);
7104514f5e3Sopenharmony_ci
7114514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> self = GetThis(argv);
7124514f5e3Sopenharmony_ci
7134514f5e3Sopenharmony_ci    if (!self->IsJSAPIArrayList()) {
7144514f5e3Sopenharmony_ci        if (self->IsJSProxy() && JSHandle<JSProxy>::Cast(self)->GetTarget().IsJSAPIArrayList()) {
7154514f5e3Sopenharmony_ci            self = JSHandle<JSTaggedValue>(thread, JSHandle<JSProxy>::Cast(self)->GetTarget());
7164514f5e3Sopenharmony_ci        } else {
7174514f5e3Sopenharmony_ci            JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::BIND_ERROR,
7184514f5e3Sopenharmony_ci                                                                "The Symbol.iterator method cannot be bound");
7194514f5e3Sopenharmony_ci            THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
7204514f5e3Sopenharmony_ci        }
7214514f5e3Sopenharmony_ci    }
7224514f5e3Sopenharmony_ci
7234514f5e3Sopenharmony_ci    JSTaggedValue values = JSAPIArrayList::GetIteratorObj(thread, JSHandle<JSAPIArrayList>::Cast(self));
7244514f5e3Sopenharmony_ci
7254514f5e3Sopenharmony_ci    return values;
7264514f5e3Sopenharmony_ci}
7274514f5e3Sopenharmony_ci}  // namespace panda::ecmascript::containers
728