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_vector.h"
17
18 #include "ecmascript/interpreter/interpreter.h"
19 #include "ecmascript/js_array.h"
20 #include "ecmascript/js_api/js_api_vector_iterator.h"
21 #include "ecmascript/js_handle.h"
22 #include "ecmascript/js_function.h"
23 #include "ecmascript/js_tagged_number.h"
24 #include "ecmascript/js_tagged_value.h"
25 #include "ecmascript/object_factory.h"
26
27 namespace panda::ecmascript {
28 static const uint32_t MAX_VALUE = 0x7fffffff;
29 static const uint32_t MAX_ARRAY_SIZE = MAX_VALUE - 8;
Add(JSThread * thread,const JSHandle<JSAPIVector> & vector,const JSHandle<JSTaggedValue> & value)30 bool JSAPIVector::Add(JSThread *thread, const JSHandle<JSAPIVector> &vector, const JSHandle<JSTaggedValue> &value)
31 {
32 int32_t length = vector->GetSize();
33 GrowCapacity(thread, vector, length + 1);
34
35 TaggedArray *elements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
36 ASSERT(!elements->IsDictionaryMode());
37 elements->Set(thread, length, value);
38 vector->SetLength(++length);
39
40 return true;
41 }
42
Insert(JSThread * thread,const JSHandle<JSAPIVector> & vector,const JSHandle<JSTaggedValue> & value,int32_t index)43 void JSAPIVector::Insert(JSThread *thread, const JSHandle<JSAPIVector> &vector,
44 const JSHandle<JSTaggedValue> &value, int32_t index)
45 {
46 int32_t length = vector->GetSize();
47 if (index < 0 || index > length) {
48 THROW_ERROR(thread, ErrorType::RANGE_ERROR, "the index is out-of-bounds");
49 }
50 GrowCapacity(thread, vector, length + 1);
51
52 TaggedArray *elements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
53 ASSERT(!elements->IsDictionaryMode());
54 for (int32_t i = length - 1; i >= index; i--) {
55 elements->Set(thread, i + 1, elements->Get(i));
56 }
57
58 elements->Set(thread, index, value);
59 vector->SetLength(++length);
60 }
61
SetLength(JSThread * thread,const JSHandle<JSAPIVector> & vector,uint32_t newSize)62 void JSAPIVector::SetLength(JSThread *thread, const JSHandle<JSAPIVector> &vector, uint32_t newSize)
63 {
64 uint32_t len = static_cast<uint32_t>(vector->GetSize());
65 if (newSize > len) {
66 GrowCapacity(thread, vector, newSize);
67 }
68 vector->SetLength(newSize);
69 }
70
GetCapacity()71 uint32_t JSAPIVector::GetCapacity()
72 {
73 TaggedArray *elementData = TaggedArray::Cast(GetElements().GetTaggedObject());
74 ASSERT(!elementData->IsDictionaryMode());
75 return elementData->GetLength();
76 }
77
IncreaseCapacityTo(JSThread * thread,const JSHandle<JSAPIVector> & vector,int32_t newCapacity)78 void JSAPIVector::IncreaseCapacityTo(JSThread *thread, const JSHandle<JSAPIVector> &vector, int32_t newCapacity)
79 {
80 if (newCapacity < 0) {
81 THROW_ERROR(thread, ErrorType::RANGE_ERROR, "An incorrect size was set");
82 }
83
84 JSHandle<TaggedArray> elementData(thread, vector->GetElements());
85 ASSERT(!elementData->IsDictionaryMode());
86 uint32_t oldCapacity = elementData->GetLength();
87 uint32_t tempCapacity = static_cast<uint32_t>(newCapacity);
88 if (oldCapacity < tempCapacity) {
89 JSHandle<TaggedArray> newElements =
90 thread->GetEcmaVM()->GetFactory()->CopyArray(elementData, oldCapacity, tempCapacity);
91 vector->SetElements(thread, newElements);
92 }
93 }
94
GetIndexOf(JSThread * thread,const JSHandle<JSAPIVector> & vector,const JSHandle<JSTaggedValue> & obj)95 int32_t JSAPIVector::GetIndexOf(JSThread *thread, const JSHandle<JSAPIVector> &vector,
96 const JSHandle<JSTaggedValue> &obj)
97 {
98 return JSAPIVector::GetIndexFrom(thread, vector, obj, 0);
99 }
100
GetIndexFrom(JSThread * thread,const JSHandle<JSAPIVector> & vector,const JSHandle<JSTaggedValue> & obj,int32_t index)101 int32_t JSAPIVector::GetIndexFrom(JSThread *thread, const JSHandle<JSAPIVector> &vector,
102 const JSHandle<JSTaggedValue> &obj, int32_t index)
103 {
104 TaggedArray *elements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
105 ASSERT(!elements->IsDictionaryMode());
106 int32_t length = vector->GetSize();
107 if (index < 0) {
108 index = 0;
109 } else if (index >= length) {
110 THROW_RANGE_ERROR_AND_RETURN(thread, "no-such-element", -1);
111 }
112
113 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
114 for (int32_t i = index; i < length; i++) {
115 value.Update(JSTaggedValue(elements->Get(i)));
116 if (JSTaggedValue::StrictEqual(thread, obj, value))
117 return i;
118 }
119 return -1;
120 }
121
IsEmpty() const122 bool JSAPIVector::IsEmpty() const
123 {
124 return GetSize() == 0;
125 }
126
GetLastElement()127 JSTaggedValue JSAPIVector::GetLastElement()
128 {
129 int32_t length = GetSize();
130 if (length == 0) {
131 return JSTaggedValue::Undefined();
132 }
133 TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
134 ASSERT(!elements->IsDictionaryMode());
135 return elements->Get(length - 1);
136 }
137
GetLastIndexOf(JSThread * thread,const JSHandle<JSAPIVector> & vector,const JSHandle<JSTaggedValue> & obj)138 int32_t JSAPIVector::GetLastIndexOf(JSThread *thread, const JSHandle<JSAPIVector> &vector,
139 const JSHandle<JSTaggedValue> &obj)
140 {
141 int32_t index = vector->GetSize() - 1;
142 if (index < 0) {
143 return -1; // vector isEmpty, defalut return -1
144 }
145 return JSAPIVector::GetLastIndexFrom(thread, vector, obj, index);
146 }
147
GetLastIndexFrom(JSThread * thread,const JSHandle<JSAPIVector> & vector,const JSHandle<JSTaggedValue> & obj,int32_t index)148 int32_t JSAPIVector::GetLastIndexFrom(JSThread *thread, const JSHandle<JSAPIVector> &vector,
149 const JSHandle<JSTaggedValue> &obj, int32_t index)
150 {
151 int32_t length = vector->GetSize();
152 if (index >= length) {
153 THROW_RANGE_ERROR_AND_RETURN(thread, "index-out-of-bounds", -1);
154 } else if (index < 0) {
155 index = 0;
156 }
157 TaggedArray *elements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
158 ASSERT(!elements->IsDictionaryMode());
159 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
160 for (int32_t i = index; i >= 0; i--) {
161 value.Update(elements->Get(i));
162 if (JSTaggedValue::StrictEqual(thread, obj, value)) {
163 return i;
164 }
165 }
166 return -1;
167 }
168
Remove(JSThread * thread,const JSHandle<JSAPIVector> & vector,const JSHandle<JSTaggedValue> & obj)169 bool JSAPIVector::Remove(JSThread *thread, const JSHandle<JSAPIVector> &vector, const JSHandle<JSTaggedValue> &obj)
170 {
171 int32_t index = GetIndexOf(thread, vector, obj);
172 int32_t length = vector->GetSize();
173 if (index >= 0) {
174 JSHandle<TaggedArray> elements(thread, vector->GetElements());
175 ASSERT(!elements->IsDictionaryMode());
176 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
177 factory->RemoveElementByIndex(elements, index, length);
178 length--;
179 vector->SetLength(length);
180 return true;
181 }
182 return false;
183 }
184
RemoveByIndex(JSThread * thread,const JSHandle<JSAPIVector> & vector,int32_t index)185 JSTaggedValue JSAPIVector::RemoveByIndex(JSThread *thread, const JSHandle<JSAPIVector> &vector, int32_t index)
186 {
187 int32_t length = vector->GetSize();
188 if (index < 0 || index >= length) {
189 THROW_RANGE_ERROR_AND_RETURN(thread, "the index is out-of-bounds", JSTaggedValue::Exception());
190 }
191 TaggedArray *resElements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
192 ASSERT(!resElements->IsDictionaryMode());
193 JSTaggedValue oldValue = resElements->Get(index);
194
195 if (index >= 0) {
196 JSHandle<TaggedArray> elements(thread, vector->GetElements());
197 ASSERT(!elements->IsDictionaryMode());
198 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
199 factory->RemoveElementByIndex(elements, index, length);
200 vector->SetLength(length - 1);
201 }
202 length--;
203 vector->SetLength(length);
204
205 return oldValue;
206 }
207
RemoveByRange(JSThread * thread,const JSHandle<JSAPIVector> & vector,int32_t fromIndex,int32_t toIndex)208 JSTaggedValue JSAPIVector::RemoveByRange(JSThread *thread, const JSHandle<JSAPIVector> &vector,
209 int32_t fromIndex, int32_t toIndex)
210 {
211 int32_t length = vector->GetSize();
212 if (toIndex <= fromIndex) {
213 THROW_RANGE_ERROR_AND_RETURN(thread, "the fromIndex cannot be less than or equal to toIndex",
214 JSTaggedValue::Exception());
215 }
216 if (fromIndex < 0 || fromIndex >= length) {
217 THROW_RANGE_ERROR_AND_RETURN(thread, "the fromIndex or the toIndex is out-of-bounds",
218 JSTaggedValue::Exception());
219 }
220
221 int32_t endIndex = toIndex >= length ? length : toIndex;
222 TaggedArray *elements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
223 ASSERT(!elements->IsDictionaryMode());
224 int32_t numMoved = length - endIndex;
225 for (int32_t i = 0; i < numMoved; i++) {
226 elements->Set(thread, fromIndex + i, elements->Get(endIndex + i));
227 }
228
229 int32_t newLength = length - (endIndex - fromIndex);
230 elements->SetLength(newLength);
231 vector->SetLength(newLength);
232 return JSTaggedValue::True();
233 }
234
SubVector(JSThread * thread,const JSHandle<JSAPIVector> & vector,int32_t fromIndex,int32_t toIndex)235 JSHandle<JSAPIVector> JSAPIVector::SubVector(JSThread *thread, const JSHandle<JSAPIVector> &vector,
236 int32_t fromIndex, int32_t toIndex)
237 {
238 int32_t length = vector->GetSize();
239 if (fromIndex < 0 || toIndex < 0 || fromIndex >= length || toIndex >= length) {
240 THROW_RANGE_ERROR_AND_RETURN(thread, "the fromIndex or the toIndex is out-of-bounds",
241 JSHandle<JSAPIVector>());
242 }
243 if (toIndex <= fromIndex) {
244 THROW_RANGE_ERROR_AND_RETURN(thread, "the fromIndex cannot be less than or equal to toIndex",
245 JSHandle<JSAPIVector>());
246 }
247
248 int32_t newLength = toIndex - fromIndex;
249 JSHandle<JSAPIVector> subVector = thread->GetEcmaVM()->GetFactory()->NewJSAPIVector(newLength);
250 TaggedArray *elements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
251
252 subVector->SetLength(newLength);
253 for (int32_t i = 0; i < newLength; i++) {
254 subVector->Set(thread, i, elements->Get(fromIndex + i));
255 }
256
257 return subVector;
258 }
259
ToString(JSThread * thread,const JSHandle<JSAPIVector> & vector)260 JSTaggedValue JSAPIVector::ToString(JSThread *thread, const JSHandle<JSAPIVector> &vector)
261 {
262 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
263 std::u16string sepHandle = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.from_bytes(",");
264
265 int32_t length = vector->GetSize();
266 std::u16string concatStr;
267 JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined());
268 for (int32_t k = 0; k < length; k++) {
269 std::u16string nextStr;
270 element.Update(Get(thread, vector, k));
271 if (!element->IsUndefined() && !element->IsNull()) {
272 JSHandle<EcmaString> nextStringHandle = JSTaggedValue::ToString(thread, element);
273 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
274 nextStr = EcmaStringAccessor(nextStringHandle).ToU16String();
275 }
276 if (k > 0) {
277 concatStr.append(sepHandle);
278 concatStr.append(nextStr);
279 continue;
280 }
281 concatStr.append(nextStr);
282 }
283
284 char16_t *char16tData = concatStr.data();
285 auto *uint16tData = reinterpret_cast<uint16_t *>(char16tData);
286 uint32_t u16strSize = concatStr.size();
287 return factory->NewFromUtf16Literal(uint16tData, u16strSize).GetTaggedValue();
288 }
289
ForEach(JSThread * thread,const JSHandle<JSTaggedValue> & thisHandle,const JSHandle<JSTaggedValue> & callbackFn,const JSHandle<JSTaggedValue> & thisArg)290 JSTaggedValue JSAPIVector::ForEach(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
291 const JSHandle<JSTaggedValue> &callbackFn,
292 const JSHandle<JSTaggedValue> &thisArg)
293 {
294 JSHandle<JSAPIVector> vector = JSHandle<JSAPIVector>::Cast(thisHandle);
295 int32_t length = vector->GetSize();
296 JSTaggedValue key = JSTaggedValue::Undefined();
297 JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
298 const int32_t argsLength = NUM_MANDATORY_JSFUNC_ARGS;
299 JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
300
301 for (int32_t k = 0; k < length; k++) {
302 kValue.Update(Get(thread, vector, k));
303 key = JSTaggedValue(k);
304 EcmaRuntimeCallInfo *info =
305 EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFn, thisArg, undefined, argsLength);
306 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
307 info->SetCallArg(kValue.GetTaggedValue(), key, thisHandle.GetTaggedValue());
308 JSTaggedValue funcResult = JSFunction::Call(info);
309 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
310 if (length != vector->GetSize()) { // prevent length change
311 length = vector->GetSize();
312 }
313 }
314
315 return JSTaggedValue::Undefined();
316 }
317
ReplaceAllElements(JSThread * thread,const JSHandle<JSTaggedValue> & thisHandle,const JSHandle<JSTaggedValue> & callbackFn,const JSHandle<JSTaggedValue> & thisArg)318 JSTaggedValue JSAPIVector::ReplaceAllElements(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
319 const JSHandle<JSTaggedValue> &callbackFn,
320 const JSHandle<JSTaggedValue> &thisArg)
321 {
322 JSHandle<JSAPIVector> vector = JSHandle<JSAPIVector>::Cast(thisHandle);
323 int32_t length = vector->GetSize();
324 JSTaggedValue key = JSTaggedValue::Undefined();
325 JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
326 const int32_t argsLength = NUM_MANDATORY_JSFUNC_ARGS;
327 JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
328
329 for (int32_t k = 0; k < length; k++) {
330 kValue.Update(Get(thread, vector, k));
331 key = JSTaggedValue(k);
332 EcmaRuntimeCallInfo *info =
333 EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFn, thisArg, undefined, argsLength);
334 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
335 info->SetCallArg(kValue.GetTaggedValue(), key, thisHandle.GetTaggedValue());
336 JSTaggedValue funcResult = JSFunction::Call(info);
337 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
338 if (length != vector->GetSize()) { // prevent length change
339 length = vector->GetSize();
340 }
341 vector->Set(thread, k, funcResult);
342 }
343
344 return JSTaggedValue::Undefined();
345 }
346
GrowCapacity(JSThread * thread,const JSHandle<JSAPIVector> & vector,uint32_t minCapacity)347 void JSAPIVector::GrowCapacity(JSThread *thread, const JSHandle<JSAPIVector> &vector, uint32_t minCapacity)
348 {
349 JSHandle<TaggedArray> elementData(thread, vector->GetElements());
350 ASSERT(!elementData->IsDictionaryMode());
351 uint32_t curCapacity = elementData->GetLength();
352 if (minCapacity > curCapacity) {
353 uint32_t oldCapacity = elementData->GetLength();
354 // 2 : 2 Capacity doubled
355 uint32_t newCapacity = oldCapacity * 2;
356 if (newCapacity < minCapacity)
357 newCapacity = minCapacity;
358
359 if (newCapacity > MAX_ARRAY_SIZE) {
360 newCapacity = (minCapacity > MAX_ARRAY_SIZE) ? MAX_VALUE : MAX_ARRAY_SIZE;
361 }
362 JSHandle<TaggedArray> newElements =
363 thread->GetEcmaVM()->GetFactory()->CopyArray(elementData, oldCapacity, newCapacity);
364
365 vector->SetElements(thread, newElements);
366 }
367 }
368
Get(JSThread * thread,const JSHandle<JSAPIVector> & vector,int32_t index)369 JSTaggedValue JSAPIVector::Get(JSThread *thread, const JSHandle<JSAPIVector> &vector, int32_t index)
370 {
371 int32_t len = vector->GetSize();
372 if (index < 0 || index >= len) {
373 THROW_RANGE_ERROR_AND_RETURN(thread, "the index is out-of-bounds", JSTaggedValue::Exception());
374 }
375
376 TaggedArray *elements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
377 return elements->Get(index);
378 }
379
Set(JSThread * thread,int32_t index,const JSTaggedValue & value)380 JSTaggedValue JSAPIVector::Set(JSThread *thread, int32_t index, const JSTaggedValue &value)
381 {
382 TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
383 elements->Set(thread, index, value);
384 return JSTaggedValue::Undefined();
385 }
386
Has(const JSTaggedValue & value) const387 bool JSAPIVector::Has(const JSTaggedValue &value) const
388 {
389 TaggedArray *elements = TaggedArray::Cast(GetElements().GetTaggedObject());
390 int32_t length = GetSize();
391 if (length == 0) {
392 return false;
393 }
394
395 for (int32_t i = 0; i < length; i++) {
396 if (JSTaggedValue::SameValue(elements->Get(i), value)) {
397 return true;
398 }
399 }
400 return false;
401 }
402
OwnKeys(JSThread * thread,const JSHandle<JSAPIVector> & obj)403 JSHandle<TaggedArray> JSAPIVector::OwnKeys(JSThread *thread, const JSHandle<JSAPIVector> &obj)
404 {
405 int32_t length = obj->GetSize();
406 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
407 JSHandle<TaggedArray> keys = factory->NewTaggedArray(length);
408
409 for (int32_t i = 0; i < length; i++) {
410 keys->Set(thread, i, JSTaggedValue(i));
411 }
412
413 return keys;
414 }
415
GetOwnProperty(JSThread * thread,const JSHandle<JSAPIVector> & obj,const JSHandle<JSTaggedValue> & key)416 bool JSAPIVector::GetOwnProperty(JSThread *thread, const JSHandle<JSAPIVector> &obj,
417 const JSHandle<JSTaggedValue> &key)
418 {
419 uint32_t index = 0;
420 if (UNLIKELY(!JSTaggedValue::ToElementIndex(key.GetTaggedValue(), &index))) {
421 THROW_TYPE_ERROR_AND_RETURN(thread, "Can not obtain attributes of no-number type", false);
422 }
423
424 uint32_t length = static_cast<uint32_t>(obj->GetSize());
425 if (index >= length) {
426 THROW_RANGE_ERROR_AND_RETURN(thread, "GetOwnProperty index out-of-bounds", false);
427 }
428
429 JSAPIVector::Get(thread, obj, index);
430 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
431 return true;
432 }
433
TrimToCurrentLength(JSThread * thread,const JSHandle<JSAPIVector> & obj)434 void JSAPIVector::TrimToCurrentLength(JSThread *thread, const JSHandle<JSAPIVector> &obj)
435 {
436 int32_t length = obj->GetSize();
437 uint32_t capacity = obj->GetCapacity();
438 TaggedArray *elements = TaggedArray::Cast(obj->GetElements().GetTaggedObject());
439 ASSERT(!elements->IsDictionaryMode());
440 if (capacity > static_cast<uint32_t>(length)) {
441 elements->Trim(thread, length);
442 }
443 }
444
Clear(JSThread * thread,const JSHandle<JSAPIVector> & obj)445 void JSAPIVector::Clear(JSThread *thread, const JSHandle<JSAPIVector> &obj)
446 {
447 int length = obj->GetLength();
448 JSHandle<TaggedArray> elements(thread, obj->GetElements());
449 ASSERT(!elements->IsDictionaryMode());
450 for (int i = 0; i <= length; ++i) {
451 elements->Set(thread, i, JSTaggedValue::Hole());
452 }
453 obj->SetLength(0);
454 }
455
Clone(JSThread * thread,const JSHandle<JSAPIVector> & obj)456 JSHandle<JSAPIVector> JSAPIVector::Clone(JSThread *thread, const JSHandle<JSAPIVector> &obj)
457 {
458 JSHandle<TaggedArray> srcElements(thread, obj->GetElements());
459 auto factory = thread->GetEcmaVM()->GetFactory();
460 JSHandle<JSAPIVector> newVector = factory->NewJSAPIVector(0);
461
462 int32_t length = obj->GetSize();
463 newVector->SetLength(length);
464
465 JSHandle<TaggedArray> dstElements = factory->NewAndCopyTaggedArray(srcElements, length, length);
466 newVector->SetElements(thread, dstElements);
467 return newVector;
468 }
469
GetFirstElement(const JSHandle<JSAPIVector> & vector)470 JSTaggedValue JSAPIVector::GetFirstElement(const JSHandle<JSAPIVector> &vector)
471 {
472 int32_t length = vector->GetSize();
473 if (length == 0) {
474 return JSTaggedValue::Undefined();
475 }
476 TaggedArray *elements = TaggedArray::Cast(vector->GetElements().GetTaggedObject());
477 return elements->Get(0);
478 }
479
GetIteratorObj(JSThread * thread,const JSHandle<JSAPIVector> & obj)480 JSTaggedValue JSAPIVector::GetIteratorObj(JSThread *thread, const JSHandle<JSAPIVector> &obj)
481 {
482 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
483 JSHandle<JSAPIVectorIterator> iter(factory->NewJSAPIVectorIterator(obj));
484
485 return iter.GetTaggedValue();
486 }
487
GetProperty(JSThread * thread,const JSHandle<JSAPIVector> & obj,const JSHandle<JSTaggedValue> & key)488 OperationResult JSAPIVector::GetProperty(JSThread *thread, const JSHandle<JSAPIVector> &obj,
489 const JSHandle<JSTaggedValue> &key)
490 {
491 int length = obj->GetSize();
492 int index = key->GetInt();
493 if (index < 0 || index >= length) {
494 THROW_RANGE_ERROR_AND_RETURN(thread, "GetProperty index out-of-bounds",
495 OperationResult(thread, JSTaggedValue::Exception(), PropertyMetaData(false)));
496 }
497
498 return OperationResult(thread, JSAPIVector::Get(thread, obj, index), PropertyMetaData(false));
499 }
500
SetProperty(JSThread * thread,const JSHandle<JSAPIVector> & obj,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value)501 bool JSAPIVector::SetProperty(JSThread *thread, const JSHandle<JSAPIVector> &obj,
502 const JSHandle<JSTaggedValue> &key,
503 const JSHandle<JSTaggedValue> &value)
504 {
505 int length = obj->GetSize();
506 int index = key->GetInt();
507 if (index < 0 || index >= length) {
508 return false;
509 }
510
511 obj->Set(thread, index, value.GetTaggedValue());
512 return true;
513 }
514 } // namespace panda::ecmascript