• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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_lightweightset.h"
17 
18 #include "ecmascript/containers/containers_errors.h"
19 #include "ecmascript/interpreter/interpreter.h"
20 #include "ecmascript/js_array.h"
21 #include "ecmascript/js_function.h"
22 
23 #include <codecvt>
24 
25 #include <codecvt>
26 
27 namespace panda::ecmascript {
28 using ContainerError = containers::ContainerError;
29 using ErrorFlag = containers::ErrorFlag;
Add(JSThread * thread,const JSHandle<JSAPILightWeightSet> & obj,const JSHandle<JSTaggedValue> & value)30 bool JSAPILightWeightSet::Add(JSThread *thread, const JSHandle<JSAPILightWeightSet> &obj,
31                               const JSHandle<JSTaggedValue> &value)
32 {
33     CheckAndCopyValues(thread, obj);
34     uint32_t hashCode = obj->Hash(thread, value.GetTaggedValue());
35     JSHandle<TaggedArray> hashArray(thread, obj->GetHashes());
36     JSHandle<TaggedArray> valueArray(thread, obj->GetValues());
37     int32_t size = static_cast<int32_t>(obj->GetLength());
38     int32_t index = obj->GetHashIndex(thread, value, size);
39     if (index >= 0) {
40         return false;
41     }
42     index ^= JSAPILightWeightSet::HASH_REBELLION;
43     if (index < size) {
44         obj->AdjustArray(thread, hashArray, index, size, true);
45         obj->AdjustArray(thread, valueArray, index, size, true);
46     }
47     uint32_t capacity = hashArray->GetLength();
48     if (size + 1 >= static_cast<int32_t>(capacity)) {
49         // need expanding
50         uint32_t newCapacity = capacity << 1U;
51         hashArray = thread->GetEcmaVM()->GetFactory()->CopyArray(hashArray, capacity, newCapacity);
52         valueArray = thread->GetEcmaVM()->GetFactory()->CopyArray(valueArray, capacity, newCapacity);
53         obj->SetHashes(thread, hashArray);
54         obj->SetValues(thread, valueArray);
55     }
56     hashArray->Set(thread, index, JSTaggedValue(hashCode));
57     valueArray->Set(thread, index, value.GetTaggedValue());
58     size++;
59     obj->SetLength(size);
60     return true;
61 }
62 
Get(const uint32_t index)63 JSTaggedValue JSAPILightWeightSet::Get(const uint32_t index)
64 {
65     TaggedArray *valueArray = TaggedArray::Cast(GetValues().GetTaggedObject());
66     return valueArray->Get(index);
67 }
68 
CreateSlot(const JSThread * thread,const uint32_t capacity)69 JSHandle<TaggedArray> JSAPILightWeightSet::CreateSlot(const JSThread *thread, const uint32_t capacity)
70 {
71     ASSERT_PRINT(capacity > 0, "size must be a non-negative integer");
72     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
73     JSHandle<TaggedArray> taggedArray = factory->NewTaggedArray(capacity);
74     for (uint32_t i = 0; i < capacity; i++) {
75         taggedArray->Set(thread, i, JSTaggedValue::Hole());
76     }
77     return taggedArray;
78 }
79 
GetHashIndex(const JSThread * thread,const JSHandle<JSTaggedValue> & value,int32_t size)80 int32_t JSAPILightWeightSet::GetHashIndex(const JSThread *thread, const JSHandle<JSTaggedValue> &value, int32_t size)
81 {
82     uint32_t hashCode = Hash(thread, value.GetTaggedValue());
83     int32_t index = BinarySearchHashes(hashCode, size);
84     if (index < 0) {
85         return index;
86     }
87     TaggedArray *valueArray = TaggedArray::Cast(GetValues().GetTaggedObject());
88     if (index < size && (JSTaggedValue::SameValue(valueArray->Get(index), value.GetTaggedValue()))) {
89         return index;
90     }
91     TaggedArray *hashArray = TaggedArray::Cast(GetHashes().GetTaggedObject());
92     int32_t right = index;
93     while (right < size && (hashArray->Get(right).GetNumber() == hashCode)) {
94         if (JSTaggedValue::SameValue(valueArray->Get(right), value.GetTaggedValue())) {
95             return right;
96         }
97         right++;
98     }
99     int32_t left = index - 1;
100     while (left >= 0 && ((hashArray->Get(left).GetNumber() == hashCode))) {
101         if (JSTaggedValue::SameValue(valueArray->Get(left), value.GetTaggedValue())) {
102             return left;
103         }
104         left--;
105     }
106     return -right;
107 }
108 
BinarySearchHashes(uint32_t hash,int32_t size)109 int32_t JSAPILightWeightSet::BinarySearchHashes(uint32_t hash, int32_t size)
110 {
111     int32_t low = 0;
112     int32_t high = size - 1;
113     TaggedArray *hashArray = TaggedArray::Cast(GetHashes().GetTaggedObject());
114     while (low <= high) {
115         int32_t mid = (low + high) >> 1U;
116         uint32_t midVal = (uint32_t)(hashArray->Get(static_cast<uint32_t>(mid)).GetNumber());
117         if (midVal < hash) {
118             low = mid + 1;
119         } else {
120             if (midVal <= hash) {
121                 return mid;
122             }
123             high = mid - 1;
124         }
125     }
126     return -(low + 1);
127 }
128 
AddAll(JSThread * thread,const JSHandle<JSAPILightWeightSet> & obj,const JSHandle<JSTaggedValue> & value)129 bool JSAPILightWeightSet::AddAll(JSThread *thread, const JSHandle<JSAPILightWeightSet> &obj,
130                                  const JSHandle<JSTaggedValue> &value)
131 {
132     bool changed = false;
133     JSHandle<JSAPILightWeightSet> srcLightWeightSet = JSHandle<JSAPILightWeightSet>::Cast(value);
134     uint32_t srcSize = srcLightWeightSet->GetSize();
135     uint32_t size = obj->GetSize();
136     obj->EnsureCapacity(thread, obj, size + srcSize);
137     JSMutableHandle<JSTaggedValue> element(thread, JSTaggedValue::Undefined());
138     for (uint32_t i = 0; i < srcSize; i++) {
139         element.Update(srcLightWeightSet->GetValueAt(i));
140         changed |= JSAPILightWeightSet::Add(thread, obj, element);
141     }
142     return changed;
143 }
144 
EnsureCapacity(const JSThread * thread,const JSHandle<JSAPILightWeightSet> & obj,uint32_t minimumCapacity)145 void JSAPILightWeightSet::EnsureCapacity(const JSThread *thread, const JSHandle<JSAPILightWeightSet> &obj,
146                                          uint32_t minimumCapacity)
147 {
148     TaggedArray *hashes = TaggedArray::Cast(obj->GetValues().GetTaggedObject());
149     uint32_t capacity = hashes->GetLength();
150     uint32_t newCapacity = capacity;
151     if (capacity > minimumCapacity) {
152         return;
153     }
154     // adjust
155     while (newCapacity <= minimumCapacity) {
156         newCapacity = newCapacity << 1U;
157     }
158     obj->SizeCopy(thread, obj, capacity, newCapacity);
159 }
160 
SizeCopy(const JSThread * thread,const JSHandle<JSAPILightWeightSet> & obj,uint32_t capacity,uint32_t newCapacity)161 void JSAPILightWeightSet::SizeCopy(const JSThread *thread, const JSHandle<JSAPILightWeightSet> &obj,
162                                    uint32_t capacity, uint32_t newCapacity)
163 {
164     JSHandle<TaggedArray> hashArray(thread, obj->GetHashes());
165     JSHandle<TaggedArray> valueArray(thread, obj->GetValues());
166     hashArray = thread->GetEcmaVM()->GetFactory()->CopyArray(hashArray, capacity, newCapacity);
167     valueArray = thread->GetEcmaVM()->GetFactory()->CopyArray(valueArray, capacity, newCapacity);
168 
169     obj->SetValues(thread, hashArray);
170     obj->SetHashes(thread, valueArray);
171 }
172 
IsEmpty()173 bool JSAPILightWeightSet::IsEmpty()
174 {
175     return GetLength() == 0;
176 }
177 
GetValueAt(int32_t index)178 JSTaggedValue JSAPILightWeightSet::GetValueAt(int32_t index)
179 {
180     int32_t size = static_cast<int32_t>(GetLength());
181     if (index < 0 || index >= size) {
182         return JSTaggedValue::Undefined();
183     }
184     TaggedArray *values = TaggedArray::Cast(GetValues().GetTaggedObject());
185     return values->Get(index);
186 }
187 
GetHashAt(int32_t index)188 JSTaggedValue JSAPILightWeightSet::GetHashAt(int32_t index)
189 {
190     int32_t size = static_cast<int32_t>(GetLength());
191     if (index < 0 || index >= size) {
192         return JSTaggedValue::Undefined();
193     }
194     TaggedArray *values = TaggedArray::Cast(GetHashes().GetTaggedObject());
195     return values->Get(index);
196 }
197 
HasAll(const JSHandle<JSTaggedValue> & value)198 bool JSAPILightWeightSet::HasAll(const JSHandle<JSTaggedValue> &value)
199 {
200     bool result = false;
201     uint32_t relocate = 0;
202     JSAPILightWeightSet *lightweightSet = JSAPILightWeightSet::Cast(value.GetTaggedValue().GetTaggedObject());
203     uint32_t size = GetLength();
204     uint32_t destSize = lightweightSet->GetLength();
205     TaggedArray *hashes = TaggedArray::Cast(GetHashes().GetTaggedObject());
206     TaggedArray *destHashes = TaggedArray::Cast(lightweightSet->GetHashes().GetTaggedObject());
207     if (destSize > size) {
208         return result;
209     }
210     for (uint32_t i = 0; i < destSize; i++) {
211         uint32_t destHashCode = destHashes->Get(i).GetNumber();
212         result = false;
213         for (uint32_t j = relocate; j < size; j++) {
214             uint32_t hashCode = hashes->Get(j).GetNumber();
215             if (destHashCode == hashCode) {
216                 result = true;
217                 relocate = j + 1;
218                 break;
219             }
220         }
221         if (!result) {
222             break;
223         }
224     }
225     return result;
226 }
227 
Has(const JSThread * thread,const JSHandle<JSTaggedValue> & value)228 bool JSAPILightWeightSet::Has(const JSThread *thread, const JSHandle<JSTaggedValue> &value)
229 {
230     uint32_t size = GetLength();
231     int32_t index = GetHashIndex(thread, value, size);
232     if (index < 0) {
233         return false;
234     }
235     return true;
236 }
237 
HasHash(const JSHandle<JSTaggedValue> & hashCode)238 bool JSAPILightWeightSet::HasHash(const JSHandle<JSTaggedValue> &hashCode)
239 {
240     uint32_t size = GetLength();
241     int32_t index = BinarySearchHashes(hashCode.GetTaggedValue().GetNumber(), size);
242     if (index < 0) {
243         return false;
244     }
245     return true;
246 }
247 
Equal(JSThread * thread,const JSHandle<JSAPILightWeightSet> & obj,const JSHandle<JSTaggedValue> & value)248 bool JSAPILightWeightSet::Equal(JSThread *thread, const JSHandle<JSAPILightWeightSet> &obj,
249                                 const JSHandle<JSTaggedValue> &value)
250 {
251     bool result = false;
252     JSHandle<TaggedArray> destHashes(thread, obj->GetValues());
253     uint32_t destSize = obj->GetLength();
254     uint32_t srcSize = 0;
255     JSMutableHandle<TaggedArray> srcHashes(thread, obj->GetHashes());
256     if (value.GetTaggedValue().IsJSAPILightWeightSet()) {
257         JSAPILightWeightSet *srcLightWeightSet = JSAPILightWeightSet::Cast(value.GetTaggedValue().GetTaggedObject());
258         srcSize = srcLightWeightSet->GetLength();
259         if (srcSize == 0 || destSize == 0) {
260             return false;
261         }
262         srcHashes.Update(srcLightWeightSet->GetHashes());
263     }
264     if (value.GetTaggedValue().IsJSArray()) {
265         srcHashes.Update(JSArray::ToTaggedArray(thread, value));
266         srcSize = srcHashes->GetLength();
267         if (srcSize == 0 || destSize == 0) {
268             return false;
269         }
270     }
271     if (srcSize != destSize) {
272         return false;
273     }
274     for (uint32_t i = 0; i < destSize; i++) {
275         JSTaggedValue compareValue = destHashes->Get(i);
276         JSTaggedValue values = srcHashes->Get(i);
277         if (compareValue.IsNumber() && values.IsNumber()) {
278             result = JSTaggedValue::SameValueNumberic(compareValue, values);
279         }
280         if (compareValue.IsString() && values.IsString()) {
281             result =
282                 JSTaggedValue::StringCompare(EcmaString::Cast(compareValue.GetTaggedObject()),
283                                              EcmaString::Cast(values.GetTaggedObject()));
284         }
285         if (!result) {
286             return result;
287         }
288     }
289     return result;
290 }
291 
IncreaseCapacityTo(JSThread * thread,const JSHandle<JSAPILightWeightSet> & obj,int32_t minCapacity)292 void JSAPILightWeightSet::IncreaseCapacityTo(JSThread *thread, const JSHandle<JSAPILightWeightSet> &obj,
293                                              int32_t minCapacity)
294 {
295     uint32_t capacity = TaggedArray::Cast(obj->GetValues().GetTaggedObject())->GetLength();
296     int32_t intCapacity = static_cast<int32_t>(capacity);
297     if (minCapacity <= 0 || intCapacity >= minCapacity) {
298         std::ostringstream oss;
299         oss << "The value of \"minimumCapacity\" is out of range. It must be > " << intCapacity
300             << ". Received value is: " << minCapacity;
301         JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
302         THROW_NEW_ERROR_AND_RETURN(thread, error);
303     }
304     JSHandle<TaggedArray> hashArray(thread, obj->GetHashes());
305     JSHandle<TaggedArray> newElements =
306         thread->GetEcmaVM()->GetFactory()->NewAndCopyTaggedArray(hashArray,
307                                                                  static_cast<uint32_t>(minCapacity), capacity);
308     obj->SetHashes(thread, newElements);
309 }
310 
GetIteratorObj(JSThread * thread,const JSHandle<JSAPILightWeightSet> & obj,IterationKind kind)311 JSHandle<JSTaggedValue> JSAPILightWeightSet::GetIteratorObj(JSThread *thread, const JSHandle<JSAPILightWeightSet> &obj,
312                                                             IterationKind kind)
313 {
314     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
315     JSHandle<JSTaggedValue> iter =
316         JSHandle<JSTaggedValue>::Cast(factory->NewJSAPILightWeightSetIterator(obj, kind));
317     return iter;
318 }
319 
ForEach(JSThread * thread,const JSHandle<JSTaggedValue> & thisHandle,const JSHandle<JSTaggedValue> & callbackFn,const JSHandle<JSTaggedValue> & thisArg)320 JSTaggedValue JSAPILightWeightSet::ForEach(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle,
321                                            const JSHandle<JSTaggedValue> &callbackFn,
322                                            const JSHandle<JSTaggedValue> &thisArg)
323 {
324     JSHandle<JSAPILightWeightSet> lightweightset = JSHandle<JSAPILightWeightSet>::Cast(thisHandle);
325     CheckAndCopyValues(thread, lightweightset);
326     uint32_t length = lightweightset->GetSize();
327     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
328     for (uint32_t k = 0; k < length; k++) {
329         JSTaggedValue kValue = lightweightset->GetValueAt(k);
330         EcmaRuntimeCallInfo *info =
331             EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFn, thisArg, undefined, 3); // 3:three args
332         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
333         info->SetCallArg(kValue, kValue, thisHandle.GetTaggedValue());
334         JSTaggedValue funcResult = JSFunction::Call(info);
335         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, funcResult);
336         if (lightweightset->GetSize() != length) {  // prevent length change
337             length = lightweightset->GetSize();
338         }
339     }
340     return JSTaggedValue::Undefined();
341 }
342 
GetIndexOf(const JSThread * thread,JSHandle<JSTaggedValue> & value)343 int32_t JSAPILightWeightSet::GetIndexOf(const JSThread *thread, JSHandle<JSTaggedValue> &value)
344 {
345     uint32_t size = GetLength();
346     int32_t index = GetHashIndex(thread, value, size);
347     return index;
348 }
349 
Remove(JSThread * thread,JSHandle<JSTaggedValue> & value)350 JSTaggedValue JSAPILightWeightSet::Remove(JSThread *thread, JSHandle<JSTaggedValue> &value)
351 {
352     uint32_t size = GetLength();
353     TaggedArray *valueArray = TaggedArray::Cast(GetValues().GetTaggedObject());
354     int32_t index = GetHashIndex(thread, value, size);
355     if (index < 0) {
356         return JSTaggedValue::Undefined();
357     }
358     JSTaggedValue result = valueArray->Get(index);
359     RemoveAt(thread, index);
360     return result;
361 }
362 
RemoveAt(JSThread * thread,int32_t index)363 bool JSAPILightWeightSet::RemoveAt(JSThread *thread, int32_t index)
364 {
365     uint32_t size = GetLength();
366     if (index < 0 || index >= static_cast<int32_t>(size)) {
367         return false;
368     }
369     JSHandle<TaggedArray> valueArray(thread, GetValues());
370     JSHandle<TaggedArray> hashArray(thread, GetHashes());
371     RemoveValue(thread, hashArray, static_cast<uint32_t>(index), true);
372     RemoveValue(thread, valueArray, static_cast<uint32_t>(index));
373     SetLength(size - 1);
374     return true;
375 }
376 
RemoveValue(const JSThread * thread,JSHandle<TaggedArray> & taggedArray,uint32_t index,bool isHash)377 void JSAPILightWeightSet::RemoveValue(const JSThread *thread, JSHandle<TaggedArray> &taggedArray,
378                                       uint32_t index, bool isHash)
379 {
380     uint32_t len = GetLength();
381     ASSERT(index < len);
382     TaggedArray::RemoveElementByIndex(thread, taggedArray, index, len, isHash);
383 }
384 
AdjustArray(JSThread * thread,JSHandle<TaggedArray> srcArray,uint32_t fromIndex,uint32_t toIndex,bool direction)385 void JSAPILightWeightSet::AdjustArray(JSThread *thread, JSHandle<TaggedArray> srcArray, uint32_t fromIndex,
386                                       uint32_t toIndex, bool direction)
387 {
388     uint32_t size = GetLength();
389     uint32_t idx = size - 1;
390     if (direction) {
391         while (fromIndex < toIndex) {
392             JSTaggedValue value = srcArray->Get(idx);
393             srcArray->Set(thread, idx + 1, value);
394             idx--;
395             fromIndex++;
396         }
397     } else {
398         uint32_t moveSize = size - fromIndex;
399         for (uint32_t i = 0; i < moveSize; i++) {
400             if ((fromIndex + i) < size) {
401                 JSTaggedValue value = srcArray->Get(fromIndex + i);
402                 srcArray->Set(thread, toIndex + i, value);
403             } else {
404                 srcArray->Set(thread, toIndex + i, JSTaggedValue::Hole());
405             }
406         }
407     }
408 }
409 
ToString(JSThread * thread,const JSHandle<JSAPILightWeightSet> & obj)410 JSTaggedValue JSAPILightWeightSet::ToString(JSThread *thread, const JSHandle<JSAPILightWeightSet> &obj)
411 {
412     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
413     std::u16string sepStr = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.from_bytes(",");
414 
415     uint32_t length = obj->GetSize();
416     JSHandle<TaggedArray> valueArray(thread, obj->GetValues());
417     std::u16string concatStr;
418     JSMutableHandle<JSTaggedValue> values(thread, JSTaggedValue::Undefined());
419     for (uint32_t k = 0; k < length; k++) {
420         std::u16string nextStr;
421         values.Update(valueArray->Get(k));
422         if (!values->IsUndefined() && !values->IsNull()) {
423             JSHandle<EcmaString> nextStringHandle = JSTaggedValue::ToString(thread, values);
424             RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
425             nextStr = EcmaStringAccessor(nextStringHandle).ToU16String();
426         }
427         if (k > 0) {
428             concatStr.append(sepStr);
429             concatStr.append(nextStr);
430             continue;
431         }
432         concatStr.append(nextStr);
433     }
434     char16_t *char16tData = concatStr.data();
435     auto *uint16tData = reinterpret_cast<uint16_t *>(char16tData);
436     uint32_t u16strSize = concatStr.size();
437     return factory->NewFromUtf16Literal(uint16tData, u16strSize).GetTaggedValue();
438 }
439 
Clear(JSThread * thread)440 void JSAPILightWeightSet::Clear(JSThread *thread)
441 {
442     TaggedArray *hashArray = TaggedArray::Cast(GetHashes().GetTaggedObject());
443     TaggedArray *valueArray = TaggedArray::Cast(GetValues().GetTaggedObject());
444     uint32_t size = GetLength();
445     for (uint32_t index = 0; index < size; index++) {
446         hashArray->Set(thread, index, JSTaggedValue::Hole());
447         valueArray->Set(thread, index, JSTaggedValue::Hole());
448     }
449     SetLength(0);
450 }
451 
Hash(const JSThread * thread,JSTaggedValue key)452 uint32_t JSAPILightWeightSet::Hash(const JSThread *thread, JSTaggedValue key)
453 {
454     if (key.IsDouble() && key.GetDouble() == 0.0) {
455         key = JSTaggedValue(0);
456     }
457     if (key.IsSymbol()) {
458         auto symbolString = JSSymbol::Cast(key.GetTaggedObject());
459         return symbolString->GetHashField();
460     }
461     if (key.IsString()) {
462         auto keyString = EcmaString::Cast(key.GetTaggedObject());
463         return EcmaStringAccessor(keyString).GetHashcode();
464     }
465     if (key.IsECMAObject()) {
466         uint32_t hash = static_cast<uint32_t>(ECMAObject::Cast(key.GetTaggedObject())->GetHash());
467         if (hash == 0) {
468             hash = static_cast<uint32_t>(base::RandomGenerator::GenerateIdentityHash());
469             JSHandle<ECMAObject> ecmaObj(thread, key);
470             ECMAObject::SetHash(thread, hash, ecmaObj);
471         }
472         return hash;
473     }
474     if (key.IsInt()) {
475         uint32_t hash = static_cast<uint32_t>(key.GetInt());
476         return hash;
477     }
478     uint64_t keyValue = key.GetRawData();
479     return GetHash32(reinterpret_cast<uint8_t *>(&keyValue), sizeof(keyValue) / sizeof(uint8_t));
480 }
481 
CheckAndCopyValues(const JSThread * thread,JSHandle<JSAPILightWeightSet> obj)482 void JSAPILightWeightSet::CheckAndCopyValues(const JSThread *thread, JSHandle<JSAPILightWeightSet> obj)
483 {
484     JSHandle<TaggedArray> values(thread, obj->GetValues());
485     // Check whether array is shared in the nonmovable space before set properties and elements.
486     // If true, then really copy array in the semi space.
487     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
488     if (values.GetTaggedValue().IsCOWArray()) {
489         auto newArray = factory->CopyArray(values, values->GetLength(), values->GetLength(),
490             JSTaggedValue::Hole(), MemSpaceType::SEMI_SPACE);
491         obj->SetValues(thread, newArray.GetTaggedValue());
492     }
493 }
494 } // namespace panda::ecmascript
495