• 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     uint32_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         TaggedArray::RemoveElementByIndex(thread, elements, index, length);
192         arrayList->SetLength(thread, JSTaggedValue(length - 1));
193     }
194 
195     return oldValue;
196 }
197 
Remove(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value)198 bool JSAPIArrayList::Remove(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
199                             const JSHandle<JSTaggedValue> &value)
200 {
201     int index = GetIndexOf(thread, arrayList, value);
202     uint32_t length = arrayList->GetSize();
203     if (index >= 0) {
204         JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
205         ASSERT(!elements->IsDictionaryMode());
206         TaggedArray::RemoveElementByIndex(thread, elements, index, length);
207         arrayList->SetLength(thread, JSTaggedValue(length - 1));
208         return true;
209     }
210     return false;
211 }
212 
RemoveByRange(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value1,const JSHandle<JSTaggedValue> & value2)213 JSTaggedValue JSAPIArrayList::RemoveByRange(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
214                                             const JSHandle<JSTaggedValue> &value1,
215                                             const JSHandle<JSTaggedValue> &value2)
216 {
217     int32_t startIndex = JSTaggedValue::ToInt32(thread, value1);
218     int32_t endIndex = JSTaggedValue::ToInt32(thread, value2);
219     int32_t length = arrayList->GetLength().GetInt();
220     int32_t size = length > endIndex ? endIndex : length;
221     if (startIndex < 0 || startIndex >= size) {
222         std::ostringstream oss;
223         oss << "The value of \"fromIndex\" is out of range. It must be >= 0 && <= " << (size - 1)
224             << ". Received value is: " << startIndex;
225         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
226         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
227     }
228     if (endIndex <= startIndex || endIndex < 0 || endIndex > length) {
229         std::ostringstream oss;
230         oss << "The value of \"toIndex\" is out of range. It must be >= 0 && <= " << length
231             << ". Received value is: " << endIndex;
232         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
233         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
234     }
235 
236     int32_t toIndex = endIndex >= length ? length : endIndex;
237 
238     JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
239     ASSERT(!elements->IsDictionaryMode());
240     int32_t numMoved = length - toIndex;
241 
242     for (int32_t i = 0; i < numMoved; i++) {
243         elements->Set(thread, startIndex + i, elements->Get(static_cast<uint32_t>(endIndex + i)));
244     }
245     int32_t newLength = length - (endIndex - startIndex);
246     arrayList->SetLength(thread, JSTaggedValue(newLength));
247     elements->SetLength(newLength);
248     return JSTaggedValue::Undefined();
249 }
250 
ReplaceAllElements(JSThread * thread,const JSHandle<JSTaggedValue> & thisHandle,const JSHandle<JSTaggedValue> & callbackFn,const JSHandle<JSTaggedValue> & thisArg)251 JSTaggedValue JSAPIArrayList::ReplaceAllElements(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
252                                                  const JSHandle<JSTaggedValue> &callbackFn,
253                                                  const JSHandle<JSTaggedValue> &thisArg)
254 {
255     JSHandle<JSAPIArrayList> arrayList = JSHandle<JSAPIArrayList>::Cast(thisHandle);
256     uint32_t length = arrayList->GetSize();
257     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
258     JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
259     const int32_t argsLength = 3;
260     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
261     for (uint32_t k = 0; k < length; k++) {
262         kValue.Update(arrayList->Get(thread, k));
263         key.Update(JSTaggedValue(k));
264         EcmaRuntimeCallInfo *info =
265             EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFn, thisArg, undefined, argsLength);
266         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
267         info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisHandle.GetTaggedValue());
268         JSTaggedValue funcResult = JSFunction::Call(info);
269         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
270 
271         arrayList->Set(thread, k, funcResult);
272     }
273 
274     return JSTaggedValue::Undefined();
275 }
276 
Set(JSThread * thread,const uint32_t index,JSTaggedValue value)277 JSTaggedValue JSAPIArrayList::Set(JSThread *thread, const uint32_t index, JSTaggedValue value)
278 {
279     if (index >= GetLength().GetArrayLength()) {
280         std::ostringstream oss;
281         oss << "The value of \"index\" is out of range. It must be >= 0 && <= "
282             << (GetLength().GetArrayLength() - 1) << ". Received value is: " << index;
283         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
284         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
285     }
286 
287     TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
288     elements->Set(thread, index, value);
289     return JSTaggedValue::Undefined();
290 }
291 
SubArrayList(JSThread * thread,const JSHandle<JSAPIArrayList> & arrayList,const JSHandle<JSTaggedValue> & value1,const JSHandle<JSTaggedValue> & value2)292 JSTaggedValue JSAPIArrayList::SubArrayList(JSThread *thread, const JSHandle<JSAPIArrayList> &arrayList,
293                                            const JSHandle<JSTaggedValue> &value1,
294                                            const JSHandle<JSTaggedValue> &value2)
295 {
296     int length = arrayList->GetLength().GetInt();
297     int fromIndex = JSTaggedValue::ToInt32(thread, value1);
298     int toIndex = JSTaggedValue::ToInt32(thread, value2);
299     int32_t size = length > toIndex ? toIndex : length;
300     if (fromIndex < 0 || fromIndex >= size) {
301         std::ostringstream oss;
302         oss << "The value of \"fromIndex\" is out of range. It must be >= 0 && <= " << (size - 1)
303             << ". Received value is: " << fromIndex;
304         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
305         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
306     }
307     if (toIndex <= fromIndex || toIndex < 0 || toIndex > length) {
308         std::ostringstream oss;
309         oss << "The value of \"toIndex\" is out of range. It must be >= 0 && <= " << length
310             << ". Received value is: " << toIndex;
311         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
312         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
313     }
314 
315     int endIndex = toIndex >= length - 1 ? length - 1 : toIndex;
316     int newLength = toIndex == length ? length - fromIndex : endIndex - fromIndex;
317     JSHandle<JSAPIArrayList> subArrayList = thread->GetEcmaVM()->GetFactory()->NewJSAPIArrayList(newLength);
318     if (newLength == 0) {
319         return subArrayList.GetTaggedValue();
320     }
321     JSHandle<TaggedArray> elements(thread, arrayList->GetElements());
322     ASSERT(!elements->IsDictionaryMode());
323     subArrayList->SetLength(thread, JSTaggedValue(newLength));
324 
325     for (int i = 0; i < newLength; i++) {
326         subArrayList->Set(thread, i, elements->Get(fromIndex + i));
327     }
328 
329     return subArrayList.GetTaggedValue();
330 }
331 
ForEach(JSThread * thread,const JSHandle<JSTaggedValue> & thisHandle,const JSHandle<JSTaggedValue> & callbackFn,const JSHandle<JSTaggedValue> & thisArg)332 JSTaggedValue JSAPIArrayList::ForEach(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
333                                       const JSHandle<JSTaggedValue> &callbackFn,
334                                       const JSHandle<JSTaggedValue> &thisArg)
335 {
336     JSHandle<JSAPIArrayList> arrayList = JSHandle<JSAPIArrayList>::Cast(thisHandle);
337     uint32_t length = arrayList->GetSize();
338     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
339     JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
340     const int32_t argsLength = 3;
341     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
342     for (uint32_t k = 0; k < length; k++) {
343         kValue.Update(arrayList->Get(thread, k));
344         key.Update(JSTaggedValue(k));
345         EcmaRuntimeCallInfo *info =
346             EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFn, thisArg, undefined, argsLength);
347         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
348         info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisHandle.GetTaggedValue());
349         JSTaggedValue funcResult = JSFunction::Call(info);
350         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
351         if (length != arrayList->GetSize()) {
352             length = arrayList->GetSize();
353         }
354     }
355 
356     return JSTaggedValue::Undefined();
357 }
358 
GrowCapacity(const JSThread * thread,const JSHandle<JSAPIArrayList> & obj,uint32_t capacity)359 JSHandle<TaggedArray> JSAPIArrayList::GrowCapacity(const JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
360                                                    uint32_t capacity)
361 {
362     JSHandle<TaggedArray> oldElements(thread, obj->GetElements());
363     ASSERT(!oldElements->IsDictionaryMode());
364     uint32_t oldCapacity = oldElements->GetLength();
365     if (capacity < oldCapacity) {
366         return oldElements;
367     }
368     uint32_t newCapacity = ComputeCapacity(capacity);
369     JSHandle<TaggedArray> newElements =
370         thread->GetEcmaVM()->GetFactory()->CopyArray(oldElements, oldCapacity, newCapacity);
371 
372     obj->SetElements(thread, newElements);
373     return newElements;
374 }
375 
Has(const JSTaggedValue value) const376 bool JSAPIArrayList::Has(const JSTaggedValue value) const
377 {
378     TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
379     uint32_t length = GetSize();
380     if (length == 0) {
381         return false;
382     }
383 
384     for (uint32_t i = 0; i < length; i++) {
385         if (JSTaggedValue::SameValue(elements->Get(i), value)) {
386             return true;
387         }
388     }
389     return false;
390 }
391 
OwnKeys(JSThread * thread,const JSHandle<JSAPIArrayList> & obj)392 JSHandle<TaggedArray> JSAPIArrayList::OwnKeys(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
393 {
394     return JSObject::GetOwnPropertyKeys(thread, JSHandle<JSObject>::Cast(obj));
395 }
396 
OwnEnumKeys(JSThread * thread,const JSHandle<JSAPIArrayList> & obj)397 JSHandle<TaggedArray> JSAPIArrayList::OwnEnumKeys(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
398 {
399     return JSObject::GetOwnEnumPropertyKeys(thread, JSHandle<JSObject>::Cast(obj));
400 }
401 
GetOwnProperty(JSThread * thread,const JSHandle<JSAPIArrayList> & obj,const JSHandle<JSTaggedValue> & key)402 bool JSAPIArrayList::GetOwnProperty(JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
403                                     const JSHandle<JSTaggedValue> &key)
404 {
405     uint32_t index = 0;
406     if (UNLIKELY(!JSTaggedValue::ToElementIndex(key.GetTaggedValue(), &index))) {
407         JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, key.GetTaggedValue());
408         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
409         CString errorMsg =
410             "The type of \"index\" can not obtain attributes of no-number type. Received value is: "
411             + ConvertToString(*result);
412         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
413         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, false);
414     }
415 
416     uint32_t length = obj->GetLength().GetArrayLength();
417     if (index >= length) {
418         std::ostringstream oss;
419         oss << "The value of \"index\" is out of range. It must be > " << (length - 1)
420             << ". Received value is: " << index;
421         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
422         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, false);
423     }
424 
425     obj->Get(thread, index);
426     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
427     return true;
428 }
429 
GetIteratorObj(JSThread * thread,const JSHandle<JSAPIArrayList> & obj)430 JSTaggedValue JSAPIArrayList::GetIteratorObj(JSThread *thread, const JSHandle<JSAPIArrayList> &obj)
431 {
432     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
433     JSHandle<JSAPIArrayListIterator> iter(factory->NewJSAPIArrayListIterator(obj));
434 
435     return iter.GetTaggedValue();
436 }
437 
GetProperty(JSThread * thread,const JSHandle<JSAPIArrayList> & obj,const JSHandle<JSTaggedValue> & key)438 OperationResult JSAPIArrayList::GetProperty(JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
439                                             const JSHandle<JSTaggedValue> &key)
440 {
441     int length = obj->GetLength().GetInt();
442     int index = key->GetInt();
443     if (index < 0 || index >= length) {
444         std::ostringstream oss;
445         oss << "The value of \"index\" is out of range. It must be >= 0 && <= " << (length - 1)
446             << ". Received value is: " << index;
447         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
448         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error,
449                                          OperationResult(thread, JSTaggedValue::Exception(), PropertyMetaData(false)));
450     }
451 
452     return OperationResult(thread, obj->Get(thread, index), PropertyMetaData(false));
453 }
454 
SetProperty(JSThread * thread,const JSHandle<JSAPIArrayList> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value)455 bool JSAPIArrayList::SetProperty(JSThread *thread, const JSHandle<JSAPIArrayList> &obj,
456                                  const JSHandle<JSTaggedValue> &key,
457                                  const JSHandle<JSTaggedValue> &value)
458 {
459     int length = obj->GetLength().GetInt();
460     int index = key->GetInt();
461     if (index < 0 || index >= length) {
462         return false;
463     }
464 
465     obj->Set(thread, index, value.GetTaggedValue());
466     return true;
467 }
468 }  // namespace panda::ecmascript
469