• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/js_api/js_api_arraylist.h"
17 
18 #include "ecmascript/containers/containers_errors.h"
19 #include "ecmascript/interpreter/interpreter.h"
20 #include "ecmascript/js_iterator.h"
21 #include "ecmascript/js_function.h"
22 #include "ecmascript/js_api/js_api_arraylist_iterator.h"
23 #include "ecmascript/js_function.h"
24 #include "ecmascript/js_iterator.h"
25 #include "ecmascript/js_tagged_value.h"
26 #include "ecmascript/object_factory.h"
27 
28 namespace panda::ecmascript {
29 using ContainerError = containers::ContainerError;
30 using ErrorFlag = containers::ErrorFlag;
Add(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value)31 bool JSAPIArrayList::Add(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
32                          const JSHandle<JSTaggedValue> &value)
33 {
34     uint32_t length = arrayList->GetLength().GetArrayLength();
35     JSHandle<TaggedArray> elements = GrowCapacity(thread, arrayList, length + 1);
36 
37     ASSERT(!elements->IsDictionaryMode());
38     elements->Set(thread, length, value);
39     arrayList->SetLength(thread, JSTaggedValue(++length));
40     return true;
41 }
42 
Insert(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value,const int & index)43 void JSAPIArrayList::Insert(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
44                             const JSHandle<JSTaggedValue> &value, const int &index)
45 {
46     int length = arrayList->GetLength().GetInt();
47     if (index < 0 || index > length) {
48         std::ostringstream oss;
49         oss << "The value of \"index\" is out of range. It must be >= 0 && <= " << length
50             << ". Received value is: " << index;
51         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
52         THROW_NEW_ERROR_AND_RETURN(thread, error);
53     }
54     JSHandle<TaggedArray> elements = GrowCapacity(thread, arrayList, length + 1);
55     ASSERT(!elements->IsDictionaryMode());
56     for (int i = length - 1; i >= index; --i) {
57         elements->Set(thread, i + 1, elements->Get(i));
58     }
59     elements->Set(thread, index, value);
60     arrayList->SetLength(thread, JSTaggedValue(++length));
61 }
62 
Clear(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList)63 void JSAPIArrayList::Clear(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList)
64 {
65     if (!arrayList.IsEmpty()) {
66         int length = arrayList->GetLength().GetInt();
67         JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
68         ASSERT(!elements->IsDictionaryMode());
69         for (int i = 0; i <= length; ++i) {
70             elements->Set(thread, i, JSTaggedValue::Hole());
71         }
72         arrayList->SetLength(thread, JSTaggedValue(0));
73     }
74 }
75 
Clone(JSThread * thread,const JSHandle<JSAPIArrayList> & obj)76 JSHandle<JSAPIArrayList> JSAPIArrayList::Clone(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
77 {
78     JSHandle<TaggedArray> srcElements(thread, obj->GetElements());
79     ASSERT(!srcElements->IsDictionaryMode());
80 
81     int32_t length = obj->GetSize();
82     auto factory = thread->GetEcmaVM()->GetFactory();
83     JSHandle<JSAPIArrayList> newArrayList = factory->NewJSAPIArrayList(0);
84     newArrayList->SetLength(thread, JSTaggedValue(length));
85 
86     JSHandle<TaggedArray> dstElements = factory->NewAndCopyTaggedArray(srcElements, length, length);
87     newArrayList->SetElements(thread, dstElements);
88     return newArrayList;
89 }
90 
GetCapacity(JSThread * thread,const JSHandle<JSAPIArrayList> & obj)91 uint32_t JSAPIArrayList::GetCapacity(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
92 {
93     JSHandle<TaggedArray> elements(thread, obj->GetElements());
94     ASSERT(!elements->IsDictionaryMode());
95     uint32_t capacity = elements->GetLength();
96     return capacity;
97 }
98 
IncreaseCapacityTo(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,int capacity)99 void JSAPIArrayList::IncreaseCapacityTo(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
100                                         int capacity)
101 {
102     JSHandle<TaggedArray> elementData(thread, arrayList->GetElements());
103     ASSERT(!elementData->IsDictionaryMode());
104     int length = arrayList->GetLength().GetInt();
105     int oldElementLength = static_cast<int>(elementData->GetLength());
106     if (oldElementLength != capacity && length < capacity) {
107         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
108         JSHandle<TaggedArray> newElements = factory->NewAndCopyTaggedArray(elementData,
109             static_cast<uint32_t>(capacity), static_cast<uint32_t>(length));
110         arrayList->SetElements(thread, newElements);
111     }
112 }
113 
TrimToCurrentLength(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList)114 void JSAPIArrayList::TrimToCurrentLength(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList)
115 {
116     uint32_t length = arrayList->GetLength().GetArrayLength();
117     uint32_t capacity = JSAPIArrayList::GetCapacity(thread, arrayList);
118     JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
119     ASSERT(!elements->IsDictionaryMode());
120     if (capacity > length) {
121         elements->Trim(thread, length);
122     }
123 }
124 
Get(JSThread * thread,const uint32_t index)125 JSTaggedValue JSAPIArrayList::Get(JSThread *thread, const uint32_t index)
126 {
127     if (index >= GetLength().GetArrayLength()) {
128         std::ostringstream oss;
129         oss << "The value of \"index\" is out of range. It must be >= 0 && <= "
130             << (GetLength().GetArrayLength() - 1) << ". Received value is: " << index;
131         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
132         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
133     }
134 
135     TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
136     return elements->Get(index);
137 }
138 
IsEmpty(const JSHandle<JSAPIArrayList> & arrayList)139 bool JSAPIArrayList::IsEmpty(const JSHandle<JSAPIArrayList> &arrayList)
140 {
141     return arrayList->GetSize() == 0;
142 }
143 
GetIndexOf(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value)144 int JSAPIArrayList::GetIndexOf(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
145                                const JSHandle<JSTaggedValue> &value)
146 {
147     JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
148     ASSERT(!elements->IsDictionaryMode());
149     uint32_t length = arrayList->GetLength().GetArrayLength();
150     JSTaggedValue targetValue = value.GetTaggedValue();
151     for (uint32_t i = 0; i < length; ++i) {
152         if (JSTaggedValue::StrictEqual(targetValue, elements->Get(i))) {
153             return i;
154         }
155     }
156     return -1;
157 }
158 
GetLastIndexOf(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value)159 int JSAPIArrayList::GetLastIndexOf(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
160                                    const JSHandle<JSTaggedValue> &value)
161 {
162     JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
163     ASSERT(!elements->IsDictionaryMode());
164     JSTaggedValue targetValue = value.GetTaggedValue();
165     int length = arrayList->GetLength().GetInt();
166     for (int i = length - 1; i >= 0; --i) {
167         if (JSTaggedValue::StrictEqual(targetValue, elements->Get(i))) {
168             return i;
169         }
170     }
171     return -1;
172 }
173 
RemoveByIndex(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,int index)174 JSTaggedValue JSAPIArrayList::RemoveByIndex(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList, int index)
175 {
176     int length = arrayList->GetLength().GetInt();
177     if (index < 0 || index >= length) {
178         std::ostringstream oss;
179         oss << "The value of \"index\" is out of range. It must be >= 0 && <= " << (length - 1)
180             << ". Received value is: " << index;
181         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
182         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
183     }
184 
185     TaggedArray *resElements = TaggedArray::Cast(arrayList->GetElements().GetTaggedObject());
186     JSTaggedValue oldValue = resElements->Get(index);
187 
188     if (index >= 0) {
189         JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
190         ASSERT(!elements->IsDictionaryMode());
191         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
192         factory->RemoveElementByIndex(elements, index, length);
193         arrayList->SetLength(thread, JSTaggedValue(length - 1));
194     }
195 
196     return oldValue;
197 }
198 
Remove(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value)199 bool JSAPIArrayList::Remove(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
200                             const JSHandle<JSTaggedValue> &value)
201 {
202     int index = GetIndexOf(thread, arrayList, value);
203     int length = arrayList->GetSize();
204     if (index >= 0) {
205         JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
206         ASSERT(!elements->IsDictionaryMode());
207         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
208         factory->RemoveElementByIndex(elements, index, length);
209         arrayList->SetLength(thread, JSTaggedValue(length - 1));
210         return true;
211     }
212     return false;
213 }
214 
RemoveByRange(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value1,const JSHandle<JSTaggedValue> & value2)215 JSTaggedValue JSAPIArrayList::RemoveByRange(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
216                                             const JSHandle<JSTaggedValue> &value1,
217                                             const JSHandle<JSTaggedValue> &value2)
218 {
219     int32_t startIndex = JSTaggedValue::ToInt32(thread, value1);
220     int32_t endIndex = JSTaggedValue::ToInt32(thread, value2);
221     int32_t length = arrayList->GetLength().GetInt();
222     int32_t size = length > endIndex ? endIndex : length;
223     if (startIndex < 0 || startIndex >= size) {
224         std::ostringstream oss;
225         oss << "The value of \"fromIndex\" is out of range. It must be >= 0 && <= " << (size - 1)
226             << ". Received value is: " << startIndex;
227         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
228         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
229     }
230     if (endIndex <= startIndex || endIndex < 0 || endIndex > length) {
231         std::ostringstream oss;
232         oss << "The value of \"toIndex\" is out of range. It must be >= 0 && <= " << length
233             << ". Received value is: " << endIndex;
234         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
235         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
236     }
237 
238     int32_t toIndex = endIndex >= length ? length : endIndex;
239 
240     JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
241     ASSERT(!elements->IsDictionaryMode());
242     int32_t numMoved = length - toIndex;
243 
244     for (int32_t i = 0; i < numMoved; i++) {
245         elements->Set(thread, startIndex + i, elements->Get(static_cast<uint32_t>(endIndex + i)));
246     }
247     int32_t newLength = length - (endIndex - startIndex);
248     arrayList->SetLength(thread, JSTaggedValue(newLength));
249     elements->SetLength(newLength);
250     return JSTaggedValue::Undefined();
251 }
252 
ReplaceAllElements(JSThread * thread,const JSHandle<JSTaggedValue> & thisHandle,const JSHandle<JSTaggedValue> & callbackFn,const JSHandle<JSTaggedValue> & thisArg)253 JSTaggedValue JSAPIArrayList::ReplaceAllElements(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
254                                                  const JSHandle<JSTaggedValue> &callbackFn,
255                                                  const JSHandle<JSTaggedValue> &thisArg)
256 {
257     JSHandle<JSAPIArrayList> arrayList = JSHandle<JSAPIArrayList>::Cast(thisHandle);
258     uint32_t length = static_cast<uint32_t>(arrayList->GetSize());
259     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
260     JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
261     const int32_t argsLength = 3;
262     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
263     for (uint32_t k = 0; k < length; k++) {
264         kValue.Update(arrayList->Get(thread, k));
265         key.Update(JSTaggedValue(k));
266         EcmaRuntimeCallInfo *info =
267             EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFn, thisArg, undefined, argsLength);
268         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
269         info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisHandle.GetTaggedValue());
270         JSTaggedValue funcResult = JSFunction::Call(info);
271         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
272 
273         arrayList->Set(thread, k, funcResult);
274     }
275 
276     return JSTaggedValue::Undefined();
277 }
278 
Set(JSThread * thread,const uint32_t index,JSTaggedValue value)279 JSTaggedValue JSAPIArrayList::Set(JSThread *thread, const uint32_t index, JSTaggedValue value)
280 {
281     if (index >= GetLength().GetArrayLength()) {
282         std::ostringstream oss;
283         oss << "The value of \"index\" is out of range. It must be >= 0 && <= "
284             << (GetLength().GetArrayLength() - 1) << ". Received value is: " << index;
285         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
286         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
287     }
288 
289     TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
290     elements->Set(thread, index, value);
291     return JSTaggedValue::Undefined();
292 }
293 
SubArrayList(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value1,const JSHandle<JSTaggedValue> & value2)294 JSTaggedValue JSAPIArrayList::SubArrayList(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
295                                            const JSHandle<JSTaggedValue> &value1,
296                                            const JSHandle<JSTaggedValue> &value2)
297 {
298     int length = arrayList->GetLength().GetInt();
299     int fromIndex = JSTaggedValue::ToInt32(thread, value1);
300     int toIndex = JSTaggedValue::ToInt32(thread, value2);
301     int32_t size = length > toIndex ? toIndex : length;
302     if (fromIndex < 0 || fromIndex >= size) {
303         std::ostringstream oss;
304         oss << "The value of \"fromIndex\" is out of range. It must be >= 0 && <= " << (size - 1)
305             << ". Received value is: " << fromIndex;
306         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
307         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
308     }
309     if (toIndex <= fromIndex || toIndex < 0 || toIndex > length) {
310         std::ostringstream oss;
311         oss << "The value of \"toIndex\" is out of range. It must be >= 0 && <= " << length
312             << ". Received value is: " << toIndex;
313         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
314         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
315     }
316 
317     int endIndex = toIndex >= length - 1 ? length - 1 : toIndex;
318     int newLength = toIndex == length ? length - fromIndex : endIndex - fromIndex;
319     JSHandle<JSAPIArrayList> subArrayList = thread->GetEcmaVM()->GetFactory()->NewJSAPIArrayList(newLength);
320     if (newLength == 0) {
321         return subArrayList.GetTaggedValue();
322     }
323     JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
324     ASSERT(!elements->IsDictionaryMode());
325     subArrayList->SetLength(thread, JSTaggedValue(newLength));
326 
327     for (int i = 0; i < newLength; i++) {
328         subArrayList->Set(thread, i, elements->Get(fromIndex + i));
329     }
330 
331     return subArrayList.GetTaggedValue();
332 }
333 
ForEach(JSThread * thread,const JSHandle<JSTaggedValue> & thisHandle,const JSHandle<JSTaggedValue> & callbackFn,const JSHandle<JSTaggedValue> & thisArg)334 JSTaggedValue JSAPIArrayList::ForEach(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
335                                       const JSHandle<JSTaggedValue> &callbackFn,
336                                       const JSHandle<JSTaggedValue> &thisArg)
337 {
338     JSHandle<JSAPIArrayList> arrayList = JSHandle<JSAPIArrayList>::Cast(thisHandle);
339     uint32_t length = static_cast<uint32_t>(arrayList->GetSize());
340     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
341     JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
342     const int32_t argsLength = 3;
343     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
344     for (uint32_t k = 0; k < length; k++) {
345         kValue.Update(arrayList->Get(thread, k));
346         key.Update(JSTaggedValue(k));
347         EcmaRuntimeCallInfo *info =
348             EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFn, thisArg, undefined, argsLength);
349         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
350         info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisHandle.GetTaggedValue());
351         JSTaggedValue funcResult = JSFunction::Call(info);
352         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
353         if (static_cast<int>(length) != arrayList->GetSize()) {
354             length = static_cast<uint32_t>(arrayList->GetSize());
355         }
356     }
357 
358     return JSTaggedValue::Undefined();
359 }
360 
GrowCapacity(const JSThread * thread,const JSHandle<JSAPIArrayList> & obj,uint32_t capacity)361 JSHandle<TaggedArray> JSAPIArrayList::GrowCapacity(const JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
362                                                    uint32_t capacity)
363 {
364     JSHandle<TaggedArray> oldElements(thread, obj->GetElements());
365     ASSERT(!oldElements->IsDictionaryMode());
366     uint32_t oldCapacity = oldElements->GetLength();
367     if (capacity < oldCapacity) {
368         return oldElements;
369     }
370     uint32_t newCapacity = ComputeCapacity(capacity);
371     JSHandle<TaggedArray> newElements =
372         thread->GetEcmaVM()->GetFactory()->CopyArray(oldElements, oldCapacity, newCapacity);
373 
374     obj->SetElements(thread, newElements);
375     return newElements;
376 }
377 
Has(const JSTaggedValue value) const378 bool JSAPIArrayList::Has(const JSTaggedValue value) const
379 {
380     TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
381     int32_t length = GetSize();
382     if (length == 0) {
383         return false;
384     }
385 
386     for (int32_t i = 0; i < length; i++) {
387         if (JSTaggedValue::SameValue(elements->Get(i), value)) {
388             return true;
389         }
390     }
391     return false;
392 }
393 
OwnKeys(JSThread * thread,const JSHandle<JSAPIArrayList> & obj)394 JSHandle<TaggedArray> JSAPIArrayList::OwnKeys(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
395 {
396     uint32_t length = obj->GetLength().GetArrayLength();
397     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
398     JSHandle<TaggedArray> keys = factory->NewTaggedArray(length);
399 
400     for (uint32_t i = 0; i < length; i++) {
401         keys->Set(thread, i, JSTaggedValue(i));
402     }
403 
404     return keys;
405 }
406 
GetOwnProperty(JSThread * thread,const JSHandle<JSAPIArrayList> & obj,const JSHandle<JSTaggedValue> & key)407 bool JSAPIArrayList::GetOwnProperty(JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
408                                     const JSHandle<JSTaggedValue> &key)
409 {
410     uint32_t index = 0;
411     if (UNLIKELY(!JSTaggedValue::ToElementIndex(key.GetTaggedValue(), &index))) {
412         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, key.GetTaggedValue());
413         CString errorMsg =
414             "The type of \"index\" can not obtain attributes of no-number type. Received value is: "
415             + ConvertToString(*result);
416         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
417         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, false);
418     }
419 
420     uint32_t length = obj->GetLength().GetArrayLength();
421     if (index >= length) {
422         std::ostringstream oss;
423         oss << "The value of \"index\" is out of range. It must be > " << (length - 1)
424             << ". Received value is: " << index;
425         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
426         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, false);
427     }
428 
429     obj->Get(thread, index);
430     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
431     return true;
432 }
433 
GetIteratorObj(JSThread * thread,const JSHandle<JSAPIArrayList> & obj)434 JSTaggedValue JSAPIArrayList::GetIteratorObj(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
435 {
436     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
437     JSHandle<JSAPIArrayListIterator> iter(factory->NewJSAPIArrayListIterator(obj));
438 
439     return iter.GetTaggedValue();
440 }
441 
GetProperty(JSThread * thread,const JSHandle<JSAPIArrayList> & obj,const JSHandle<JSTaggedValue> & key)442 OperationResult JSAPIArrayList::GetProperty(JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
443                                             const JSHandle<JSTaggedValue> &key)
444 {
445     int length = obj->GetLength().GetInt();
446     int index = key->GetInt();
447     if (index < 0 || index >= length) {
448         std::ostringstream oss;
449         oss << "The value of \"index\" is out of range. It must be >= 0 && <= " << (length - 1)
450             << ". Received value is: " << index;
451         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
452         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error,
453                                          OperationResult(thread, JSTaggedValue::Exception(), PropertyMetaData(false)));
454     }
455 
456     return OperationResult(thread, obj->Get(thread, index), PropertyMetaData(false));
457 }
458 
SetProperty(JSThread * thread,const JSHandle<JSAPIArrayList> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value)459 bool JSAPIArrayList::SetProperty(JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
460                                  const JSHandle<JSTaggedValue> &key,
461                                  const JSHandle<JSTaggedValue> &value)
462 {
463     int length = obj->GetLength().GetInt();
464     int index = key->GetInt();
465     if (index < 0 || index >= length) {
466         return false;
467     }
468 
469     obj->Set(thread, index, value.GetTaggedValue());
470     return true;
471 }
472 }  // namespace panda::ecmascript
473