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