1 /*
2  * Copyright (c) 2021-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/dfx/native_module_failure_info.h"
17 #include "ecmascript/builtins/builtins.h"
18 #include "ecmascript/builtins/builtins_errors.h"
19 #include "ecmascript/ecma_string_table.h"
20 #include "ecmascript/ecma_string-inl.h"
21 #include "ecmascript/ic/ic_handler.h"
22 #include "ecmascript/ic/profile_type_info.h"
23 #include "ecmascript/ic/proto_change_details.h"
24 #include "ecmascript/jobs/pending_job.h"
25 #include "ecmascript/js_api/js_api_arraylist.h"
26 #include "ecmascript/js_api/js_api_arraylist_iterator.h"
27 #include "ecmascript/js_api/js_api_bitvector.h"
28 #include "ecmascript/js_api/js_api_bitvector_iterator.h"
29 #include "ecmascript/js_api/js_api_deque.h"
30 #include "ecmascript/js_api/js_api_deque_iterator.h"
31 #include "ecmascript/js_api/js_api_hashmap_iterator.h"
32 #include "ecmascript/js_api/js_api_hashset.h"
33 #include "ecmascript/js_api/js_api_hashset_iterator.h"
34 #include "ecmascript/js_api/js_api_lightweightmap.h"
35 #include "ecmascript/js_api/js_api_lightweightmap_iterator.h"
36 #include "ecmascript/js_api/js_api_lightweightset.h"
37 #include "ecmascript/js_api/js_api_lightweightset_iterator.h"
38 #include "ecmascript/js_api/js_api_linked_list.h"
39 #include "ecmascript/js_api/js_api_linked_list_iterator.h"
40 #include "ecmascript/js_api/js_api_list.h"
41 #include "ecmascript/js_api/js_api_list_iterator.h"
42 #include "ecmascript/js_api/js_api_plain_array.h"
43 #include "ecmascript/js_api/js_api_plain_array_iterator.h"
44 #include "ecmascript/js_api/js_api_queue.h"
45 #include "ecmascript/js_api/js_api_queue_iterator.h"
46 #include "ecmascript/js_api/js_api_stack_iterator.h"
47 #include "ecmascript/js_api/js_api_tree_map.h"
48 #include "ecmascript/js_api/js_api_tree_map_iterator.h"
49 #include "ecmascript/js_api/js_api_tree_set.h"
50 #include "ecmascript/js_api/js_api_tree_set_iterator.h"
51 #include "ecmascript/js_api/js_api_vector.h"
52 #include "ecmascript/js_api/js_api_vector_iterator.h"
53 #include "ecmascript/js_arguments.h"
54 #include "ecmascript/js_array_iterator.h"
55 #include "ecmascript/js_arraybuffer.h"
56 #include "ecmascript/js_async_from_sync_iterator.h"
57 #include "ecmascript/js_async_function.h"
58 #include "ecmascript/js_async_generator_object.h"
59 #include "ecmascript/js_finalization_registry.h"
60 #include "ecmascript/js_for_in_iterator.h"
61 #include "ecmascript/js_map.h"
62 #include "ecmascript/js_map_iterator.h"
63 #include "ecmascript/js_primitive_ref.h"
64 #include "ecmascript/js_promise.h"
65 #include "ecmascript/js_realm.h"
66 #include "ecmascript/js_regexp.h"
67 #include "ecmascript/js_regexp_iterator.h"
68 #include "ecmascript/js_set.h"
69 #include "ecmascript/js_set_iterator.h"
70 #include "ecmascript/js_string_iterator.h"
71 #include "ecmascript/js_weak_container.h"
72 #include "ecmascript/js_weak_ref.h"
73 #include "ecmascript/jspandafile/program_object.h"
74 #include "ecmascript/marker_cell.h"
75 #include "ecmascript/object_factory.h"
76 #include "ecmascript/require/js_cjs_exports.h"
77 #include "ecmascript/require/js_cjs_require.h"
78 #include "ecmascript/shared_mm/shared_mm.h"
79 #include "ecmascript/shared_objects/js_shared_array.h"
80 #include "ecmascript/shared_objects/js_sendable_arraybuffer.h"
81 #include "ecmascript/shared_objects/js_shared_array_iterator.h"
82 #include "ecmascript/shared_objects/js_shared_map.h"
83 #include "ecmascript/shared_objects/js_shared_map_iterator.h"
84 #include "ecmascript/shared_objects/js_shared_set.h"
85 #include "ecmascript/shared_objects/js_shared_set_iterator.h"
86 #include "ecmascript/shared_objects/js_shared_typed_array.h"
87 #include "ecmascript/symbol_table.h"
88 #include "ecmascript/template_map.h"
89 #include "ecmascript/vtable.h"
90 #ifdef ARK_SUPPORT_INTL
91 #include "ecmascript/js_collator.h"
92 #include "ecmascript/js_date_time_format.h"
93 #include "ecmascript/js_displaynames.h"
94 #include "ecmascript/js_list_format.h"
95 #include "ecmascript/js_number_format.h"
96 #include "ecmascript/js_plural_rules.h"
97 #include "ecmascript/js_relative_time_format.h"
98 #include "ecmascript/js_segmenter.h"
99 #include "ecmascript/js_segments.h"
100 #include "ecmascript/js_segment_iterator.h"
101 #endif
102 namespace panda::ecmascript {
103 using Error = builtins::BuiltinsError;
104 using RangeError = builtins::BuiltinsRangeError;
105 using ReferenceError = builtins::BuiltinsReferenceError;
106 using TypeError = builtins::BuiltinsTypeError;
107 using AggregateError = builtins::BuiltinsAggregateError;
108 using URIError = builtins::BuiltinsURIError;
109 using SyntaxError = builtins::BuiltinsSyntaxError;
110 using EvalError = builtins::BuiltinsEvalError;
111 using OOMError = builtins::BuiltinsOOMError;
112 using ErrorType = base::ErrorType;
113 using ErrorHelper = base::ErrorHelper;
114 
ObjectFactory(JSThread *thread, Heap *heap, SharedHeap *sHeap)115 ObjectFactory::ObjectFactory(JSThread *thread, Heap *heap, SharedHeap *sHeap)
116     : thread_(thread), vm_(thread->GetEcmaVM()), heap_(heap), sHeap_(sHeap) {}
117 
NewMethodForNativeFunction(const void *func, FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId, MemSpaceType methodSpaceType)118 JSHandle<Method> ObjectFactory::NewMethodForNativeFunction(const void *func, FunctionKind kind,
119                                                            kungfu::BuiltinsStubCSigns::ID builtinId,
120                                                            MemSpaceType methodSpaceType)
121 {
122     uint32_t numArgs = 2;  // function object and this
123     auto method = NewSMethod(nullptr, methodSpaceType);
124     method->SetNativePointer(const_cast<void *>(func));
125     method->SetNativeBit(true);
126     if (builtinId != kungfu::BuiltinsStubCSigns::INVALID) {
127         bool isFast = kungfu::BuiltinsStubCSigns::IsFastBuiltin(builtinId);
128         method->SetFastBuiltinBit(isFast);
129         method->SetBuiltinId(static_cast<uint8_t>(builtinId));
130     }
131     method->SetNumArgsWithCallField(numArgs);
132     method->SetFunctionKind(kind);
133     return method;
134 }
135 
NewEcmaHClassClass(JSHClass *hclass, uint32_t size, JSType type)136 JSHandle<JSHClass> ObjectFactory::NewEcmaHClassClass(JSHClass *hclass, uint32_t size, JSType type)
137 {
138     NewObjectHook();
139     uint32_t classSize = JSHClass::SIZE;
140     auto *newClass = static_cast<JSHClass *>(heap_->AllocateClassClass(hclass, classSize));
141     newClass->Initialize(thread_, size, type, 0);
142 
143     return JSHandle<JSHClass>(thread_, newClass);
144 }
145 
InitClassClass()146 JSHandle<JSHClass> ObjectFactory::InitClassClass()
147 {
148     JSHandle<JSHClass> hClassHandle = NewEcmaHClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS);
149     JSHClass *hclass = reinterpret_cast<JSHClass *>(hClassHandle.GetTaggedValue().GetTaggedObject());
150     hclass->SetClass(thread_, hclass);
151     return hClassHandle;
152 }
153 
NewEcmaHClass(JSHClass *hclass, uint32_t size, JSType type, uint32_t inlinedProps)154 JSHandle<JSHClass> ObjectFactory::NewEcmaHClass(JSHClass *hclass, uint32_t size, JSType type, uint32_t inlinedProps)
155 {
156     NewObjectHook();
157     uint32_t classSize = JSHClass::SIZE;
158     auto *newClass = static_cast<JSHClass *>(heap_->AllocateNonMovableOrHugeObject(hclass, classSize));
159     newClass->Initialize(thread_, size, type, inlinedProps);
160 
161     return JSHandle<JSHClass>(thread_, newClass);
162 }
163 
164 // This function don't UpdateProtoClass
NewEcmaHClass(uint32_t size, uint32_t inlinedProps, JSType type, const JSHandle<JSTaggedValue> &prototype, const JSHandle<JSTaggedValue> &layout)165 JSHandle<JSHClass> ObjectFactory::NewEcmaHClass(uint32_t size, uint32_t inlinedProps, JSType type,
166     const JSHandle<JSTaggedValue> &prototype, const JSHandle<JSTaggedValue> &layout)
167 {
168     NewSObjectHook();
169     uint32_t classSize = JSHClass::SIZE;
170     auto *newClass = static_cast<JSHClass *>(heap_->AllocateNonMovableOrHugeObject(
171         JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()), classSize));
172     newClass->Initialize(thread_, size, type, inlinedProps, layout);
173     JSHandle<JSHClass> hclass(thread_, newClass);
174     if (prototype->IsJSObject()) {
175         prototype->GetTaggedObject()->GetClass()->SetIsPrototype(true);
176     }
177     hclass->SetProto(thread_, prototype.GetTaggedValue());
178     hclass->SetNumberOfProps(inlinedProps);
179     hclass->SetExtensible(false);
180     return hclass;
181 }
182 
NewEcmaReadOnlyHClass(JSHClass *hclass, uint32_t size, JSType type, uint32_t inlinedProps)183 JSHandle<JSHClass> ObjectFactory::NewEcmaReadOnlyHClass(JSHClass *hclass, uint32_t size, JSType type,
184                                                         uint32_t inlinedProps)
185 {
186     NewObjectHook();
187     uint32_t classSize = JSHClass::SIZE;
188     auto *newClass = static_cast<JSHClass *>(heap_->AllocateReadOnlyOrHugeObject(hclass, classSize));
189     ASSERT(newClass != nullptr);
190     newClass->Initialize(thread_, size, type, inlinedProps);
191 
192     return JSHandle<JSHClass>(thread_, newClass);
193 }
194 
NewEcmaHClass(uint32_t size, JSType type, uint32_t inlinedProps)195 JSHandle<JSHClass> ObjectFactory::NewEcmaHClass(uint32_t size, JSType type, uint32_t inlinedProps)
196 {
197     return NewEcmaHClass(JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()),
198                          size, type, inlinedProps);
199 }
200 
InitObjectFields(const TaggedObject *object)201 void ObjectFactory::InitObjectFields(const TaggedObject *object)
202 {
203     auto *klass = object->GetClass();
204     auto objBodySize = klass->GetObjectSize() - TaggedObject::TaggedObjectSize();
205     ASSERT(objBodySize % JSTaggedValue::TaggedTypeSize() == 0);
206     uint32_t numOfFields = objBodySize / JSTaggedValue::TaggedTypeSize();
207     size_t addr = reinterpret_cast<uintptr_t>(object) + TaggedObject::TaggedObjectSize();
208     for (uint32_t i = 0; i < numOfFields; i++) {
209         auto *fieldAddr = reinterpret_cast<JSTaggedType *>(addr + i * JSTaggedValue::TaggedTypeSize());
210         *fieldAddr = JSTaggedValue::Undefined().GetRawData();
211     }
212 }
213 
NewJSArrayBufferData(const JSHandle<JSArrayBuffer> &array, int32_t length)214 void ObjectFactory::NewJSArrayBufferData(const JSHandle<JSArrayBuffer> &array, int32_t length)
215 {
216     if (length == 0) {
217         return;
218     }
219 
220     JSTaggedValue data = array->GetArrayBufferData();
221     size_t size = static_cast<size_t>(length) * sizeof(uint8_t);
222     if (!data.IsUndefined()) {
223         auto *pointer = JSNativePointer::Cast(data.GetTaggedObject());
224         auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
225         heap_->IncNativeSizeAfterLastGC(size);
226         if (memset_s(newData, length, 0, length) != EOK) {
227             LOG_FULL(FATAL) << "memset_s failed";
228             UNREACHABLE();
229         }
230         pointer->ResetExternalPointer(thread_, newData);
231         vm_->GetNativeAreaAllocator()->ModifyNativeSizeStats(pointer->GetBindingSize(), size,
232                                                              NativeFlag::ARRAY_BUFFER);
233         return;
234     }
235 
236     auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
237     heap_->IncNativeSizeAfterLastGC(size);
238     if (memset_s(newData, length, 0, length) != EOK) {
239         LOG_FULL(FATAL) << "memset_s failed";
240         UNREACHABLE();
241     }
242     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newData, NativeAreaAllocator::FreeBufferFunc,
243                                                            vm_->GetNativeAreaAllocator(), false, size, Concurrent::NO,
244                                                            NativeFlag::ARRAY_BUFFER);
245     array->SetArrayBufferData(thread_, pointer);
246     array->SetWithNativeAreaAllocator(true);
247     vm_->GetNativeAreaAllocator()->IncreaseNativeSizeStats(length, NativeFlag::ARRAY_BUFFER);
248 }
249 
NewJSSendableArrayBufferData(const JSHandle<JSSendableArrayBuffer> &array, int32_t length)250 void ObjectFactory::NewJSSendableArrayBufferData(const JSHandle<JSSendableArrayBuffer> &array, int32_t length)
251 {
252     if (length == 0) {
253         return;
254     }
255 
256     JSTaggedValue data = array->GetArrayBufferData();
257     size_t size = static_cast<size_t>(length) * sizeof(uint8_t);
258     NativeAreaAllocator *nativeAreaAllocator = sHeap_->GetNativeAreaAllocator();
259     if (!data.IsUndefined()) {
260         auto *pointer = JSNativePointer::Cast(data.GetTaggedObject());
261         auto newData = nativeAreaAllocator->AllocateBuffer(size);
262         if (newData == nullptr) {
263             LOG_ECMA(FATAL) << "ObjectFactory::NewJSSendableArrayBufferData:newData is nullptr";
264         }
265         if (memset_s(newData, length, 0, length) != EOK) {
266             LOG_FULL(FATAL) << "memset_s failed";
267             UNREACHABLE();
268         }
269         pointer->ResetExternalPointer(thread_, newData);
270         nativeAreaAllocator->ModifyNativeSizeStats(pointer->GetBindingSize(), size,
271                                                    NativeFlag::ARRAY_BUFFER);
272         return;
273     }
274 
275     auto newData = nativeAreaAllocator->AllocateBuffer(size);
276     if (newData == nullptr) {
277         LOG_ECMA(FATAL) << "ObjectFactory::NewJSSendableArrayBufferData:newData is nullptr";
278     }
279     if (memset_s(newData, length, 0, length) != EOK) {
280         LOG_FULL(FATAL) << "memset_s failed";
281         UNREACHABLE();
282     }
283     JSHandle<JSNativePointer> pointer = NewSJSNativePointer(newData, NativeAreaAllocator::FreeBufferFunc,
284                                                             nativeAreaAllocator, false, size,
285                                                             NativeFlag::ARRAY_BUFFER);
286     array->SetArrayBufferData(thread_, pointer);
287     array->SetWithNativeAreaAllocator(true);
288     nativeAreaAllocator->IncreaseNativeSizeStats(length, NativeFlag::ARRAY_BUFFER);
289 }
290 
NewJSSendableArrayBuffer(int32_t length)291 JSHandle<JSSendableArrayBuffer> ObjectFactory::NewJSSendableArrayBuffer(int32_t length)
292 {
293     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
294 
295     JSHandle<JSFunction> constructor(env->GetSBuiltininArrayBufferFunction());
296     JSHandle<JSSendableArrayBuffer> sendableArrayBuffer(NewJSObjectByConstructor(constructor));
297     sendableArrayBuffer->SetArrayBufferByteLength(length);
298     if (length > 0) {
299         NewJSSendableArrayBufferData(sendableArrayBuffer, length);
300         sendableArrayBuffer->SetShared(false);
301     }
302     return sendableArrayBuffer;
303 }
304 
NewJSSendableArrayBuffer(void *buffer, int32_t length, const NativePointerCallback &deleter, void *data)305 JSHandle<JSSendableArrayBuffer> ObjectFactory::NewJSSendableArrayBuffer(void *buffer, int32_t length,
306                                                                         const NativePointerCallback &deleter,
307                                                                         void *data)
308 {
309     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
310 
311     JSHandle<JSFunction> constructor(env->GetSBuiltininArrayBufferFunction());
312     JSHandle<JSSendableArrayBuffer> sendableArrayBuffer(NewJSObjectByConstructor(constructor));
313     length = buffer == nullptr ? 0 : length;
314     sendableArrayBuffer->SetArrayBufferByteLength(length);
315     if (length > 0) {
316         JSHandle<JSNativePointer> pointer = NewSJSNativePointer(buffer, deleter, data, false, length);
317         sendableArrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue());
318         sendableArrayBuffer->SetShared(false);
319         sendableArrayBuffer->SetWithNativeAreaAllocator(deleter == NativeAreaAllocator::FreeBufferFunc &&
320                                                 data == vm_->GetNativeAreaAllocator());
321     }
322     return sendableArrayBuffer;
323 }
324 
NewJSSharedArrayBufferData(const JSHandle<JSArrayBuffer> &array, int32_t length)325 void ObjectFactory::NewJSSharedArrayBufferData(const JSHandle<JSArrayBuffer> &array, int32_t length)
326 {
327     if (length == 0) {
328         return;
329     }
330     void *newData = nullptr;
331     size_t size =
332         JSSharedMemoryManager::GetInstance()->CreateOrLoad(&newData, length) ? static_cast<size_t>(length) : 0U;
333     if (memset_s(newData, length, 0, length) != EOK) {
334         LOG_FULL(FATAL) << "memset_s failed";
335         UNREACHABLE();
336     }
337     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newData, JSSharedMemoryManager::RemoveSharedMemory,
338                                                            JSSharedMemoryManager::GetInstance(), false, size);
339     array->SetArrayBufferData(thread_, pointer);
340     array->SetWithNativeAreaAllocator(false);
341 }
342 
NewJSArrayBuffer(int32_t length)343 JSHandle<JSArrayBuffer> ObjectFactory::NewJSArrayBuffer(int32_t length)
344 {
345     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
346 
347     JSHandle<JSFunction> constructor(env->GetArrayBufferFunction());
348     JSHandle<JSArrayBuffer> arrayBuffer(NewJSObjectByConstructor(constructor));
349     arrayBuffer->SetArrayBufferByteLength(length);
350     if (length > 0) {
351         auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(length);
352         heap_->IncNativeSizeAfterLastGC(length);
353         if (memset_s(newData, length, 0, length) != EOK) {
354             LOG_FULL(FATAL) << "memset_s failed";
355             UNREACHABLE();
356         }
357         JSHandle<JSNativePointer> pointer = NewJSNativePointer(newData, NativeAreaAllocator::FreeBufferFunc,
358                                                                vm_->GetNativeAreaAllocator(), false, length,
359                                                                Concurrent::NO, NativeFlag::ARRAY_BUFFER);
360         arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue());
361         arrayBuffer->SetWithNativeAreaAllocator(true);
362         vm_->GetNativeAreaAllocator()->IncreaseNativeSizeStats(length, NativeFlag::ARRAY_BUFFER);
363     }
364     return arrayBuffer;
365 }
366 
NewJSArrayBuffer(void *buffer, int32_t length, const NativePointerCallback &deleter, void *data, bool share)367 JSHandle<JSArrayBuffer> ObjectFactory::NewJSArrayBuffer(void *buffer, int32_t length,
368                                                         const NativePointerCallback &deleter, void *data, bool share)
369 {
370     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
371 
372     JSHandle<JSFunction> constructor(env->GetArrayBufferFunction());
373     JSHandle<JSArrayBuffer> arrayBuffer(NewJSObjectByConstructor(constructor));
374     length = buffer == nullptr ? 0 : length;
375     arrayBuffer->SetArrayBufferByteLength(length);
376     if (length > 0) {
377         JSHandle<JSNativePointer> pointer = NewJSNativePointer(buffer, deleter, data, false, length);
378         arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue());
379         arrayBuffer->SetShared(share);
380         arrayBuffer->SetWithNativeAreaAllocator(deleter == NativeAreaAllocator::FreeBufferFunc &&
381                                                 data == vm_->GetNativeAreaAllocator());
382     }
383     return arrayBuffer;
384 }
385 
NewJSDataView(JSHandle<JSArrayBuffer> buffer, uint32_t offset, uint32_t length)386 JSHandle<JSDataView> ObjectFactory::NewJSDataView(JSHandle<JSArrayBuffer> buffer, uint32_t offset, uint32_t length)
387 {
388     uint32_t arrayLength = buffer->GetArrayBufferByteLength();
389     if (arrayLength - offset < length) {
390         THROW_TYPE_ERROR_AND_RETURN(thread_, "offset or length error",
391                                     JSHandle<JSDataView>(thread_, JSTaggedValue::Undefined()));
392     }
393     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
394 
395     JSHandle<JSFunction> constructor(env->GetDataViewFunction());
396     JSHandle<JSDataView> arrayBuffer(NewJSObjectByConstructor(constructor));
397     arrayBuffer->SetDataView(thread_, JSTaggedValue::True());
398     arrayBuffer->SetViewedArrayBuffer(thread_, buffer.GetTaggedValue());
399     arrayBuffer->SetByteLength(length);
400     arrayBuffer->SetByteOffset(offset);
401     return arrayBuffer;
402 }
403 
NewJSSharedArrayBuffer(int32_t length)404 JSHandle<JSArrayBuffer> ObjectFactory::NewJSSharedArrayBuffer(int32_t length)
405 {
406     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
407 
408     JSHandle<JSFunction> constructor(env->GetSharedArrayBufferFunction());
409     JSHandle<JSArrayBuffer> sharedArrayBuffer(NewJSObjectByConstructor(constructor));
410     sharedArrayBuffer->SetArrayBufferByteLength(length);
411     if (length > 0) {
412         NewJSSharedArrayBufferData(sharedArrayBuffer, length);
413         sharedArrayBuffer->SetShared(true);
414     }
415     return sharedArrayBuffer;
416 }
417 
NewJSSharedArrayBuffer(void *buffer, int32_t length)418 JSHandle<JSArrayBuffer> ObjectFactory::NewJSSharedArrayBuffer(void *buffer, int32_t length)
419 {
420     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
421 
422     JSHandle<JSFunction> constructor(env->GetSharedArrayBufferFunction());
423     JSHandle<JSArrayBuffer> sharedArrayBuffer(NewJSObjectByConstructor(constructor));
424     length = buffer == nullptr ? 0 : length;
425     sharedArrayBuffer->SetArrayBufferByteLength(length);
426     if (length > 0) {
427         JSHandle<JSNativePointer> pointer = NewJSNativePointer(buffer, JSSharedMemoryManager::RemoveSharedMemory,
428                                                                JSSharedMemoryManager::GetInstance(), false, length);
429         sharedArrayBuffer->SetArrayBufferData(thread_, pointer);
430         sharedArrayBuffer->SetShared(true);
431         sharedArrayBuffer->SetWithNativeAreaAllocator(false);
432     }
433     return sharedArrayBuffer;
434 }
435 
NewJSRegExpByteCodeData(const JSHandle<JSRegExp> &regexp, void *buffer, size_t size)436 void ObjectFactory::NewJSRegExpByteCodeData(const JSHandle<JSRegExp> &regexp, void *buffer, size_t size)
437 {
438     if (buffer == nullptr) {
439         return;
440     }
441 
442     auto newBuffer = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
443     heap_->IncNativeSizeAfterLastGC(size);
444     if (memcpy_s(newBuffer, size, buffer, size) != EOK) {
445         LOG_FULL(FATAL) << "memcpy_s failed";
446         UNREACHABLE();
447     }
448     JSTaggedValue data = regexp->GetByteCodeBuffer();
449     if (!data.IsUndefined()) {
450         JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject());
451         native->ResetExternalPointer(thread_, newBuffer);
452         return;
453     }
454     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newBuffer, NativeAreaAllocator::FreeBufferFunc,
455                                                            vm_->GetNativeAreaAllocator(), false, size, Concurrent::NO,
456                                                            NativeFlag::REGEXP_BTYECODE);
457     regexp->SetByteCodeBuffer(thread_, pointer.GetTaggedValue());
458     regexp->SetLength(static_cast<uint32_t>(size));
459     vm_->GetNativeAreaAllocator()->IncreaseNativeSizeStats(size, NativeFlag::REGEXP_BTYECODE);
460 }
461 
NewEcmaHClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype)462 JSHandle<JSHClass> ObjectFactory::NewEcmaHClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype)
463 {
464     const int inlinedProps = JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS;
465     return NewEcmaHClass(size, inlinedProps, type, prototype);
466 }
467 
NewEcmaHClass(uint32_t size, uint32_t inlinedProps, JSType type, const JSHandle<JSTaggedValue> &prototype)468 JSHandle<JSHClass> ObjectFactory::NewEcmaHClass(uint32_t size, uint32_t inlinedProps, JSType type,
469                                                 const JSHandle<JSTaggedValue> &prototype)
470 {
471     NewObjectHook();
472     uint32_t classSize = JSHClass::SIZE;
473     auto *newClass = static_cast<JSHClass *>(heap_->AllocateNonMovableOrHugeObject(
474         JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()), classSize));
475     newClass->Initialize(thread_, size, type, inlinedProps);
476     JSHandle<JSHClass> hclass(thread_, newClass);
477     hclass->SetPrototype(thread_, prototype.GetTaggedValue());
478     return hclass;
479 }
480 
NewJSObject(const JSHandle<JSHClass> &jshclass)481 JSHandle<JSObject> ObjectFactory::NewJSObject(const JSHandle<JSHClass> &jshclass)
482 {
483     JSHandle<JSObject> obj(thread_, JSObject::Cast(NewObject(jshclass)));
484     JSHandle<TaggedArray> emptyArray = EmptyArray();
485     obj->InitializeHash();
486     obj->SetElements(thread_, emptyArray, SKIP_BARRIER);
487     obj->SetProperties(thread_, emptyArray, SKIP_BARRIER);
488     return obj;
489 }
490 
CloneProperties(const JSHandle<TaggedArray> &old)491 JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray> &old)
492 {
493     uint32_t newLength = old->GetLength();
494     if (newLength == 0) {
495         return EmptyArray();
496     }
497     NewObjectHook();
498     auto klass = old->GetClass();
499     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
500     auto header = heap_->AllocateYoungOrHugeObject(klass, size);
501     JSHandle<TaggedArray> newArray(thread_, header);
502     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
503     for (uint32_t i = 0; i < newLength; i++) {
504         JSTaggedValue value = old->Get(i);
505         newArray->Set(thread_, i, value);
506     }
507     return newArray;
508 }
509 
CloneObjectLiteral(JSHandle<JSObject> object)510 JSHandle<JSObject> ObjectFactory::CloneObjectLiteral(JSHandle<JSObject> object)
511 {
512     NewObjectHook();
513     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
514 
515     JSHandle<JSObject> cloneObject = NewJSObject(klass);
516 
517     JSHandle<TaggedArray> elements(thread_, object->GetElements());
518     auto newElements = CloneProperties(elements);
519     cloneObject->SetElements(thread_, newElements.GetTaggedValue());
520 
521     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
522     auto newProperties = CloneProperties(properties);
523     cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
524     uint32_t length = std::min(klass->GetInlinedProperties(), klass->NumberOfProps());
525 
526     for (uint32_t i = 0; i < length; i++) {
527         cloneObject->SetPropertyInlinedPropsWithRep(thread_, i, object->GetPropertyInlinedProps(i));
528     }
529     return cloneObject;
530 }
531 
CloneArrayLiteral(JSHandle<JSArray> object)532 JSHandle<JSArray> ObjectFactory::CloneArrayLiteral(JSHandle<JSArray> object)
533 {
534     NewObjectHook();
535     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
536 
537     JSHandle<JSArray> cloneObject(NewJSObject(klass));
538     cloneObject->SetArrayLength(thread_, object->GetArrayLength());
539     cloneObject->SetTrackInfo(thread_, JSTaggedValue::Undefined());
540 
541     JSHandle<TaggedArray> elements(thread_, object->GetElements());
542     static constexpr uint8_t MAX_READ_ONLY_ARRAY_LENGTH = 10;
543     uint32_t elementsLength = elements->GetLength();
544     MemSpaceType type = elementsLength > MAX_READ_ONLY_ARRAY_LENGTH ?
545         MemSpaceType::SEMI_SPACE : MemSpaceType::NON_MOVABLE;
546 
547 #if !defined ENABLE_COW_ARRAY
548     type = MemSpaceType::SEMI_SPACE;
549 #endif
550 
551     if (type == MemSpaceType::NON_MOVABLE && elements.GetTaggedValue().IsCOWArray()) {
552         // share the same elements array in nonmovable space.
553         cloneObject->SetElements(thread_, elements.GetTaggedValue());
554     } else {
555         auto newElements = CopyArray(elements, elementsLength, elementsLength, JSTaggedValue::Hole(), type);
556         cloneObject->SetElements(thread_, newElements.GetTaggedValue());
557     }
558 
559     if (type == MemSpaceType::NON_MOVABLE && !object->GetElements().IsCOWArray()) {
560         ASSERT(!Region::ObjectAddressToRange(object->GetElements().GetTaggedObject())->InNonMovableSpace());
561         // Set the first shared elements into the old object.
562         object->SetElements(thread_, cloneObject->GetElements());
563     }
564 
565     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
566     uint32_t propertiesLength = properties->GetLength();
567     type = propertiesLength > MAX_READ_ONLY_ARRAY_LENGTH ?
568         MemSpaceType::SEMI_SPACE : MemSpaceType::NON_MOVABLE;
569 
570 #if !defined ENABLE_COW_ARRAY
571     type = MemSpaceType::SEMI_SPACE;
572 #endif
573 
574     if (type == MemSpaceType::NON_MOVABLE && properties.GetTaggedValue().IsCOWArray()) {
575         // share the same properties array in nonmovable space.
576         cloneObject->SetProperties(thread_, properties.GetTaggedValue());
577     } else {
578         auto newProperties = CopyArray(properties, propertiesLength, propertiesLength, JSTaggedValue::Hole(), type);
579         cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
580     }
581 
582     if (type == MemSpaceType::NON_MOVABLE && !object->GetProperties().IsCOWArray()) {
583         ASSERT(!Region::ObjectAddressToRange(object->GetProperties().GetTaggedObject())->InNonMovableSpace());
584         // Set the first shared properties into the old object.
585         object->SetProperties(thread_, cloneObject->GetProperties());
586     }
587 
588     for (uint32_t i = 0; i < klass->GetInlinedProperties(); i++) {
589         cloneObject->SetPropertyInlinedPropsWithRep(thread_, i, object->GetPropertyInlinedProps(i));
590     }
591     return cloneObject;
592 }
593 
CloneProperties(const JSHandle<TaggedArray> &old, const JSHandle<JSTaggedValue> &env, const JSHandle<JSObject> &obj)594 JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray> &old,
595                                                      const JSHandle<JSTaggedValue> &env, const JSHandle<JSObject> &obj)
596 {
597     uint32_t newLength = old->GetLength();
598     if (newLength == 0) {
599         return EmptyArray();
600     }
601     NewObjectHook();
602     auto klass = old->GetClass();
603     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
604     auto header = heap_->AllocateYoungOrHugeObject(klass, size);
605     JSHandle<TaggedArray> newArray(thread_, header);
606     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
607 
608     for (uint32_t i = 0; i < newLength; i++) {
609         JSTaggedValue value = old->Get(i);
610         if (!value.IsJSFunction()) {
611             newArray->Set(thread_, i, value);
612         } else {
613             JSHandle<JSFunction> valueHandle(thread_, value);
614             JSHandle<JSFunction> newFunc = CloneJSFunction(valueHandle);
615             newFunc->SetLexicalEnv(thread_, env);
616             newFunc->SetHomeObject(thread_, obj);
617             newArray->Set(thread_, i, newFunc);
618         }
619     }
620     return newArray;
621 }
622 
CloneObjectLiteral(JSHandle<JSObject> object, const JSHandle<JSTaggedValue> &env, bool canShareHClass)623 JSHandle<JSObject> ObjectFactory::CloneObjectLiteral(JSHandle<JSObject> object,
624                                                      const JSHandle<JSTaggedValue> &env,
625                                                      bool canShareHClass)
626 {
627     NewObjectHook();
628     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
629 
630     if (!canShareHClass) {
631         klass = JSHClass::Clone(thread_, klass);
632     }
633 
634     JSHandle<JSObject> cloneObject = NewJSObject(klass);
635 
636     JSHandle<TaggedArray> elements(thread_, object->GetElements());
637     auto newElements = CloneProperties(elements, env, cloneObject);
638     cloneObject->SetElements(thread_, newElements.GetTaggedValue());
639 
640     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
641     auto newProperties = CloneProperties(properties, env, cloneObject);
642     cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
643     uint32_t length = std::min(klass->GetInlinedProperties(), klass->NumberOfProps());
644 
645     for (uint32_t i = 0; i < length; i++) {
646         auto layout = LayoutInfo::Cast(klass->GetLayout().GetTaggedObject());
647         JSTaggedValue value = object->GetPropertyInlinedProps(i);
648         if (!layout->GetAttr(i).IsTaggedRep() || (!value.IsJSFunction() && !value.IsAccessorData())) {
649             cloneObject->SetPropertyInlinedPropsWithRep(thread_, i, value);
650         } else if (value.IsJSFunction()) {
651             JSHandle<JSFunction> valueHandle(thread_, value);
652             JSHandle<JSFunction> newFunc = CloneJSFunction(valueHandle);
653             newFunc->SetLexicalEnv(thread_, env);
654             newFunc->SetHomeObject(thread_, cloneObject);
655             cloneObject->SetPropertyInlinedProps(thread_, i, newFunc.GetTaggedValue());
656         } else {
657             if (value.IsAccessorData()) {
658                 JSHandle<AccessorData> accessor = NewAccessorData();
659                 value = accessor.GetTaggedValue();
660             }
661             cloneObject->SetPropertyInlinedPropsWithRep(thread_, i, value);
662         }
663     }
664     return cloneObject;
665 }
666 
CloneJSFunction(JSHandle<JSFunction> func)667 JSHandle<JSFunction> ObjectFactory::CloneJSFunction(JSHandle<JSFunction> func)
668 {
669     JSHandle<JSHClass> jshclass(thread_, func->GetJSHClass());
670     JSHandle<Method> method(thread_, func->GetMethod());
671     JSHandle<JSFunction> cloneFunc = NewJSFunctionByHClass(method, jshclass);
672 
673     JSTaggedValue length = func->GetPropertyInlinedProps(JSFunction::LENGTH_INLINE_PROPERTY_INDEX);
674     cloneFunc->SetPropertyInlinedProps(thread_, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length);
675     cloneFunc->SetLength(func->GetLength());
676     cloneFunc->SetModule(thread_, func->GetModule());
677     return cloneFunc;
678 }
679 
CloneSFunction(JSHandle<JSFunction> func)680 JSHandle<JSFunction> ObjectFactory::CloneSFunction(JSHandle<JSFunction> func)
681 {
682     ASSERT(func.GetTaggedValue().IsJSSharedFunction());
683     JSHandle<JSHClass> jshclass(thread_, func->GetJSHClass());
684     JSHandle<Method> method(thread_, func->GetMethod());
685     JSHandle<JSFunction> cloneFunc = NewSFunctionByHClass(method, jshclass);
686 
687     JSTaggedValue length = func->GetPropertyInlinedProps(JSFunction::LENGTH_INLINE_PROPERTY_INDEX);
688     cloneFunc->SetPropertyInlinedProps(thread_, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length);
689     cloneFunc->SetLength(func->GetLength());
690     cloneFunc->SetModule(thread_, func->GetModule());
691     return cloneFunc;
692 }
693 
CreateJSFunctionFromTemplate(JSHandle<FunctionTemplate> funcTemp)694 JSHandle<JSFunction> ObjectFactory::CreateJSFunctionFromTemplate(JSHandle<FunctionTemplate> funcTemp)
695 {
696     NewObjectHook();
697     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
698     auto kind = funcTemp->GetFunctionKind();
699     JSHandle<JSHClass> jshclass;
700     if (kind == FunctionKind::NORMAL_FUNCTION ||
701         kind == FunctionKind::GETTER_FUNCTION ||
702         kind == FunctionKind::SETTER_FUNCTION) {
703         jshclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
704     } else if (kind == FunctionKind::ASYNC_FUNCTION) {
705         jshclass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
706     } else {
707         jshclass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
708     }
709     JSHandle<Method> method = JSHandle<Method>(thread_, funcTemp->GetMethod());
710     JSHandle<JSFunction> newFunc = NewJSFunctionByHClass(method, jshclass);
711 
712     newFunc->SetLength(funcTemp->GetLength());
713     newFunc->SetModule(thread_, funcTemp->GetModule());
714     return newFunc;
715 }
716 
CreateSFunctionFromTemplate(JSHandle<FunctionTemplate> funcTemp)717 JSHandle<JSFunction> ObjectFactory::CreateSFunctionFromTemplate(JSHandle<FunctionTemplate> funcTemp)
718 {
719     NewObjectHook();
720     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
721     auto kind = funcTemp->GetFunctionKind();
722     JSHandle<JSHClass> jshclass;
723     if (kind == FunctionKind::NORMAL_FUNCTION ||
724         kind == FunctionKind::GETTER_FUNCTION ||
725         kind == FunctionKind::SETTER_FUNCTION) {
726         jshclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutProto());
727     } else if (kind == FunctionKind::ASYNC_FUNCTION) {
728         jshclass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
729     } else {
730         jshclass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
731     }
732     JSHandle<Method> method(thread_, funcTemp->GetMethod());
733     JSHandle<JSFunction> newFunc = NewSFunctionByHClass(method, jshclass);
734 
735     newFunc->SetLength(funcTemp->GetLength());
736     newFunc->SetModule(thread_, funcTemp->GetModule());
737     return newFunc;
738 }
739 
CloneClassCtor(JSHandle<JSFunction> ctor, const JSHandle<JSTaggedValue> &lexenv, bool canShareHClass)740 JSHandle<JSFunction> ObjectFactory::CloneClassCtor(JSHandle<JSFunction> ctor, const JSHandle<JSTaggedValue> &lexenv,
741                                                    bool canShareHClass)
742 {
743     NewObjectHook();
744     JSHandle<JSHClass> hclass(thread_, ctor->GetClass());
745 
746     if (!canShareHClass) {
747         hclass = JSHClass::Clone(thread_, hclass);
748     }
749 
750     JSHandle<Method> method(thread_, ctor->GetMethod());
751     ASSERT_PRINT(method->GetFunctionKind() == FunctionKind::CLASS_CONSTRUCTOR ||
752                  method->GetFunctionKind() == FunctionKind::DERIVED_CONSTRUCTOR,
753                  "cloned function is not class");
754     JSHandle<JSFunction> cloneCtor = NewJSFunctionByHClass(method, hclass);
755     uint32_t length = std::min(hclass->GetInlinedProperties(), hclass->NumberOfProps());
756 
757     for (uint32_t i = 0; i < length; i++) {
758         auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
759         JSTaggedValue value = ctor->GetPropertyInlinedProps(i);
760         if (!layout->GetAttr(i).IsTaggedRep() || !value.IsJSFunction()) {
761             cloneCtor->SetPropertyInlinedPropsWithRep(thread_, i, value);
762         } else {
763             JSHandle<JSFunction> valueHandle(thread_, value);
764             JSHandle<JSFunction> newFunc = CloneJSFunction(valueHandle);
765             newFunc->SetLexicalEnv(thread_, lexenv);
766             newFunc->SetHomeObject(thread_, cloneCtor);
767             cloneCtor->SetPropertyInlinedProps(thread_, i, newFunc.GetTaggedValue());
768         }
769     }
770 
771     JSHandle<TaggedArray> elements(thread_, ctor->GetElements());
772     auto newElements = CloneProperties(elements, lexenv, JSHandle<JSObject>(cloneCtor));
773     cloneCtor->SetElements(thread_, newElements.GetTaggedValue());
774 
775     JSHandle<TaggedArray> properties(thread_, ctor->GetProperties());
776     auto newProperties = CloneProperties(properties, lexenv, JSHandle<JSObject>(cloneCtor));
777     cloneCtor->SetProperties(thread_, newProperties.GetTaggedValue());
778 
779     return cloneCtor;
780 }
781 
NewNonMovableJSObject(const JSHandle<JSHClass> &jshclass)782 JSHandle<JSObject> ObjectFactory::NewNonMovableJSObject(const JSHandle<JSHClass> &jshclass)
783 {
784     JSHandle<JSObject> obj(thread_,
785                            JSObject::Cast(NewNonMovableObject(jshclass, jshclass->GetInlinedProperties())));
786     obj->InitializeHash();
787     obj->SetElements(thread_, EmptyArray(), SKIP_BARRIER);
788     obj->SetProperties(thread_, EmptyArray(), SKIP_BARRIER);
789     return obj;
790 }
791 
NewJSPrimitiveRef(const JSHandle<JSHClass> &hclass, const JSHandle<JSTaggedValue> &object)792 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(const JSHandle<JSHClass> &hclass,
793                                                           const JSHandle<JSTaggedValue> &object)
794 {
795     JSHandle<JSPrimitiveRef> obj = JSHandle<JSPrimitiveRef>::Cast(NewJSObject(hclass));
796     obj->SetValue(thread_, object);
797     return obj;
798 }
799 
NewJSArray()800 JSHandle<JSArray> ObjectFactory::NewJSArray()
801 {
802     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
803     JSHandle<JSFunction> function(env->GetArrayFunction());
804     return JSHandle<JSArray>(NewJSObjectByConstructor(function));
805 }
806 
NewJSArray(size_t length, JSHandle<JSHClass> &hclass)807 JSHandle<JSArray> ObjectFactory::NewJSArray(size_t length, JSHandle<JSHClass> &hclass)
808 {
809     JSHandle<JSObject> obj = NewJSObject(hclass);
810     JSArray::Cast(*obj)->SetLength(length);
811     JSArray::Cast(*obj)->SetTrackInfo(thread_, JSTaggedValue::Undefined());
812     auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
813     JSArray::Cast(*obj)->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
814     return JSHandle<JSArray>(obj);
815 }
816 
NewJsonFixedArray(size_t start, size_t length, const std::vector<JSHandle<JSTaggedValue>> &vec)817 JSHandle<TaggedArray> ObjectFactory::NewJsonFixedArray(size_t start, size_t length,
818                                                        const std::vector<JSHandle<JSTaggedValue>> &vec)
819 {
820     if (length == 0) {
821         return EmptyArray();
822     }
823 
824     MemSpaceType spaceType = length < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
825     JSHandle<TaggedArray> array = NewTaggedArrayWithoutInit(length, spaceType);
826     array->SetExtraLength(0);
827     for (size_t i = 0; i < length; i++) {
828         array->Set(thread_, i, vec[start + i]);
829     }
830     return array;
831 }
832 
NewJSForinIterator(const JSHandle<JSTaggedValue> &obj, const JSHandle<JSTaggedValue> keys, const JSHandle<JSTaggedValue> cachedHclass)833 JSHandle<JSForInIterator> ObjectFactory::NewJSForinIterator(const JSHandle<JSTaggedValue> &obj,
834                                                             const JSHandle<JSTaggedValue> keys,
835                                                             const JSHandle<JSTaggedValue> cachedHclass)
836 {
837     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
838     JSHandle<JSHClass> hclass(env->GetForinIteratorClass());
839 
840     JSHandle<JSForInIterator> it = JSHandle<JSForInIterator>::Cast(NewJSObject(hclass));
841     it->SetObject(thread_, obj);
842     it->SetCachedHclass(thread_, cachedHclass);
843     it->SetKeys(thread_, keys);
844     it->SetIndex(EnumCache::ENUM_CACHE_HEADER_SIZE);
845     uint32_t enumLength = JSHandle<TaggedArray>::Cast(keys)->GetLength();
846     it->SetLength(enumLength);
847     return it;
848 }
849 
CreateJSRegExpInstanceClass(JSHandle<JSTaggedValue> proto)850 JSHandle<JSHClass> ObjectFactory::CreateJSRegExpInstanceClass(JSHandle<JSTaggedValue> proto)
851 {
852     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
853     JSHandle<JSHClass> regexpClass = NewEcmaHClass(JSRegExp::SIZE, JSType::JS_REG_EXP, proto);
854 
855     uint32_t fieldOrder = 0;
856     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(1);
857     {
858         PropertyAttributes attributes = PropertyAttributes::Default(true, false, false);
859         attributes.SetIsInlinedProps(true);
860         attributes.SetRepresentation(Representation::TAGGED);
861         attributes.SetOffset(fieldOrder++);
862         layoutInfoHandle->AddKey(thread_, 0, globalConst->GetLastIndexString(), attributes);
863     }
864 
865     {
866         regexpClass->SetLayout(thread_, layoutInfoHandle);
867         regexpClass->SetNumberOfProps(fieldOrder);
868     }
869 
870     return regexpClass;
871 }
872 
CreateJSArrayInstanceClass(JSHandle<JSTaggedValue> proto, uint32_t inlinedProps)873 JSHandle<JSHClass> ObjectFactory::CreateJSArrayInstanceClass(JSHandle<JSTaggedValue> proto, uint32_t inlinedProps)
874 {
875     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
876     JSHandle<JSHClass> arrayClass = NewEcmaHClass(JSArray::SIZE, inlinedProps, JSType::JS_ARRAY, proto);
877 
878     uint32_t fieldOrder = 0;
879     ASSERT(JSArray::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
880     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(1);
881     {
882         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(true, false, false);
883         attributes.SetIsInlinedProps(true);
884         attributes.SetRepresentation(Representation::TAGGED);
885         attributes.SetOffset(fieldOrder++);
886         layoutInfoHandle->AddKey(thread_, 0, globalConst->GetLengthString(), attributes);
887     }
888 
889     {
890         arrayClass->SetLayout(thread_, layoutInfoHandle);
891         arrayClass->SetNumberOfProps(fieldOrder);
892     }
893     arrayClass->SetIsStableElements(true);
894     arrayClass->SetHasConstructor(false);
895 
896     return arrayClass;
897 }
898 
CreateJSArguments(const JSHandle<GlobalEnv> &env)899 JSHandle<JSHClass> ObjectFactory::CreateJSArguments(const JSHandle<GlobalEnv> &env)
900 {
901     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
902     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
903 
904     JSHandle<JSHClass> argumentsClass = NewEcmaHClass(JSArguments::SIZE, JSType::JS_ARGUMENTS, proto);
905 
906     uint32_t fieldOrder = 0;
907     ASSERT(JSArguments::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
908     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(JSArguments::LENGTH_OF_INLINE_PROPERTIES);
909     {
910         PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);
911         attributes.SetIsInlinedProps(true);
912         attributes.SetRepresentation(Representation::TAGGED);
913         attributes.SetOffset(fieldOrder++);
914         layoutInfoHandle->AddKey(thread_, JSArguments::LENGTH_INLINE_PROPERTY_INDEX, globalConst->GetLengthString(),
915                                  attributes);
916     }
917 
918     ASSERT(JSArguments::ITERATOR_INLINE_PROPERTY_INDEX == fieldOrder);
919     {
920         PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);
921         attributes.SetIsInlinedProps(true);
922         attributes.SetRepresentation(Representation::TAGGED);
923         attributes.SetOffset(fieldOrder++);
924         layoutInfoHandle->AddKey(thread_, JSArguments::ITERATOR_INLINE_PROPERTY_INDEX,
925                                  env->GetIteratorSymbol().GetTaggedValue(), attributes);
926     }
927 
928     {
929         ASSERT(JSArguments::CALLER_INLINE_PROPERTY_INDEX == fieldOrder);
930         PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
931         attributes.SetIsInlinedProps(true);
932         attributes.SetIsAccessor(true);
933         attributes.SetRepresentation(Representation::TAGGED);
934         attributes.SetOffset(fieldOrder++);
935         layoutInfoHandle->AddKey(thread_, JSArguments::CALLER_INLINE_PROPERTY_INDEX,
936                                  thread_->GlobalConstants()->GetHandledCallerString().GetTaggedValue(), attributes);
937     }
938 
939     {
940         ASSERT(JSArguments::CALLEE_INLINE_PROPERTY_INDEX == fieldOrder);
941         PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
942         attributes.SetIsInlinedProps(true);
943         attributes.SetIsAccessor(true);
944         attributes.SetRepresentation(Representation::TAGGED);
945         attributes.SetOffset(fieldOrder++);
946         layoutInfoHandle->AddKey(thread_, JSArguments::CALLEE_INLINE_PROPERTY_INDEX,
947                                  thread_->GlobalConstants()->GetHandledCalleeString().GetTaggedValue(), attributes);
948     }
949 
950     {
951         argumentsClass->SetLayout(thread_, layoutInfoHandle);
952         argumentsClass->SetNumberOfProps(fieldOrder);
953     }
954     argumentsClass->SetIsStableElements(true);
955     return argumentsClass;
956 }
957 
NewJSArguments()958 JSHandle<JSArguments> ObjectFactory::NewJSArguments()
959 {
960     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
961     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetArgumentsClass());
962     JSHandle<JSArguments> obj = JSHandle<JSArguments>::Cast(NewJSObject(hclass));
963     return obj;
964 }
965 
GetJSError(const ErrorType &errorType, const char *data, StackCheck needCheckStack)966 JSHandle<JSObject> ObjectFactory::GetJSError(const ErrorType &errorType, const char *data, StackCheck needCheckStack)
967 {
968     ASSERT_PRINT(errorType == ErrorType::ERROR || errorType == ErrorType::EVAL_ERROR ||
969                      errorType == ErrorType::RANGE_ERROR || errorType == ErrorType::REFERENCE_ERROR ||
970                      errorType == ErrorType::SYNTAX_ERROR || errorType == ErrorType::TYPE_ERROR ||
971                      errorType == ErrorType::URI_ERROR || errorType == ErrorType::OOM_ERROR ||
972                      errorType == ErrorType::TERMINATION_ERROR,
973                  "The error type is not in the valid range.");
974     if (data != nullptr) {
975         JSHandle<EcmaString> handleMsg = NewFromUtf8(data);
976         return NewJSError(errorType, handleMsg, needCheckStack);
977     }
978     JSHandle<EcmaString> emptyString(thread_->GlobalConstants()->GetHandledEmptyString());
979     return NewJSError(errorType, emptyString, needCheckStack);
980 }
981 
NewJSError(const ErrorType &errorType, const JSHandle<EcmaString> &message, StackCheck needCheckStack)982 JSHandle<JSObject> ObjectFactory::NewJSError(const ErrorType &errorType, const JSHandle<EcmaString> &message,
983     StackCheck needCheckStack)
984 {
985     // if there have exception in thread, then return current exception, no need to new js error.
986     if (thread_->HasPendingException()) {
987         JSHandle<JSObject> obj(thread_, thread_->GetException());
988         return obj;
989     }
990 
991     // current frame may be entry frame, exception happened in JSFunction::Call and JSFunction::Construct,
992     // in this case sp = the prev frame (interpreter frame).
993     if (!thread_->IsAsmInterpreter()) {
994         FrameHandler frameHandler(thread_);
995         if (frameHandler.IsInterpretedEntryFrame()) {
996             thread_->SetCurrentSPFrame(frameHandler.GetPrevJSFrame());
997         }
998     }
999 
1000     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1001     JSHandle<JSTaggedValue> nativeConstructor;
1002     switch (errorType) {
1003         case ErrorType::RANGE_ERROR:
1004             nativeConstructor = env->GetRangeErrorFunction();
1005             break;
1006         case ErrorType::EVAL_ERROR:
1007             nativeConstructor = env->GetEvalErrorFunction();
1008             break;
1009         case ErrorType::REFERENCE_ERROR:
1010             nativeConstructor = env->GetReferenceErrorFunction();
1011             break;
1012         case ErrorType::TYPE_ERROR:
1013             nativeConstructor = env->GetTypeErrorFunction();
1014             break;
1015         case ErrorType::URI_ERROR:
1016             nativeConstructor = env->GetURIErrorFunction();
1017             break;
1018         case ErrorType::SYNTAX_ERROR:
1019             nativeConstructor = env->GetSyntaxErrorFunction();
1020             break;
1021         case ErrorType::OOM_ERROR:
1022             nativeConstructor = env->GetOOMErrorFunction();
1023             break;
1024         case ErrorType::TERMINATION_ERROR:
1025             nativeConstructor = env->GetTerminationErrorFunction();
1026             break;
1027         default:
1028             nativeConstructor = env->GetErrorFunction();
1029             break;
1030     }
1031     JSHandle<JSFunction> nativeFunc = JSHandle<JSFunction>::Cast(nativeConstructor);
1032     JSHandle<JSTaggedValue> nativePrototype(thread_, nativeFunc->GetFunctionPrototype());
1033     JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
1034     EcmaRuntimeCallInfo *info =
1035         EcmaInterpreter::NewRuntimeCallInfo(thread_, nativeConstructor, nativePrototype, undefined, 1, needCheckStack);
1036     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread_);
1037     info->SetCallArg(message.GetTaggedValue());
1038     Method *method = JSHandle<ECMAObject>::Cast(nativeConstructor)->GetCallTarget();
1039     JSTaggedValue obj = reinterpret_cast<EcmaEntrypoint>(const_cast<void *>(method->GetNativePointer()))(info);
1040     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread_);
1041     JSHandle<JSObject> handleNativeInstanceObj(thread_, obj);
1042     auto sp = const_cast<JSTaggedType *>(thread_->GetCurrentSPFrame());
1043     ASSERT(FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_ENTRY_FRAME);
1044     auto prevEntry = InterpretedEntryFrame::GetFrameFromSp(sp)->GetPrevFrameFp();
1045     thread_->SetCurrentSPFrame(prevEntry);
1046     return handleNativeInstanceObj;
1047 }
1048 
NewJSAggregateError()1049 JSHandle<JSObject> ObjectFactory::NewJSAggregateError()
1050 {
1051     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1052     JSHandle<JSFunction> constructor(env->GetAggregateErrorFunction());
1053     return NewJSObjectByConstructor(constructor);
1054 }
1055 
NewJSObjectByConstructor(JSHandle<GlobalEnv> env, const JSHandle<JSFunction> &constructor, uint32_t inlinedProps)1056 JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(JSHandle<GlobalEnv> env,
1057     const JSHandle<JSFunction> &constructor, uint32_t inlinedProps)
1058 {
1059     if (!constructor->HasFunctionPrototype() ||
1060         (constructor->GetProtoOrHClass().IsHeapObject() && constructor->GetFunctionPrototype().IsECMAObject())) {
1061         JSHandle<JSHClass> jshclass;
1062         if (LIKELY(inlinedProps == JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS)) {
1063             jshclass = JSHandle<JSHClass>(thread_, JSFunction::GetOrCreateInitialJSHClass(thread_, constructor));
1064         } else {
1065             jshclass = NewEcmaHClass(JSObject::SIZE, inlinedProps, JSType::JS_OBJECT,
1066                                      env->GetObjectFunctionPrototype());
1067         }
1068         JSHandle<JSObject> obj;
1069         if (jshclass->IsJSSharedObject()) {
1070             obj = NewSharedOldSpaceJSObject(jshclass);
1071             if (jshclass->IsDictionaryMode()) {
1072                 auto fieldLayout = jshclass->GetLayout();
1073                 ASSERT(fieldLayout.IsDictionary());
1074                 auto dict = JSHandle<TaggedArray>(thread_, fieldLayout);
1075                 auto properties = NewAndCopySNameDictionary(dict, dict->GetLength());
1076                 obj->SetProperties(thread_, properties);
1077             }
1078         } else {
1079             obj = NewJSObjectWithInit(jshclass);
1080         }
1081         return obj;
1082     }
1083     JSHandle<JSObject> result =
1084         NewJSObjectByConstructor(JSHandle<JSFunction>(env->GetObjectFunction()), JSHandle<JSTaggedValue>(constructor));
1085     if (thread_->HasPendingException()) {
1086         LOG_FULL(FATAL) << "NewJSObjectByConstructor should not throw Exception! ";
1087     }
1088     return result;
1089 }
1090 
NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor, uint32_t inlinedProps)1091 JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor,
1092                                                            uint32_t inlinedProps)
1093 {
1094     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1095     if (!constructor->HasFunctionPrototype() ||
1096         (constructor->GetProtoOrHClass().IsHeapObject() && constructor->GetFunctionPrototype().IsECMAObject())) {
1097         JSHandle<JSHClass> jshclass;
1098         if (LIKELY(inlinedProps == JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS)) {
1099             jshclass = JSHandle<JSHClass>(thread_, JSFunction::GetOrCreateInitialJSHClass(thread_, constructor));
1100         } else {
1101             jshclass = NewEcmaHClass(JSObject::SIZE, inlinedProps, JSType::JS_OBJECT,
1102                                      env->GetObjectFunctionPrototype());
1103         }
1104         JSHandle<JSObject> obj;
1105         if (jshclass->IsJSShared()) {
1106             obj = NewSharedOldSpaceJSObject(jshclass);
1107             if (jshclass->IsDictionaryMode()) {
1108                 auto fieldLayout = jshclass->GetLayout();
1109                 ASSERT(fieldLayout.IsDictionary());
1110                 auto dict = JSHandle<TaggedArray>(thread_, fieldLayout);
1111                 auto properties = NewAndCopySNameDictionary(dict, dict->GetLength());
1112                 obj->SetProperties(thread_, properties);
1113             }
1114             InitializeJSObject(obj, jshclass);
1115         } else {
1116             obj = NewJSObjectWithInit(jshclass);
1117         }
1118         return obj;
1119     }
1120     JSHandle<JSObject> result =
1121         NewJSObjectByConstructor(JSHandle<JSFunction>(env->GetObjectFunction()), JSHandle<JSTaggedValue>(constructor));
1122     if (thread_->HasPendingException()) {
1123         LOG_FULL(FATAL) << "NewJSObjectByConstructor should not throw Exception! ";
1124     }
1125     return result;
1126 }
1127 
NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor, const JSHandle<JSTaggedValue> &newTarget)1128 JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor,
1129                                                            const JSHandle<JSTaggedValue> &newTarget)
1130 {
1131     if (constructor->IsJSShared() && !newTarget->IsJSShared()) {
1132         THROW_TYPE_ERROR_AND_RETURN(thread_, "shared ctor cannot assign unshared newTarget",
1133                                     JSHandle<JSObject>(thread_, JSTaggedValue::Undefined()));
1134     }
1135     JSHandle<JSHClass> jshclass;
1136     if (!constructor->HasFunctionPrototype() ||
1137         (constructor->GetProtoOrHClass().IsHeapObject() && constructor->GetFunctionPrototype().IsECMAObject())) {
1138         jshclass = JSFunction::GetInstanceJSHClass(thread_, constructor, newTarget);
1139     } else {
1140         JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1141         jshclass = JSFunction::GetInstanceJSHClass(thread_, JSHandle<JSFunction>(env->GetObjectFunction()), newTarget);
1142     }
1143     // Check this exception elsewhere
1144     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread_);
1145     JSHandle<JSObject> obj;
1146     if (jshclass->IsJSShared()) {
1147         obj = NewSharedOldSpaceJSObject(jshclass);
1148         if (jshclass->IsDictionaryMode()) {
1149             auto fieldLayout = jshclass->GetLayout();
1150             ASSERT(fieldLayout.IsDictionary());
1151             auto dict = JSHandle<TaggedArray>(thread_, fieldLayout);
1152             auto properties = NewAndCopySNameDictionary(dict, dict->GetLength());
1153             obj->SetProperties(thread_, properties);
1154         }
1155         InitializeJSObject(obj, jshclass);
1156     } else {
1157         obj = NewJSObjectWithInit(jshclass);
1158     }
1159     return obj;
1160 }
1161 
NewJSObjectWithInit(const JSHandle<JSHClass> &jshclass)1162 JSHandle<JSObject> ObjectFactory::NewJSObjectWithInit(const JSHandle<JSHClass> &jshclass)
1163 {
1164     JSHandle<JSObject> obj = NewJSObject(jshclass);
1165     InitializeJSObject(obj, jshclass);
1166     return obj;
1167 }
1168 
InitializeJSObject(const JSHandle<JSObject> &obj, const JSHandle<JSHClass> &jshclass)1169 void ObjectFactory::InitializeJSObject(const JSHandle<JSObject> &obj, const JSHandle<JSHClass> &jshclass)
1170 {
1171     JSType type = jshclass->GetObjectType();
1172     switch (type) {
1173         case JSType::JS_OBJECT:
1174         case JSType::JS_ERROR:
1175         case JSType::JS_EVAL_ERROR:
1176         case JSType::JS_RANGE_ERROR:
1177         case JSType::JS_REFERENCE_ERROR:
1178         case JSType::JS_TYPE_ERROR:
1179         case JSType::JS_AGGREGATE_ERROR:
1180         case JSType::JS_URI_ERROR:
1181         case JSType::JS_SYNTAX_ERROR:
1182         case JSType::JS_OOM_ERROR:
1183         case JSType::JS_TERMINATION_ERROR:
1184         case JSType::JS_ASYNCITERATOR:
1185         case JSType::JS_SHARED_OBJECT:
1186         case JSType::JS_SHARED_FUNCTION:
1187         case JSType::JS_ITERATOR: {
1188             break;
1189         }
1190 #ifdef ARK_SUPPORT_INTL
1191         case JSType::JS_INTL: {
1192             JSIntl::Cast(*obj)->SetFallbackSymbol(thread_, JSTaggedValue::Undefined());
1193             JSHandle<JSSymbol> jsSymbol = NewPublicSymbolWithChar("IntlLegacyConstructedSymbol");
1194             JSIntl::Cast(*obj)->SetFallbackSymbol(thread_, jsSymbol);
1195             break;
1196         }
1197         case JSType::JS_LOCALE: {
1198             JSLocale::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
1199             break;
1200         }
1201         case JSType::JS_DATE_TIME_FORMAT: {
1202             JSDateTimeFormat::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1203             JSDateTimeFormat::Cast(*obj)->SetCalendar(thread_, JSTaggedValue::Undefined());
1204             JSDateTimeFormat::Cast(*obj)->SetNumberingSystem(thread_, JSTaggedValue::Undefined());
1205             JSDateTimeFormat::Cast(*obj)->SetTimeZone(thread_, JSTaggedValue::Undefined());
1206             JSDateTimeFormat::Cast(*obj)->SetLocaleIcu(thread_, JSTaggedValue::Undefined());
1207             JSDateTimeFormat::Cast(*obj)->SetSimpleDateTimeFormatIcu(thread_, JSTaggedValue::Undefined());
1208             JSDateTimeFormat::Cast(*obj)->SetIso8601(thread_, JSTaggedValue::Undefined());
1209             JSDateTimeFormat::Cast(*obj)->SetBoundFormat(thread_, JSTaggedValue::Undefined());
1210             JSDateTimeFormat::Cast(*obj)->SetHourCycle(HourCycleOption::EXCEPTION);
1211             JSDateTimeFormat::Cast(*obj)->SetDateStyle(DateTimeStyleOption::EXCEPTION);
1212             JSDateTimeFormat::Cast(*obj)->SetTimeStyle(DateTimeStyleOption::EXCEPTION);
1213             break;
1214         }
1215         case JSType::JS_NUMBER_FORMAT: {
1216             JSNumberFormat::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1217             JSNumberFormat::Cast(*obj)->SetNumberingSystem(thread_, JSTaggedValue::Undefined());
1218             JSNumberFormat::Cast(*obj)->SetCurrency(thread_, JSTaggedValue::Undefined());
1219             JSNumberFormat::Cast(*obj)->SetUnit(thread_, JSTaggedValue::Undefined());
1220             JSNumberFormat::Cast(*obj)->SetMinimumIntegerDigits(thread_, JSTaggedValue::Undefined());
1221             JSNumberFormat::Cast(*obj)->SetMinimumFractionDigits(thread_, JSTaggedValue::Undefined());
1222             JSNumberFormat::Cast(*obj)->SetMaximumFractionDigits(thread_, JSTaggedValue::Undefined());
1223             JSNumberFormat::Cast(*obj)->SetMinimumSignificantDigits(thread_, JSTaggedValue::Undefined());
1224             JSNumberFormat::Cast(*obj)->SetMaximumSignificantDigits(thread_, JSTaggedValue::Undefined());
1225             JSNumberFormat::Cast(*obj)->SetUseGrouping(thread_, JSTaggedValue::Undefined());
1226             JSNumberFormat::Cast(*obj)->SetBoundFormat(thread_, JSTaggedValue::Undefined());
1227             JSNumberFormat::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
1228             JSNumberFormat::Cast(*obj)->SetStyle(StyleOption::EXCEPTION);
1229             JSNumberFormat::Cast(*obj)->SetCurrencySign(CurrencySignOption::EXCEPTION);
1230             JSNumberFormat::Cast(*obj)->SetCurrencyDisplay(CurrencyDisplayOption::EXCEPTION);
1231             JSNumberFormat::Cast(*obj)->SetUnitDisplay(UnitDisplayOption::EXCEPTION);
1232             JSNumberFormat::Cast(*obj)->SetSignDisplay(SignDisplayOption::EXCEPTION);
1233             JSNumberFormat::Cast(*obj)->SetCompactDisplay(CompactDisplayOption::EXCEPTION);
1234             JSNumberFormat::Cast(*obj)->SetNotation(NotationOption::EXCEPTION);
1235             JSNumberFormat::Cast(*obj)->SetRoundingType(RoundingType::EXCEPTION);
1236             break;
1237         }
1238         case JSType::JS_RELATIVE_TIME_FORMAT: {
1239             JSRelativeTimeFormat::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1240             JSRelativeTimeFormat::Cast(*obj)->SetNumberingSystem(thread_, JSTaggedValue::Undefined());
1241             JSRelativeTimeFormat::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
1242             JSRelativeTimeFormat::Cast(*obj)->SetStyle(RelativeStyleOption::EXCEPTION);
1243             JSRelativeTimeFormat::Cast(*obj)->SetNumeric(NumericOption::EXCEPTION);
1244             break;
1245         }
1246         case JSType::JS_COLLATOR: {
1247             JSCollator::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
1248             JSCollator::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1249             JSCollator::Cast(*obj)->SetCollation(thread_, JSTaggedValue::Undefined());
1250             JSCollator::Cast(*obj)->SetBoundCompare(thread_, JSTaggedValue::Undefined());
1251             JSCollator::Cast(*obj)->SetUsage(UsageOption::EXCEPTION);
1252             JSCollator::Cast(*obj)->SetCaseFirst(CaseFirstOption::EXCEPTION);
1253             JSCollator::Cast(*obj)->SetSensitivity(SensitivityOption::EXCEPTION);
1254             JSCollator::Cast(*obj)->SetIgnorePunctuation(false);
1255             JSCollator::Cast(*obj)->SetNumeric(false);
1256             break;
1257         }
1258         case JSType::JS_PLURAL_RULES: {
1259             JSPluralRules::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1260             JSPluralRules::Cast(*obj)->SetMinimumIntegerDigits(thread_, JSTaggedValue::Undefined());
1261             JSPluralRules::Cast(*obj)->SetMinimumFractionDigits(thread_, JSTaggedValue::Undefined());
1262             JSPluralRules::Cast(*obj)->SetMaximumFractionDigits(thread_, JSTaggedValue::Undefined());
1263             JSPluralRules::Cast(*obj)->SetMinimumSignificantDigits(thread_, JSTaggedValue::Undefined());
1264             JSPluralRules::Cast(*obj)->SetMaximumSignificantDigits(thread_, JSTaggedValue::Undefined());
1265             JSPluralRules::Cast(*obj)->SetIcuPR(thread_, JSTaggedValue::Undefined());
1266             JSPluralRules::Cast(*obj)->SetIcuNF(thread_, JSTaggedValue::Undefined());
1267             JSPluralRules::Cast(*obj)->SetRoundingType(RoundingType::EXCEPTION);
1268             JSPluralRules::Cast(*obj)->SetType(TypeOption::EXCEPTION);
1269             break;
1270         }
1271         case JSType::JS_DISPLAYNAMES: {
1272             JSDisplayNames::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1273             JSDisplayNames::Cast(*obj)->SetType(TypednsOption::EXCEPTION);
1274             JSDisplayNames::Cast(*obj)->SetStyle(StyOption::EXCEPTION);
1275             JSDisplayNames::Cast(*obj)->SetFallback(FallbackOption::EXCEPTION);
1276             JSDisplayNames::Cast(*obj)->SetIcuLDN(thread_, JSTaggedValue::Undefined());
1277             break;
1278         }
1279         case JSType::JS_SEGMENTER: {
1280             JSSegmenter::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1281             JSSegmenter::Cast(*obj)->SetGranularity(GranularityOption::EXCEPTION);
1282             JSSegmenter::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
1283             break;
1284         }
1285         case JSType::JS_SEGMENTS: {
1286             JSSegments::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
1287             JSSegments::Cast(*obj)->SetSegmentsString(thread_, JSTaggedValue::Undefined());
1288             JSSegments::Cast(*obj)->SetUnicodeString(thread_, JSTaggedValue::Undefined());
1289             JSSegments::Cast(*obj)->SetGranularity(GranularityOption::EXCEPTION);
1290             break;
1291         }
1292         case JSType::JS_SEGMENT_ITERATOR: {
1293             JSSegmentIterator::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
1294             JSSegmentIterator::Cast(*obj)->SetIteratedString(thread_, JSTaggedValue::Undefined());
1295             JSSegmentIterator::Cast(*obj)->SetUnicodeString(thread_, JSTaggedValue::Undefined());
1296             JSSegmentIterator::Cast(*obj)->SetGranularity(GranularityOption::EXCEPTION);
1297             break;
1298         }
1299         case JSType::JS_LIST_FORMAT: {
1300             JSListFormat::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1301             JSListFormat::Cast(*obj)->SetType(ListTypeOption::EXCEPTION);
1302             JSListFormat::Cast(*obj)->SetStyle(ListStyleOption::EXCEPTION);
1303             JSListFormat::Cast(*obj)->SetIcuLF(thread_, JSTaggedValue::Undefined());
1304             break;
1305         }
1306 #else
1307         case JSType::JS_INTL:
1308         case JSType::JS_LOCALE:
1309         case JSType::JS_DATE_TIME_FORMAT:
1310         case JSType::JS_NUMBER_FORMAT:
1311         case JSType::JS_RELATIVE_TIME_FORMAT:
1312         case JSType::JS_COLLATOR:
1313         case JSType::JS_PLURAL_RULES:
1314         case JSType::JS_DISPLAYNAMES:
1315         case JSType::JS_SEGMENTER:
1316         case JSType::JS_SEGMENTS:
1317         case JSType::JS_SEGMENT_ITERATOR:
1318         case JSType::JS_LIST_FORMAT: {
1319             break;
1320         }
1321 #endif
1322         case JSType::JS_ARRAY: {
1323             JSArray::Cast(*obj)->SetLength(0);
1324             JSArray::Cast(*obj)->SetTrackInfo(thread_, JSTaggedValue::Undefined());
1325             ASSERT(!obj->GetJSHClass()->IsDictionaryMode());
1326             auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
1327             JSArray::Cast(*obj)->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
1328             break;
1329         }
1330         case JSType::JS_SHARED_ARRAY: {
1331             JSSharedArray::Cast(*obj)->SetLength(0);
1332             JSSharedArray::Cast(*obj)->SetTrackInfo(thread_, JSTaggedValue::Undefined());
1333             ASSERT(!obj->GetJSHClass()->IsDictionaryMode());
1334             JSSharedArray::Cast(*obj)->SetModRecord(0);
1335             auto accessor = thread_->GlobalConstants()->GetSharedArrayLengthAccessor();
1336             JSSharedArray::Cast(*obj)->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX,
1337                                                                accessor);
1338             break;
1339         }
1340         case JSType::JS_DATE:
1341             JSDate::Cast(*obj)->SetTimeValue(thread_, JSTaggedValue(0.0));
1342             JSDate::Cast(*obj)->SetLocalOffset(thread_, JSTaggedValue(JSDate::MAX_DOUBLE));
1343             break;
1344         case JSType::JS_TYPED_ARRAY:
1345         case JSType::JS_INT8_ARRAY:
1346         case JSType::JS_UINT8_ARRAY:
1347         case JSType::JS_UINT8_CLAMPED_ARRAY:
1348         case JSType::JS_INT16_ARRAY:
1349         case JSType::JS_UINT16_ARRAY:
1350         case JSType::JS_INT32_ARRAY:
1351         case JSType::JS_UINT32_ARRAY:
1352         case JSType::JS_FLOAT32_ARRAY:
1353         case JSType::JS_FLOAT64_ARRAY:
1354         case JSType::JS_BIGINT64_ARRAY:
1355         case JSType::JS_BIGUINT64_ARRAY:
1356             JSTypedArray::Cast(*obj)->SetViewedArrayBufferOrByteArray(thread_, JSTaggedValue::Undefined());
1357             JSTypedArray::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined());
1358             JSTypedArray::Cast(*obj)->SetByteLength(0);
1359             JSTypedArray::Cast(*obj)->SetByteOffset(0);
1360             JSTypedArray::Cast(*obj)->SetArrayLength(0);
1361             JSTypedArray::Cast(*obj)->SetContentType(ContentType::None);
1362             break;
1363         case JSType::JS_SHARED_TYPED_ARRAY:
1364         case JSType::JS_SHARED_INT8_ARRAY:
1365         case JSType::JS_SHARED_UINT8_ARRAY:
1366         case JSType::JS_SHARED_UINT8_CLAMPED_ARRAY:
1367         case JSType::JS_SHARED_INT16_ARRAY:
1368         case JSType::JS_SHARED_UINT16_ARRAY:
1369         case JSType::JS_SHARED_INT32_ARRAY:
1370         case JSType::JS_SHARED_UINT32_ARRAY:
1371         case JSType::JS_SHARED_FLOAT32_ARRAY:
1372         case JSType::JS_SHARED_FLOAT64_ARRAY:
1373         case JSType::JS_SHARED_BIGINT64_ARRAY:
1374         case JSType::JS_SHARED_BIGUINT64_ARRAY:
1375             JSSharedTypedArray::Cast(*obj)->SetViewedArrayBufferOrByteArray(thread_, JSTaggedValue::Undefined());
1376             JSSharedTypedArray::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined());
1377             JSSharedTypedArray::Cast(*obj)->SetByteLength(0);
1378             JSSharedTypedArray::Cast(*obj)->SetByteOffset(0);
1379             JSSharedTypedArray::Cast(*obj)->SetArrayLength(0);
1380             JSSharedTypedArray::Cast(*obj)->SetContentType(ContentType::None);
1381             JSSharedTypedArray::Cast(*obj)->SetModRecord(0);
1382             break;
1383         case JSType::JS_REG_EXP:
1384             JSRegExp::Cast(*obj)->SetByteCodeBuffer(thread_, JSTaggedValue::Undefined());
1385             JSRegExp::Cast(*obj)->SetOriginalSource(thread_, JSTaggedValue::Undefined());
1386             JSRegExp::Cast(*obj)->SetOriginalFlags(thread_, JSTaggedValue(0));
1387             JSRegExp::Cast(*obj)->SetGroupName(thread_, JSTaggedValue::Undefined());
1388             JSRegExp::Cast(*obj)->SetLength(0);
1389             break;
1390         case JSType::JS_PRIMITIVE_REF:
1391             JSPrimitiveRef::Cast(*obj)->SetValue(thread_, JSTaggedValue::Undefined());
1392             break;
1393         case JSType::JS_SET:
1394             JSSet::Cast(*obj)->SetLinkedSet(thread_, JSTaggedValue::Undefined());
1395             break;
1396         case JSType::JS_SHARED_SET:
1397             JSSharedSet::Cast(*obj)->SetLinkedSet(thread_, JSTaggedValue::Undefined());
1398             JSSharedSet::Cast(*obj)->SetModRecord(0);
1399             break;
1400         case JSType::JS_MAP:
1401             JSMap::Cast(*obj)->SetLinkedMap(thread_, JSTaggedValue::Undefined());
1402             break;
1403         case JSType::JS_SHARED_MAP:
1404             JSSharedMap::Cast(*obj)->SetLinkedMap(thread_, JSTaggedValue::Undefined());
1405             JSSharedMap::Cast(*obj)->SetModRecord(0);
1406             break;
1407         case JSType::JS_WEAK_MAP:
1408             JSWeakMap::Cast(*obj)->SetLinkedMap(thread_, JSTaggedValue::Undefined());
1409             break;
1410         case JSType::JS_WEAK_SET:
1411             JSWeakSet::Cast(*obj)->SetLinkedSet(thread_, JSTaggedValue::Undefined());
1412             break;
1413         case JSType::JS_WEAK_REF:
1414             JSWeakRef::Cast(*obj)->SetWeakObject(thread_, JSTaggedValue::Undefined());
1415             break;
1416         case JSType::JS_FINALIZATION_REGISTRY:
1417             JSFinalizationRegistry::Cast(*obj)->SetCleanupCallback(thread_, JSTaggedValue::Undefined());
1418             JSFinalizationRegistry::Cast(*obj)->SetNoUnregister(thread_, JSTaggedValue::Undefined());
1419             JSFinalizationRegistry::Cast(*obj)->SetMaybeUnregister(thread_, JSTaggedValue::Undefined());
1420             JSFinalizationRegistry::Cast(*obj)->SetNext(thread_, JSTaggedValue::Null());
1421             JSFinalizationRegistry::Cast(*obj)->SetPrev(thread_, JSTaggedValue::Null());
1422             break;
1423         case JSType::JS_GENERATOR_OBJECT:
1424             JSGeneratorObject::Cast(*obj)->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
1425             JSGeneratorObject::Cast(*obj)->SetResumeResult(thread_, JSTaggedValue::Undefined());
1426             JSGeneratorObject::Cast(*obj)->SetGeneratorState(JSGeneratorState::UNDEFINED);
1427             JSGeneratorObject::Cast(*obj)->SetResumeMode(GeneratorResumeMode::UNDEFINED);
1428             break;
1429         case JSType::JS_ASYNC_GENERATOR_OBJECT:
1430             JSAsyncGeneratorObject::Cast(*obj)->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
1431             JSAsyncGeneratorObject::Cast(*obj)->SetAsyncGeneratorQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1432             JSAsyncGeneratorObject::Cast(*obj)->SetGeneratorBrand(thread_, JSTaggedValue::Undefined());
1433             JSAsyncGeneratorObject::Cast(*obj)->SetResumeResult(thread_, JSTaggedValue::Undefined());
1434             JSAsyncGeneratorObject::Cast(*obj)->SetAsyncGeneratorState(JSAsyncGeneratorState::UNDEFINED);
1435             JSAsyncGeneratorObject::Cast(*obj)->SetResumeMode(AsyncGeneratorResumeMode::UNDEFINED);
1436             break;
1437         case JSType::JS_STRING_ITERATOR:
1438             JSStringIterator::Cast(*obj)->SetStringIteratorNextIndex(0);
1439             JSStringIterator::Cast(*obj)->SetIteratedString(thread_, JSTaggedValue::Undefined());
1440             break;
1441         case JSType::JS_ASYNC_FROM_SYNC_ITERATOR:
1442             JSAsyncFromSyncIterator::Cast(*obj)->SetSyncIteratorRecord(thread_, JSTaggedValue::Undefined());
1443             break;
1444         case JSType::JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION:
1445             JSAsyncFromSyncIterUnwarpFunction::Cast(*obj)->SetDone(thread_, JSTaggedValue::Undefined());
1446             break;
1447         case JSType::JS_ARRAY_BUFFER:
1448             JSArrayBuffer::Cast(*obj)->SetArrayBufferData(thread_, JSTaggedValue::Undefined());
1449             JSArrayBuffer::Cast(*obj)->SetArrayBufferByteLength(0);
1450             JSArrayBuffer::Cast(*obj)->ClearBitField();
1451             break;
1452         case JSType::JS_SHARED_ARRAY_BUFFER:
1453             JSArrayBuffer::Cast(*obj)->SetArrayBufferData(thread_, JSTaggedValue::Undefined());
1454             JSArrayBuffer::Cast(*obj)->SetArrayBufferByteLength(0);
1455             JSArrayBuffer::Cast(*obj)->SetShared(true);
1456             break;
1457         case JSType::JS_SENDABLE_ARRAY_BUFFER:
1458             JSSendableArrayBuffer::Cast(*obj)->SetArrayBufferData(thread_, JSTaggedValue::Undefined());
1459             JSSendableArrayBuffer::Cast(*obj)->SetArrayBufferByteLength(0);
1460             break;
1461         case JSType::JS_PROMISE:
1462             JSPromise::Cast(*obj)->SetPromiseState(PromiseState::PENDING);
1463             JSPromise::Cast(*obj)->SetPromiseResult(thread_, JSTaggedValue::Undefined());
1464             JSPromise::Cast(*obj)->SetPromiseRejectReactions(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1465             JSPromise::Cast(*obj)->SetPromiseFulfillReactions(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1466 
1467             JSPromise::Cast(*obj)->SetPromiseIsHandled(false);
1468             break;
1469         case JSType::JS_DATA_VIEW:
1470             JSDataView::Cast(*obj)->SetDataView(thread_, JSTaggedValue(false));
1471             JSDataView::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined());
1472             JSDataView::Cast(*obj)->SetByteLength(0);
1473             JSDataView::Cast(*obj)->SetByteOffset(0);
1474             break;
1475         // non ECMA standard jsapi container
1476         case JSType::JS_API_ARRAY_LIST: {
1477             JSAPIArrayList::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
1478             break;
1479         }
1480         case JSType::JS_API_HASH_MAP: {
1481             JSAPIHashMap::Cast(*obj)->SetSize(0);
1482             JSAPIHashMap::Cast(*obj)->SetTable(thread_, JSTaggedValue::Undefined());
1483             break;
1484         }
1485         case JSType::JS_API_HASH_SET: {
1486             JSAPIHashSet::Cast(*obj)->SetSize(0);
1487             JSAPIHashSet::Cast(*obj)->SetTable(thread_, JSTaggedValue::Undefined());
1488             break;
1489         }
1490         case JSType::JS_API_TREE_MAP: {
1491             JSAPITreeMap::Cast(*obj)->SetTreeMap(thread_, JSTaggedValue::Undefined());
1492             break;
1493         }
1494         case JSType::JS_API_TREE_SET: {
1495             JSAPITreeSet::Cast(*obj)->SetTreeSet(thread_, JSTaggedValue::Undefined());
1496             break;
1497         }
1498         case JSType::JS_API_QUEUE: {
1499             JSAPIQueue::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
1500             JSAPIQueue::Cast(*obj)->SetFront(0);
1501             JSAPIQueue::Cast(*obj)->SetTail(0);
1502             break;
1503         }
1504         case JSType::JS_API_PLAIN_ARRAY: {
1505             JSAPIPlainArray::Cast(*obj)->SetLength(0);
1506             JSAPIPlainArray::Cast(*obj)->SetValues(thread_, JSTaggedValue(0));
1507             JSAPIPlainArray::Cast(*obj)->SetKeys(thread_, JSTaggedValue(0));
1508             break;
1509         }
1510         case JSType::JS_API_STACK: {
1511             JSAPIStack::Cast(*obj)->SetTop(0);
1512             break;
1513         }
1514         case JSType::JS_API_DEQUE: {
1515             JSAPIDeque::Cast(*obj)->SetFirst(0);
1516             JSAPIDeque::Cast(*obj)->SetLast(0);
1517             break;
1518         }
1519         case JSType::JS_API_LIGHT_WEIGHT_MAP: {
1520             JSAPILightWeightMap::Cast(*obj)->SetLength(0);
1521             JSAPILightWeightMap::Cast(*obj)->SetHashes(thread_, JSTaggedValue::Undefined());
1522             JSAPILightWeightMap::Cast(*obj)->SetKeys(thread_, JSTaggedValue::Undefined());
1523             JSAPILightWeightMap::Cast(*obj)->SetValues(thread_, JSTaggedValue::Undefined());
1524             break;
1525         }
1526         case JSType::JS_API_LIGHT_WEIGHT_SET: {
1527             JSAPILightWeightSet::Cast(*obj)->SetLength(0);
1528             JSAPILightWeightSet::Cast(*obj)->SetHashes(thread_, JSTaggedValue::Undefined());
1529             JSAPILightWeightSet::Cast(*obj)->SetValues(thread_, JSTaggedValue::Undefined());
1530             break;
1531         }
1532         case JSType::JS_API_VECTOR: {
1533             JSAPIVector::Cast(*obj)->SetLength(0);
1534             break;
1535         }
1536         case JSType::JS_API_BITVECTOR: {
1537             JSAPIBitVector::Cast(*obj)->SetLength(0);
1538             JSAPIBitVector::Cast(*obj)->SetModRecord(0);
1539             break;
1540         }
1541         case JSType::JS_API_LIST: {
1542             JSAPIList::Cast(*obj)->SetSingleList(thread_, JSTaggedValue::Undefined());
1543             JSAPIList::Cast(*obj)->SetBitField(0UL);
1544             break;
1545         }
1546         case JSType::JS_API_LINKED_LIST: {
1547             JSAPILinkedList::Cast(*obj)->SetDoubleList(thread_, JSTaggedValue::Undefined());
1548             break;
1549         }
1550         case JSType::JS_ASYNC_FUNC_OBJECT:
1551             JSAsyncFuncObject::Cast(*obj)->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
1552             JSAsyncFuncObject::Cast(*obj)->SetResumeResult(thread_, JSTaggedValue::Undefined());
1553             JSAsyncFuncObject::Cast(*obj)->SetPromise(thread_, JSTaggedValue::Undefined());
1554             break;
1555         case JSType::JS_FUNCTION:
1556         case JSType::JS_GENERATOR_FUNCTION:
1557             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1558             break;
1559         case JSType::JS_ASYNC_GENERATOR_FUNCTION:
1560             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1561             break;
1562         case JSType::JS_PROXY_REVOC_FUNCTION:
1563             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1564             JSProxyRevocFunction::Cast(*obj)->SetRevocableProxy(thread_, JSTaggedValue::Undefined());
1565             break;
1566         case JSType::JS_PROMISE_REACTIONS_FUNCTION:
1567             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1568             JSPromiseReactionsFunction::Cast(*obj)->SetPromise(thread_, JSTaggedValue::Undefined());
1569             JSPromiseReactionsFunction::Cast(*obj)->SetAlreadyResolved(thread_, JSTaggedValue::Undefined());
1570             break;
1571         case JSType::JS_PROMISE_EXECUTOR_FUNCTION:
1572             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1573             JSPromiseExecutorFunction::Cast(*obj)->SetCapability(thread_, JSTaggedValue::Undefined());
1574             break;
1575         case JSType::JS_ASYNC_MODULE_FULFILLED_FUNCTION:
1576             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1577             JSAsyncModuleFulfilledFunction::Cast(*obj)->SetModule(thread_, JSTaggedValue::Undefined());
1578             break;
1579         case JSType::JS_ASYNC_MODULE_REJECTED_FUNCTION:
1580             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1581             JSAsyncModuleRejectedFunction::Cast(*obj)->SetModule(thread_, JSTaggedValue::Undefined());
1582             break;
1583         case JSType::JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN:
1584             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1585             JSAsyncGeneratorResNextRetProRstFtn::Cast(*obj)->SetAsyncGeneratorObject(thread_,
1586                                                                                      JSTaggedValue::Undefined());
1587             break;
1588         case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION:
1589             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1590             JSPromiseAllResolveElementFunction::Cast(*obj)->SetIndex(thread_, JSTaggedValue::Undefined());
1591             JSPromiseAllResolveElementFunction::Cast(*obj)->SetValues(thread_, JSTaggedValue::Undefined());
1592             JSPromiseAllResolveElementFunction::Cast(*obj)->SetCapabilities(thread_, JSTaggedValue::Undefined());
1593             JSPromiseAllResolveElementFunction::Cast(*obj)->SetRemainingElements(thread_, JSTaggedValue::Undefined());
1594             JSPromiseAllResolveElementFunction::Cast(*obj)->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
1595             break;
1596         case JSType::JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION:
1597             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1598             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetIndex(0);
1599             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetErrors(thread_, JSTaggedValue::Undefined());
1600             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetCapability(thread_, JSTaggedValue::Undefined());
1601             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetRemainingElements(thread_, JSTaggedValue::Undefined());
1602             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
1603             break;
1604         case JSType::JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION:
1605             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1606             JSPromiseAllSettledElementFunction::Cast(*obj)->SetIndex(0);
1607             JSPromiseAllSettledElementFunction::Cast(*obj)->SetValues(thread_, JSTaggedValue::Undefined());
1608             JSPromiseAllSettledElementFunction::Cast(*obj)->SetCapability(thread_, JSTaggedValue::Undefined());
1609             JSPromiseAllSettledElementFunction::Cast(*obj)->SetRemainingElements(thread_, JSTaggedValue::Undefined());
1610             JSPromiseAllSettledElementFunction::Cast(*obj)->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
1611             break;
1612         case JSType::JS_PROMISE_FINALLY_FUNCTION:
1613             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1614             JSPromiseFinallyFunction::Cast(*obj)->SetOnFinally(thread_, JSTaggedValue::Undefined());
1615             JSPromiseFinallyFunction::Cast(*obj)->SetConstructor(thread_, JSTaggedValue::Undefined());
1616             break;
1617         case JSType::JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION:
1618             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1619             JSPromiseValueThunkOrThrowerFunction::Cast(*obj)->SetResult(thread_, JSTaggedValue::Undefined());
1620             break;
1621         case JSType::JS_INTL_BOUND_FUNCTION:
1622             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1623             JSIntlBoundFunction::Cast(*obj)->SetNumberFormat(thread_, JSTaggedValue::Undefined());
1624             JSIntlBoundFunction::Cast(*obj)->SetDateTimeFormat(thread_, JSTaggedValue::Undefined());
1625             JSIntlBoundFunction::Cast(*obj)->SetCollator(thread_, JSTaggedValue::Undefined());
1626             break;
1627         case JSType::JS_BOUND_FUNCTION:
1628             JSBoundFunction::Cast(*obj)->SetMethod(thread_, JSTaggedValue::Undefined());
1629             JSBoundFunction::Cast(*obj)->SetBoundTarget(thread_, JSTaggedValue::Undefined());
1630             JSBoundFunction::Cast(*obj)->SetBoundThis(thread_, JSTaggedValue::Undefined());
1631             JSBoundFunction::Cast(*obj)->SetBoundArguments(thread_, JSTaggedValue::Undefined());
1632             break;
1633         case JSType::JS_ARGUMENTS:
1634             break;
1635         case JSType::JS_FORIN_ITERATOR:
1636         case JSType::JS_MAP_ITERATOR:
1637         case JSType::JS_SET_ITERATOR:
1638         case JSType::JS_REG_EXP_ITERATOR:
1639         case JSType::JS_API_ARRAYLIST_ITERATOR:
1640         case JSType::JS_API_TREEMAP_ITERATOR:
1641         case JSType::JS_API_TREESET_ITERATOR:
1642         case JSType::JS_API_QUEUE_ITERATOR:
1643         case JSType::JS_API_DEQUE_ITERATOR:
1644         case JSType::JS_API_LIGHT_WEIGHT_MAP_ITERATOR:
1645         case JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR:
1646         case JSType::JS_API_STACK_ITERATOR:
1647         case JSType::JS_API_VECTOR_ITERATOR:
1648         case JSType::JS_API_BITVECTOR_ITERATOR:
1649         case JSType::JS_API_HASHMAP_ITERATOR:
1650         case JSType::JS_API_HASHSET_ITERATOR:
1651         case JSType::JS_ARRAY_ITERATOR:
1652         case JSType::JS_API_PLAIN_ARRAY_ITERATOR:
1653             break;
1654         case JSType::JS_CJS_MODULE:
1655             CjsModule::Cast(*obj)->SetId(thread_, JSTaggedValue::Undefined());
1656             CjsModule::Cast(*obj)->SetExports(thread_, JSTaggedValue::Undefined());
1657             CjsModule::Cast(*obj)->SetPath(thread_, JSTaggedValue::Undefined());
1658             CjsModule::Cast(*obj)->SetFilename(thread_, JSTaggedValue::Undefined());
1659             CjsModule::Cast(*obj)->SetStatus(CjsModuleStatus::UNLOAD);
1660             break;
1661         case JSType::JS_CJS_EXPORTS:
1662             CjsExports::Cast(*obj)->SetExports(thread_, JSTaggedValue::Undefined());
1663             break;
1664         case JSType::JS_CJS_REQUIRE:
1665             CjsRequire::Cast(*obj)->SetCache(thread_, JSTaggedValue::Undefined());
1666             CjsRequire::Cast(*obj)->SetParent(thread_, JSTaggedValue::Undefined());
1667             break;
1668         default:
1669             LOG_ECMA(FATAL) << "this branch is unreachable";
1670             UNREACHABLE();
1671     }
1672 }
1673 
FillFreeObject(uintptr_t address, size_t size, RemoveSlots removeSlots, uintptr_t hugeObjectHead)1674 FreeObject *ObjectFactory::FillFreeObject(uintptr_t address, size_t size, RemoveSlots removeSlots,
1675                                           uintptr_t hugeObjectHead)
1676 {
1677     FreeObject *object = nullptr;
1678     const GlobalEnvConstants *globalConst = thread_->GetFirstGlobalConst();
1679     if (size >= FreeObject::SIZE_OFFSET && size < FreeObject::SIZE) {
1680         object = reinterpret_cast<FreeObject *>(address);
1681         object->SetClassWithoutBarrier(JSHClass::Cast(globalConst->GetFreeObjectWithOneFieldClass().GetTaggedObject()));
1682         object->SetNext(INVALID_OBJECT);
1683     } else if (size >= FreeObject::SIZE) {
1684         object = reinterpret_cast<FreeObject *>(address);
1685         object->SetClassWithoutBarrier(
1686             JSHClass::Cast(globalConst->GetFreeObjectWithTwoFieldClass().GetTaggedObject()));
1687         object->SetAvailable(size);
1688         object->SetNext(INVALID_OBJECT);
1689         if (UNLIKELY(heap_->ShouldVerifyHeap())) {
1690             FillFreeMemoryRange(address + FreeObject::SIZE, address + size);
1691         }
1692     } else if (size == FreeObject::NEXT_OFFSET) {
1693         object = reinterpret_cast<FreeObject *>(address);
1694         object->SetClassWithoutBarrier(
1695             JSHClass::Cast(globalConst->GetFreeObjectWithNoneFieldClass().GetTaggedObject()));
1696     } else {
1697         LOG_ECMA(DEBUG) << "Fill free object size is smaller";
1698     }
1699 
1700     if (removeSlots == RemoveSlots::YES) {
1701         // For huge object, the region of `object` might not be its 1st region. Use `hugeObjectHead` instead.
1702         Region *region = Region::ObjectAddressToRange(hugeObjectHead == 0 ? object :
1703                                                       reinterpret_cast<TaggedObject *>(hugeObjectHead));
1704         heap_->ClearSlotsRange(region, address, address + size);
1705     }
1706     return object;
1707 }
1708 
NewObject(const JSHandle<JSHClass> &hclass)1709 TaggedObject *ObjectFactory::NewObject(const JSHandle<JSHClass> &hclass)
1710 {
1711     NewObjectHook();
1712     TaggedObject *header = heap_->AllocateYoungOrHugeObject(*hclass);
1713     uint32_t inobjPropCount = hclass->GetInlinedProperties();
1714     if (inobjPropCount > 0) {
1715         InitializeExtraProperties(hclass, header, inobjPropCount);
1716     }
1717     return header;
1718 }
1719 
NewNonMovableObject(const JSHandle<JSHClass> &hclass, uint32_t inobjPropCount)1720 TaggedObject *ObjectFactory::NewNonMovableObject(const JSHandle<JSHClass> &hclass, uint32_t inobjPropCount)
1721 {
1722     NewObjectHook();
1723     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(*hclass);
1724     if (inobjPropCount > 0) {
1725         InitializeExtraProperties(hclass, header, inobjPropCount);
1726     }
1727     return header;
1728 }
1729 
InitializeExtraProperties(const JSHandle<JSHClass> &hclass, TaggedObject *obj, uint32_t inobjPropCount)1730 void ObjectFactory::InitializeExtraProperties(const JSHandle<JSHClass> &hclass,
1731                                               TaggedObject *obj, uint32_t inobjPropCount)
1732 {
1733     ASSERT(inobjPropCount * JSTaggedValue::TaggedTypeSize() < hclass->GetObjectSize());
1734     auto paddr = reinterpret_cast<uintptr_t>(obj) + hclass->GetObjectSize();
1735     // The object which created by AOT speculative hclass, should be initialized as hole, means does not exist,
1736     // to follow ECMA spec.
1737     JSTaggedType initVal = hclass->IsTS() ? JSTaggedValue::VALUE_HOLE : JSTaggedValue::VALUE_UNDEFINED;
1738     for (uint32_t i = 0; i < inobjPropCount; ++i) {
1739         paddr -= JSTaggedValue::TaggedTypeSize();
1740         *reinterpret_cast<JSTaggedType *>(paddr) = initVal;
1741     }
1742 }
1743 
OrdinaryNewJSObjectCreate(const JSHandle<JSTaggedValue> &proto)1744 JSHandle<JSObject> ObjectFactory::OrdinaryNewJSObjectCreate(const JSHandle<JSTaggedValue> &proto)
1745 {
1746     JSHandle<JSTaggedValue> protoValue(proto);
1747     JSHandle<JSHClass> hclass(thread_, thread_->GlobalConstants()->GetObjectClass().GetTaggedObject());
1748     JSHandle<JSHClass> newClass = JSHClass::TransProtoWithoutLayout(thread_, hclass, protoValue);
1749     JSHandle<JSObject> newObj = NewJSObject(newClass);
1750     newObj->GetJSHClass()->SetExtensible(true);
1751     return newObj;
1752 }
1753 
NewJSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc, FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId, MemSpaceType methodSpaceType)1754 JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc,
1755                                                   FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId,
1756                                                   MemSpaceType methodSpaceType)
1757 {
1758     JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, kind, builtinId, methodSpaceType);
1759     return NewJSFunction(env, target);
1760 }
1761 
NewJSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<Method> &method)1762 JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<GlobalEnv> &env,
1763                                                   const JSHandle<Method> &method)
1764 {
1765     FunctionKind kind = method->GetFunctionKind();
1766     JSHandle<JSHClass> hclass;
1767     if (kind == FunctionKind::BASE_CONSTRUCTOR) {
1768         hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
1769     } else if (JSFunction::IsConstructorKind(kind)) {
1770         hclass = JSHandle<JSHClass>::Cast(env->GetConstructorFunctionClass());
1771     } else if (kind == FunctionKind::CONCURRENT_FUNCTION) {
1772         hclass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
1773     } else {
1774         hclass = JSHandle<JSHClass>::Cast(env->GetNormalFunctionClass());
1775     }
1776 
1777     return NewJSFunctionByHClass(method, hclass);
1778 }
1779 
NewSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc, FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId, MemSpaceType spaceType)1780 JSHandle<JSFunction> ObjectFactory::NewSFunction(const JSHandle<GlobalEnv> &env,
1781                                                  const void *nativeFunc,
1782                                                  FunctionKind kind,
1783                                                  kungfu::BuiltinsStubCSigns::ID builtinId,
1784                                                  MemSpaceType spaceType)
1785 {
1786     JSHandle<Method> method = NewSMethodForNativeFunction(nativeFunc, kind, builtinId, spaceType);
1787     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutProto());
1788     JSHandle<JSFunction> sfunc = NewSFunctionByHClass(method, hclass);
1789     return sfunc;
1790 }
1791 
CreateFunctionClass(FunctionKind kind, uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype)1792 JSHandle<JSHClass> ObjectFactory::CreateFunctionClass(FunctionKind kind, uint32_t size, JSType type,
1793                                                       const JSHandle<JSTaggedValue> &prototype)
1794 {
1795     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1796     JSHandle<JSHClass> functionClass = NewEcmaHClass(size, type, prototype);
1797     {
1798         functionClass->SetCallable(true);
1799         // FunctionKind = BASE_CONSTRUCTOR
1800         if (JSFunction::IsConstructorKind(kind)) {
1801             functionClass->SetConstructor(true);
1802         }
1803         functionClass->SetExtensible(true);
1804     }
1805 
1806     uint32_t fieldOrder = 0;
1807     ASSERT(JSFunction::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
1808     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(JSFunction::LENGTH_OF_INLINE_PROPERTIES);
1809     {
1810         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true);
1811         attributes.SetIsInlinedProps(true);
1812         attributes.SetRepresentation(Representation::TAGGED);
1813         attributes.SetOffset(fieldOrder);
1814         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetLengthString(), attributes);
1815         fieldOrder++;
1816     }
1817 
1818     ASSERT(JSFunction::NAME_INLINE_PROPERTY_INDEX == fieldOrder);
1819     // not set name in-object property on class which may have a name() method
1820     if (!JSFunction::IsClassConstructor(kind)) {
1821         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true);
1822         attributes.SetIsInlinedProps(true);
1823         attributes.SetRepresentation(Representation::TAGGED);
1824         attributes.SetOffset(fieldOrder);
1825         layoutInfoHandle->AddKey(thread_, fieldOrder,
1826                                  thread_->GlobalConstants()->GetHandledNameString().GetTaggedValue(), attributes);
1827         fieldOrder++;
1828     }
1829 
1830     if (JSFunction::HasPrototype(kind) && !JSFunction::IsClassConstructor(kind)) {
1831         ASSERT(JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX == fieldOrder);
1832         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(true, false, false);
1833         attributes.SetIsInlinedProps(true);
1834         attributes.SetRepresentation(Representation::TAGGED);
1835         attributes.SetOffset(fieldOrder);
1836         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetPrototypeString(), attributes);
1837         fieldOrder++;
1838     } else if (JSFunction::IsClassConstructor(kind)) {
1839         ASSERT(JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX == fieldOrder);
1840         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, false);
1841         attributes.SetIsInlinedProps(true);
1842         attributes.SetRepresentation(Representation::TAGGED);
1843         attributes.SetOffset(fieldOrder);
1844         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetPrototypeString(), attributes);
1845         fieldOrder++;
1846     }
1847 
1848     {
1849         functionClass->SetLayout(thread_, layoutInfoHandle);
1850         functionClass->SetNumberOfProps(fieldOrder);
1851     }
1852     return functionClass;
1853 }
1854 
CreateBoundFunctionClass()1855 JSHandle<JSHClass> ObjectFactory::CreateBoundFunctionClass()
1856 {
1857     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1858     JSHandle<JSTaggedValue> proto = env->GetFunctionPrototype();
1859     JSHandle<JSHClass> hclass = NewEcmaHClass(JSBoundFunction::SIZE, JSType::JS_BOUND_FUNCTION, proto);
1860     hclass->SetCallable(true);
1861 
1862     // set hclass layout
1863     uint32_t fieldOrder = 0;
1864     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1865     ASSERT(JSFunction::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
1866     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(JSFunction::LENGTH_OF_INLINE_PROPERTIES);
1867     {
1868         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true);
1869         attributes.SetIsInlinedProps(true);
1870         attributes.SetRepresentation(Representation::TAGGED);
1871         attributes.SetOffset(fieldOrder);
1872         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetLengthString(), attributes);
1873         fieldOrder++;
1874     }
1875 
1876     ASSERT(JSFunction::NAME_INLINE_PROPERTY_INDEX == fieldOrder);
1877     // not set name in-object property on class which may have a name() method
1878     {
1879         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true);
1880         attributes.SetIsInlinedProps(true);
1881         attributes.SetRepresentation(Representation::TAGGED);
1882         attributes.SetOffset(fieldOrder);
1883         layoutInfoHandle->AddKey(thread_, fieldOrder,
1884                                  globalConst->GetHandledNameString().GetTaggedValue(), attributes);
1885         fieldOrder++;
1886     }
1887 
1888     {
1889         hclass->SetLayout(thread_, layoutInfoHandle);
1890         hclass->SetNumberOfProps(fieldOrder);
1891     }
1892     return hclass;
1893 }
1894 
CreateDefaultClassPrototypeHClass(JSHClass *hclass)1895 JSHandle<JSHClass> ObjectFactory::CreateDefaultClassPrototypeHClass(JSHClass *hclass)
1896 {
1897     uint32_t size = ClassInfoExtractor::NON_STATIC_RESERVED_LENGTH;
1898     JSHandle<LayoutInfo> layout = CreateLayoutInfo(size, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
1899     PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);  // non-enumerable
1900 
1901     attributes.SetIsInlinedProps(true);
1902     attributes.SetRepresentation(Representation::TAGGED);
1903     attributes.SetOffset(ClassInfoExtractor::CONSTRUCTOR_INDEX);
1904     layout->AddKey(thread_, ClassInfoExtractor::CONSTRUCTOR_INDEX,
1905         thread_->GlobalConstants()->GetConstructorString(), attributes);
1906 
1907     JSHandle<JSHClass> defaultHclass = NewEcmaHClass(hclass, JSObject::SIZE, JSType::JS_OBJECT, size);
1908     defaultHclass->SetLayout(thread_, layout);
1909     defaultHclass->SetNumberOfProps(size);
1910     defaultHclass->SetClassPrototype(true);
1911     defaultHclass->SetIsPrototype(true);
1912     return defaultHclass;
1913 }
1914 
CreateDefaultClassConstructorHClass(JSHClass *hclass)1915 JSHandle<JSHClass> ObjectFactory::CreateDefaultClassConstructorHClass(JSHClass *hclass)
1916 {
1917     uint32_t size = ClassInfoExtractor::STATIC_RESERVED_LENGTH;
1918     JSHandle<LayoutInfo> layout = CreateLayoutInfo(size, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
1919 
1920     JSHandle<TaggedArray> array = NewTaggedArray(size);
1921     array->Set(thread_, ClassInfoExtractor::LENGTH_INDEX, thread_->GlobalConstants()->GetLengthString());
1922     array->Set(thread_, ClassInfoExtractor::NAME_INDEX, thread_->GlobalConstants()->GetNameString());
1923     array->Set(thread_, ClassInfoExtractor::PROTOTYPE_INDEX, thread_->GlobalConstants()->GetPrototypeString());
1924     for (uint32_t index = ClassInfoExtractor::LENGTH_INDEX; index < size; index++) {
1925         PropertyAttributes attributes;
1926         if (index == ClassInfoExtractor::PROTOTYPE_INDEX) {
1927             attributes = PropertyAttributes::DefaultAccessor(false, false, false);
1928         } else {
1929             attributes = PropertyAttributes::Default(false, false, true);
1930         }
1931         attributes.SetIsInlinedProps(true);
1932         attributes.SetRepresentation(Representation::TAGGED);
1933         attributes.SetOffset(index);
1934         layout->AddKey(thread_, index, array->Get(index), attributes);
1935     }
1936 
1937     JSHandle<JSHClass> defaultHclass = NewEcmaHClass(hclass, JSFunction::SIZE, JSType::JS_FUNCTION, size);
1938     defaultHclass->SetLayout(thread_, layout);
1939     defaultHclass->SetNumberOfProps(size);
1940     defaultHclass->SetClassConstructor(true);
1941     defaultHclass->SetConstructor(true);
1942     return defaultHclass;
1943 }
1944 
NewJSFunctionByHClass(const JSHandle<Method> &method, const JSHandle<JSHClass> &clazz, MemSpaceType type)1945 JSHandle<JSFunction> ObjectFactory::NewJSFunctionByHClass(const JSHandle<Method> &method,
1946                                                           const JSHandle<JSHClass> &clazz,
1947                                                           MemSpaceType type)
1948 {
1949     JSHandle<JSFunction> function;
1950     switch (type) {
1951         case MemSpaceType::SEMI_SPACE:
1952             function = JSHandle<JSFunction>::Cast(NewJSObject(clazz));
1953             break;
1954         case MemSpaceType::OLD_SPACE:
1955             function = JSHandle<JSFunction>::Cast(NewOldSpaceJSObject(clazz));
1956             break;
1957         case MemSpaceType::NON_MOVABLE:
1958             function = JSHandle<JSFunction>::Cast(NewNonMovableJSObject(clazz));
1959             break;
1960         default:
1961             LOG_ECMA(FATAL) << "this branch is unreachable";
1962             UNREACHABLE();
1963     }
1964     clazz->SetCallable(true);
1965     clazz->SetExtensible(true);
1966     JSFunction::InitializeJSFunction(thread_, function, method->GetFunctionKind());
1967     function->SetMethod(thread_, method);
1968     function->SetTaskConcurrentFuncFlag(0); // 0 : default value
1969     if (method->IsAotWithCallField()) {
1970         thread_->GetEcmaVM()->GetAOTFileManager()->
1971             SetAOTFuncEntry(method->GetJSPandaFile(), *function, *method);
1972     }
1973     return function;
1974 }
1975 
NewJSFunctionByHClass(const void *func, const JSHandle<JSHClass> &clazz, FunctionKind kind)1976 JSHandle<JSFunction> ObjectFactory::NewJSFunctionByHClass(const void *func, const JSHandle<JSHClass> &clazz,
1977                                                           FunctionKind kind)
1978 {
1979     JSHandle<Method> method = NewMethodForNativeFunction(func, kind);
1980     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(NewJSObject(clazz));
1981     clazz->SetCallable(true);
1982     clazz->SetExtensible(true);
1983     JSFunction::InitializeJSFunction(thread_, function, kind);
1984     function->SetMethod(thread_, method);
1985     return function;
1986 }
1987 
1988 // new function with name/length accessor
NewJSFunctionByHClassWithoutAccessor(const void *func, const JSHandle<JSHClass> &clazz, FunctionKind kind)1989 JSHandle<JSFunction> ObjectFactory::NewJSFunctionByHClassWithoutAccessor(const void *func,
1990     const JSHandle<JSHClass> &clazz, FunctionKind kind)
1991 {
1992     JSHandle<Method> method = NewMethodForNativeFunction(func, kind);
1993     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(NewJSObject(clazz));
1994     clazz->SetCallable(true);
1995     clazz->SetExtensible(true);
1996     JSFunction::InitializeWithDefaultValue(thread_, function);
1997     function->SetMethod(thread_, method);
1998     return function;
1999 }
2000 
InitializeMethod(const MethodLiteral *methodLiteral, JSHandle<Method> &method)2001 void ObjectFactory::InitializeMethod(const MethodLiteral *methodLiteral, JSHandle<Method> &method)
2002 {
2003     if (methodLiteral != nullptr) {
2004         method->SetCallField(methodLiteral->GetCallField());
2005         method->SetLiteralInfo(methodLiteral->GetLiteralInfo());
2006         method->SetNativePointerOrBytecodeArray(const_cast<void *>(methodLiteral->GetNativePointer()));
2007         method->SetExtraLiteralInfo(methodLiteral->GetExtraLiteralInfo());
2008     } else {
2009         method->SetCallField(0ULL);
2010         method->SetLiteralInfo(0ULL);
2011         method->SetNativePointerOrBytecodeArray(nullptr);
2012         method->SetExtraLiteralInfo(0ULL);
2013     }
2014     method->SetCodeEntryOrLiteral(reinterpret_cast<uintptr_t>(methodLiteral));
2015     method->SetConstantPool(thread_, JSTaggedValue::Undefined());
2016     method->SetFpDelta(0);
2017 }
2018 
NewMethod(const MethodLiteral *methodLiteral, MemSpaceType spaceType)2019 JSHandle<Method> ObjectFactory::NewMethod(const MethodLiteral *methodLiteral, MemSpaceType spaceType)
2020 {
2021     NewObjectHook();
2022     TaggedObject *header = nullptr;
2023     if (spaceType == NON_MOVABLE) {
2024         header = heap_->AllocateNonMovableOrHugeObject(
2025             JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
2026     } else {
2027         header = heap_->AllocateOldOrHugeObject(
2028             JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
2029     }
2030     JSHandle<Method> method(thread_, header);
2031     InitializeMethod(methodLiteral, method);
2032     return method;
2033 }
2034 
NewMethod(const JSPandaFile *jsPandaFile, MethodLiteral *methodLiteral, JSHandle<ConstantPool> constpool, uint32_t entryIndex, bool needSetAotFlag, bool *canFastCall)2035 JSHandle<Method> ObjectFactory::NewMethod(const JSPandaFile *jsPandaFile, MethodLiteral *methodLiteral,
2036                                           JSHandle<ConstantPool> constpool, uint32_t entryIndex,
2037                                           bool needSetAotFlag, bool *canFastCall)
2038 {
2039     JSHandle<Method> method;
2040     if (jsPandaFile->IsNewVersion()) {
2041         method = Method::Create(thread_, jsPandaFile, methodLiteral);
2042     } else {
2043         method = NewMethod(methodLiteral);
2044         method->SetConstantPool(thread_, constpool);
2045     }
2046     if (needSetAotFlag) {
2047         thread_->GetEcmaVM()->GetAOTFileManager()->
2048             SetAOTFuncEntry(jsPandaFile, nullptr, *method, entryIndex, canFastCall);
2049     } else {
2050         method->InitInterpreterStatusForCompiledMethod(thread_);
2051     }
2052     return method;
2053 }
2054 
NewJSNativeErrorFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc)2055 JSHandle<JSFunction> ObjectFactory::NewJSNativeErrorFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc)
2056 {
2057     JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, FunctionKind::BUILTIN_CONSTRUCTOR);
2058     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetNativeErrorFunctionClass());
2059     return NewJSFunctionByHClass(target, hclass);
2060 }
2061 
NewSpecificTypedArrayFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc, kungfu::BuiltinsStubCSigns::ID builtinId)2062 JSHandle<JSFunction> ObjectFactory::NewSpecificTypedArrayFunction(const JSHandle<GlobalEnv> &env,
2063                                                                   const void *nativeFunc,
2064                                                                   kungfu::BuiltinsStubCSigns::ID builtinId)
2065 {
2066     JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, FunctionKind::BUILTIN_CONSTRUCTOR, builtinId);
2067     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSpecificTypedArrayFunctionClass());
2068     return NewJSFunctionByHClass(target, hclass);
2069 }
2070 
NewAotFunction(uint32_t numArgs, uintptr_t codeEntry)2071 JSHandle<JSFunction> ObjectFactory::NewAotFunction(uint32_t numArgs, uintptr_t codeEntry)
2072 {
2073     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2074     JSHandle<Method> method = NewMethodForNativeFunction(reinterpret_cast<void *>(codeEntry));
2075     method->SetAotCodeBit(true);
2076     method->SetNativeBit(false);
2077     method->SetNumArgsWithCallField(numArgs);
2078     method->SetCodeEntryOrLiteral(codeEntry);
2079     JSHandle<JSFunction> jsfunc = NewJSFunction(env, method);
2080     return jsfunc;
2081 }
2082 
NewJSBoundFunction(const JSHandle<JSTaggedValue> &target, const JSHandle<JSTaggedValue> &boundThis, const JSHandle<TaggedArray> &args)2083 JSHandle<JSBoundFunction> ObjectFactory::NewJSBoundFunction(const JSHandle<JSTaggedValue> &target,
2084                                                             const JSHandle<JSTaggedValue> &boundThis,
2085                                                             const JSHandle<TaggedArray> &args)
2086 {
2087     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2088     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2089 
2090     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetBoundFunctionClass());
2091     JSHandle<JSBoundFunction> bundleFunction = JSHandle<JSBoundFunction>::Cast(NewJSObject(hclass));
2092     // set properties
2093     JSHandle<JSTaggedValue> accessor = globalConst->GetHandledFunctionNameAccessor();
2094     bundleFunction->SetPropertyInlinedProps(thread_, JSFunction::NAME_INLINE_PROPERTY_INDEX,
2095                                             accessor.GetTaggedValue());
2096     accessor = globalConst->GetHandledFunctionLengthAccessor();
2097     bundleFunction->SetPropertyInlinedProps(thread_, JSFunction::LENGTH_INLINE_PROPERTY_INDEX,
2098                                             accessor.GetTaggedValue());
2099 
2100     bundleFunction->SetBoundTarget(thread_, target);
2101     bundleFunction->SetBoundThis(thread_, boundThis);
2102     bundleFunction->SetBoundArguments(thread_, args);
2103 
2104     if (target.GetTaggedValue().IsConstructor()) {
2105         bundleFunction->SetConstructor(true);
2106     }
2107     bundleFunction->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_GLOBAL_CALL_JS_BOUND_FUNCTION));
2108     return bundleFunction;
2109 }
2110 
NewJSIntlBoundFunction(MethodIndex idx, int functionLength)2111 JSHandle<JSIntlBoundFunction> ObjectFactory::NewJSIntlBoundFunction(MethodIndex idx, int functionLength)
2112 {
2113     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2114     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetJSIntlBoundFunctionClass());
2115 
2116     JSHandle<JSIntlBoundFunction> intlBoundFunc = JSHandle<JSIntlBoundFunction>::Cast(NewJSObject(hclass));
2117     intlBoundFunc->SetNumberFormat(thread_, JSTaggedValue::Undefined());
2118     intlBoundFunc->SetDateTimeFormat(thread_, JSTaggedValue::Undefined());
2119     intlBoundFunc->SetCollator(thread_, JSTaggedValue::Undefined());
2120     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(intlBoundFunc);
2121     JSFunction::InitializeJSFunction(thread_, function);
2122     function->SetMethod(thread_, vm_->GetMethodByIndex(idx));
2123     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(functionLength));
2124     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2125     JSHandle<JSTaggedValue> emptyString = globalConst->GetHandledEmptyString();
2126     JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
2127     PropertyDescriptor nameDesc(thread_, emptyString, false, false, true);
2128     JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>::Cast(function), nameKey, nameDesc);
2129     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSIntlBoundFunction, thread_);
2130     return intlBoundFunc;
2131 }
2132 
NewJSProxyRevocFunction(const JSHandle<JSProxy> &proxy)2133 JSHandle<JSProxyRevocFunction> ObjectFactory::NewJSProxyRevocFunction(const JSHandle<JSProxy> &proxy)
2134 {
2135     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2136     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2137     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetProxyRevocFunctionClass());
2138 
2139     JSHandle<JSProxyRevocFunction> revocFunction = JSHandle<JSProxyRevocFunction>::Cast(NewJSObject(hclass));
2140     revocFunction->SetRevocableProxy(thread_, JSTaggedValue::Undefined());
2141     revocFunction->SetRevocableProxy(thread_, proxy);
2142     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(revocFunction);
2143     JSFunction::InitializeJSFunction(thread_, function);
2144     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROXY_INVALIDATE_PROXY_FUNCTION));
2145     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(0));
2146     JSHandle<JSTaggedValue> emptyString = globalConst->GetHandledEmptyString();
2147     JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
2148     PropertyDescriptor nameDesc(thread_, emptyString, false, false, true);
2149     JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>::Cast(function), nameKey, nameDesc);
2150     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSProxyRevocFunction, thread_);
2151     return revocFunction;
2152 }
2153 
NewJSAsyncAwaitStatusFunction(MethodIndex idx)2154 JSHandle<JSAsyncAwaitStatusFunction> ObjectFactory::NewJSAsyncAwaitStatusFunction(MethodIndex idx)
2155 {
2156     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2157     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetAsyncAwaitStatusFunctionClass());
2158 
2159     JSHandle<JSAsyncAwaitStatusFunction> awaitFunction =
2160         JSHandle<JSAsyncAwaitStatusFunction>::Cast(NewJSObject(hclass));
2161     awaitFunction->SetAsyncContext(thread_, JSTaggedValue::Undefined());
2162     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(awaitFunction));
2163     awaitFunction->SetMethod(thread_, vm_->GetMethodByIndex(idx));
2164     return awaitFunction;
2165 }
2166 
NewJSGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)2167 JSHandle<JSGeneratorObject> ObjectFactory::NewJSGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)
2168 {
2169     JSHandle<JSTaggedValue> proto(thread_, JSHandle<JSFunction>::Cast(generatorFunction)->GetProtoOrHClass());
2170     if (!proto->IsECMAObject()) {
2171         JSHandle<GlobalEnv> realmHandle = JSObject::GetFunctionRealm(thread_, generatorFunction);
2172         RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSGeneratorObject, thread_);
2173         proto = realmHandle->GetGeneratorPrototype();
2174     }
2175     JSHandle<JSHClass> hclass = NewEcmaHClass(JSGeneratorObject::SIZE, JSType::JS_GENERATOR_OBJECT, proto);
2176     JSHandle<JSGeneratorObject> generatorObject = JSHandle<JSGeneratorObject>::Cast(NewJSObjectWithInit(hclass));
2177     generatorObject->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
2178     generatorObject->SetResumeResult(thread_, JSTaggedValue::Undefined());
2179     return generatorObject;
2180 }
2181 
NewJSAsyncGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)2182 JSHandle<JSAsyncGeneratorObject> ObjectFactory::NewJSAsyncGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)
2183 {
2184     JSHandle<JSTaggedValue> proto(thread_, JSHandle<JSFunction>::Cast(generatorFunction)->GetProtoOrHClass());
2185     if (!proto->IsECMAObject()) {
2186         JSHandle<GlobalEnv> realmHandle = JSObject::GetFunctionRealm(thread_, generatorFunction);
2187         RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSAsyncGeneratorObject, thread_);
2188         proto = realmHandle->GetAsyncGeneratorPrototype();
2189     }
2190     JSHandle<JSHClass> hclass = NewEcmaHClass(JSAsyncGeneratorObject::SIZE,
2191                                               JSType::JS_ASYNC_GENERATOR_OBJECT, proto);
2192     JSHandle<JSAsyncGeneratorObject> generatorObject =
2193         JSHandle<JSAsyncGeneratorObject>::Cast(NewJSObjectWithInit(hclass));
2194     return generatorObject;
2195 }
2196 
NewJSAsyncFuncObject()2197 JSHandle<JSAsyncFuncObject> ObjectFactory::NewJSAsyncFuncObject()
2198 {
2199     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2200     JSHandle<JSTaggedValue> proto = env->GetInitialGenerator();
2201     JSHandle<JSHClass> hclass = NewEcmaHClass(JSAsyncFuncObject::SIZE, JSType::JS_ASYNC_FUNC_OBJECT, proto);
2202     JSHandle<JSAsyncFuncObject> asyncFuncObject = JSHandle<JSAsyncFuncObject>::Cast(NewJSObjectWithInit(hclass));
2203     return asyncFuncObject;
2204 }
2205 
NewCompletionRecord(CompletionRecordType type, JSHandle<JSTaggedValue> value)2206 JSHandle<CompletionRecord> ObjectFactory::NewCompletionRecord(CompletionRecordType type, JSHandle<JSTaggedValue> value)
2207 {
2208     NewObjectHook();
2209     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2210         JSHClass::Cast(thread_->GlobalConstants()->GetCompletionRecordClass().GetTaggedObject()));
2211     JSHandle<CompletionRecord> obj(thread_, header);
2212     obj->SetType(type);
2213     obj->SetValue(thread_, value);
2214     return obj;
2215 }
2216 
NewGeneratorContext()2217 JSHandle<GeneratorContext> ObjectFactory::NewGeneratorContext()
2218 {
2219     NewObjectHook();
2220     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2221         JSHClass::Cast(thread_->GlobalConstants()->GetGeneratorContextClass().GetTaggedObject()));
2222     JSHandle<GeneratorContext> obj(thread_, header);
2223     obj->SetRegsArray(thread_, JSTaggedValue::Undefined());
2224     obj->SetMethod(thread_, JSTaggedValue::Undefined());
2225     obj->SetThis(thread_, JSTaggedValue::Undefined());
2226     obj->SetAcc(thread_, JSTaggedValue::Undefined());
2227     obj->SetGeneratorObject(thread_, JSTaggedValue::Undefined());
2228     obj->SetLexicalEnv(thread_, JSTaggedValue::Undefined());
2229     obj->SetNRegs(0);
2230     obj->SetBCOffset(0);
2231     return obj;
2232 }
2233 
NewJSPrimitiveRef(const JSHandle<JSFunction> &function, const JSHandle<JSTaggedValue> &object)2234 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(const JSHandle<JSFunction> &function,
2235                                                           const JSHandle<JSTaggedValue> &object)
2236 {
2237     JSHandle<JSPrimitiveRef> obj(NewJSObjectByConstructor(function));
2238     obj->SetValue(thread_, object);
2239 
2240     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2241     if (function.GetTaggedValue() == env->GetStringFunction().GetTaggedValue()) {
2242         JSHandle<JSTaggedValue> lengthStr = thread_->GlobalConstants()->GetHandledLengthString();
2243         uint32_t length = EcmaStringAccessor(object.GetTaggedValue()).GetLength();
2244         PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>(thread_, JSTaggedValue(length)), false, false, false);
2245         JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>(obj), lengthStr, desc);
2246         RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSPrimitiveRef, thread_);
2247     }
2248 
2249     return obj;
2250 }
2251 
NewJSPrimitiveRef(PrimitiveType type, const JSHandle<JSTaggedValue> &object)2252 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(PrimitiveType type, const JSHandle<JSTaggedValue> &object)
2253 {
2254     ObjectFactory *factory = vm_->GetFactory();
2255     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2256     JSHandle<JSTaggedValue> function;
2257     switch (type) {
2258         case PrimitiveType::PRIMITIVE_NUMBER:
2259             function = env->GetNumberFunction();
2260             break;
2261         case PrimitiveType::PRIMITIVE_STRING:
2262             function = env->GetStringFunction();
2263             break;
2264         case PrimitiveType::PRIMITIVE_SYMBOL:
2265             function = env->GetSymbolFunction();
2266             break;
2267         case PrimitiveType::PRIMITIVE_BOOLEAN:
2268             function = env->GetBooleanFunction();
2269             break;
2270         case PrimitiveType::PRIMITIVE_BIGINT:
2271             function = env->GetBigIntFunction();
2272             break;
2273         default:
2274             break;
2275     }
2276     JSHandle<JSFunction> funcHandle(function);
2277     return factory->NewJSPrimitiveRef(funcHandle, object);
2278 }
2279 
NewJSString(const JSHandle<JSTaggedValue> &str, const JSHandle<JSTaggedValue> &newTarget)2280 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSString(const JSHandle<JSTaggedValue> &str,
2281                                                     const JSHandle<JSTaggedValue> &newTarget)
2282 {
2283     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2284     JSHandle<JSFunction> stringFunc(env->GetStringFunction());
2285     JSHandle<JSPrimitiveRef> obj;
2286     if (newTarget->IsUndefined()) {
2287         obj = JSHandle<JSPrimitiveRef>::Cast(NewJSObjectByConstructor(stringFunc));
2288     } else {
2289         JSHandle<JSObject> newObject = NewJSObjectByConstructor(stringFunc, newTarget);
2290         RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSPrimitiveRef, thread_);
2291         obj = JSHandle<JSPrimitiveRef>::Cast(newObject);
2292     }
2293     obj->SetValue(thread_, str);
2294     return obj;
2295 }
2296 
NewGlobalEnv(JSHClass *globalEnvClass)2297 JSHandle<GlobalEnv> ObjectFactory::NewGlobalEnv(JSHClass *globalEnvClass)
2298 {
2299     NewObjectHook();
2300     // Note: Global env must be allocated in non-movable heap, since its getters will directly return
2301     //       the offsets of the properties as the address of Handles.
2302     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(globalEnvClass);
2303     InitObjectFields(header);
2304     return JSHandle<GlobalEnv>(thread_, GlobalEnv::Cast(header));
2305 }
2306 
NewLexicalEnv(int numSlots)2307 JSHandle<LexicalEnv> ObjectFactory::NewLexicalEnv(int numSlots)
2308 {
2309     NewObjectHook();
2310     size_t size = LexicalEnv::ComputeSize(numSlots);
2311     auto header = heap_->AllocateYoungOrHugeObject(
2312         JSHClass::Cast(thread_->GlobalConstants()->GetEnvClass().GetTaggedObject()), size);
2313     JSHandle<LexicalEnv> array(thread_, header);
2314     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), numSlots + LexicalEnv::RESERVED_ENV_LENGTH);
2315     return array;
2316 }
2317 
NewEmptySymbol()2318 JSHandle<JSSymbol> ObjectFactory::NewEmptySymbol()
2319 {
2320     NewObjectHook();
2321     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(
2322         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
2323     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
2324     obj->SetDescription(thread_, JSTaggedValue::Undefined());
2325     obj->SetFlags(0);
2326     obj->SetHashField(0);
2327     return obj;
2328 }
2329 
NewJSSymbol()2330 JSHandle<JSSymbol> ObjectFactory::NewJSSymbol()
2331 {
2332     NewObjectHook();
2333     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2334         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
2335     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
2336     obj->SetDescription(thread_, JSTaggedValue::Undefined());
2337     obj->SetFlags(0);
2338     obj->SetHashField(SymbolTable::Hash(obj.GetTaggedValue()));
2339     return obj;
2340 }
2341 
NewPrivateSymbol()2342 JSHandle<JSSymbol> ObjectFactory::NewPrivateSymbol()
2343 {
2344     JSHandle<JSSymbol> obj = NewJSSymbol();
2345     obj->SetPrivate();
2346     return obj;
2347 }
2348 
NewPrivateNameSymbol(const JSHandle<JSTaggedValue> &name)2349 JSHandle<JSSymbol> ObjectFactory::NewPrivateNameSymbol(const JSHandle<JSTaggedValue> &name)
2350 {
2351     NewObjectHook();
2352     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2353         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
2354     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
2355     obj->SetFlags(0);
2356     obj->SetPrivateNameSymbol();
2357     obj->SetDescription(thread_, name);
2358     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
2359     return obj;
2360 }
2361 
NewWellKnownSymbol(const JSHandle<JSTaggedValue> &name)2362 JSHandle<JSSymbol> ObjectFactory::NewWellKnownSymbol(const JSHandle<JSTaggedValue> &name)
2363 {
2364     NewObjectHook();
2365     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2366         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
2367     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
2368     obj->SetFlags(0);
2369     obj->SetWellKnownSymbol();
2370     obj->SetDescription(thread_, name);
2371     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
2372     return obj;
2373 }
2374 
NewPublicSymbol(const JSHandle<JSTaggedValue> &name)2375 JSHandle<JSSymbol> ObjectFactory::NewPublicSymbol(const JSHandle<JSTaggedValue> &name)
2376 {
2377     NewObjectHook();
2378     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2379         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
2380     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
2381     obj->SetFlags(0);
2382     obj->SetDescription(thread_, name);
2383     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
2384     return obj;
2385 }
2386 
NewSymbolWithTable(const JSHandle<JSTaggedValue> &name)2387 JSHandle<JSSymbol> ObjectFactory::NewSymbolWithTable(const JSHandle<JSTaggedValue> &name)
2388 {
2389     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2390     JSHandle<SymbolTable> tableHandle(env->GetRegisterSymbols());
2391     if (tableHandle->ContainsKey(name.GetTaggedValue())) {
2392         JSTaggedValue objValue = tableHandle->GetSymbol(name.GetTaggedValue());
2393         return JSHandle<JSSymbol>(thread_, objValue);
2394     }
2395 
2396     JSHandle<JSSymbol> obj = NewPublicSymbol(name);
2397     JSHandle<JSTaggedValue> valueHandle(obj);
2398     JSHandle<JSTaggedValue> keyHandle(name);
2399     JSHandle<SymbolTable> table = SymbolTable::Insert(thread_, tableHandle, keyHandle, valueHandle);
2400     env->SetRegisterSymbols(thread_, table);
2401     return obj;
2402 }
2403 
NewPrivateNameSymbolWithChar(std::string_view description)2404 JSHandle<JSSymbol> ObjectFactory::NewPrivateNameSymbolWithChar(std::string_view description)
2405 {
2406     JSHandle<EcmaString> string = NewFromUtf8(description);
2407     return NewPrivateNameSymbol(JSHandle<JSTaggedValue>(string));
2408 }
2409 
NewWellKnownSymbolWithChar(std::string_view description)2410 JSHandle<JSSymbol> ObjectFactory::NewWellKnownSymbolWithChar(std::string_view description)
2411 {
2412     JSHandle<EcmaString> string = NewFromUtf8(description);
2413     return NewWellKnownSymbol(JSHandle<JSTaggedValue>(string));
2414 }
2415 
NewPublicSymbolWithChar(std::string_view description)2416 JSHandle<JSSymbol> ObjectFactory::NewPublicSymbolWithChar(std::string_view description)
2417 {
2418     JSHandle<EcmaString> string = NewFromUtf8(description);
2419     return NewPublicSymbol(JSHandle<JSTaggedValue>(string));
2420 }
2421 
NewSymbolWithTableWithChar(std::string_view description)2422 JSHandle<JSSymbol> ObjectFactory::NewSymbolWithTableWithChar(std::string_view description)
2423 {
2424     JSHandle<EcmaString> string = NewFromUtf8(description);
2425     return NewSymbolWithTable(JSHandle<JSTaggedValue>(string));
2426 }
2427 
NewAccessorData()2428 JSHandle<AccessorData> ObjectFactory::NewAccessorData()
2429 {
2430     NewObjectHook();
2431     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2432         JSHClass::Cast(thread_->GlobalConstants()->GetAccessorDataClass().GetTaggedObject()));
2433     JSHandle<AccessorData> acc(thread_, AccessorData::Cast(header));
2434     acc->SetGetter(thread_, JSTaggedValue::Undefined());
2435     acc->SetSetter(thread_, JSTaggedValue::Undefined());
2436     return acc;
2437 }
2438 
NewInternalAccessor(void *setter, void *getter)2439 JSHandle<AccessorData> ObjectFactory::NewInternalAccessor(void *setter, void *getter)
2440 {
2441     NewObjectHook();
2442     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(
2443         JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject()));
2444     JSHandle<InternalAccessor> obj(thread_, InternalAccessor::Cast(header));
2445 
2446     obj->SetSetter(reinterpret_cast<InternalAccessor::InternalSetFunc>(setter));
2447     obj->SetGetter(reinterpret_cast<InternalAccessor::InternalGetFunc>(getter));
2448     return JSHandle<AccessorData>::Cast(obj);
2449 }
2450 
NewPromiseCapability()2451 JSHandle<PromiseCapability> ObjectFactory::NewPromiseCapability()
2452 {
2453     NewObjectHook();
2454     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2455         JSHClass::Cast(thread_->GlobalConstants()->GetCapabilityRecordClass().GetTaggedObject()));
2456     JSHandle<PromiseCapability> obj(thread_, header);
2457     obj->SetPromise(thread_, JSTaggedValue::Undefined());
2458     obj->SetResolve(thread_, JSTaggedValue::Undefined());
2459     obj->SetReject(thread_, JSTaggedValue::Undefined());
2460     return obj;
2461 }
2462 
NewPromiseReaction()2463 JSHandle<PromiseReaction> ObjectFactory::NewPromiseReaction()
2464 {
2465     NewObjectHook();
2466     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2467         JSHClass::Cast(thread_->GlobalConstants()->GetReactionsRecordClass().GetTaggedObject()));
2468     JSHandle<PromiseReaction> obj(thread_, header);
2469     obj->SetPromiseCapability(thread_, JSTaggedValue::Undefined());
2470     obj->SetHandler(thread_, JSTaggedValue::Undefined());
2471     obj->SetType(PromiseType::RESOLVE);
2472     return obj;
2473 }
2474 
NewPromiseIteratorRecord(const JSHandle<JSTaggedValue> &itor, bool done)2475 JSHandle<PromiseIteratorRecord> ObjectFactory::NewPromiseIteratorRecord(const JSHandle<JSTaggedValue> &itor, bool done)
2476 {
2477     NewObjectHook();
2478     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2479         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseIteratorRecordClass().GetTaggedObject()));
2480     JSHandle<PromiseIteratorRecord> obj(thread_, header);
2481     obj->SetIterator(thread_, itor.GetTaggedValue());
2482     obj->SetDone(done);
2483     return obj;
2484 }
2485 
NewMicroJobQueue()2486 JSHandle<job::MicroJobQueue> ObjectFactory::NewMicroJobQueue()
2487 {
2488     NewObjectHook();
2489     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(
2490         JSHClass::Cast(thread_->GlobalConstants()->GetMicroJobQueueClass().GetTaggedObject()));
2491     JSHandle<job::MicroJobQueue> obj(thread_, header);
2492     obj->SetPromiseJobQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue());
2493     obj->SetScriptJobQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue());
2494     return obj;
2495 }
2496 
NewPendingJob(const JSHandle<JSFunction> &func, const JSHandle<TaggedArray> &argv)2497 JSHandle<job::PendingJob> ObjectFactory::NewPendingJob(const JSHandle<JSFunction> &func,
2498                                                        const JSHandle<TaggedArray> &argv)
2499 {
2500     NewObjectHook();
2501     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2502         JSHClass::Cast(thread_->GlobalConstants()->GetPendingJobClass().GetTaggedObject()));
2503     JSHandle<job::PendingJob> obj(thread_, header);
2504     obj->SetJob(thread_, func.GetTaggedValue());
2505     obj->SetArguments(thread_, argv.GetTaggedValue());
2506 #if defined(ENABLE_HITRACE)
2507     obj->SetChainId(0);
2508     obj->SetSpanId(0);
2509     obj->SetParentSpanId(0);
2510     obj->SetFlags(0);
2511     obj->SetJobId(0);
2512 #endif
2513     return obj;
2514 }
2515 
NewJSProxy(const JSHandle<JSTaggedValue> &target, const JSHandle<JSTaggedValue> &handler)2516 JSHandle<JSProxy> ObjectFactory::NewJSProxy(const JSHandle<JSTaggedValue> &target,
2517                                             const JSHandle<JSTaggedValue> &handler)
2518 {
2519     NewObjectHook();
2520     TaggedObject *header = nullptr;
2521     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2522     JSHandle<JSObject> emptyObject = OrdinaryNewJSObjectCreate(vm_->GetGlobalEnv()->GetObjectFunctionPrototype());
2523 
2524     if (target->IsCallable()) {
2525         auto jsProxyCallableClass = JSHClass::Cast(globalConst->GetJSProxyCallableClass().GetTaggedObject());
2526         auto jsProxyConstructClass = JSHClass::Cast(globalConst->GetJSProxyConstructClass().GetTaggedObject());
2527         header = target->IsConstructor() ? heap_->AllocateYoungOrHugeObject(jsProxyConstructClass)
2528                                          : heap_->AllocateYoungOrHugeObject(jsProxyCallableClass);
2529     } else {
2530         header = heap_->AllocateYoungOrHugeObject(
2531             JSHClass::Cast(thread_->GlobalConstants()->GetJSProxyOrdinaryClass().GetTaggedObject()));
2532     }
2533 
2534     JSHandle<JSProxy> proxy(thread_, header);
2535     proxy->InitializeHash();
2536     proxy->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_GLOBAL_CALL_JS_PROXY));
2537     proxy->SetTarget(thread_, target.GetTaggedValue());
2538     proxy->SetHandler(thread_, handler.GetTaggedValue());
2539     proxy->SetPrivateField(thread_, emptyObject.GetTaggedValue());
2540     proxy->SetIsRevoked(false);
2541     return proxy;
2542 }
2543 
NewJSRealm()2544 JSHandle<JSRealm> ObjectFactory::NewJSRealm()
2545 {
2546     JSHandle<JSHClass> hClassHandle = NewEcmaHClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS);
2547     JSHClass *hclass = reinterpret_cast<JSHClass *>(hClassHandle.GetTaggedValue().GetTaggedObject());
2548     hclass->SetClass(thread_, hclass);
2549     JSHandle<JSHClass> realmEnvClass = NewEcmaHClass(*hClassHandle, GlobalEnv::SIZE, JSType::GLOBAL_ENV);
2550     JSHandle<GlobalEnv> realmEnvHandle = NewGlobalEnv(*realmEnvClass);
2551 
2552     auto result = TemplateMap::Create(thread_);
2553     realmEnvHandle->SetTemplateMap(thread_, result);
2554     realmEnvHandle->SetJSThread(thread_);
2555     Builtins builtins;
2556     builtins.Initialize(realmEnvHandle, thread_, false, true);
2557     JSHandle<JSTaggedValue> protoValue = thread_->GlobalConstants()->GetHandledJSRealmClass();
2558     JSHandle<JSHClass> hclassHandle = NewEcmaHClass(JSRealm::SIZE, JSType::JS_REALM, protoValue);
2559     JSHandle<JSRealm> realm(NewJSObject(hclassHandle));
2560     realm->SetGlobalEnv(thread_, realmEnvHandle.GetTaggedValue());
2561     realm->SetValue(thread_, JSTaggedValue::Undefined());
2562 
2563     JSHandle<JSTaggedValue> realmObj = realmEnvHandle->GetJSGlobalObject();
2564     JSHandle<JSTaggedValue> realmkey(thread_->GlobalConstants()->GetHandledGlobalString());
2565     PropertyDescriptor realmDesc(thread_, JSHandle<JSTaggedValue>::Cast(realmObj), true, false, true);
2566     [[maybe_unused]] bool status =
2567         JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(realm), realmkey, realmDesc);
2568     ASSERT_PRINT(status == true, "Realm defineOwnProperty failed");
2569 
2570     return realm;
2571 }
2572 
NewTaggedArray(uint32_t length, JSTaggedValue initVal, bool nonMovable)2573 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal, bool nonMovable)
2574 {
2575     if (nonMovable) {
2576         return NewTaggedArray(length, initVal, MemSpaceType::NON_MOVABLE);
2577     }
2578     return NewTaggedArray(length, initVal, MemSpaceType::SEMI_SPACE);
2579 }
2580 
NewTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType)2581 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType)
2582 {
2583     NewObjectHook();
2584     if (length == 0) {
2585         return EmptyArray();
2586     }
2587 
2588     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2589     TaggedObject *header = nullptr;
2590     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2591     switch (spaceType) {
2592         case MemSpaceType::SEMI_SPACE:
2593             header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
2594             break;
2595         case MemSpaceType::OLD_SPACE:
2596             header = heap_->AllocateOldOrHugeObject(arrayClass, size);
2597             break;
2598         case MemSpaceType::NON_MOVABLE:
2599             header = heap_->AllocateNonMovableOrHugeObject(arrayClass, size);
2600             break;
2601         case MemSpaceType::SHARED_OLD_SPACE:
2602             header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
2603             break;
2604         case MemSpaceType::SHARED_NON_MOVABLE:
2605             header = sHeap_->AllocateNonMovableOrHugeObject(thread_, arrayClass, size);
2606             break;
2607         default:
2608             LOG_ECMA(FATAL) << "this branch is unreachable";
2609             UNREACHABLE();
2610     }
2611 
2612     JSHandle<TaggedArray> array(thread_, header);
2613     array->InitializeWithSpecialValue(initVal, length);
2614     return array;
2615 }
2616 
NewAndCopyTaggedArray(JSHandle<TaggedArray> &srcElements, uint32_t newLength, uint32_t oldLength, uint32_t k)2617 JSHandle<TaggedArray> ObjectFactory::NewAndCopyTaggedArray(JSHandle<TaggedArray> &srcElements, uint32_t newLength,
2618                                                            uint32_t oldLength, uint32_t k)
2619 {
2620     ASSERT(oldLength <= newLength);
2621     MemSpaceType spaceType = newLength < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
2622     JSHandle<TaggedArray> dstElements = NewTaggedArrayWithoutInit(newLength, spaceType);
2623     dstElements->SetExtraLength(srcElements->GetExtraLength());
2624     if (newLength == 0) {
2625         return dstElements;
2626     }
2627     dstElements->Copy(thread_, 0, k, srcElements.GetObject<TaggedArray>(), oldLength);
2628     for (uint32_t i = oldLength; i < newLength; i++) {
2629         dstElements->Set(thread_, i, JSTaggedValue::Hole());
2630     }
2631     return dstElements;
2632 }
2633 
NewAndCopyTaggedArraySkipBarrier(JSHandle<TaggedArray> &srcElements, uint32_t newLength, uint32_t oldLength, uint32_t k)2634 JSHandle<TaggedArray> ObjectFactory::NewAndCopyTaggedArraySkipBarrier(JSHandle<TaggedArray> &srcElements,
2635     uint32_t newLength, uint32_t oldLength, uint32_t k)
2636 {
2637     ASSERT(oldLength <= newLength);
2638     MemSpaceType spaceType = newLength < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
2639     JSHandle<TaggedArray> dstElements = NewTaggedArrayWithoutInit(newLength, spaceType);
2640     if (newLength == 0) {
2641         return dstElements;
2642     }
2643     dstElements->Copy<false>(thread_, 0, k, srcElements.GetObject<TaggedArray>(), oldLength);
2644     for (uint32_t i = oldLength; i < newLength; i++) {
2645         dstElements->Set(thread_, i, JSTaggedValue::Hole());
2646     }
2647     return dstElements;
2648 }
2649 
NewAndCopySNameDictionary(JSHandle<TaggedArray> &srcElements, uint32_t length)2650 JSHandle<TaggedArray> ObjectFactory::NewAndCopySNameDictionary(JSHandle<TaggedArray> &srcElements, uint32_t length)
2651 {
2652     JSHandle<TaggedArray> dstElements = NewSDictionaryArray(length);
2653     if (length == 0) {
2654         return dstElements;
2655     }
2656     for (uint32_t i = 0; i < length; i++) {
2657         dstElements->Set(thread_, i, srcElements->Get(i));
2658     }
2659     return dstElements;
2660 }
2661 
NewAndCopyJSArrayObject(JSHandle<JSObject> thisObjHandle, uint32_t newLength, uint32_t oldLength, uint32_t k)2662 JSHandle<JSObject> ObjectFactory::NewAndCopyJSArrayObject(JSHandle<JSObject> thisObjHandle, uint32_t newLength,
2663                                                           uint32_t oldLength, uint32_t k)
2664 {
2665     ASSERT(oldLength <= newLength);
2666     JSHandle<TaggedArray> dstElements(NewTaggedArray(newLength));
2667     JSHandle<JSTaggedValue> holeHandle(thread_, JSTaggedValue::Hole());
2668     JSHandle<JSObject> arrayObj = JSHandle<JSObject>(NewJSStableArrayWithElements(dstElements));
2669     if (newLength == 0) {
2670         return JSHandle<JSObject>(arrayObj);
2671     }
2672     for (uint32_t i = 0; i < oldLength; i++) {
2673         JSHandle<JSTaggedValue> value(thread_, ElementAccessor::Get(thisObjHandle, i + k));
2674         ElementAccessor::Set(thread_, arrayObj, i, value, true);
2675     }
2676     for (uint32_t i = oldLength; i < newLength; i++) {
2677         ElementAccessor::Set(thread_, arrayObj, i, holeHandle, true);
2678     }
2679     return arrayObj;
2680 }
2681 
NewAndCopyTaggedArrayByObject(JSHandle<JSObject> thisObjHandle, uint32_t newLength, uint32_t oldLength, uint32_t k)2682 JSHandle<TaggedArray> ObjectFactory::NewAndCopyTaggedArrayByObject(JSHandle<JSObject> thisObjHandle, uint32_t newLength,
2683                                                                    uint32_t oldLength, uint32_t k)
2684 {
2685     ASSERT(oldLength <= newLength);
2686     MemSpaceType spaceType = newLength < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
2687     JSHandle<TaggedArray> dstElements(NewTaggedArrayWithoutInit(newLength, spaceType));
2688     TaggedArray *srcElements = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
2689     dstElements->SetExtraLength(srcElements->GetExtraLength());
2690     if (newLength == 0) {
2691         return dstElements;
2692     }
2693 
2694     for (uint32_t i = 0; i < oldLength; i++) {
2695         dstElements->Set(thread_, i, ElementAccessor::Get(thisObjHandle, i + k));
2696     }
2697     for (uint32_t i = oldLength; i < newLength; i++) {
2698         dstElements->Set(thread_, i, JSTaggedValue::Hole());
2699     }
2700     return dstElements;
2701 }
2702 
NewAndCopyMutantTaggedArrayByObject(JSHandle<JSObject> thisObjHandle, uint32_t newLength, uint32_t oldLength, uint32_t k)2703 JSHandle<MutantTaggedArray> ObjectFactory::NewAndCopyMutantTaggedArrayByObject(JSHandle<JSObject> thisObjHandle,
2704                                                                                uint32_t newLength, uint32_t oldLength,
2705                                                                                uint32_t k)
2706 {
2707     ASSERT(oldLength <= newLength);
2708     MemSpaceType spaceType = newLength < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
2709     JSHandle<MutantTaggedArray> dstElements(NewMutantTaggedArrayWithoutInit(newLength, spaceType));
2710     MutantTaggedArray *srcElements = MutantTaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
2711     dstElements->SetExtraLength(srcElements->GetExtraLength());
2712     if (newLength == 0) {
2713         return dstElements;
2714     }
2715     for (uint32_t i = 0; i < oldLength; i++) {
2716         ElementsKind kind = thisObjHandle->GetClass()->GetElementsKind();
2717         JSTaggedValue value = JSTaggedValue(ElementAccessor::ConvertTaggedValueWithElementsKind(
2718             ElementAccessor::Get(thisObjHandle, i + k), kind));
2719         dstElements->Set<false>(thread_, i, value);
2720     }
2721     for (uint32_t i = oldLength; i < newLength; i++) {
2722         ElementsKind kind = thisObjHandle->GetClass()->GetElementsKind();
2723         JSTaggedValue value = JSTaggedValue(ElementAccessor::ConvertTaggedValueWithElementsKind(JSTaggedValue::Hole(),
2724                                                                                                 kind));
2725         dstElements->Set<false>(thread_, i, value);
2726     }
2727     return dstElements;
2728 }
2729 
2730 // private
NewTaggedArrayWithoutInit(uint32_t length, MemSpaceType spaceType)2731 JSHandle<TaggedArray> ObjectFactory::NewTaggedArrayWithoutInit(uint32_t length, MemSpaceType spaceType)
2732 {
2733     NewObjectHook();
2734     if (length == 0) {
2735         return EmptyArray();
2736     }
2737 
2738     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2739     TaggedObject *header = nullptr;
2740     auto arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2741     switch (spaceType) {
2742         case MemSpaceType::SEMI_SPACE:
2743             header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
2744             break;
2745         case MemSpaceType::OLD_SPACE:
2746             header = heap_->AllocateOldOrHugeObject(arrayClass, size);
2747             break;
2748         case MemSpaceType::SHARED_OLD_SPACE:
2749             header = sHeap_->AllocateOldOrHugeObject(thread_, arrayClass, size);
2750             break;
2751         default:
2752             LOG_ECMA(FATAL) << "this branch is unreachable";
2753             UNREACHABLE();
2754     }
2755     JSHandle<TaggedArray> array(thread_, header);
2756     array->SetLength(length);
2757     return array;
2758 }
2759 
2760 // private
NewMutantTaggedArrayWithoutInit(uint32_t length, MemSpaceType spaceType)2761 JSHandle<MutantTaggedArray> ObjectFactory::NewMutantTaggedArrayWithoutInit(uint32_t length, MemSpaceType spaceType)
2762 {
2763     NewObjectHook();
2764     if (length == 0) {
2765         return EmptyMutantArray();
2766     }
2767 
2768     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2769     TaggedObject *header = nullptr;
2770     auto arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetMutantTaggedArrayClass().GetTaggedObject());
2771     switch (spaceType) {
2772         case MemSpaceType::SEMI_SPACE:
2773             header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
2774             break;
2775         case MemSpaceType::OLD_SPACE:
2776             header = heap_->AllocateOldOrHugeObject(arrayClass, size);
2777             break;
2778         default:
2779             LOG_ECMA(FATAL) << "this branch is unreachable";
2780             UNREACHABLE();
2781     }
2782     JSHandle<MutantTaggedArray> array(thread_, header);
2783     array->SetLength(length);
2784     return array;
2785 }
2786 
NewTaggedArray(uint32_t length, JSTaggedValue initVal)2787 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal)
2788 {
2789     NewObjectHook();
2790     if (length == 0) {
2791         return EmptyArray();
2792     }
2793     MemSpaceType spaceType = length < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
2794     JSHandle<TaggedArray> array = NewTaggedArrayWithoutInit(length, spaceType);
2795     array->InitializeWithSpecialValue(initVal, length);
2796     return array;
2797 }
2798 
NewCOWTaggedArray(uint32_t length, JSTaggedValue initVal)2799 JSHandle<COWTaggedArray> ObjectFactory::NewCOWTaggedArray(uint32_t length, JSTaggedValue initVal)
2800 {
2801     NewObjectHook();
2802     ASSERT(length > 0);
2803 
2804     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2805     auto header = heap_->AllocateNonMovableOrHugeObject(
2806         JSHClass::Cast(thread_->GlobalConstants()->GetCOWArrayClass().GetTaggedObject()), size);
2807     JSHandle<COWTaggedArray> cowArray(thread_, header);
2808     cowArray->InitializeWithSpecialValue(initVal, length);
2809     return cowArray;
2810 }
2811 
NewCOWMutantTaggedArray(uint32_t length, JSTaggedType initVal)2812 JSHandle<COWMutantTaggedArray> ObjectFactory::NewCOWMutantTaggedArray(uint32_t length, JSTaggedType initVal)
2813 {
2814     NewObjectHook();
2815     ASSERT(length > 0);
2816 
2817     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2818     auto header = heap_->AllocateNonMovableOrHugeObject(
2819         JSHClass::Cast(thread_->GlobalConstants()->GetCOWMutantTaggedArrayClass().GetTaggedObject()), size);
2820     JSHandle<COWMutantTaggedArray> cowMutantTaggedArray(thread_, header);
2821     cowMutantTaggedArray->InitializeWithSpecialValue(initVal, length);
2822     return cowMutantTaggedArray;
2823 }
2824 
NewMutantTaggedArray(uint32_t length, JSTaggedType initVal)2825 JSHandle<MutantTaggedArray> ObjectFactory::NewMutantTaggedArray(uint32_t length, JSTaggedType initVal)
2826 {
2827     NewObjectHook();
2828     ASSERT(length > 0);
2829 
2830     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2831     auto header = heap_->AllocateYoungOrHugeObject(
2832         JSHClass::Cast(thread_->GlobalConstants()->GetMutantTaggedArrayClass().GetTaggedObject()), size);
2833     JSHandle<MutantTaggedArray> mutantTaggedArray(thread_, header);
2834     mutantTaggedArray->InitializeWithSpecialValue(initVal, length);
2835     return mutantTaggedArray;
2836 }
2837 
NewTaggedHashArray(uint32_t length)2838 JSHandle<TaggedHashArray> ObjectFactory::NewTaggedHashArray(uint32_t length)
2839 {
2840     if (length == 0) {
2841         return JSHandle<TaggedHashArray>::Cast(EmptyArray());
2842     }
2843 
2844     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2845     auto header = heap_->AllocateYoungOrHugeObject(
2846         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
2847     JSHandle<TaggedHashArray> array(thread_, header);
2848     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), length);
2849     return array;
2850 }
2851 
NewByteArray(uint32_t length, uint32_t size, void *srcData, MemSpaceType spaceType)2852 JSHandle<ByteArray> ObjectFactory::NewByteArray(uint32_t length, uint32_t size, void *srcData,
2853                                                 MemSpaceType spaceType)
2854 {
2855     size_t byteSize = ByteArray::ComputeSize(size, length);
2856     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetByteArrayClass().GetTaggedObject());
2857     TaggedObject *header = AllocObjectWithSpaceType(byteSize, arrayClass, spaceType);
2858     JSHandle<ByteArray> array(thread_, header);
2859 
2860     void *data = array->GetData();
2861 
2862     if (srcData != nullptr) {
2863         if (memcpy_s(data, length * size, srcData, length * size) != EOK) {
2864             LOG_FULL(FATAL) << "memcpy_s failed";
2865             UNREACHABLE();
2866         }
2867     } else {
2868         if (memset_s(data, length * size, 0, length * size) != EOK) {
2869             LOG_FULL(FATAL) << "memset_s failed";
2870             UNREACHABLE();
2871         }
2872     }
2873 
2874     array->SetArrayLength(length);
2875     array->SetByteLength(size);
2876     return array;
2877 }
2878 
NewLinkedNode(int hash, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value, const JSHandle<LinkedNode> &next)2879 JSHandle<LinkedNode> ObjectFactory::NewLinkedNode(int hash, const JSHandle<JSTaggedValue> &key,
2880                                                   const JSHandle<JSTaggedValue> &value,
2881                                                   const JSHandle<LinkedNode> &next)
2882 {
2883     NewObjectHook();
2884     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2885     auto header = heap_->AllocateYoungOrHugeObject(
2886         JSHClass::Cast(globalConst->GetLinkedNode().GetTaggedObject()), LinkedNode::SIZE);
2887     JSHandle<LinkedNode> node(thread_, header);
2888     node->InitLinkedNode(thread_, hash, key, value, next);
2889 
2890     return node;
2891 }
2892 
NewTreeNode(int hash, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value)2893 JSHandle<RBTreeNode> ObjectFactory::NewTreeNode(int hash, const JSHandle<JSTaggedValue> &key,
2894                                                 const JSHandle<JSTaggedValue> &value)
2895 {
2896     NewObjectHook();
2897     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2898     auto header = heap_->AllocateYoungOrHugeObject(
2899         JSHClass::Cast(globalConst->GetRBTreeNode().GetTaggedObject()), RBTreeNode::SIZE);
2900     JSHandle<RBTreeNode> treenode(thread_, header);
2901     treenode->InitRBTreeNode(thread_, hash, key, value, 1);
2902     return treenode;
2903 }
2904 
NewDictionaryArray(uint32_t length)2905 JSHandle<TaggedArray> ObjectFactory::NewDictionaryArray(uint32_t length)
2906 {
2907     NewObjectHook();
2908     ASSERT(length > 0);
2909 
2910     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2911     auto header = heap_->AllocateYoungOrHugeObject(
2912         JSHClass::Cast(thread_->GlobalConstants()->GetDictionaryClass().GetTaggedObject()), size);
2913     JSHandle<TaggedArray> array(thread_, header);
2914     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
2915 
2916     return array;
2917 }
2918 
ExtendArray(const JSHandle<TaggedArray> &old, uint32_t length, JSTaggedValue initVal, MemSpaceType type, [[maybe_unused]] ElementsKind kind)2919 JSHandle<TaggedArray> ObjectFactory::ExtendArray(const JSHandle<TaggedArray> &old, uint32_t length,
2920                                                  JSTaggedValue initVal, MemSpaceType type,
2921                                                  [[maybe_unused]] ElementsKind kind)
2922 {
2923     ASSERT(length >= old->GetLength());
2924     NewObjectHook();
2925     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2926     JSHClass *arrayClass = nullptr;
2927     // If old element is Mutantarray, need conversion according to kind.
2928     if (old->GetClass()->IsMutantTaggedArray()) {
2929         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetMutantTaggedArrayClass().GetTaggedObject());
2930     } else {
2931         arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2932     }
2933     TaggedObject *header = AllocObjectWithSpaceType(size, arrayClass, type);
2934     JSHandle<TaggedArray> newArray(thread_, header);
2935     newArray->SetLength(length);
2936     newArray->SetExtraLength(old->GetExtraLength());
2937 
2938     uint32_t oldLength = old->GetLength();
2939     uint32_t index = 0;
2940     auto isMutantTaggedArray = old->GetClass()->IsMutantTaggedArray();
2941     for (; index < oldLength; ++index) {
2942         if (isMutantTaggedArray) {
2943             newArray->Set<false>(thread_, index, old->Get(index));
2944         } else {
2945             newArray->Set(thread_, index, old->Get(index));
2946         }
2947     }
2948     auto isSpecialHole = initVal.IsHole() && isMutantTaggedArray;
2949     JSTaggedValue specialHole = JSTaggedValue(base::SPECIAL_HOLE);
2950     for (; index < length; ++index) {
2951         if (isSpecialHole) {
2952             newArray->Set<false>(thread_, index, specialHole);
2953         } else {
2954             newArray->Set(thread_, index, initVal);
2955         }
2956     }
2957 
2958     return newArray;
2959 }
2960 
CopyPartArray(const JSHandle<TaggedArray> &old, uint32_t start, uint32_t end)2961 JSHandle<TaggedArray> ObjectFactory::CopyPartArray(const JSHandle<TaggedArray> &old, uint32_t start,
2962                                                    uint32_t end)
2963 {
2964     ASSERT(start <= end);
2965     ASSERT(end <= old->GetLength());
2966 
2967     uint32_t newLength = end - start;
2968     if (newLength == 0) {
2969         return EmptyArray();
2970     }
2971 
2972     NewObjectHook();
2973     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
2974     auto header = heap_->AllocateYoungOrHugeObject(
2975         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
2976     JSHandle<TaggedArray> newArray(thread_, header);
2977     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
2978 
2979     for (uint32_t i = 0; i < newLength; i++) {
2980         JSTaggedValue value = old->Get(i + start);
2981         if (value.IsHole()) {
2982             break;
2983         }
2984         newArray->Set(thread_, i, value);
2985     }
2986     return newArray;
2987 }
2988 
CopyArray(const JSHandle<TaggedArray> &old, uint32_t oldLength, uint32_t newLength, JSTaggedValue initVal, MemSpaceType type, ElementsKind kind)2989 JSHandle<TaggedArray> ObjectFactory::CopyArray(const JSHandle<TaggedArray> &old, uint32_t oldLength, uint32_t newLength,
2990                                                JSTaggedValue initVal, MemSpaceType type, ElementsKind kind)
2991 {
2992     if (newLength == 0) {
2993         return EmptyArray();
2994     }
2995     if (newLength > oldLength) {
2996         return ExtendArray(old, newLength, initVal, type, kind);
2997     }
2998     NewObjectHook();
2999     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
3000     TaggedObject *header = nullptr;
3001     if (type == MemSpaceType::NON_MOVABLE) {
3002         // COW array is shared in nonmovable space.
3003         JSHClass *cowArrayClass = nullptr;
3004         if (old->GetClass()->IsMutantTaggedArray()) {
3005             cowArrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetCOWMutantTaggedArrayClass()
3006                                            .GetTaggedObject());
3007         } else {
3008             cowArrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetCOWArrayClass().GetTaggedObject());
3009         }
3010         header = AllocObjectWithSpaceType(size, cowArrayClass, type);
3011     } else {
3012         JSHClass *arrayClass = nullptr;
3013         if (old->GetClass()->IsMutantTaggedArray()) {
3014             arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetMutantTaggedArrayClass().GetTaggedObject());
3015         } else {
3016             arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
3017         }
3018         header = AllocObjectWithSpaceType(size, arrayClass, type);
3019     }
3020 
3021     JSHandle<TaggedArray> newArray(thread_, header);
3022     newArray->SetLength(newLength);
3023     newArray->SetExtraLength(old->GetExtraLength());
3024     if (old->GetClass()->IsMutantTaggedArray()) {
3025         newArray->Copy<false>(thread_, 0, 0, *old, newLength);
3026     } else {
3027         newArray->Copy(thread_, 0, 0, *old, newLength);
3028     }
3029 
3030     return newArray;
3031 }
3032 
CopyFromEnumCache(const JSHandle<TaggedArray> &old)3033 JSHandle<TaggedArray> ObjectFactory::CopyFromEnumCache(const JSHandle<TaggedArray> &old)
3034 {
3035     NewObjectHook();
3036     uint32_t oldLength = old->GetLength();
3037     uint32_t newLength = oldLength - EnumCache::ENUM_CACHE_HEADER_SIZE;
3038     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
3039     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3040         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
3041     JSHandle<TaggedArray> newArray(thread_, header);
3042     newArray->SetLength(newLength);
3043     newArray->SetExtraLength(old->GetExtraLength());
3044 
3045     for (uint32_t i = 0; i < newLength; i++) {
3046         JSTaggedValue value = old->Get(i + EnumCache::ENUM_CACHE_HEADER_SIZE);
3047         newArray->Set(thread_, i, value);
3048     }
3049     return newArray;
3050 }
3051 
CreateLayoutInfo(int properties, MemSpaceType type, GrowMode mode)3052 JSHandle<LayoutInfo> ObjectFactory::CreateLayoutInfo(int properties, MemSpaceType type, GrowMode mode)
3053 {
3054     int growLength =
3055         mode == GrowMode::GROW ? static_cast<int>(LayoutInfo::ComputeGrowCapacity(properties)) : properties;
3056     uint32_t arrayLength = LayoutInfo::ComputeArrayLength(growLength);
3057     JSHandle<LayoutInfo> layoutInfoHandle = JSHandle<LayoutInfo>::Cast(NewTaggedArrayWithoutInit(arrayLength, type));
3058     layoutInfoHandle->Initialize(thread_);
3059     return layoutInfoHandle;
3060 }
3061 
ExtendLayoutInfo(const JSHandle<LayoutInfo> &old, int properties)3062 JSHandle<LayoutInfo> ObjectFactory::ExtendLayoutInfo(const JSHandle<LayoutInfo> &old, int properties)
3063 {
3064     ASSERT(properties >= old->NumberOfElements());
3065     uint32_t arrayLength = LayoutInfo::ComputeArrayLength(LayoutInfo::ComputeGrowCapacity(properties));
3066     ASSERT(arrayLength > old->GetLength());
3067 
3068     auto oldArray = JSHandle<TaggedArray>(old);
3069     auto newArray = NewTaggedArrayWithoutInit(arrayLength, MemSpaceType::SEMI_SPACE);
3070     JSHandle<LayoutInfo>::Cast(newArray)->Initialize(thread_, oldArray->GetExtraLength());
3071 
3072     uint32_t oldLength = old->GetLength();
3073     for (uint32_t i = 0; i < oldLength; i++) {
3074         JSTaggedValue value = oldArray->Get(i);
3075         newArray->Set(thread_, i, value);
3076     }
3077     return JSHandle<LayoutInfo>::Cast(newArray);
3078 }
3079 
CopyLayoutInfo(const JSHandle<LayoutInfo> &old)3080 JSHandle<LayoutInfo> ObjectFactory::CopyLayoutInfo(const JSHandle<LayoutInfo> &old)
3081 {
3082     uint32_t newLength = old->GetLength();
3083     return JSHandle<LayoutInfo>(CopyArray(JSHandle<TaggedArray>::Cast(old), newLength, newLength));
3084 }
3085 
CopyAndReSort(const JSHandle<LayoutInfo> &old, int end, int capacity)3086 JSHandle<LayoutInfo> ObjectFactory::CopyAndReSort(const JSHandle<LayoutInfo> &old, int end, int capacity)
3087 {
3088     ASSERT(capacity >= end);
3089     JSHandle<LayoutInfo> newArr = CreateLayoutInfo(capacity);
3090     Span<struct Properties> sp(old->GetProperties(), end);
3091     for (int i = 0; i < end; i++) {
3092         newArr->AddKey(thread_, i, sp[i].key_, PropertyAttributes(sp[i].attr_));
3093     }
3094 
3095     return newArr;
3096 }
3097 
NewConstantPool(uint32_t capacity)3098 JSHandle<ConstantPool> ObjectFactory::NewConstantPool(uint32_t capacity)
3099 {
3100     NewObjectHook();
3101     size_t size = ConstantPool::ComputeSize(capacity);
3102     auto header = heap_->AllocateOldOrHugeObject(
3103         JSHClass::Cast(thread_->GlobalConstants()->GetConstantPoolClass().GetTaggedObject()), size);
3104     JSHandle<ConstantPool> array(thread_, header);
3105     array->InitializeWithSpecialValue(thread_, JSTaggedValue::Hole(), capacity);
3106     return array;
3107 }
3108 
NewProgram()3109 JSHandle<Program> ObjectFactory::NewProgram()
3110 {
3111     NewObjectHook();
3112     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3113         JSHClass::Cast(thread_->GlobalConstants()->GetProgramClass().GetTaggedObject()));
3114     JSHandle<Program> p(thread_, header);
3115     p->InitializeHash();
3116     p->SetMainFunction(thread_, JSTaggedValue::Undefined());
3117     return p;
3118 }
3119 
NewModuleNamespace()3120 JSHandle<ModuleNamespace> ObjectFactory::NewModuleNamespace()
3121 {
3122     NewObjectHook();
3123     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3124     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetModuleNamespaceClass());
3125     JSHandle<JSObject> obj = NewJSObject(hclass);
3126 
3127     JSHandle<ModuleNamespace> moduleNamespace = JSHandle<ModuleNamespace>::Cast(obj);
3128     moduleNamespace->SetModule(thread_, JSTaggedValue::Undefined());
3129     moduleNamespace->SetExports(thread_, JSTaggedValue::Undefined());
3130     moduleNamespace->SetDeregisterProcession(thread_, JSTaggedValue::Undefined());
3131     return moduleNamespace;
3132 }
3133 
NewNativeModuleFailureInfo()3134 JSHandle<NativeModuleFailureInfo> ObjectFactory::NewNativeModuleFailureInfo()
3135 {
3136     NewObjectHook();
3137     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3138     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetNativeModuleFailureInfoClass());
3139     JSHandle<JSObject> obj = NewJSObject(hclass);
3140 
3141     JSHandle<NativeModuleFailureInfo> nativeModuleFailureInfo = JSHandle<NativeModuleFailureInfo>::Cast(obj);
3142     nativeModuleFailureInfo->SetArkNativeModuleFailureInfo(thread_, JSTaggedValue::Undefined());
3143     return nativeModuleFailureInfo;
3144 }
3145 
NewCjsModule()3146 JSHandle<CjsModule> ObjectFactory::NewCjsModule()
3147 {
3148     NewObjectHook();
3149     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3150     JSHandle<JSFunction> moduleObj(env->GetCjsModuleFunction());
3151     JSHandle<CjsModule> cjsModule = JSHandle<CjsModule>(NewJSObjectByConstructor(moduleObj));
3152     return cjsModule;
3153 }
3154 
NewCjsExports()3155 JSHandle<CjsExports> ObjectFactory::NewCjsExports()
3156 {
3157     NewObjectHook();
3158     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3159     JSHandle<JSFunction> exportsObj(env->GetCjsExportsFunction());
3160     JSHandle<CjsExports> cjsExports = JSHandle<CjsExports>(NewJSObjectByConstructor(exportsObj));
3161     return cjsExports;
3162 }
3163 
NewCjsRequire()3164 JSHandle<CjsRequire> ObjectFactory::NewCjsRequire()
3165 {
3166     NewObjectHook();
3167     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3168     JSHandle<JSFunction> requireObj(env->GetCjsRequireFunction());
3169     JSHandle<CjsRequire> cjsRequire = JSHandle<CjsRequire>(NewJSObjectByConstructor(requireObj));
3170     return cjsRequire;
3171 }
3172 
GetEmptyString() const3173 JSHandle<EcmaString> ObjectFactory::GetEmptyString() const
3174 {
3175     return JSHandle<EcmaString>(thread_->GlobalConstants()->GetHandledEmptyString());
3176 }
3177 
EmptyArray() const3178 JSHandle<TaggedArray> ObjectFactory::EmptyArray() const
3179 {
3180     return JSHandle<TaggedArray>(thread_->GlobalConstants()->GetHandledEmptyArray());
3181 }
3182 
EmptyMutantArray() const3183 JSHandle<MutantTaggedArray> ObjectFactory::EmptyMutantArray() const
3184 {
3185     return JSHandle<MutantTaggedArray>(thread_->GlobalConstants()->GetHandledEmptyArray());
3186 }
3187 
GetStringFromStringTable(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress) const3188 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const uint8_t *utf8Data, uint32_t utf8Len,
3189                                                              bool canBeCompress) const
3190 {
3191     NewObjectHook();
3192     if (utf8Len == 0) {
3193         return GetEmptyString();
3194     }
3195     auto stringTable = vm_->GetEcmaStringTable();
3196     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(vm_, utf8Data, utf8Len, canBeCompress));
3197 }
3198 
GetCompressedSubStringFromStringTable(const JSHandle<EcmaString> &string, uint32_t offset, uint32_t utf8Len) const3199 JSHandle<EcmaString> ObjectFactory::GetCompressedSubStringFromStringTable(const JSHandle<EcmaString> &string,
3200                                                                           uint32_t offset, uint32_t utf8Len) const
3201 {
3202     NewObjectHook();
3203     if (UNLIKELY(utf8Len == 0)) {
3204         return GetEmptyString();
3205     }
3206     auto *stringTable = vm_->GetEcmaStringTable();
3207     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternCompressedSubString(vm_, string, offset, utf8Len));
3208 }
3209 
GetStringFromStringTableNonMovable(const uint8_t *utf8Data, uint32_t utf8Len) const3210 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTableNonMovable(const uint8_t *utf8Data, uint32_t utf8Len) const
3211 {
3212     NewObjectHook();
3213     if (utf8Len == 0) {
3214         return GetEmptyString();
3215     }
3216     auto stringTable = vm_->GetEcmaStringTable();
3217     return JSHandle<EcmaString>(thread_, stringTable->CreateAndInternStringNonMovable(vm_, utf8Data, utf8Len));
3218 }
3219 
GetStringFromStringTableReadOnly(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress) const3220 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTableReadOnly(const uint8_t *utf8Data, uint32_t utf8Len,
3221                                                                      bool canBeCompress) const
3222 {
3223     NewObjectHook();
3224     if (utf8Len == 0) {
3225         return GetEmptyString();
3226     }
3227     auto stringTable = vm_->GetEcmaStringTable();
3228     return JSHandle<EcmaString>(thread_, stringTable->CreateAndInternStringReadOnly(vm_, utf8Data, utf8Len,
3229                                                                                     canBeCompress));
3230 }
3231 
GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress) const3232 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len,
3233                                                              bool canBeCompress) const
3234 {
3235     NewObjectHook();
3236     if (utf16Len == 0) {
3237         return GetEmptyString();
3238     }
3239     auto stringTable = vm_->GetEcmaStringTable();
3240     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(vm_, utf16Data, utf16Len, canBeCompress));
3241 }
3242 
GetStringFromStringTable(EcmaString *string) const3243 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(EcmaString *string) const
3244 {
3245     ASSERT(string != nullptr);
3246     if (EcmaStringAccessor(string).GetLength() == 0) {
3247         return GetEmptyString();
3248     }
3249     auto stringTable = vm_->GetEcmaStringTable();
3250     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(vm_, string));
3251 }
3252 
3253 // NB! don't do special case for C0 80, it means '\u0000', so don't convert to UTF-8
GetRawStringFromStringTable(StringData sd, MemSpaceType type, bool isConstantString, uint32_t idOffset) const3254 EcmaString *ObjectFactory::GetRawStringFromStringTable(StringData sd, MemSpaceType type, bool isConstantString,
3255     uint32_t idOffset) const
3256 {
3257     NewObjectHook();
3258     uint32_t utf16Len = sd.utf16_length;
3259     if (UNLIKELY(utf16Len == 0)) {
3260         return *GetEmptyString();
3261     }
3262 
3263     bool canBeCompressed = sd.is_ascii;
3264     const uint8_t *mutf8Data = sd.data;
3265     if (canBeCompressed) {
3266         // This branch will use constant string, which has a pointer at the string in the pandafile.
3267         return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceType(vm_, mutf8Data, utf16Len, true, type,
3268                                                                          isConstantString, idOffset);
3269     }
3270     return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceType(vm_, mutf8Data, utf16Len, type);
3271 }
3272 
3273 // used in jit thread, which unsupport create jshandle
GetRawStringFromStringTableWithoutJSHandle(StringData sd, MemSpaceType type, bool isConstantString, uint32_t idOffset) const3274 EcmaString *ObjectFactory::GetRawStringFromStringTableWithoutJSHandle(StringData sd, MemSpaceType type,
3275     bool isConstantString, uint32_t idOffset) const
3276 {
3277     NewObjectHook();
3278     uint32_t utf16Len = sd.utf16_length;
3279     if (UNLIKELY(utf16Len == 0)) {
3280         return *GetEmptyString();
3281     }
3282 
3283     bool canBeCompressed = sd.is_ascii;
3284     const uint8_t *mutf8Data = sd.data;
3285     if (canBeCompressed) {
3286         // This branch will use constant string, which has a pointer at the string in the pandafile.
3287         return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceType(vm_, mutf8Data, utf16Len, true, type,
3288                                                                          isConstantString, idOffset);
3289     }
3290     return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceTypeWithoutJSHandle(vm_, mutf8Data, utf16Len, type);
3291 }
3292 
NewPropertyBox(const JSHandle<JSTaggedValue> &value)3293 JSHandle<PropertyBox> ObjectFactory::NewPropertyBox(const JSHandle<JSTaggedValue> &value)
3294 {
3295     NewObjectHook();
3296     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3297         JSHClass::Cast(thread_->GlobalConstants()->GetPropertyBoxClass().GetTaggedObject()));
3298     JSHandle<PropertyBox> box(thread_, header);
3299     box->SetValue(thread_, value);
3300     return box;
3301 }
3302 
NewProtoChangeMarker()3303 JSHandle<ProtoChangeMarker> ObjectFactory::NewProtoChangeMarker()
3304 {
3305     NewObjectHook();
3306     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3307         JSHClass::Cast(thread_->GlobalConstants()->GetProtoChangeMarkerClass().GetTaggedObject()));
3308     JSHandle<ProtoChangeMarker> marker(thread_, header);
3309     marker->ClearBitField();
3310     return marker;
3311 }
3312 
NewMarkerCell()3313 JSHandle<MarkerCell> ObjectFactory::NewMarkerCell()
3314 {
3315     NewObjectHook();
3316     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3317         JSHClass::Cast(thread_->GlobalConstants()->GetMarkerCellClass().GetTaggedObject()));
3318     JSHandle<MarkerCell> marker(thread_, header);
3319     marker->ClearBitField();
3320     return marker;
3321 }
3322 
NewProtoChangeDetails()3323 JSHandle<ProtoChangeDetails> ObjectFactory::NewProtoChangeDetails()
3324 {
3325     NewObjectHook();
3326     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3327         JSHClass::Cast(thread_->GlobalConstants()->GetProtoChangeDetailsClass().GetTaggedObject()));
3328     JSHandle<ProtoChangeDetails> protoInfo(thread_, header);
3329     protoInfo->SetChangeListener(thread_, JSTaggedValue::Undefined());
3330     protoInfo->SetRegisterIndex(ProtoChangeDetails::UNREGISTERED);
3331     return protoInfo;
3332 }
3333 
NewProfileTypeInfo(uint32_t icSlotSize)3334 JSHandle<ProfileTypeInfo> ObjectFactory::NewProfileTypeInfo(uint32_t icSlotSize)
3335 {
3336     NewObjectHook();
3337     size_t size = ProfileTypeInfo::ComputeSize(icSlotSize);
3338     auto header = heap_->AllocateYoungOrHugeObject(
3339         JSHClass::Cast(thread_->GlobalConstants()->GetProfileTypeInfoClass().GetTaggedObject()), size);
3340     JSHandle<ProfileTypeInfo> array(thread_, header);
3341     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), icSlotSize);
3342     if (vm_->IsEnableFastJit()) {
3343         uint16_t threshold = vm_->GetJSOptions().GetJitHotnessThreshold();
3344         ASSERT(threshold != ProfileTypeInfo::JIT_DISABLE_FLAG);
3345         array->SetJitHotnessThreshold(threshold);
3346         threshold = vm_->GetJSOptions().GetOsrHotnessThreshold();
3347         array->SetOsrHotnessThreshold(threshold);
3348         uint8_t jitCallThreshold = vm_->GetJSOptions().GetJitCallThreshold();
3349         array->SetJitCallThreshold(jitCallThreshold);
3350     }
3351     if (vm_->IsEnableBaselineJit()) {
3352         uint16_t threshold = vm_->GetJSOptions().GetBaselineJitHotnessThreshold();
3353         array->SetBaselineJitHotnessThreshold(threshold);
3354     }
3355     return array;
3356 }
3357 
NewBigInt(uint32_t length)3358 JSHandle<BigInt> ObjectFactory::NewBigInt(uint32_t length)
3359 {
3360     NewObjectHook();
3361     ASSERT(length > 0);
3362     size_t size = BigInt::ComputeSize(length);
3363     auto header = sHeap_->AllocateNonMovableOrHugeObject(thread_,
3364         JSHClass::Cast(thread_->GlobalConstants()->GetBigIntClass().GetTaggedObject()), size);
3365     JSHandle<BigInt> bigint(thread_, header);
3366     bigint->SetLength(length);
3367     bigint->SetSign(false);
3368     bigint->InitializationZero();
3369     return bigint;
3370 }
3371 
3372 // static
NewObjectHook() const3373 void ObjectFactory::NewObjectHook() const
3374 {
3375     CHECK_NO_HEAP_ALLOC;
3376 #ifndef NDEBUG
3377     if (vm_->GetJSOptions().EnableForceGC() && vm_->IsInitialized() && thread_->IsAllContextsInitialized() &&
3378         !heap_->InSensitiveStatus() && heap_->TriggerCollectionOnNewObjectEnabled()) {
3379         if (vm_->GetJSOptions().ForceFullGC()) {
3380             vm_->CollectGarbage(TriggerGCType::YOUNG_GC);
3381             vm_->CollectGarbage(TriggerGCType::OLD_GC);
3382             vm_->CollectGarbage(TriggerGCType::FULL_GC);
3383         } else {
3384             vm_->CollectGarbage(TriggerGCType::YOUNG_GC);
3385             vm_->CollectGarbage(TriggerGCType::OLD_GC);
3386         }
3387     }
3388 #endif
3389 }
3390 
NewTaggedQueue(uint32_t length)3391 JSHandle<TaggedQueue> ObjectFactory::NewTaggedQueue(uint32_t length)
3392 {
3393     uint32_t queueLength = TaggedQueue::QueueToArrayIndex(length);
3394     auto queue = JSHandle<TaggedQueue>::Cast(NewTaggedArray(queueLength, JSTaggedValue::Hole()));
3395     queue->SetStart(thread_, JSTaggedValue(0));  // equal to 0 when add 1.
3396     queue->SetEnd(thread_, JSTaggedValue(0));
3397     queue->SetCapacity(thread_, JSTaggedValue(length));
3398 
3399     return queue;
3400 }
3401 
GetEmptyTaggedQueue() const3402 JSHandle<TaggedQueue> ObjectFactory::GetEmptyTaggedQueue() const
3403 {
3404     return JSHandle<TaggedQueue>(thread_->GlobalConstants()->GetHandledEmptyTaggedQueue());
3405 }
3406 
NewJSSetIterator(const JSHandle<JSSharedSet> &set, IterationKind kind)3407 JSHandle<JSSharedSetIterator> ObjectFactory::NewJSSetIterator(const JSHandle<JSSharedSet> &set, IterationKind kind)
3408 {
3409     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3410     JSHandle<JSTaggedValue> protoValue = env->GetSharedSetIteratorPrototype();
3411     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3412     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSSharedSetIteratorClass());
3413     hclassHandle->SetPrototype(thread_, protoValue);
3414     JSHandle<JSSharedSetIterator> iter(NewJSObject(hclassHandle));
3415     iter->GetJSHClass()->SetExtensible(true);
3416     iter->SetIteratedSet(thread_, set.GetTaggedValue());
3417     iter->SetNextIndex(0);
3418     iter->SetIterationKind(kind);
3419     ASSERT(iter.GetTaggedValue().IsJSSharedSetIterator());
3420     return iter;
3421 }
3422 
NewJSSetIterator(const JSHandle<JSSet> &set, IterationKind kind)3423 JSHandle<JSSetIterator> ObjectFactory::NewJSSetIterator(const JSHandle<JSSet> &set, IterationKind kind)
3424 {
3425     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3426     JSHandle<JSTaggedValue> protoValue = env->GetSetIteratorPrototype();
3427     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3428     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSSetIteratorClass());
3429     hclassHandle->SetPrototype(thread_, protoValue);
3430     JSHandle<JSSetIterator> iter(NewJSObject(hclassHandle));
3431     iter->GetJSHClass()->SetExtensible(true);
3432     iter->SetIteratedSet(thread_, set->GetLinkedSet());
3433     iter->SetNextIndex(0);
3434     iter->SetIterationKind(kind);
3435     return iter;
3436 }
3437 
NewJSRegExpIterator(const JSHandle<JSTaggedValue> &matcher, const JSHandle<EcmaString> &inputStr, bool global, bool fullUnicode)3438 JSHandle<JSRegExpIterator> ObjectFactory::NewJSRegExpIterator(const JSHandle<JSTaggedValue> &matcher,
3439                                                               const JSHandle<EcmaString> &inputStr, bool global,
3440                                                               bool fullUnicode)
3441 {
3442     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3443     JSHandle<JSTaggedValue> protoValue = env->GetRegExpIteratorPrototype();
3444     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3445     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSRegExpIteratorClass());
3446     hclassHandle->SetPrototype(thread_, protoValue);
3447     JSHandle<JSRegExpIterator> iter(NewJSObject(hclassHandle));
3448     iter->GetJSHClass()->SetExtensible(true);
3449     iter->SetIteratingRegExp(thread_, matcher.GetTaggedValue());
3450     iter->SetIteratedString(thread_, inputStr.GetTaggedValue());
3451     iter->SetGlobal(global);
3452     iter->SetUnicode(fullUnicode);
3453     iter->SetDone(false);
3454     return iter;
3455 }
3456 
NewJSMapIterator(const JSHandle<JSMap> &map, IterationKind kind)3457 JSHandle<JSMapIterator> ObjectFactory::NewJSMapIterator(const JSHandle<JSMap> &map, IterationKind kind)
3458 {
3459     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3460     JSHandle<JSTaggedValue> protoValue = env->GetMapIteratorPrototype();
3461     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3462     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSMapIteratorClass());
3463     hclassHandle->SetPrototype(thread_, protoValue);
3464     JSHandle<JSMapIterator> iter(NewJSObject(hclassHandle));
3465     iter->GetJSHClass()->SetExtensible(true);
3466     iter->SetIteratedMap(thread_, map->GetLinkedMap());
3467     iter->SetNextIndex(0);
3468     iter->SetIterationKind(kind);
3469     return iter;
3470 }
3471 
NewJSMapIterator(const JSHandle<JSSharedMap> &map, IterationKind kind)3472 JSHandle<JSSharedMapIterator> ObjectFactory::NewJSMapIterator(const JSHandle<JSSharedMap> &map, IterationKind kind)
3473 {
3474     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3475     JSHandle<JSTaggedValue> protoValue = env->GetSharedMapIteratorPrototype();
3476     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3477     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSSharedMapIteratorClass());
3478     hclassHandle->SetPrototype(thread_, protoValue);
3479     JSHandle<JSSharedMapIterator> iter(NewJSObject(hclassHandle));
3480     iter->GetJSHClass()->SetExtensible(true);
3481     iter->SetIteratedMap(thread_, map.GetTaggedValue());
3482     iter->SetNextIndex(0);
3483     iter->SetIterationKind(kind);
3484     ASSERT(iter.GetTaggedValue().IsJSSharedMapIterator());
3485     return iter;
3486 }
3487 
NewJSAPIHashMapIterator(const JSHandle<JSAPIHashMap> &hashMap, IterationKind kind)3488 JSHandle<JSAPIHashMapIterator> ObjectFactory::NewJSAPIHashMapIterator(const JSHandle<JSAPIHashMap> &hashMap,
3489                                                                       IterationKind kind)
3490 {
3491     NewObjectHook();
3492     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3493     JSHandle<JSTaggedValue> undefinedHandle = globalConst->GetHandledUndefined();
3494     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetHashMapIteratorPrototype());
3495     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIHashMapIteratorClass());
3496     hclassHandle->SetPrototype(thread_, proto);
3497     JSHandle<JSAPIHashMapIterator> iter(NewJSObject(hclassHandle));
3498     iter->GetJSHClass()->SetExtensible(true);
3499     iter->SetCurrentNodeResult(thread_, undefinedHandle);
3500     iter->SetIteratedHashMap(thread_, hashMap);
3501     iter->SetNextIndex(0);
3502     iter->SetTaggedQueue(thread_, JSTaggedValue::Undefined());
3503     JSHandle<TaggedQueue> queue = NewTaggedQueue(0);
3504     iter->SetTaggedQueue(thread_, queue);
3505     iter->SetIterationKind(kind);
3506     return iter;
3507 }
3508 
NewJSAPIHashSetIterator(const JSHandle<JSAPIHashSet> &hashSet, IterationKind kind)3509 JSHandle<JSAPIHashSetIterator> ObjectFactory::NewJSAPIHashSetIterator(const JSHandle<JSAPIHashSet> &hashSet,
3510                                                                       IterationKind kind)
3511 {
3512     NewObjectHook();
3513     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3514     JSHandle<JSTaggedValue> undefinedHandle = globalConst->GetHandledUndefined();
3515     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetHashSetIteratorPrototype());
3516     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIHashSetIteratorClass());
3517     hclassHandle->SetPrototype(thread_, proto);
3518     JSHandle<JSAPIHashSetIterator> iter(NewJSObject(hclassHandle));
3519     iter->GetJSHClass()->SetExtensible(true);
3520     iter->SetCurrentNodeResult(thread_, undefinedHandle);
3521     iter->SetIteratedHashSet(thread_, hashSet);
3522     iter->SetNextIndex(0);
3523     iter->SetTableIndex(0);
3524     iter->SetTaggedQueue(thread_, JSTaggedValue::Undefined());
3525     JSHandle<TaggedQueue> queue = NewTaggedQueue(0);
3526     iter->SetTaggedQueue(thread_, queue);
3527     iter->SetIterationKind(kind);
3528     return iter;
3529 }
3530 
NewJSArrayIterator(const JSHandle<JSObject> &array, IterationKind kind)3531 JSHandle<JSArrayIterator> ObjectFactory::NewJSArrayIterator(const JSHandle<JSObject> &array, IterationKind kind)
3532 {
3533     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3534     JSHandle<JSTaggedValue> protoValue = env->GetArrayIteratorPrototype();
3535     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3536     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSArrayIteratorClass());
3537     hclassHandle->SetPrototype(thread_, protoValue);
3538     JSHandle<JSArrayIterator> iter(NewJSObject(hclassHandle));
3539     iter->GetJSHClass()->SetExtensible(true);
3540     iter->SetIteratedArray(thread_, array);
3541     iter->SetNextIndex(0);
3542     iter->SetIterationKind(kind);
3543     return iter;
3544 }
3545 
NewJSSharedArrayIterator(const JSHandle<JSObject> &array, IterationKind kind)3546 JSHandle<JSSharedArrayIterator> ObjectFactory::NewJSSharedArrayIterator(const JSHandle<JSObject> &array,
3547                                                                         IterationKind kind)
3548 {
3549     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3550     JSHandle<JSTaggedValue> protoValue = env->GetSharedArrayIteratorPrototype();
3551     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3552     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSSharedArrayIteratorClass());
3553     hclassHandle->SetPrototype(thread_, protoValue);
3554     JSHandle<JSSharedArrayIterator> iter(NewJSObject(hclassHandle));
3555     iter->GetJSHClass()->SetExtensible(true);
3556     iter->SetIteratedArray(thread_, array);
3557     iter->SetNextIndex(0);
3558     iter->SetIterationKind(kind);
3559     return iter;
3560 }
3561 
CreateJSPromiseReactionsFunction(MethodIndex idx)3562 JSHandle<JSPromiseReactionsFunction> ObjectFactory::CreateJSPromiseReactionsFunction(MethodIndex idx)
3563 {
3564     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3565     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseReactionFunctionClass());
3566 
3567     JSHandle<JSPromiseReactionsFunction> reactionsFunction =
3568         JSHandle<JSPromiseReactionsFunction>::Cast(NewJSObject(hclass));
3569     reactionsFunction->SetPromise(thread_, JSTaggedValue::Hole());
3570     reactionsFunction->SetAlreadyResolved(thread_, JSTaggedValue::Hole());
3571     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(reactionsFunction);
3572     JSFunction::InitializeJSFunction(thread_, function);
3573     reactionsFunction->SetMethod(thread_, vm_->GetMethodByIndex(idx));
3574     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(1));
3575     return reactionsFunction;
3576 }
3577 
CreateJSPromiseExecutorFunction()3578 JSHandle<JSPromiseExecutorFunction> ObjectFactory::CreateJSPromiseExecutorFunction()
3579 {
3580     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3581     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseExecutorFunctionClass());
3582     JSHandle<JSPromiseExecutorFunction> executorFunction =
3583         JSHandle<JSPromiseExecutorFunction>::Cast(NewJSObject(hclass));
3584     executorFunction->SetCapability(thread_, JSTaggedValue::Undefined());
3585     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(executorFunction);
3586     JSFunction::InitializeJSFunction(thread_, function);
3587     executorFunction->SetMethod(
3588         thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_EXECUTOR));
3589     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(FunctionLength::TWO));
3590     return executorFunction;
3591 }
3592 
CreateJSAsyncModuleFulfilledFunction()3593 JSHandle<JSAsyncModuleFulfilledFunction> ObjectFactory::CreateJSAsyncModuleFulfilledFunction()
3594 {
3595     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3596     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetAsyncModuleFulfilledFunctionClass());
3597     JSHandle<JSAsyncModuleFulfilledFunction> fulfilledFunction =
3598         JSHandle<JSAsyncModuleFulfilledFunction>::Cast(NewJSObject(hclass));
3599     fulfilledFunction->SetModule(thread_, JSTaggedValue::Undefined());
3600     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(fulfilledFunction);
3601     JSFunction::InitializeJSFunction(thread_, function);
3602     fulfilledFunction->SetMethod(
3603         thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_ASYNC_MODULE_FULFILLED_FUNCTION));
3604     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(FunctionLength::ONE));
3605     return fulfilledFunction;
3606 }
3607 
CreateJSAsyncModuleRejectedFunction()3608 JSHandle<JSAsyncModuleRejectedFunction> ObjectFactory::CreateJSAsyncModuleRejectedFunction()
3609 {
3610     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3611     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetAsyncModuleRejectedFunctionClass());
3612     JSHandle<JSAsyncModuleRejectedFunction> rejectedFunction =
3613         JSHandle<JSAsyncModuleRejectedFunction>::Cast(NewJSObject(hclass));
3614     rejectedFunction->SetModule(thread_, JSTaggedValue::Undefined());
3615     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(rejectedFunction);
3616     JSFunction::InitializeJSFunction(thread_, function);
3617     rejectedFunction->SetMethod(
3618         thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_ASYNC_MODULE_REJECTED_FUNCTION));
3619     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(FunctionLength::ONE));
3620     return rejectedFunction;
3621 }
3622 
NewJSPromiseAllResolveElementFunction()3623 JSHandle<JSPromiseAllResolveElementFunction> ObjectFactory::NewJSPromiseAllResolveElementFunction()
3624 {
3625     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3626     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseAllResolveElementFunctionClass());
3627     JSHandle<JSPromiseAllResolveElementFunction> function =
3628         JSHandle<JSPromiseAllResolveElementFunction>::Cast(NewJSObject(hclass));
3629     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3630     function->SetMethod(
3631         thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_RESOLVE_ELEMENT_FUNCTION));
3632     function->SetIndex(thread_, JSTaggedValue::Undefined());
3633     function->SetValues(thread_, JSTaggedValue::Undefined());
3634     function->SetCapabilities(thread_, JSTaggedValue::Undefined());
3635     function->SetRemainingElements(thread_, JSTaggedValue::Undefined());
3636     function->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
3637     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3638     return function;
3639 }
3640 
NewJSPromiseAnyRejectElementFunction()3641 JSHandle<JSPromiseAnyRejectElementFunction> ObjectFactory::NewJSPromiseAnyRejectElementFunction()
3642 {
3643     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3644     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseAnyRejectElementFunctionClass());
3645     JSHandle<JSPromiseAnyRejectElementFunction> function =
3646         JSHandle<JSPromiseAnyRejectElementFunction>::Cast(NewJSObject(hclass));
3647     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3648     function->SetMethod(
3649         thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_ANY_REJECT_ELEMENT_FUNCTION));
3650     function->SetIndex(0);
3651     function->SetErrors(thread_, JSTaggedValue::Undefined());
3652     function->SetCapability(thread_, JSTaggedValue::Undefined());
3653     function->SetRemainingElements(thread_, JSTaggedValue::Undefined());
3654     function->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
3655     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3656     return function;
3657 }
3658 
NewJSPromiseAllSettledResolveElementFunction()3659 JSHandle<JSPromiseAllSettledElementFunction> ObjectFactory::NewJSPromiseAllSettledResolveElementFunction()
3660 {
3661     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3662     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseAllSettledElementFunctionClass());
3663     JSHandle<JSPromiseAllSettledElementFunction> function =
3664         JSHandle<JSPromiseAllSettledElementFunction>::Cast(NewJSObject(hclass));
3665     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3666     function->SetMethod(thread_,
3667         vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_ALL_SETTLED_RESOLVE_ELEMENT_FUNCTION));
3668     function->SetIndex(0);
3669     function->SetValues(thread_, JSTaggedValue::Undefined());
3670     function->SetCapability(thread_, JSTaggedValue::Undefined());
3671     function->SetRemainingElements(thread_, JSTaggedValue::Undefined());
3672     function->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
3673     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3674     return function;
3675 }
3676 
NewJSPromiseAllSettledRejectElementFunction()3677 JSHandle<JSPromiseAllSettledElementFunction> ObjectFactory::NewJSPromiseAllSettledRejectElementFunction()
3678 {
3679     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3680     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseAllSettledElementFunctionClass());
3681     JSHandle<JSPromiseAllSettledElementFunction> function =
3682         JSHandle<JSPromiseAllSettledElementFunction>::Cast(NewJSObject(hclass));
3683     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3684     function->SetMethod(thread_,
3685         vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_ALL_SETTLED_REJECT_ELEMENT_FUNCTION));
3686     function->SetIndex(0);
3687     function->SetValues(thread_, JSTaggedValue::Undefined());
3688     function->SetCapability(thread_, JSTaggedValue::Undefined());
3689     function->SetRemainingElements(thread_, JSTaggedValue::Undefined());
3690     function->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
3691     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3692     return function;
3693 }
3694 
NewJSPromiseThenFinallyFunction()3695 JSHandle<JSPromiseFinallyFunction> ObjectFactory::NewJSPromiseThenFinallyFunction()
3696 {
3697     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3698     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseFinallyFunctionClass());
3699     JSHandle<JSPromiseFinallyFunction> function =
3700         JSHandle<JSPromiseFinallyFunction>::Cast(NewJSObject(hclass));
3701     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3702     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_THEN_FINALLY_FUNCTION));
3703     function->SetConstructor(thread_, JSTaggedValue::Undefined());
3704     function->SetOnFinally(thread_, JSTaggedValue::Undefined());
3705     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3706     return function;
3707 }
3708 
NewJSPromiseCatchFinallyFunction()3709 JSHandle<JSPromiseFinallyFunction> ObjectFactory::NewJSPromiseCatchFinallyFunction()
3710 {
3711     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3712     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseFinallyFunctionClass());
3713     JSHandle<JSPromiseFinallyFunction> function =
3714         JSHandle<JSPromiseFinallyFunction>::Cast(NewJSObject(hclass));
3715     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3716     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_CATCH_FINALLY_FUNCTION));
3717     function->SetConstructor(thread_, JSTaggedValue::Undefined());
3718     function->SetOnFinally(thread_, JSTaggedValue::Undefined());
3719     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3720     return function;
3721 }
3722 
NewJSAsyGenResNextRetProRstFulfilledFtn()3723 JSHandle<JSAsyncGeneratorResNextRetProRstFtn> ObjectFactory::NewJSAsyGenResNextRetProRstFulfilledFtn()
3724 {
3725     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3726     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(
3727         env->GetAsyncGeneratorResNextRetProRstFtnClass());
3728     JSHandle<JSAsyncGeneratorResNextRetProRstFtn> function =
3729         JSHandle<JSAsyncGeneratorResNextRetProRstFtn>::Cast(NewJSObject(hclass));
3730     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3731     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_ASYNC_GENERATOR_NEXT_FULFILLED_FUNCTION));
3732     function->SetAsyncGeneratorObject(thread_, JSTaggedValue::Undefined());
3733     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3734     return function;
3735 }
3736 
NewJSAsyncFromSyncIterUnwarpFunction()3737 JSHandle<JSAsyncFromSyncIterUnwarpFunction> ObjectFactory::NewJSAsyncFromSyncIterUnwarpFunction()
3738 {
3739     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3740     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetAsyncFromSyncIterUnwarpClass());
3741     JSHandle<JSAsyncFromSyncIterUnwarpFunction> function =
3742         JSHandle<JSAsyncFromSyncIterUnwarpFunction>::Cast(NewJSObject(hclass));
3743     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3744     JSTaggedValue debugVaule =  vm_->GetMethodByIndex(MethodIndex::BUILTINS_ASYNC_FROM_SYNC_ITERATOR_FUNCTION);
3745     function->SetMethod(thread_, debugVaule);
3746     function->SetDone(thread_, JSTaggedValue::Undefined());
3747     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3748     return function;
3749 }
3750 
NewJSAsyGenResNextRetProRstRejectedFtn()3751 JSHandle<JSAsyncGeneratorResNextRetProRstFtn> ObjectFactory::NewJSAsyGenResNextRetProRstRejectedFtn()
3752 {
3753     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3754     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(
3755         env->GetAsyncGeneratorResNextRetProRstFtnClass());
3756     JSHandle<JSAsyncGeneratorResNextRetProRstFtn> function =
3757         JSHandle<JSAsyncGeneratorResNextRetProRstFtn>::Cast(NewJSObject(hclass));
3758     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3759     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_ASYNC_GENERATOR_NEXT_REJECTED_FUNCTION));
3760     function->SetAsyncGeneratorObject(thread_, JSTaggedValue::Undefined());
3761     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
3762     return function;
3763 }
3764 
NewJSPromiseValueThunkFunction()3765 JSHandle<JSPromiseValueThunkOrThrowerFunction> ObjectFactory::NewJSPromiseValueThunkFunction()
3766 {
3767     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3768     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseValueThunkOrThrowerFunctionClass());
3769     JSHandle<JSPromiseValueThunkOrThrowerFunction> function =
3770         JSHandle<JSPromiseValueThunkOrThrowerFunction>::Cast(NewJSObject(hclass));
3771     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3772     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_VALUE_THUNK_FUNCTION));
3773     function->SetResult(thread_, JSTaggedValue::Undefined());
3774     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(0));
3775     return function;
3776 }
3777 
NewJSPromiseThrowerFunction()3778 JSHandle<JSPromiseValueThunkOrThrowerFunction> ObjectFactory::NewJSPromiseThrowerFunction()
3779 {
3780     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3781     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseValueThunkOrThrowerFunctionClass());
3782     JSHandle<JSPromiseValueThunkOrThrowerFunction> function =
3783         JSHandle<JSPromiseValueThunkOrThrowerFunction>::Cast(NewJSObject(hclass));
3784     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
3785     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_THROWER_FUNCTION));
3786     function->SetResult(thread_, JSTaggedValue::Undefined());
3787     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(0));
3788     return function;
3789 }
3790 
InternString(const JSHandle<JSTaggedValue> &key)3791 EcmaString *ObjectFactory::InternString(const JSHandle<JSTaggedValue> &key)
3792 {
3793     EcmaString *str = EcmaString::Cast(key->GetTaggedObject());
3794     if (EcmaStringAccessor(str).IsInternString()) {
3795         return str;
3796     }
3797 
3798     EcmaStringTable *stringTable = vm_->GetEcmaStringTable();
3799     return stringTable->GetOrInternString(vm_, str);
3800 }
3801 
NewTransitionHandler()3802 JSHandle<TransitionHandler> ObjectFactory::NewTransitionHandler()
3803 {
3804     NewObjectHook();
3805     TransitionHandler *handler =
3806         TransitionHandler::Cast(heap_->AllocateYoungOrHugeObject(
3807             JSHClass::Cast(thread_->GlobalConstants()->GetTransitionHandlerClass().GetTaggedObject())));
3808     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
3809     handler->SetTransitionHClass(thread_, JSTaggedValue::Undefined());
3810     return JSHandle<TransitionHandler>(thread_, handler);
3811 }
3812 
NewPrototypeHandler()3813 JSHandle<PrototypeHandler> ObjectFactory::NewPrototypeHandler()
3814 {
3815     NewObjectHook();
3816     PrototypeHandler *header =
3817         PrototypeHandler::Cast(heap_->AllocateYoungOrHugeObject(
3818             JSHClass::Cast(thread_->GlobalConstants()->GetPrototypeHandlerClass().GetTaggedObject())));
3819     JSHandle<PrototypeHandler> handler(thread_, header);
3820     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
3821     handler->SetProtoCell(thread_, JSTaggedValue::Undefined());
3822     handler->SetHolder(thread_, JSTaggedValue::Undefined());
3823     handler->SetAccessorJSFunction(thread_, JSTaggedValue::Undefined());
3824     handler->SetAccessorMethodId(0);
3825     return handler;
3826 }
3827 
NewTransWithProtoHandler()3828 JSHandle<TransWithProtoHandler> ObjectFactory::NewTransWithProtoHandler()
3829 {
3830     NewObjectHook();
3831     TransWithProtoHandler *header =
3832         TransWithProtoHandler::Cast(heap_->AllocateYoungOrHugeObject(
3833             JSHClass::Cast(thread_->GlobalConstants()->GetTransWithProtoHandlerClass().GetTaggedObject())));
3834     JSHandle<TransWithProtoHandler> handler(thread_, header);
3835     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
3836     handler->SetProtoCell(thread_, JSTaggedValue::Undefined());
3837     handler->SetTransitionHClass(thread_, JSTaggedValue::Undefined());
3838     return handler;
3839 }
3840 
NewStoreTSHandler()3841 JSHandle<StoreTSHandler> ObjectFactory::NewStoreTSHandler()
3842 {
3843     NewObjectHook();
3844     StoreTSHandler *header =
3845         StoreTSHandler::Cast(heap_->AllocateYoungOrHugeObject(
3846             JSHClass::Cast(thread_->GlobalConstants()->GetStoreTSHandlerClass().GetTaggedObject())));
3847     JSHandle<StoreTSHandler> handler(thread_, header);
3848     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
3849     handler->SetProtoCell(thread_, JSTaggedValue::Undefined());
3850     handler->SetHolder(thread_, JSTaggedValue::Undefined());
3851     return handler;
3852 }
3853 
NewPromiseRecord()3854 JSHandle<PromiseRecord> ObjectFactory::NewPromiseRecord()
3855 {
3856     NewObjectHook();
3857     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3858         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseRecordClass().GetTaggedObject()));
3859     JSHandle<PromiseRecord> obj(thread_, header);
3860     obj->SetValue(thread_, JSTaggedValue::Undefined());
3861     return obj;
3862 }
3863 
NewResolvingFunctionsRecord()3864 JSHandle<ResolvingFunctionsRecord> ObjectFactory::NewResolvingFunctionsRecord()
3865 {
3866     NewObjectHook();
3867     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3868         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseResolvingFunctionsRecordClass().GetTaggedObject()));
3869     JSHandle<ResolvingFunctionsRecord> obj(thread_, header);
3870     obj->SetResolveFunction(thread_, JSTaggedValue::Undefined());
3871     obj->SetRejectFunction(thread_, JSTaggedValue::Undefined());
3872     return obj;
3873 }
3874 
CreateObjectClass(const JSHandle<TaggedArray> &properties, size_t length)3875 JSHandle<JSHClass> ObjectFactory::CreateObjectClass(const JSHandle<TaggedArray> &properties, size_t length)
3876 {
3877     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3878     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
3879 
3880     uint32_t fieldOrder = 0;
3881     JSMutableHandle<JSTaggedValue> key(thread_, JSTaggedValue::Undefined());
3882     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(length);
3883     while (fieldOrder < length) {
3884         key.Update(properties->Get(fieldOrder * 2));  // 2: Meaning to double
3885         ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
3886         PropertyAttributes attributes = PropertyAttributes::Default();
3887 
3888         if (properties->Get(fieldOrder * 2 + 1).IsAccessor()) {  // 2: Meaning to double
3889             attributes.SetIsAccessor(true);
3890         }
3891 
3892         attributes.SetIsInlinedProps(true);
3893         attributes.SetRepresentation(Representation::TAGGED);
3894         attributes.SetOffset(fieldOrder);
3895         layoutInfoHandle->AddKey(thread_, fieldOrder, key.GetTaggedValue(), attributes);
3896         fieldOrder++;
3897     }
3898     ASSERT(fieldOrder <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
3899     JSHandle<JSHClass> objClass = NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, fieldOrder);
3900     objClass->SetPrototype(thread_, proto.GetTaggedValue());
3901     {
3902         objClass->SetExtensible(true);
3903         objClass->SetLayout(thread_, layoutInfoHandle);
3904         objClass->SetNumberOfProps(fieldOrder);
3905     }
3906     return objClass;
3907 }
3908 
SetLayoutInObjHClass(const JSHandle<TaggedArray> &properties, size_t length, const JSHandle<JSHClass> &objClass)3909 JSHandle<JSHClass> ObjectFactory::SetLayoutInObjHClass(const JSHandle<TaggedArray> &properties, size_t length,
3910                                                        const JSHandle<JSHClass> &objClass)
3911 {
3912     JSMutableHandle<JSTaggedValue> key(thread_, JSTaggedValue::Undefined());
3913     JSHandle<JSHClass> newObjHclass(objClass);
3914 
3915     for (size_t fieldOffset = 0; fieldOffset < length; fieldOffset++) {
3916         key.Update(properties->Get(fieldOffset * 2)); // 2 : pair of key and value
3917         ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
3918         PropertyAttributes attributes = PropertyAttributes::Default();
3919         auto value = properties->Get(fieldOffset * 2 + 1);
3920         if (value.IsAccessor()) {  // 2: Meaning to double
3921             attributes.SetIsAccessor(true);
3922         }
3923         attributes.SetIsInlinedProps(true);
3924         attributes.SetRepresentation(Representation::TAGGED);
3925         attributes.SetOffset(fieldOffset);
3926         attributes.SetRepresentation(Representation::TAGGED);
3927         auto rep = PropertyAttributes::TranslateToRep(value);
3928         newObjHclass = JSHClass::SetPropertyOfObjHClass(thread_, newObjHclass, key, attributes, rep);
3929     }
3930     return newObjHclass;
3931 }
3932 
CanObjectLiteralHClassCache(size_t length)3933 bool ObjectFactory::CanObjectLiteralHClassCache(size_t length)
3934 {
3935     return length <= MAX_LITERAL_HCLASS_CACHE_SIZE;
3936 }
3937 
CreateObjectLiteralRootHClass(size_t length)3938 JSHandle<JSHClass> ObjectFactory::CreateObjectLiteralRootHClass(size_t length)
3939 {
3940     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3941     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
3942     JSHandle<JSHClass> hclass = NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, length);
3943     hclass->SetPrototype(thread_, proto.GetTaggedValue());
3944     {
3945         hclass->SetNumberOfProps(0);
3946         hclass->SetExtensible(true);
3947     }
3948     return hclass;
3949 }
3950 
GetObjectLiteralRootHClass(size_t length)3951 JSHandle<JSHClass> ObjectFactory::GetObjectLiteralRootHClass(size_t length)
3952 {
3953     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3954     JSHandle<JSTaggedValue> maybeCache = env->GetObjectLiteralHClassCache();
3955     if (UNLIKELY(maybeCache->IsHole())) {
3956         JSHandle<TaggedArray> cacheArr = NewTaggedArray(MAX_LITERAL_HCLASS_CACHE_SIZE + 1);
3957         env->SetObjectLiteralHClassCache(thread_, cacheArr.GetTaggedValue());
3958         JSHandle<JSHClass> objHClass = CreateObjectLiteralRootHClass(length);
3959         cacheArr->Set(thread_, length, objHClass);
3960         return objHClass;
3961     }
3962     JSHandle<TaggedArray> hclassCacheArr = JSHandle<TaggedArray>::Cast(maybeCache);
3963     JSTaggedValue maybeHClass = hclassCacheArr->Get(length);
3964     if (UNLIKELY(maybeHClass.IsHole())) {
3965         JSHandle<JSHClass> objHClass = CreateObjectLiteralRootHClass(length);
3966         hclassCacheArr->Set(thread_, length, objHClass);
3967         return objHClass;
3968     }
3969     return JSHandle<JSHClass>(thread_, maybeHClass);
3970 }
3971 
GetObjectLiteralHClass(const JSHandle<TaggedArray> &properties, size_t length)3972 JSHandle<JSHClass> ObjectFactory::GetObjectLiteralHClass(const JSHandle<TaggedArray> &properties, size_t length)
3973 {
3974     ASSERT(length <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
3975     // 64 : If object literal gets too many properties, create hclass directly.
3976     if (!CanObjectLiteralHClassCache(length)) {
3977         return CreateObjectClass(properties, length);
3978     }
3979     JSHandle<JSHClass> rootHClass = GetObjectLiteralRootHClass(length);
3980     return SetLayoutInObjHClass(properties, length, rootHClass);
3981 }
3982 
NewOldSpaceObjLiteralByHClass(const JSHandle<JSHClass> &hclass)3983 JSHandle<JSObject> ObjectFactory::NewOldSpaceObjLiteralByHClass(const JSHandle<JSHClass> &hclass)
3984 {
3985     JSHandle<JSObject> obj = NewOldSpaceJSObject(hclass);
3986     InitializeJSObject(obj, hclass);
3987     return obj;
3988 }
3989 
NewEmptyJSObject(uint32_t inlinedProps)3990 JSHandle<JSObject> ObjectFactory::NewEmptyJSObject(uint32_t inlinedProps)
3991 {
3992     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3993     JSHandle<JSFunction> builtinObj(env->GetObjectFunction());
3994     return NewJSObjectByConstructor(builtinObj, inlinedProps);
3995 }
3996 
CreateNullJSObject()3997 JSHandle<JSObject> ObjectFactory::CreateNullJSObject()
3998 {
3999     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4000     JSHandle<JSTaggedValue> nullValue = globalConst->GetHandledNull();
4001     return OrdinaryNewJSObjectCreate(nullValue);
4002 }
4003 
NewSpaceBySnapshotAllocator(size_t size)4004 uintptr_t ObjectFactory::NewSpaceBySnapshotAllocator(size_t size)
4005 {
4006     NewObjectHook();
4007     return heap_->AllocateSnapshotSpace(size);
4008 }
4009 
NewMachineCodeObject(size_t length, MachineCodeDesc &desc)4010 TaggedObject *ObjectFactory::NewMachineCodeObject(size_t length,
4011     MachineCodeDesc &desc)
4012 {
4013     NewObjectHook();
4014     TaggedObject *obj = heap_->AllocateMachineCodeObject(
4015         JSHClass::Cast(thread_->GlobalConstants()->GetMachineCodeClass().GetTaggedObject()),
4016         length + MachineCode::SIZE, &desc);
4017     return (obj);
4018 }
4019 
NewMachineCodeObject(size_t length, const MachineCodeDesc &desc, JSHandle<Method> &method)4020 JSHandle<MachineCode> ObjectFactory::NewMachineCodeObject(size_t length,
4021     const MachineCodeDesc &desc, JSHandle<Method> &method)
4022 {
4023     NewObjectHook();
4024     TaggedObject *obj = heap_->AllocateMachineCodeObject(
4025         JSHClass::Cast(thread_->GlobalConstants()->GetMachineCodeClass().GetTaggedObject()),
4026         length + MachineCode::SIZE);
4027     return SetMachineCodeObjectData(obj, length, desc, method);
4028 }
4029 
SetMachineCodeObjectData(TaggedObject *obj, size_t length, const MachineCodeDesc &desc, JSHandle<Method> &method)4030 JSHandle<MachineCode> ObjectFactory::SetMachineCodeObjectData(TaggedObject *obj, size_t length,
4031     const MachineCodeDesc &desc, JSHandle<Method> &method)
4032 {
4033     MachineCode *code = MachineCode::Cast(obj);
4034     if (code == nullptr) {
4035         LOG_FULL(FATAL) << "machine code cast failed";
4036         UNREACHABLE();
4037     }
4038     if (code->SetData(desc, method, length)) {
4039         JSHandle<MachineCode> codeObj(thread_, code);
4040         return codeObj;
4041     } else {
4042         JSHandle<MachineCode> codeObj;
4043         return codeObj;
4044     }
4045 }
4046 
NewClassInfoExtractor(JSHandle<JSTaggedValue> method)4047 JSHandle<ClassInfoExtractor> ObjectFactory::NewClassInfoExtractor(JSHandle<JSTaggedValue> method)
4048 {
4049     NewObjectHook();
4050     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4051         JSHClass::Cast(thread_->GlobalConstants()->GetClassInfoExtractorHClass().GetTaggedObject()));
4052     JSHandle<ClassInfoExtractor> obj(thread_, header);
4053     obj->ClearBitField();
4054     obj->SetConstructorMethod(thread_, method.GetTaggedValue());
4055     JSHandle<TaggedArray> emptyArray = EmptyArray();
4056     obj->SetNonStaticKeys(thread_, emptyArray, SKIP_BARRIER);
4057     obj->SetNonStaticProperties(thread_, emptyArray, SKIP_BARRIER);
4058     obj->SetNonStaticElements(thread_, emptyArray, SKIP_BARRIER);
4059     obj->SetStaticKeys(thread_, emptyArray, SKIP_BARRIER);
4060     obj->SetStaticProperties(thread_, emptyArray, SKIP_BARRIER);
4061     obj->SetStaticElements(thread_, emptyArray, SKIP_BARRIER);
4062     return obj;
4063 }
4064 
4065 // ----------------------------------- new string ----------------------------------------
NewFromASCII(std::string_view data)4066 JSHandle<EcmaString> ObjectFactory::NewFromASCII(std::string_view data)
4067 {
4068     auto utf8Data = reinterpret_cast<const uint8_t *>(data.data());
4069     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, data.length()));
4070     return GetStringFromStringTable(utf8Data, data.length(), true);
4071 }
4072 
4073 // At this situation, Create string directly without using a StringTable.
NewFromASCIISkippingStringTable(std::string_view data)4074 JSHandle<EcmaString> ObjectFactory::NewFromASCIISkippingStringTable(std::string_view data)
4075 {
4076     auto utf8Data = reinterpret_cast<const uint8_t *>(data.data());
4077     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, data.length()));
4078     EcmaString *str = EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, data.length(), true);
4079     return JSHandle<EcmaString>(thread_, str);
4080 }
4081 
NewFromASCIINonMovable(std::string_view data)4082 JSHandle<EcmaString> ObjectFactory::NewFromASCIINonMovable(std::string_view data)
4083 {
4084     auto utf8Data = reinterpret_cast<const uint8_t *>(data.data());
4085     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, data.length()));
4086     return GetStringFromStringTableNonMovable(utf8Data, data.length());
4087 }
4088 
NewFromASCIIReadOnly(std::string_view data)4089 JSHandle<EcmaString> ObjectFactory::NewFromASCIIReadOnly(std::string_view data)
4090 {
4091     auto utf8Data = reinterpret_cast<const uint8_t *>(data.data());
4092     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, data.length()));
4093     return GetStringFromStringTableReadOnly(utf8Data, data.length());
4094 }
4095 
NewFromUtf8WithoutStringTable(std::string_view data)4096 JSHandle<EcmaString> ObjectFactory::NewFromUtf8WithoutStringTable(std::string_view data)
4097 {
4098     auto utf8Data = reinterpret_cast<const uint8_t *>(data.data());
4099     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, data.length());
4100     uint32_t utf8Len = data.length();
4101     NewObjectHook();
4102     if (utf8Len == 0) {
4103         return GetEmptyString();
4104     }
4105     EcmaString *str =
4106         EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress, MemSpaceType::SHARED_OLD_SPACE);
4107     uint32_t hashCode = EcmaStringAccessor::ComputeHashcodeUtf8(utf8Data, utf8Len, canBeCompress);
4108     str->SetMixHashcode(hashCode);
4109     return JSHandle<EcmaString>(thread_, str);
4110 }
4111 
NewFromUtf8(std::string_view data)4112 JSHandle<EcmaString> ObjectFactory::NewFromUtf8(std::string_view data)
4113 {
4114     auto utf8Data = reinterpret_cast<const uint8_t *>(data.data());
4115     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, data.length());
4116     return GetStringFromStringTable(utf8Data, data.length(), canBeCompress);
4117 }
4118 
NewFromUtf8(std::string_view data, bool canBeCompress)4119 JSHandle<EcmaString> ObjectFactory::NewFromUtf8(std::string_view data, bool canBeCompress)
4120 {
4121     auto utf8Data = reinterpret_cast<const uint8_t *>(data.data());
4122     ASSERT(canBeCompress == EcmaStringAccessor::CanBeCompressed(utf8Data, data.length()));
4123     return GetStringFromStringTable(utf8Data, data.length(), canBeCompress);
4124 }
4125 
NewFromUtf8ReadOnly(std::string_view data)4126 JSHandle<EcmaString> ObjectFactory::NewFromUtf8ReadOnly(std::string_view data)
4127 {
4128     auto utf8Data = reinterpret_cast<const uint8_t *>(data.data());
4129     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, data.length());
4130     return GetStringFromStringTableReadOnly(utf8Data, data.length(), canBeCompress);
4131 }
4132 
NewFromUtf16WithoutStringTable(std::u16string_view data)4133 JSHandle<EcmaString> ObjectFactory::NewFromUtf16WithoutStringTable(std::u16string_view data)
4134 {
4135     uint32_t utf16Len = data.length();
4136     auto utf16Data = reinterpret_cast<const uint16_t *>(data.data());
4137     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len);
4138     NewObjectHook();
4139     if (utf16Len == 0) {
4140         return GetEmptyString();
4141     }
4142     EcmaString *str =
4143         EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, canBeCompress, MemSpaceType::SHARED_OLD_SPACE);
4144     uint32_t hashCode = EcmaStringAccessor::ComputeHashcodeUtf16(const_cast<uint16_t *>(utf16Data), utf16Len);
4145     str->SetMixHashcode(hashCode);
4146     return JSHandle<EcmaString>(thread_, str);
4147 }
4148 
NewFromUtf16(std::u16string_view data)4149 JSHandle<EcmaString> ObjectFactory::NewFromUtf16(std::u16string_view data)
4150 {
4151     uint32_t length = data.length();
4152     auto utf16Data = reinterpret_cast<const uint16_t *>(data.data());
4153     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf16Data, length);
4154     return GetStringFromStringTable(utf16Data, length, canBeCompress);
4155 }
4156 
NewFromStdString(const std::string &data)4157 JSHandle<EcmaString> ObjectFactory::NewFromStdString(const std::string &data)
4158 {
4159     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
4160     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, data.length());
4161     return GetStringFromStringTable(utf8Data, data.size(), canBeCompress);
4162 }
4163 
NewFromUtf8WithoutStringTable(const uint8_t *utf8Data, uint32_t utf8Len)4164 JSHandle<EcmaString> ObjectFactory::NewFromUtf8WithoutStringTable(const uint8_t *utf8Data, uint32_t utf8Len)
4165 {
4166     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, utf8Len);
4167     NewObjectHook();
4168     if (utf8Len == 0) {
4169         return GetEmptyString();
4170     }
4171     EcmaString *str =
4172         EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress, MemSpaceType::SHARED_OLD_SPACE);
4173     uint32_t hashCode = EcmaStringAccessor::ComputeHashcodeUtf8(utf8Data, utf8Len, canBeCompress);
4174     str->SetMixHashcode(hashCode);
4175     return JSHandle<EcmaString>(thread_, str);
4176 }
4177 
NewFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len)4178 JSHandle<EcmaString> ObjectFactory::NewFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len)
4179 {
4180     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, utf8Len);
4181     return GetStringFromStringTable(utf8Data, utf8Len, canBeCompress);
4182 }
4183 
NewFromUtf16WithoutStringTable(const uint16_t *utf16Data, uint32_t utf16Len)4184 JSHandle<EcmaString> ObjectFactory::NewFromUtf16WithoutStringTable(const uint16_t *utf16Data, uint32_t utf16Len)
4185 {
4186     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len);
4187     NewObjectHook();
4188     if (utf16Len == 0) {
4189         return GetEmptyString();
4190     }
4191     EcmaString *str =
4192         EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, canBeCompress, MemSpaceType::SHARED_OLD_SPACE);
4193     uint32_t hashCode = EcmaStringAccessor::ComputeHashcodeUtf16(const_cast<uint16_t *>(utf16Data), utf16Len);
4194     str->SetMixHashcode(hashCode);
4195     return JSHandle<EcmaString>(thread_, str);
4196 }
4197 
NewFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len)4198 JSHandle<EcmaString> ObjectFactory::NewFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len)
4199 {
4200     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len);
4201     return GetStringFromStringTable(utf16Data, utf16Len, canBeCompress);
4202 }
4203 
NewFromUtf16Compress(const uint16_t *utf16Data, uint32_t utf16Len)4204 JSHandle<EcmaString> ObjectFactory::NewFromUtf16Compress(const uint16_t *utf16Data, uint32_t utf16Len)
4205 {
4206     ASSERT(EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len));
4207     return GetStringFromStringTable(utf16Data, utf16Len, true);
4208 }
4209 
NewFromUtf16NotCompress(const uint16_t *utf16Data, uint32_t utf16Len)4210 JSHandle<EcmaString> ObjectFactory::NewFromUtf16NotCompress(const uint16_t *utf16Data, uint32_t utf16Len)
4211 {
4212     ASSERT(!EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len));
4213     return GetStringFromStringTable(utf16Data, utf16Len, false);
4214 }
4215 
NewFromUtf8Literal(const uint8_t *utf8Data, uint32_t utf8Len)4216 JSHandle<EcmaString> ObjectFactory::NewFromUtf8Literal(const uint8_t *utf8Data, uint32_t utf8Len)
4217 {
4218     NewObjectHook();
4219     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, utf8Len);
4220     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress));
4221 }
4222 
NewFromUtf8LiteralCompress(const uint8_t *utf8Data, uint32_t utf8Len)4223 JSHandle<EcmaString> ObjectFactory::NewFromUtf8LiteralCompress(const uint8_t *utf8Data, uint32_t utf8Len)
4224 {
4225     NewObjectHook();
4226     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, utf8Len));
4227     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, true));
4228 }
4229 
NewFromUtf8LiteralCompressSubString(const JSHandle<EcmaString> &string, uint32_t offset, uint32_t utf8Len)4230 JSHandle<EcmaString> ObjectFactory::NewFromUtf8LiteralCompressSubString(const JSHandle<EcmaString> &string,
4231                                                                         uint32_t offset, uint32_t utf8Len)
4232 {
4233     NewObjectHook();
4234     ASSERT(EcmaStringAccessor::CanBeCompressed(EcmaStringAccessor(string).GetDataUtf8() + offset, utf8Len));
4235     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf8CompressedSubString(vm_, string,
4236         offset, utf8Len));
4237 }
4238 
NewCompressedUtf8(const uint8_t *utf8Data, uint32_t utf8Len)4239 JSHandle<EcmaString> ObjectFactory::NewCompressedUtf8(const uint8_t *utf8Data, uint32_t utf8Len)
4240 {
4241     NewObjectHook();
4242     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, utf8Len));
4243     return GetStringFromStringTable(utf8Data, utf8Len, true);
4244 }
4245 
NewCompressedUtf8SubString(const JSHandle<EcmaString> &string, uint32_t offset, uint32_t utf8Len)4246 JSHandle<EcmaString> ObjectFactory::NewCompressedUtf8SubString(const JSHandle<EcmaString> &string,
4247                                                                uint32_t offset, uint32_t utf8Len)
4248 {
4249     NewObjectHook();
4250     ASSERT(EcmaStringAccessor::CanBeCompressed(EcmaStringAccessor(string).GetDataUtf8() + offset, utf8Len));
4251     return GetCompressedSubStringFromStringTable(string, offset, utf8Len);
4252 }
4253 
NewFromUtf16Literal(const uint16_t *utf16Data, uint32_t utf16Len)4254 JSHandle<EcmaString> ObjectFactory::NewFromUtf16Literal(const uint16_t *utf16Data, uint32_t utf16Len)
4255 {
4256     NewObjectHook();
4257     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len);
4258     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, canBeCompress));
4259 }
4260 
NewFromUtf16LiteralCompress(const uint16_t *utf16Data, uint32_t utf16Len)4261 JSHandle<EcmaString> ObjectFactory::NewFromUtf16LiteralCompress(const uint16_t *utf16Data, uint32_t utf16Len)
4262 {
4263     NewObjectHook();
4264     ASSERT(EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len));
4265     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, true));
4266 }
4267 
NewFromUtf16LiteralNotCompress(const uint16_t *utf16Data, uint32_t utf16Len)4268 JSHandle<EcmaString> ObjectFactory::NewFromUtf16LiteralNotCompress(const uint16_t *utf16Data, uint32_t utf16Len)
4269 {
4270     NewObjectHook();
4271     ASSERT(!EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len));
4272     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, false));
4273 }
4274 
ConcatFromString(const JSHandle<EcmaString> &firstString, const JSHandle<EcmaString> &secondString)4275 JSHandle<EcmaString> ObjectFactory::ConcatFromString(const JSHandle<EcmaString> &firstString,
4276                                                      const JSHandle<EcmaString> &secondString)
4277 {
4278     if (EcmaStringAccessor(firstString).GetLength() == 0) {
4279         return secondString;
4280     }
4281     if (EcmaStringAccessor(secondString).GetLength() == 0) {
4282         return firstString;
4283     }
4284     return GetStringFromStringTable(firstString, secondString);
4285 }
4286 
GetStringFromStringTable(const JSHandle<EcmaString> &firstString, const JSHandle<EcmaString> &secondString)4287 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const JSHandle<EcmaString> &firstString,
4288                                                              const JSHandle<EcmaString> &secondString)
4289 {
4290     auto stringTable = vm_->GetEcmaStringTable();
4291     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(vm_, firstString, secondString));
4292 }
4293 
NewJSAPIArrayList(uint32_t capacity)4294 JSHandle<JSAPIArrayList> ObjectFactory::NewJSAPIArrayList(uint32_t capacity)
4295 {
4296     NewObjectHook();
4297     JSHandle<JSFunction> builtinObj(thread_, thread_->GlobalConstants()->GetArrayListFunction());
4298     JSHandle<JSAPIArrayList> obj = JSHandle<JSAPIArrayList>(NewJSObjectByConstructor(builtinObj));
4299     ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory();
4300     JSHandle<TaggedArray> elements = factory->NewTaggedArray(capacity);
4301     obj->SetElements(thread_, elements);
4302 
4303     return obj;
4304 }
4305 
NewJSAPIArrayListIterator(const JSHandle<JSAPIArrayList> &arrayList)4306 JSHandle<JSAPIArrayListIterator> ObjectFactory::NewJSAPIArrayListIterator(const JSHandle<JSAPIArrayList> &arrayList)
4307 {
4308     NewObjectHook();
4309     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4310     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetArrayListIteratorPrototype());
4311     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIArrayListIteratorClass());
4312     hclassHandle->SetPrototype(thread_, protoValue);
4313     JSHandle<JSAPIArrayListIterator> iter(NewJSObject(hclassHandle));
4314     iter->GetJSHClass()->SetExtensible(true);
4315     iter->SetIteratedArrayList(thread_, arrayList);
4316     iter->SetNextIndex(0);
4317     return iter;
4318 }
4319 
NewJSAPILightWeightMapIterator( const JSHandle<JSAPILightWeightMap> &obj, IterationKind kind)4320 JSHandle<JSAPILightWeightMapIterator> ObjectFactory::NewJSAPILightWeightMapIterator(
4321     const JSHandle<JSAPILightWeightMap> &obj, IterationKind kind)
4322 {
4323     NewObjectHook();
4324     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4325     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetLightWeightMapIteratorPrototype());
4326     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPILightWeightMapIteratorClass());
4327     hclassHandle->SetPrototype(thread_, protoValue);
4328     JSHandle<JSAPILightWeightMapIterator> iter(NewJSObject(hclassHandle));
4329     iter->GetJSHClass()->SetExtensible(true);
4330     iter->SetIteratedLightWeightMap(thread_, obj);
4331     iter->SetNextIndex(0);
4332     iter->SetIterationKind(kind);
4333     return iter;
4334 }
4335 
NewJSAPILightWeightSetIterator( const JSHandle<JSAPILightWeightSet> &obj, IterationKind kind)4336 JSHandle<JSAPILightWeightSetIterator> ObjectFactory::NewJSAPILightWeightSetIterator(
4337     const JSHandle<JSAPILightWeightSet> &obj, IterationKind kind)
4338 {
4339     NewObjectHook();
4340     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4341     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetLightWeightSetIteratorPrototype());
4342     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPILightWeightSetIteratorClass());
4343     hclassHandle->SetPrototype(thread_, protoValue);
4344     JSHandle<JSAPILightWeightSetIterator> iter(NewJSObject(hclassHandle));
4345     iter->GetJSHClass()->SetExtensible(true);
4346     iter->SetIteratedLightWeightSet(thread_, obj);
4347     iter->SetNextIndex(0);
4348     iter->SetIterationKind(kind);
4349     return iter;
4350 }
4351 
NewJSAPIPlainArray(uint32_t capacity)4352 JSHandle<JSAPIPlainArray> ObjectFactory::NewJSAPIPlainArray(uint32_t capacity)
4353 {
4354     NewObjectHook();
4355     JSHandle<JSFunction> builtinObj(thread_, thread_->GlobalConstants()->GetPlainArrayFunction());
4356     JSHandle<JSAPIPlainArray> obj = JSHandle<JSAPIPlainArray>(NewJSObjectByConstructor(builtinObj));
4357     ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory();
4358     JSHandle<TaggedArray> keyArray = factory->NewTaggedArray(capacity);
4359     JSHandle<TaggedArray> valueArray = factory->NewTaggedArray(capacity);
4360     obj->SetKeys(thread_, keyArray);
4361     obj->SetValues(thread_, valueArray);
4362 
4363     return obj;
4364 }
4365 
NewJSAPIPlainArrayIterator(const JSHandle<JSAPIPlainArray> &plainarray, IterationKind kind)4366 JSHandle<JSAPIPlainArrayIterator> ObjectFactory::NewJSAPIPlainArrayIterator(const JSHandle<JSAPIPlainArray> &plainarray,
4367                                                                             IterationKind kind)
4368 {
4369     NewObjectHook();
4370     JSHandle<JSTaggedValue> protoValue(thread_, thread_->GlobalConstants()->GetPlainArrayIteratorPrototype());
4371     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4372     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIPlainArrayIteratorClass());
4373     hclassHandle->SetPrototype(thread_, protoValue);
4374     JSHandle<JSAPIPlainArrayIterator> iter(NewJSObject(hclassHandle));
4375     iter->GetJSHClass()->SetExtensible(true);
4376     iter->SetIteratedPlainArray(thread_, plainarray);
4377     iter->SetNextIndex(0);
4378     iter->SetIterationKind(kind);
4379     return iter;
4380 }
4381 
NewJSAPIStackIterator(const JSHandle<JSAPIStack> &stack)4382 JSHandle<JSAPIStackIterator> ObjectFactory::NewJSAPIStackIterator(const JSHandle<JSAPIStack> &stack)
4383 {
4384     NewObjectHook();
4385     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4386     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetStackIteratorPrototype());
4387     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIStackIteratorClass());
4388     hclassHandle->SetPrototype(thread_, protoValue);
4389     JSHandle<JSAPIStackIterator> iter(NewJSObject(hclassHandle));
4390     iter->GetJSHClass()->SetExtensible(true);
4391     iter->SetIteratedStack(thread_, stack);
4392     iter->SetNextIndex(0);
4393     return iter;
4394 }
4395 
CopyDeque(const JSHandle<TaggedArray> &old, uint32_t newLength, [[maybe_unused]] uint32_t oldLength, uint32_t first, uint32_t last)4396 JSHandle<TaggedArray> ObjectFactory::CopyDeque(const JSHandle<TaggedArray> &old, uint32_t newLength,
4397                                                [[maybe_unused]] uint32_t oldLength, uint32_t first, uint32_t last)
4398 {
4399     NewObjectHook();
4400     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
4401     auto header = heap_->AllocateYoungOrHugeObject(
4402         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
4403     JSHandle<TaggedArray> newArray(thread_, header);
4404     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
4405 
4406     uint32_t curIndex = first;
4407     // newIndex use in new TaggedArray, 0 : New TaggedArray index
4408     uint32_t newIndex = 0;
4409     uint32_t oldCapacity = old->GetLength();
4410     while (curIndex != last) {
4411         JSTaggedValue value = old->Get(curIndex);
4412         newArray->Set(thread_, newIndex, value);
4413         ASSERT(oldCapacity != 0);
4414         curIndex = (curIndex + 1) % oldCapacity;
4415         newIndex = newIndex + 1;
4416     }
4417     return newArray;
4418 }
4419 
NewJSAPIDequeIterator(const JSHandle<JSAPIDeque> &deque)4420 JSHandle<JSAPIDequeIterator> ObjectFactory::NewJSAPIDequeIterator(const JSHandle<JSAPIDeque> &deque)
4421 {
4422     NewObjectHook();
4423     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4424     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetDequeIteratorPrototype());
4425     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIDequeIteratorClass());
4426     hclassHandle->SetPrototype(thread_, protoValue);
4427     JSHandle<JSAPIDequeIterator> iter(NewJSObject(hclassHandle));
4428     iter->GetJSHClass()->SetExtensible(true);
4429     iter->SetIteratedDeque(thread_, deque);
4430     iter->SetNextIndex(deque->GetFirst());
4431     return iter;
4432 }
4433 
CopyQueue(const JSHandle<TaggedArray> &old, uint32_t newLength, uint32_t front, uint32_t tail)4434 JSHandle<TaggedArray> ObjectFactory::CopyQueue(const JSHandle<TaggedArray> &old, uint32_t newLength,
4435                                                uint32_t front, uint32_t tail)
4436 {
4437     NewObjectHook();
4438     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
4439     auto header = heap_->AllocateYoungOrHugeObject(
4440         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
4441     JSHandle<TaggedArray> newArray(thread_, header);
4442     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
4443 
4444     uint32_t curIndex = front;
4445     // newIndex use in new TaggedArray, 0 : New TaggedArray index
4446     uint32_t newIndex = 0;
4447     uint32_t oldCapacity = old->GetLength();
4448     while (curIndex != tail) {
4449         JSTaggedValue value = old->Get(curIndex);
4450         newArray->Set(thread_, newIndex, value);
4451         ASSERT(oldCapacity != 0);
4452         curIndex = (curIndex + 1) % oldCapacity;
4453         newIndex = newIndex + 1;
4454     }
4455     return newArray;
4456 }
4457 
NewJSAPIQueueIterator(const JSHandle<JSAPIQueue> &queue)4458 JSHandle<JSAPIQueueIterator> ObjectFactory::NewJSAPIQueueIterator(const JSHandle<JSAPIQueue> &queue)
4459 {
4460     NewObjectHook();
4461     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4462     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetQueueIteratorPrototype());
4463     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIQueueIteratorClass());
4464     hclassHandle->SetPrototype(thread_, protoValue);
4465     JSHandle<JSAPIQueueIterator> iter(NewJSObject(hclassHandle));
4466     iter->GetJSHClass()->SetExtensible(true);
4467     iter->SetIteratedQueue(thread_, queue); // IteratedQueue
4468     iter->SetNextIndex(0);
4469     return iter;
4470 }
4471 
NewJSAPITreeMapIterator(const JSHandle<JSAPITreeMap> &map, IterationKind kind)4472 JSHandle<JSAPITreeMapIterator> ObjectFactory::NewJSAPITreeMapIterator(const JSHandle<JSAPITreeMap> &map,
4473                                                                       IterationKind kind)
4474 {
4475     NewObjectHook();
4476     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4477     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetTreeMapIteratorPrototype());
4478     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPITreeMapIteratorClass());
4479     hclassHandle->SetPrototype(thread_, proto);
4480     JSHandle<JSAPITreeMapIterator> iter(NewJSObject(hclassHandle));
4481     iter->GetJSHClass()->SetExtensible(true);
4482     iter->SetIteratedMap(thread_, map);
4483     iter->SetNextIndex(0);
4484     iter->SetEntries(thread_, JSTaggedValue::Hole());
4485     iter->SetIterationKind(kind);
4486     return iter;
4487 }
4488 
NewJSAPITreeSetIterator(const JSHandle<JSAPITreeSet> &set, IterationKind kind)4489 JSHandle<JSAPITreeSetIterator> ObjectFactory::NewJSAPITreeSetIterator(const JSHandle<JSAPITreeSet> &set,
4490                                                                       IterationKind kind)
4491 {
4492     NewObjectHook();
4493     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4494     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetTreeSetIteratorPrototype());
4495     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPITreeSetIteratorClass());
4496     hclassHandle->SetPrototype(thread_, proto);
4497     JSHandle<JSAPITreeSetIterator> iter(NewJSObject(hclassHandle));
4498     iter->GetJSHClass()->SetExtensible(true);
4499     iter->SetIteratedSet(thread_, set);
4500     iter->SetNextIndex(0);
4501     iter->SetEntries(thread_, JSTaggedValue::Hole());
4502     iter->SetIterationKind(kind);
4503     return iter;
4504 }
4505 
NewJSAPIVector(uint32_t capacity)4506 JSHandle<JSAPIVector> ObjectFactory::NewJSAPIVector(uint32_t capacity)
4507 {
4508     NewObjectHook();
4509     JSHandle<JSFunction> builtinObj(thread_, thread_->GlobalConstants()->GetVectorFunction());
4510     JSHandle<JSAPIVector> obj = JSHandle<JSAPIVector>(NewJSObjectByConstructor(builtinObj));
4511     JSHandle<TaggedArray> newVector = NewTaggedArray(capacity);
4512     obj->SetElements(thread_, newVector);
4513 
4514     return obj;
4515 }
4516 
NewJSAPIVectorIterator(const JSHandle<JSAPIVector> &vector)4517 JSHandle<JSAPIVectorIterator> ObjectFactory::NewJSAPIVectorIterator(const JSHandle<JSAPIVector> &vector)
4518 {
4519     NewObjectHook();
4520     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4521     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetVectorIteratorPrototype());
4522     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIVectorIteratorClass());
4523     hclassHandle->SetPrototype(thread_, proto);
4524     JSHandle<JSAPIVectorIterator> iter(NewJSObject(hclassHandle));
4525     iter->GetJSHClass()->SetExtensible(true);
4526     iter->SetIteratedVector(thread_, vector);
4527     iter->SetNextIndex(0);
4528     return iter;
4529 }
4530 
NewJSAPIBitVector(uint32_t capacity)4531 JSHandle<JSAPIBitVector> ObjectFactory::NewJSAPIBitVector(uint32_t capacity)
4532 {
4533     NewObjectHook();
4534     JSHandle<JSFunction> builtinObj(thread_, thread_->GlobalConstants()->GetBitVectorFunction());
4535     JSHandle<JSAPIBitVector> obj = JSHandle<JSAPIBitVector>(NewJSObjectByConstructor(builtinObj));
4536     uint32_t taggedArrayCapacity = (capacity >> JSAPIBitVector::TAGGED_VALUE_BIT_SIZE) + 1;
4537     auto *newBitSetVector = new std::vector<std::bitset<JSAPIBitVector::BIT_SET_LENGTH>>();
4538     newBitSetVector->resize(taggedArrayCapacity, 0);
4539     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newBitSetVector);
4540     obj->SetNativePointer(thread_, pointer);
4541 
4542     return obj;
4543 }
4544 
NewJSAPIBitVectorIterator(const JSHandle<JSAPIBitVector> &bitVector)4545 JSHandle<JSAPIBitVectorIterator> ObjectFactory::NewJSAPIBitVectorIterator(const JSHandle<JSAPIBitVector> &bitVector)
4546 {
4547     NewObjectHook();
4548     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4549     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetBitVectorIteratorPrototype());
4550     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIBitVectorIteratorClass());
4551     hclassHandle->SetPrototype(thread_, proto);
4552     JSHandle<JSAPIBitVectorIterator> iter(NewJSObject(hclassHandle));
4553     iter->GetJSHClass()->SetExtensible(true);
4554     iter->SetIteratedBitVector(thread_, bitVector);
4555     iter->SetNextIndex(0);
4556     return iter;
4557 }
4558 
NewJSAPILinkedListIterator(const JSHandle<JSAPILinkedList> &linkedList)4559 JSHandle<JSAPILinkedListIterator> ObjectFactory::NewJSAPILinkedListIterator(const JSHandle<JSAPILinkedList> &linkedList)
4560 {
4561     NewObjectHook();
4562     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4563     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetLinkedListIteratorPrototype());
4564     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPILinkedListIteratorClass());
4565     hclassHandle->SetPrototype(thread_, proto);
4566     JSHandle<JSAPILinkedListIterator> iter(NewJSObject(hclassHandle));
4567     iter->GetJSHClass()->SetExtensible(true);
4568     iter->SetIteratedLinkedList(thread_, linkedList->GetDoubleList());
4569     iter->SetNextIndex(0);
4570     const uint32_t linkedListElementStartIndex = 4;
4571     iter->SetDataIndex(linkedListElementStartIndex);
4572     return iter;
4573 }
4574 
NewJSAPIListIterator(const JSHandle<JSAPIList> &List)4575 JSHandle<JSAPIListIterator> ObjectFactory::NewJSAPIListIterator(const JSHandle<JSAPIList> &List)
4576 {
4577     NewObjectHook();
4578     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
4579     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetListIteratorPrototype());
4580     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIListIteratorClass());
4581     hclassHandle->SetPrototype(thread_, proto);
4582     JSHandle<JSAPIListIterator> iter(NewJSObject(hclassHandle));
4583     iter->GetJSHClass()->SetExtensible(true);
4584     iter->SetIteratedList(thread_, List->GetSingleList());
4585     iter->SetNextIndex(0);
4586     const uint32_t linkedListElementStartIndex = 4;
4587     iter->SetDataIndex(linkedListElementStartIndex);
4588     return iter;
4589 }
4590 
NewJSAPIList()4591 JSHandle<JSAPIList> ObjectFactory::NewJSAPIList()
4592 {
4593     NewObjectHook();
4594     JSHandle<JSFunction> function(thread_, thread_->GlobalConstants()->GetListFunction());
4595     return JSHandle<JSAPIList>::Cast(NewJSObjectByConstructor(function));
4596 }
4597 
NewJSAPILinkedList()4598 JSHandle<JSAPILinkedList> ObjectFactory::NewJSAPILinkedList()
4599 {
4600     NewObjectHook();
4601     JSHandle<JSFunction> function(thread_, thread_->GlobalConstants()->GetLinkedListFunction());
4602     return JSHandle<JSAPILinkedList>::Cast(NewJSObjectByConstructor(function));
4603 }
4604 
NewImportEntry()4605 JSHandle<ImportEntry> ObjectFactory::NewImportEntry()
4606 {
4607     JSHandle<JSTaggedValue> defautValue = thread_->GlobalConstants()->GetHandledUndefined();
4608     return NewImportEntry(defautValue, defautValue, defautValue, SharedTypes::UNSENDABLE_MODULE);
4609 }
4610 
NewImportEntry(const JSHandle<JSTaggedValue> &moduleRequest, const JSHandle<JSTaggedValue> &importName, const JSHandle<JSTaggedValue> &localName, SharedTypes sharedTypes)4611 JSHandle<ImportEntry> ObjectFactory::NewImportEntry(const JSHandle<JSTaggedValue> &moduleRequest,
4612                                                     const JSHandle<JSTaggedValue> &importName,
4613                                                     const JSHandle<JSTaggedValue> &localName,
4614                                                     SharedTypes sharedTypes)
4615 {
4616     if (sharedTypes == SharedTypes::SHARED_MODULE) {
4617         return NewSImportEntry(moduleRequest, importName, localName);
4618     }
4619     NewObjectHook();
4620     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4621         JSHClass::Cast(thread_->GlobalConstants()->GetImportEntryClass().GetTaggedObject()));
4622     JSHandle<ImportEntry> obj(thread_, header);
4623     obj->SetModuleRequest(thread_, moduleRequest);
4624     obj->SetImportName(thread_, importName);
4625     obj->SetLocalName(thread_, localName);
4626     return obj;
4627 }
4628 
NewLocalExportEntry()4629 JSHandle<LocalExportEntry> ObjectFactory::NewLocalExportEntry()
4630 {
4631     JSHandle<JSTaggedValue> defautValue = thread_->GlobalConstants()->GetHandledUndefined();
4632     return NewLocalExportEntry(defautValue, defautValue, LocalExportEntry::LOCAL_DEFAULT_INDEX,
4633                                SharedTypes::UNSENDABLE_MODULE);
4634 }
4635 
NewLocalExportEntry(const JSHandle<JSTaggedValue> &exportName, const JSHandle<JSTaggedValue> &localName, const uint32_t index, SharedTypes sharedTypes)4636 JSHandle<LocalExportEntry> ObjectFactory::NewLocalExportEntry(const JSHandle<JSTaggedValue> &exportName,
4637     const JSHandle<JSTaggedValue> &localName, const uint32_t index, SharedTypes sharedTypes)
4638 {
4639     if (sharedTypes == SharedTypes::SHARED_MODULE) {
4640         return NewSLocalExportEntry(exportName, localName, index);
4641     }
4642     NewObjectHook();
4643     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4644         JSHClass::Cast(thread_->GlobalConstants()->GetLocalExportEntryClass().GetTaggedObject()));
4645     JSHandle<LocalExportEntry> obj(thread_, header);
4646     obj->SetExportName(thread_, exportName);
4647     obj->SetLocalName(thread_, localName);
4648     obj->SetLocalIndex(index);
4649     return obj;
4650 }
4651 
NewIndirectExportEntry()4652 JSHandle<IndirectExportEntry> ObjectFactory::NewIndirectExportEntry()
4653 {
4654     JSHandle<JSTaggedValue> defautValue = thread_->GlobalConstants()->GetHandledUndefined();
4655     return NewIndirectExportEntry(defautValue, defautValue, defautValue, SharedTypes::UNSENDABLE_MODULE);
4656 }
4657 
NewIndirectExportEntry(const JSHandle<JSTaggedValue> &exportName, const JSHandle<JSTaggedValue> &moduleRequest, const JSHandle<JSTaggedValue> &importName, SharedTypes sharedTypes)4658 JSHandle<IndirectExportEntry> ObjectFactory::NewIndirectExportEntry(const JSHandle<JSTaggedValue> &exportName,
4659                                                                     const JSHandle<JSTaggedValue> &moduleRequest,
4660                                                                     const JSHandle<JSTaggedValue> &importName,
4661                                                                     SharedTypes sharedTypes)
4662 {
4663     if (sharedTypes == SharedTypes::SHARED_MODULE) {
4664         return NewSIndirectExportEntry(exportName, moduleRequest, importName);
4665     }
4666     NewObjectHook();
4667     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4668         JSHClass::Cast(thread_->GlobalConstants()->GetIndirectExportEntryClass().GetTaggedObject()));
4669     JSHandle<IndirectExportEntry> obj(thread_, header);
4670     obj->SetExportName(thread_, exportName);
4671     obj->SetModuleRequest(thread_, moduleRequest);
4672     obj->SetImportName(thread_, importName);
4673     return obj;
4674 }
4675 
NewStarExportEntry()4676 JSHandle<StarExportEntry> ObjectFactory::NewStarExportEntry()
4677 {
4678     JSHandle<JSTaggedValue> defautValue = thread_->GlobalConstants()->GetHandledUndefined();
4679     return NewStarExportEntry(defautValue, SharedTypes::UNSENDABLE_MODULE);
4680 }
4681 
NewStarExportEntry(const JSHandle<JSTaggedValue> &moduleRequest, SharedTypes sharedTypes)4682 JSHandle<StarExportEntry> ObjectFactory::NewStarExportEntry(const JSHandle<JSTaggedValue> &moduleRequest,
4683                                                             SharedTypes sharedTypes)
4684 {
4685     if (sharedTypes == SharedTypes::SHARED_MODULE) {
4686         return NewSStarExportEntry(moduleRequest);
4687     }
4688     NewObjectHook();
4689     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4690         JSHClass::Cast(thread_->GlobalConstants()->GetStarExportEntryClass().GetTaggedObject()));
4691     JSHandle<StarExportEntry> obj(thread_, header);
4692     obj->SetModuleRequest(thread_, moduleRequest);
4693     return obj;
4694 }
4695 
NewSourceTextModule()4696 JSHandle<SourceTextModule> ObjectFactory::NewSourceTextModule()
4697 {
4698     NewObjectHook();
4699     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4700         JSHClass::Cast(thread_->GlobalConstants()->GetSourceTextModuleClass().GetTaggedObject()));
4701     JSHandle<SourceTextModule> obj(thread_, header);
4702     JSTaggedValue undefinedValue = thread_->GlobalConstants()->GetUndefined();
4703     obj->SetEnvironment(thread_, undefinedValue);
4704     obj->SetNamespace(thread_, undefinedValue);
4705     obj->SetRequestedModules(thread_, undefinedValue);
4706     obj->SetImportEntries(thread_, undefinedValue);
4707     obj->SetLocalExportEntries(thread_, undefinedValue);
4708     obj->SetIndirectExportEntries(thread_, undefinedValue);
4709     obj->SetStarExportEntries(thread_, undefinedValue);
4710     obj->SetNameDictionary(thread_, undefinedValue);
4711     // [[CycleRoot]]: For a module not in a cycle, this would be the module itself.
4712     obj->SetCycleRoot(thread_, obj);
4713     obj->SetTopLevelCapability(thread_, undefinedValue);
4714     obj->SetAsyncParentModules(thread_, undefinedValue);
4715     obj->SetHasTLA(false);
4716     obj->SetAsyncEvaluatingOrdinal(SourceTextModule::NOT_ASYNC_EVALUATED);
4717     obj->SetPendingAsyncDependencies(SourceTextModule::UNDEFINED_INDEX);
4718     obj->SetDFSIndex(SourceTextModule::UNDEFINED_INDEX);
4719     obj->SetDFSAncestorIndex(SourceTextModule::UNDEFINED_INDEX);
4720     obj->SetEvaluationError(SourceTextModule::UNDEFINED_INDEX);
4721     obj->SetStatus(ModuleStatus::UNINSTANTIATED);
4722     obj->SetTypes(ModuleTypes::UNKNOWN);
4723     obj->SetIsNewBcVersion(false);
4724     obj->SetRegisterCounts(UINT16_MAX);
4725     obj->SetLazyImportStatus(ToUintPtr(nullptr));
4726     obj->SetEcmaModuleFilename(ToUintPtr(nullptr));
4727     obj->SetEcmaModuleRecordName(ToUintPtr(nullptr));
4728     obj->SetSharedType(SharedTypes::UNSENDABLE_MODULE);
4729     obj->SetSendableEnv(thread_, undefinedValue);
4730     return obj;
4731 }
4732 
NewResolvedBindingRecord()4733 JSHandle<ResolvedBinding> ObjectFactory::NewResolvedBindingRecord()
4734 {
4735     JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
4736     JSHandle<SourceTextModule> ecmaModule(undefinedValue);
4737     JSHandle<JSTaggedValue> bindingName(undefinedValue);
4738     return NewResolvedBindingRecord(ecmaModule, bindingName);
4739 }
4740 
NewResolvedBindingRecord(const JSHandle<SourceTextModule> &module, const JSHandle<JSTaggedValue> &bindingName)4741 JSHandle<ResolvedBinding> ObjectFactory::NewResolvedBindingRecord(const JSHandle<SourceTextModule> &module,
4742                                                                   const JSHandle<JSTaggedValue> &bindingName)
4743 {
4744     NewObjectHook();
4745     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4746         JSHClass::Cast(thread_->GlobalConstants()->GetResolvedBindingClass().GetTaggedObject()));
4747     JSHandle<ResolvedBinding> obj(thread_, header);
4748     obj->SetModule(thread_, module);
4749     obj->SetBindingName(thread_, bindingName);
4750     return obj;
4751 }
4752 
NewResolvedIndexBindingRecord()4753 JSHandle<ResolvedIndexBinding> ObjectFactory::NewResolvedIndexBindingRecord()
4754 {
4755     JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
4756     JSHandle<SourceTextModule> ecmaModule(undefinedValue);
4757     int32_t index = 0;
4758     return NewResolvedIndexBindingRecord(ecmaModule, index);
4759 }
4760 
NewResolvedIndexBindingRecord(const JSHandle<SourceTextModule> &module, int32_t index)4761 JSHandle<ResolvedIndexBinding> ObjectFactory::NewResolvedIndexBindingRecord(const JSHandle<SourceTextModule> &module,
4762                                                                             int32_t index)
4763 {
4764     NewObjectHook();
4765     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4766         JSHClass::Cast(thread_->GlobalConstants()->GetResolvedIndexBindingClass().GetTaggedObject()));
4767     JSHandle<ResolvedIndexBinding> obj(thread_, header);
4768     obj->SetModule(thread_, module);
4769     obj->SetIndex(index);
4770     return obj;
4771 }
4772 
NewCellRecord()4773 JSHandle<CellRecord> ObjectFactory::NewCellRecord()
4774 {
4775     NewObjectHook();
4776     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4777         JSHClass::Cast(thread_->GlobalConstants()->GetCellRecordClass().GetTaggedObject()));
4778     JSHandle<CellRecord> obj(thread_, header);
4779     obj->SetWeakRefTarget(thread_, JSTaggedValue::Undefined());
4780     obj->SetHeldValue(thread_, JSTaggedValue::Undefined());
4781     return obj;
4782 }
4783 
CreateIteratorResultInstanceClass(const JSHandle<GlobalEnv> &env)4784 JSHandle<JSHClass> ObjectFactory::CreateIteratorResultInstanceClass(const JSHandle<GlobalEnv> &env)
4785 {
4786     auto globalConst = thread_->GlobalConstants();
4787     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
4788     JSHandle<JSHClass> iterResultClass = NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, proto);
4789 
4790     uint32_t fieldOrder = 0;
4791     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(2); // 2 means two field
4792     {
4793         ASSERT(JSIterator::VALUE_INLINE_PROPERTY_INDEX == fieldOrder);
4794         PropertyAttributes attributes = PropertyAttributes::Default();
4795         attributes.SetIsInlinedProps(true);
4796         attributes.SetRepresentation(Representation::TAGGED);
4797         attributes.SetOffset(fieldOrder);
4798         layoutInfoHandle->AddKey(thread_, fieldOrder++, globalConst->GetValueString(), attributes);
4799     }
4800     {
4801         ASSERT(JSIterator::DONE_INLINE_PROPERTY_INDEX == fieldOrder);
4802         PropertyAttributes attributes = PropertyAttributes::Default();
4803         attributes.SetIsInlinedProps(true);
4804         attributes.SetRepresentation(Representation::TAGGED);
4805         attributes.SetOffset(fieldOrder);
4806         layoutInfoHandle->AddKey(thread_, fieldOrder++, globalConst->GetDoneString(), attributes);
4807     }
4808 
4809     {
4810         iterResultClass->SetLayout(thread_, layoutInfoHandle);
4811         iterResultClass->SetNumberOfProps(fieldOrder);
4812     }
4813     return iterResultClass;
4814 }
4815 
NewOldSpaceObject(const JSHandle<JSHClass> &hclass)4816 TaggedObject *ObjectFactory::NewOldSpaceObject(const JSHandle<JSHClass> &hclass)
4817 {
4818     NewObjectHook();
4819     TaggedObject *header = heap_->AllocateOldOrHugeObject(*hclass);
4820     uint32_t inobjPropCount = hclass->GetInlinedProperties();
4821     if (inobjPropCount > 0) {
4822         InitializeExtraProperties(hclass, header, inobjPropCount);
4823     }
4824     return header;
4825 }
4826 
NewOldSpaceJSObject(const JSHandle<JSHClass> &jshclass)4827 JSHandle<JSObject> ObjectFactory::NewOldSpaceJSObject(const JSHandle<JSHClass> &jshclass)
4828 {
4829     JSHandle<JSObject> obj(thread_, JSObject::Cast(NewOldSpaceObject(jshclass)));
4830     JSHandle<TaggedArray> emptyArray = EmptyArray();
4831     obj->InitializeHash();
4832     obj->SetElements(thread_, emptyArray);
4833     obj->SetProperties(thread_, emptyArray);
4834     return obj;
4835 }
4836 
NewOldSpaceTaggedArray(uint32_t length, JSTaggedValue initVal)4837 JSHandle<TaggedArray> ObjectFactory::NewOldSpaceTaggedArray(uint32_t length, JSTaggedValue initVal)
4838 {
4839     return NewTaggedArray(length, initVal, MemSpaceType::OLD_SPACE);
4840 }
4841 
NewJSStableArrayWithElements(const JSHandle<TaggedArray> &elements)4842 JSHandle<JSArray> ObjectFactory::NewJSStableArrayWithElements(const JSHandle<TaggedArray> &elements)
4843 {
4844     JSHandle<JSHClass> cls(thread_,
4845                            JSHandle<JSFunction>::Cast(vm_->GetGlobalEnv()->GetArrayFunction())->GetProtoOrHClass());
4846     JSHandle<JSArray> array = JSHandle<JSArray>::Cast(NewJSObject(cls));
4847     array->SetElements(thread_, elements);
4848     array->SetLength(elements->GetLength());
4849     array->SetTrackInfo(thread_, JSTaggedValue::Undefined());
4850     auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
4851     array->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
4852     return array;
4853 }
4854 
NewJSAsyncGeneratorFunction(const JSHandle<Method> &method)4855 JSHandle<JSFunction> ObjectFactory::NewJSAsyncGeneratorFunction(const JSHandle<Method> &method)
4856 {
4857     NewObjectHook();
4858     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
4859 
4860     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetAsyncGeneratorFunctionClass());
4861     JSHandle<JSFunction> asyncGeneratorFunc = JSHandle<JSFunction>::Cast(NewJSObject(hclass));
4862     JSFunction::InitializeJSFunction(thread_, asyncGeneratorFunc, FunctionKind::ASYNC_GENERATOR_FUNCTION);
4863     asyncGeneratorFunc->SetMethod(thread_, method);
4864     return asyncGeneratorFunc;
4865 }
4866 
NewAsyncGeneratorRequest()4867 JSHandle<AsyncGeneratorRequest> ObjectFactory::NewAsyncGeneratorRequest()
4868 {
4869     NewObjectHook();
4870     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4871         JSHClass::Cast(thread_->GlobalConstants()->GetAsyncGeneratorRequestRecordClass().GetTaggedObject()));
4872     JSHandle<AsyncGeneratorRequest> obj(thread_, header);
4873     obj->SetCompletion(thread_, JSTaggedValue::Undefined());
4874     obj->SetCapability(thread_, JSTaggedValue::Undefined());
4875     return obj;
4876 }
4877 
NewAsyncIteratorRecord(const JSHandle<JSTaggedValue> &itor, const JSHandle<JSTaggedValue> &next, bool done)4878 JSHandle<AsyncIteratorRecord> ObjectFactory::NewAsyncIteratorRecord(const JSHandle<JSTaggedValue> &itor,
4879                                                                     const JSHandle<JSTaggedValue> &next, bool done)
4880 {
4881     NewObjectHook();
4882     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4883         JSHClass::Cast(thread_->GlobalConstants()->GetAsyncIteratorRecordClass().GetTaggedObject()));
4884     JSHandle<AsyncIteratorRecord> obj(thread_, header);
4885     obj->SetIterator(thread_, itor.GetTaggedValue());
4886     obj->SetNextMethod(thread_, next.GetTaggedValue());
4887     obj->SetDone(done);
4888     return obj;
4889 }
4890 
NewAOTLiteralInfo(uint32_t length, JSTaggedValue initVal)4891 JSHandle<AOTLiteralInfo> ObjectFactory::NewAOTLiteralInfo(uint32_t length, JSTaggedValue initVal)
4892 {
4893     NewObjectHook();
4894     size_t size = AOTLiteralInfo::ComputeSize(length);
4895     auto header = heap_->AllocateYoungOrHugeObject(
4896         JSHClass::Cast(thread_->GlobalConstants()->GetAOTLiteralInfoClass().GetTaggedObject()), size);
4897 
4898     JSHandle<AOTLiteralInfo> aotLiteralInfo(thread_, header);
4899     aotLiteralInfo->InitializeWithSpecialValue(initVal, length);
4900     return aotLiteralInfo;
4901 }
4902 
NewExtraProfileTypeInfo()4903 JSHandle<ExtraProfileTypeInfo> ObjectFactory::NewExtraProfileTypeInfo()
4904 {
4905     NewObjectHook();
4906     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4907         JSHClass::Cast(thread_->GlobalConstants()->GetExtraProfileTypeInfoClass().GetTaggedObject()));
4908     JSHandle<ExtraProfileTypeInfo> extraProfileTypeInfo(thread_, header);
4909     extraProfileTypeInfo->SetReceiverObject(thread_, JSTaggedValue::Undefined());
4910     extraProfileTypeInfo->SetHolderObject(thread_, JSTaggedValue::Undefined());
4911     return extraProfileTypeInfo;
4912 }
4913 
NewProfileTypeInfoCell(const JSHandle<JSTaggedValue> &value)4914 JSHandle<ProfileTypeInfoCell> ObjectFactory::NewProfileTypeInfoCell(const JSHandle<JSTaggedValue> &value)
4915 {
4916     NewObjectHook();
4917     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4918         JSHClass::Cast(thread_->GlobalConstants()->GetProfileTypeInfoCell0Class().GetTaggedObject()));
4919     JSHandle<ProfileTypeInfoCell> profileTypeInfoCell(thread_, header);
4920     profileTypeInfoCell->SetValue(thread_, value.GetTaggedValue());
4921     profileTypeInfoCell->SetMachineCode(thread_, JSTaggedValue::Hole());
4922     profileTypeInfoCell->SetHandle(thread_, JSTaggedValue::Undefined());
4923     return profileTypeInfoCell;
4924 }
4925 
NewFunctionTemplate( const JSHandle<Method> &method, const JSHandle<JSTaggedValue> &module, int32_t length)4926 JSHandle<FunctionTemplate> ObjectFactory::NewFunctionTemplate(
4927     const JSHandle<Method> &method, const JSHandle<JSTaggedValue> &module, int32_t length)
4928 {
4929     NewObjectHook();
4930     auto globalConstants = thread_->GlobalConstants();
4931     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4932         JSHClass::Cast(globalConstants->GetFunctionTemplateClass().GetTaggedObject()));
4933     JSHandle<FunctionTemplate> funcTemp(thread_, header);
4934     funcTemp->SetMethod(thread_, method);
4935     funcTemp->SetModule(thread_, module);
4936     funcTemp->SetRawProfileTypeInfo(thread_, globalConstants->GetEmptyProfileTypeInfoCell(), SKIP_BARRIER);
4937     funcTemp->SetLength(length);
4938     return funcTemp;
4939 }
4940 
NewVTable(uint32_t length, JSTaggedValue initVal)4941 JSHandle<VTable> ObjectFactory::NewVTable(uint32_t length, JSTaggedValue initVal)
4942 {
4943     NewObjectHook();
4944     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length * VTable::TUPLE_SIZE);
4945     auto header = heap_->AllocateYoungOrHugeObject(
4946         JSHClass::Cast(thread_->GlobalConstants()->GetVTableClass().GetTaggedObject()), size);
4947 
4948     JSHandle<VTable> vtable(thread_, header);
4949     vtable->InitializeWithSpecialValue(initVal, length * VTable::TUPLE_SIZE);
4950     return vtable;
4951 }
4952 
NewClassLiteral()4953 JSHandle<ClassLiteral> ObjectFactory::NewClassLiteral()
4954 {
4955     NewObjectHook();
4956 
4957     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4958         JSHClass::Cast(thread_->GlobalConstants()->GetClassLiteralClass().GetTaggedObject()));
4959     JSHandle<TaggedArray> emptyArray = EmptyArray();
4960 
4961     JSHandle<ClassLiteral> classLiteral(thread_, header);
4962     classLiteral->SetArray(thread_, emptyArray);
4963     classLiteral->SetIsAOTUsed(false);
4964 
4965     return classLiteral;
4966 }
4967 
NewJSFunction(const JSHandle<Method> &methodHandle)4968 JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<Method> &methodHandle)
4969 {
4970     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
4971     FunctionKind kind = methodHandle->GetFunctionKind();
4972     JSHandle<JSHClass> hclass;
4973     switch (kind) {
4974         case FunctionKind::NORMAL_FUNCTION:
4975         case FunctionKind::BASE_CONSTRUCTOR: {
4976             hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
4977             break;
4978         }
4979         case FunctionKind::ARROW_FUNCTION: {
4980             hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
4981             break;
4982         }
4983         case FunctionKind::GENERATOR_FUNCTION: {
4984             hclass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
4985             break;
4986         }
4987         case FunctionKind::CONCURRENT_FUNCTION:
4988         case FunctionKind::ASYNC_ARROW_FUNCTION:
4989         case FunctionKind::ASYNC_FUNCTION: {
4990             hclass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
4991             break;
4992         }
4993         case FunctionKind::ASYNC_GENERATOR_FUNCTION: {
4994             hclass = JSHandle<JSHClass>::Cast(env->GetAsyncGeneratorFunctionClass());
4995             break;
4996         }
4997         default:
4998             LOG_ECMA(FATAL) << "this branch is unreachable";
4999             UNREACHABLE();
5000     }
5001 
5002     JSHandle<JSFunction> jsfunc = NewJSFunctionByHClass(methodHandle, hclass);
5003     ASSERT_NO_ABRUPT_COMPLETION(thread_);
5004     return jsfunc;
5005 }
5006 
NewJSFunction(const JSHandle<Method> &methodHandle, const JSHandle<JSTaggedValue> &homeObject)5007 JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<Method> &methodHandle,
5008                                                   const JSHandle<JSTaggedValue> &homeObject)
5009 {
5010     ASSERT(homeObject->IsECMAObject());
5011     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
5012     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
5013 
5014     JSHandle<JSFunction> jsFunc = NewJSFunctionByHClass(methodHandle, hclass);
5015     jsFunc->SetHomeObject(thread_, homeObject);
5016     ASSERT_NO_ABRUPT_COMPLETION(thread_);
5017     return jsFunc;
5018 }
5019 
CreateJSObjectWithProperties(size_t propertyCount, const Local<JSValueRef> *keys, const PropertyDescriptor *descs)5020 JSHandle<JSTaggedValue> ObjectFactory::CreateJSObjectWithProperties(size_t propertyCount,
5021                                                                     const Local<JSValueRef> *keys,
5022                                                                     const PropertyDescriptor *descs)
5023 {
5024     if (!CanObjectLiteralHClassCache(propertyCount)) {
5025         return CreateLargeJSObjectWithProperties(propertyCount, keys, descs);
5026     }
5027 
5028     // At least 4 inlined slot
5029     int inlineProps = std::max(static_cast<int>(propertyCount), JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS);
5030     JSMutableHandle<JSHClass> hclassHandle(thread_, GetObjectLiteralRootHClass(inlineProps));
5031     for (size_t i = 0; i < propertyCount; ++i) {
5032         JSMutableHandle<JSTaggedValue> key(JSNApiHelper::ToJSMutableHandle(keys[i]));
5033         if (key->IsString() && !EcmaStringAccessor(key.GetTaggedValue()).IsInternString()) {
5034             // update string stable
5035             key.Update(JSTaggedValue(InternString(key)));
5036         }
5037         ASSERT(EcmaStringAccessor(key->GetTaggedObject()).IsInternString());
5038         if (UNLIKELY(!JSTaggedValue::IsPureString(key.GetTaggedValue()))) {
5039             THROW_TYPE_ERROR_AND_RETURN(thread_, "property key must be string and can not convert into element index",
5040                                         JSHandle<JSTaggedValue>());
5041         }
5042         PropertyAttributes attr(descs[i]);
5043         attr.SetIsInlinedProps(true);
5044         attr.SetOffset(i);
5045         attr.SetRepresentation(Representation::TAGGED);
5046         auto value = descs[i].GetValue().GetTaggedValue();
5047         auto rep = PropertyAttributes::TranslateToRep(value);
5048         hclassHandle.Update(JSHClass::SetPropertyOfObjHClass<true>(thread_, hclassHandle, key, attr, rep));
5049         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, JSHandle<JSTaggedValue>());
5050     }
5051     JSHandle<JSObject> object = NewJSObject(hclassHandle);
5052 
5053     for (size_t i = 0; i < propertyCount; ++i) {
5054         object->SetPropertyInlinedProps<true>(thread_, i, descs[i].GetValue().GetTaggedValue());
5055     }
5056     return JSHandle<JSTaggedValue>(object);
5057 }
5058 
CreateLargeJSObjectWithProperties(size_t propertyCount, const Local<JSValueRef> *keys, const PropertyDescriptor *descs)5059 JSHandle<JSTaggedValue> ObjectFactory::CreateLargeJSObjectWithProperties(size_t propertyCount,
5060                                                                          const Local<JSValueRef> *keys,
5061                                                                          const PropertyDescriptor *descs)
5062 {
5063     ASSERT(!CanObjectLiteralHClassCache(propertyCount));
5064     if (UNLIKELY(propertyCount > PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
5065         return CreateDictionaryJSObjectWithProperties(propertyCount, keys, descs);
5066     }
5067     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
5068     JSHandle<JSTaggedValue> objFuncProto = env->GetObjectFunctionPrototype();
5069 
5070     JSHandle<JSHClass> hClassHandle = NewEcmaHClass(JSObject::SIZE, propertyCount, JSType::JS_OBJECT, objFuncProto);
5071     JSHandle<LayoutInfo> layoutHandle = CreateLayoutInfo(propertyCount);
5072     JSHandle<JSObject> object = NewJSObject(hClassHandle);
5073 
5074     for (size_t i = 0; i < propertyCount; ++i) {
5075         JSMutableHandle<JSTaggedValue> key(JSNApiHelper::ToJSMutableHandle(keys[i]));
5076         if (key->IsString() && !EcmaStringAccessor(key.GetTaggedValue()).IsInternString()) {
5077             // update string stable
5078             key.Update(JSTaggedValue(InternString(key)));
5079         }
5080         ASSERT(EcmaStringAccessor(key->GetTaggedObject()).IsInternString());
5081         if (UNLIKELY(!JSTaggedValue::IsPureString(key.GetTaggedValue()))) {
5082             THROW_TYPE_ERROR_AND_RETURN(thread_, "property key must be string and can not convert into element index",
5083                                         JSHandle<JSTaggedValue>());
5084         }
5085         PropertyAttributes attr(descs[i]);
5086         attr.SetIsInlinedProps(true);
5087         attr.SetOffset(i);
5088         LayoutInfo *layout = LayoutInfo::Cast(layoutHandle.GetTaggedValue().GetTaggedObject());
5089         layout->AddKey<true>(thread_, i, key.GetTaggedValue(), attr);
5090         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, JSHandle<JSTaggedValue>());
5091         object->SetPropertyInlinedProps<true>(thread_, i, descs[i].GetValue().GetTaggedValue());
5092     }
5093     hClassHandle->SetNumberOfProps(propertyCount);
5094     hClassHandle->SetLayout(thread_, layoutHandle);
5095     return JSHandle<JSTaggedValue>(object);
5096 }
5097 
CreateDictionaryJSObjectWithProperties(size_t propertyCount, const Local<JSValueRef> *keys, const PropertyDescriptor *descs)5098 JSHandle<JSTaggedValue> ObjectFactory::CreateDictionaryJSObjectWithProperties(size_t propertyCount,
5099                                                                               const Local<JSValueRef> *keys,
5100                                                                               const PropertyDescriptor *descs)
5101 {
5102     ASSERT(propertyCount > PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
5103     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
5104     JSHandle<JSTaggedValue> objFuncProto = env->GetObjectFunctionPrototype();
5105     JSHandle<JSHClass> hClassHandle = NewEcmaHClass(JSObject::SIZE, 0, JSType::JS_OBJECT, objFuncProto);
5106     hClassHandle->SetNumberOfProps(0);
5107     hClassHandle->SetIsDictionaryMode(true);
5108     JSHandle<JSObject> object = NewJSObject(hClassHandle);
5109 
5110     JSMutableHandle<NameDictionary> dict(
5111         thread_, NameDictionary::Create(thread_, NameDictionary::ComputeHashTableSize(propertyCount)));
5112     for (size_t i = 0; i < propertyCount; ++i) {
5113         JSMutableHandle<JSTaggedValue> key(JSNApiHelper::ToJSMutableHandle(keys[i]));
5114         if (key->IsString() && !EcmaStringAccessor(key.GetTaggedValue()).IsInternString()) {
5115             // update string stable
5116             key.Update(JSTaggedValue(InternString(key)));
5117         }
5118         ASSERT(EcmaStringAccessor(key->GetTaggedObject()).IsInternString());
5119         if (UNLIKELY(!JSTaggedValue::IsPureString(key.GetTaggedValue()))) {
5120             THROW_TYPE_ERROR_AND_RETURN(thread_, "property key must be string and can not convert into element index",
5121                                         JSHandle<JSTaggedValue>());
5122         }
5123         PropertyAttributes attr(descs[i]);
5124         dict.Update(NameDictionary::PutIfAbsent(thread_, dict, key, descs[i].GetValue(), attr));
5125     }
5126     if (UNLIKELY(dict->EntriesCount() != static_cast<int>(propertyCount))) {
5127         THROW_TYPE_ERROR_AND_RETURN(thread_, "property keys can not duplicate", JSHandle<JSTaggedValue>());
5128     }
5129     object->SetProperties(thread_, dict);
5130     return JSHandle<JSTaggedValue>(object);
5131 }
5132 
CreateJSObjectWithNamedProperties(size_t propertyCount, const char **keys, const Local<JSValueRef> *values)5133 JSHandle<JSTaggedValue> ObjectFactory::CreateJSObjectWithNamedProperties(size_t propertyCount, const char **keys,
5134                                                                          const Local<JSValueRef> *values)
5135 {
5136     if (!CanObjectLiteralHClassCache(propertyCount)) {
5137         return CreateLargeJSObjectWithNamedProperties(propertyCount, keys, values);
5138     }
5139 
5140     // At least 4 inlined slot
5141     int inlineProps = std::max(static_cast<int>(propertyCount), JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS);
5142     JSMutableHandle<JSHClass> hclassHandle(thread_, GetObjectLiteralRootHClass(inlineProps));
5143     for (size_t i = 0; i < propertyCount; ++i) {
5144         JSHandle<JSTaggedValue> key(NewFromUtf8(keys[i]));
5145         ASSERT(EcmaStringAccessor(key->GetTaggedObject()).IsInternString());
5146         if (UNLIKELY(!JSTaggedValue::IsPureString(key.GetTaggedValue()))) {
5147             THROW_TYPE_ERROR_AND_RETURN(thread_, "property key must be string and can not convert into element index",
5148                                         JSHandle<JSTaggedValue>());
5149         }
5150         PropertyAttributes attr(PropertyAttributes::GetDefaultAttributes());
5151         attr.SetIsInlinedProps(true);
5152         attr.SetOffset(i);
5153         attr.SetRepresentation(Representation::TAGGED);
5154         auto value = JSNApiHelper::ToJSHandle(values[i]).GetTaggedValue();
5155         auto rep = PropertyAttributes::TranslateToRep(value);
5156         hclassHandle.Update(JSHClass::SetPropertyOfObjHClass<true>(thread_, hclassHandle, key, attr, rep));
5157         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, JSHandle<JSTaggedValue>());
5158     }
5159     JSHandle<JSObject> object = NewJSObject(hclassHandle);
5160 
5161     for (size_t i = 0; i < propertyCount; ++i) {
5162         object->SetPropertyInlinedProps<true>(thread_, i, JSNApiHelper::ToJSHandle(values[i]).GetTaggedValue());
5163     }
5164     return JSHandle<JSTaggedValue>(object);
5165 }
5166 
CreateLargeJSObjectWithNamedProperties(size_t propertyCount, const char **keys, const Local<JSValueRef> *values)5167 JSHandle<JSTaggedValue> ObjectFactory::CreateLargeJSObjectWithNamedProperties(size_t propertyCount, const char **keys,
5168                                                                               const Local<JSValueRef> *values)
5169 {
5170     ASSERT(!CanObjectLiteralHClassCache(propertyCount));
5171     if (UNLIKELY(propertyCount > PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
5172         return CreateDictionaryJSObjectWithNamedProperties(propertyCount, keys, values);
5173     }
5174     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
5175     JSHandle<JSTaggedValue> objFuncProto = env->GetObjectFunctionPrototype();
5176 
5177     JSHandle<JSHClass> hClassHandle = NewEcmaHClass(JSObject::SIZE, propertyCount, JSType::JS_OBJECT, objFuncProto);
5178     JSHandle<LayoutInfo> layoutHandle = CreateLayoutInfo(propertyCount);
5179     JSHandle<JSObject> object = NewJSObject(hClassHandle);
5180 
5181     for (size_t i = 0; i < propertyCount; ++i) {
5182         JSHandle<JSTaggedValue> key(NewFromUtf8(keys[i]));
5183         ASSERT(EcmaStringAccessor(key->GetTaggedObject()).IsInternString());
5184         if (UNLIKELY(!JSTaggedValue::IsPureString(key.GetTaggedValue()))) {
5185             THROW_TYPE_ERROR_AND_RETURN(thread_, "property key must be string and can not convert into element index",
5186                                         JSHandle<JSTaggedValue>());
5187         }
5188         PropertyAttributes attr(PropertyAttributes::GetDefaultAttributes());
5189         attr.SetIsInlinedProps(true);
5190         attr.SetOffset(i);
5191         LayoutInfo *layout = LayoutInfo::Cast(layoutHandle.GetTaggedValue().GetTaggedObject());
5192         layout->AddKey<true>(thread_, i, key.GetTaggedValue(), attr);
5193         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread_, JSHandle<JSTaggedValue>());
5194         object->SetPropertyInlinedProps<true>(thread_, i, JSNApiHelper::ToJSHandle(values[i]).GetTaggedValue());
5195     }
5196     hClassHandle->SetNumberOfProps(propertyCount);
5197     hClassHandle->SetLayout(thread_, layoutHandle);
5198     return JSHandle<JSTaggedValue>(object);
5199 }
5200 
CreateDictionaryJSObjectWithNamedProperties(size_t propertyCount, const char **keys, const Local<JSValueRef> *values)5201 JSHandle<JSTaggedValue> ObjectFactory::CreateDictionaryJSObjectWithNamedProperties(size_t propertyCount,
5202                                                                                    const char **keys,
5203                                                                                    const Local<JSValueRef> *values)
5204 {
5205     ASSERT(propertyCount > PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
5206     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
5207     JSHandle<JSTaggedValue> objFuncProto = env->GetObjectFunctionPrototype();
5208     JSHandle<JSHClass> hClassHandle = NewEcmaHClass(JSObject::SIZE, 0, JSType::JS_OBJECT, objFuncProto);
5209     hClassHandle->SetNumberOfProps(0);
5210     hClassHandle->SetIsDictionaryMode(true);
5211     JSHandle<JSObject> object = NewJSObject(hClassHandle);
5212 
5213     JSMutableHandle<NameDictionary> dict(
5214         thread_, NameDictionary::Create(thread_, NameDictionary::ComputeHashTableSize(propertyCount)));
5215     for (size_t i = 0; i < propertyCount; ++i) {
5216         JSHandle<JSTaggedValue> key(NewFromUtf8(keys[i]));
5217         ASSERT(EcmaStringAccessor(key->GetTaggedObject()).IsInternString());
5218         if (UNLIKELY(!JSTaggedValue::IsPureString(key.GetTaggedValue()))) {
5219             THROW_TYPE_ERROR_AND_RETURN(thread_, "property key must be string and can not convert into element index",
5220                                         JSHandle<JSTaggedValue>());
5221         }
5222         PropertyAttributes attr(PropertyAttributes::GetDefaultAttributes());
5223         dict.Update(NameDictionary::PutIfAbsent(thread_, dict, key, JSNApiHelper::ToJSHandle(values[i]), attr));
5224     }
5225     if (UNLIKELY(dict->EntriesCount() != static_cast<int>(propertyCount))) {
5226         THROW_TYPE_ERROR_AND_RETURN(thread_, "property keys can not duplicate", JSHandle<JSTaggedValue>());
5227     }
5228     object->SetProperties(thread_, dict);
5229     return JSHandle<JSTaggedValue>(object);
5230 }
5231 
FillFreeMemoryRange(uintptr_t start, uintptr_t end)5232 void ObjectFactory::FillFreeMemoryRange(uintptr_t start, uintptr_t end)
5233 {
5234     ASSERT(start <= end);
5235     ASSERT(start % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT) == 0);
5236     ASSERT(end % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT) == 0);
5237     while (start < end) {
5238         Barriers::SetPrimitive<JSTaggedType>(reinterpret_cast<void*>(start), 0, FREE_MEMMORY_ADDRESS_ZAM_VALUE);
5239         start += sizeof(JSTaggedType);
5240     }
5241 }
5242 }  // namespace panda::ecmascript
5243