• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/accessor_data.h"
17 #include "ecmascript/base/error_helper.h"
18 #include "ecmascript/builtins/builtins.h"
19 #include "ecmascript/builtins/builtins_errors.h"
20 #include "ecmascript/builtins/builtins_async_from_sync_iterator.h"
21 #include "ecmascript/compiler/builtins/builtins_call_signature.h"
22 #include "ecmascript/ecma_vm.h"
23 #include "ecmascript/ecma_macros.h"
24 #include "ecmascript/ecma_string_table.h"
25 #include "ecmascript/free_object.h"
26 #include "ecmascript/global_env.h"
27 #include "ecmascript/global_env_constants-inl.h"
28 #include "ecmascript/global_env_constants.h"
29 #include "ecmascript/ic/ic_handler.h"
30 #include "ecmascript/ic/profile_type_info.h"
31 #include "ecmascript/ic/property_box.h"
32 #include "ecmascript/ic/proto_change_details.h"
33 #include "ecmascript/interpreter/frame_handler.h"
34 #include "ecmascript/jobs/micro_job_queue.h"
35 #include "ecmascript/jobs/pending_job.h"
36 #include "ecmascript/jspandafile/class_info_extractor.h"
37 #include "ecmascript/jspandafile/class_literal.h"
38 #include "ecmascript/jspandafile/js_pandafile.h"
39 #include "ecmascript/jspandafile/program_object.h"
40 #include "ecmascript/js_api/js_api_arraylist.h"
41 #include "ecmascript/js_api/js_api_arraylist_iterator.h"
42 #include "ecmascript/js_api/js_api_deque.h"
43 #include "ecmascript/js_api/js_api_deque_iterator.h"
44 #include "ecmascript/js_api/js_api_hashmap.h"
45 #include "ecmascript/js_api/js_api_hashset.h"
46 #include "ecmascript/js_api/js_api_hashmap_iterator.h"
47 #include "ecmascript/js_api/js_api_hashset_iterator.h"
48 #include "ecmascript/js_api/js_api_lightweightmap.h"
49 #include "ecmascript/js_api/js_api_lightweightmap_iterator.h"
50 #include "ecmascript/js_api/js_api_lightweightset.h"
51 #include "ecmascript/js_api/js_api_lightweightset_iterator.h"
52 #include "ecmascript/js_api/js_api_linked_list.h"
53 #include "ecmascript/js_api/js_api_linked_list_iterator.h"
54 #include "ecmascript/js_api/js_api_list.h"
55 #include "ecmascript/js_api/js_api_list_iterator.h"
56 #include "ecmascript/js_api/js_api_plain_array.h"
57 #include "ecmascript/js_api/js_api_plain_array_iterator.h"
58 #include "ecmascript/js_api/js_api_queue.h"
59 #include "ecmascript/js_api/js_api_queue_iterator.h"
60 #include "ecmascript/js_api/js_api_stack.h"
61 #include "ecmascript/js_api/js_api_stack_iterator.h"
62 #include "ecmascript/js_api/js_api_tree_map.h"
63 #include "ecmascript/js_api/js_api_tree_map_iterator.h"
64 #include "ecmascript/js_api/js_api_tree_set.h"
65 #include "ecmascript/js_api/js_api_tree_set_iterator.h"
66 #include "ecmascript/js_api/js_api_vector.h"
67 #include "ecmascript/js_api/js_api_vector_iterator.h"
68 #include "ecmascript/js_arguments.h"
69 #include "ecmascript/js_array.h"
70 #include "ecmascript/js_array_iterator.h"
71 #include "ecmascript/js_arraybuffer.h"
72 #include "ecmascript/js_async_function.h"
73 #include "ecmascript/js_async_generator_object.h"
74 #include "ecmascript/js_bigint.h"
75 #include "ecmascript/js_collator.h"
76 #include "ecmascript/js_dataview.h"
77 #include "ecmascript/js_date.h"
78 #include "ecmascript/js_date_time_format.h"
79 #include "ecmascript/js_displaynames.h"
80 #include "ecmascript/js_list_format.h"
81 #include "ecmascript/js_finalization_registry.h"
82 #include "ecmascript/js_for_in_iterator.h"
83 #include "ecmascript/js_generator_object.h"
84 #include "ecmascript/js_hclass-inl.h"
85 #include "ecmascript/js_hclass.h"
86 #include "ecmascript/js_iterator.h"
87 #include "ecmascript/js_map.h"
88 #include "ecmascript/js_map_iterator.h"
89 #include "ecmascript/js_number_format.h"
90 #include "ecmascript/js_object-inl.h"
91 #include "ecmascript/js_plural_rules.h"
92 #include "ecmascript/js_primitive_ref.h"
93 #include "ecmascript/js_promise.h"
94 #include "ecmascript/js_proxy.h"
95 #include "ecmascript/js_realm.h"
96 #include "ecmascript/js_regexp.h"
97 #include "ecmascript/js_regexp_iterator.h"
98 #include "ecmascript/js_relative_time_format.h"
99 #include "ecmascript/js_set.h"
100 #include "ecmascript/js_set_iterator.h"
101 #include "ecmascript/js_string_iterator.h"
102 #include "ecmascript/js_async_from_sync_iterator.h"
103 #include "ecmascript/js_symbol.h"
104 #include "ecmascript/js_tagged_value-inl.h"
105 #include "ecmascript/js_thread.h"
106 #include "ecmascript/js_typed_array.h"
107 #include "ecmascript/js_weak_container.h"
108 #include "ecmascript/js_weak_ref.h"
109 #include "ecmascript/layout_info-inl.h"
110 #include "ecmascript/linked_hash_table.h"
111 #include "ecmascript/mem/heap-inl.h"
112 #include "ecmascript/mem/space.h"
113 #include "ecmascript/mem/region.h"
114 #include "ecmascript/module/js_module_namespace.h"
115 #include "ecmascript/module/js_module_source_text.h"
116 #include "ecmascript/object_factory.h"
117 #include "ecmascript/record.h"
118 #include "ecmascript/require/js_cjs_exports.h"
119 #include "ecmascript/require/js_cjs_module.h"
120 #include "ecmascript/require/js_cjs_require.h"
121 #include "ecmascript/shared_mm/shared_mm.h"
122 #include "ecmascript/symbol_table.h"
123 #include "ecmascript/tagged_hash_array.h"
124 #include "ecmascript/tagged_list.h"
125 #include "ecmascript/tagged_node.h"
126 #include "ecmascript/tagged_tree.h"
127 #include "ecmascript/template_map.h"
128 #include "ecmascript/ts_types/ts_obj_layout_info.h"
129 #include "ecmascript/ts_types/ts_type.h"
130 #include "ecmascript/ts_types/ts_type_table.h"
131 #include "ecmascript/aot_file_manager.h"
132 
133 namespace panda::ecmascript {
134 using Error = builtins::BuiltinsError;
135 using RangeError = builtins::BuiltinsRangeError;
136 using ReferenceError = builtins::BuiltinsReferenceError;
137 using TypeError = builtins::BuiltinsTypeError;
138 using AggregateError = builtins::BuiltinsAggregateError;
139 using URIError = builtins::BuiltinsURIError;
140 using SyntaxError = builtins::BuiltinsSyntaxError;
141 using EvalError = builtins::BuiltinsEvalError;
142 using OOMError = builtins::BuiltinsOOMError;
143 using ErrorType = base::ErrorType;
144 using ErrorHelper = base::ErrorHelper;
145 
ObjectFactory(JSThread * thread,Heap * heap)146 ObjectFactory::ObjectFactory(JSThread *thread, Heap *heap)
147     : thread_(thread), vm_(thread->GetEcmaVM()), heap_(heap) {}
148 
NewMethodForNativeFunction(const void * func,FunctionKind kind,kungfu::BuiltinsStubCSigns::ID builtinId)149 JSHandle<Method> ObjectFactory::NewMethodForNativeFunction(const void *func, FunctionKind kind,
150                                                            kungfu::BuiltinsStubCSigns::ID builtinId)
151 {
152     uint32_t numArgs = 2;  // function object and this
153     auto method = NewMethod(nullptr);
154     method->SetNativePointer(const_cast<void *>(func));
155     method->SetNativeBit(true);
156     if (builtinId != kungfu::BuiltinsStubCSigns::INVALID) {
157         bool isFast = kungfu::BuiltinsStubCSigns::IsFastBuiltin(builtinId);
158         method->SetFastBuiltinBit(isFast);
159         method->SetBuiltinId(static_cast<uint8_t>(builtinId));
160     }
161     method->SetNumArgsWithCallField(numArgs);
162     method->SetFunctionKind(kind);
163     return method;
164 }
165 
NewEcmaHClassClass(JSHClass * hclass,uint32_t size,JSType type)166 JSHandle<JSHClass> ObjectFactory::NewEcmaHClassClass(JSHClass *hclass, uint32_t size, JSType type)
167 {
168     NewObjectHook();
169     uint32_t classSize = JSHClass::SIZE;
170     auto *newClass = static_cast<JSHClass *>(heap_->AllocateClassClass(hclass, classSize));
171     newClass->Initialize(thread_, size, type, 0);
172 
173     return JSHandle<JSHClass>(thread_, newClass);
174 }
175 
InitClassClass()176 JSHandle<JSHClass> ObjectFactory::InitClassClass()
177 {
178     JSHandle<JSHClass> hClassHandle = NewEcmaHClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS);
179     JSHClass *hclass = reinterpret_cast<JSHClass *>(hClassHandle.GetTaggedValue().GetTaggedObject());
180     hclass->SetClass(hclass);
181     return hClassHandle;
182 }
183 
NewEcmaHClass(JSHClass * hclass,uint32_t size,JSType type,uint32_t inlinedProps)184 JSHandle<JSHClass> ObjectFactory::NewEcmaHClass(JSHClass *hclass, uint32_t size, JSType type, uint32_t inlinedProps)
185 {
186     NewObjectHook();
187     uint32_t classSize = JSHClass::SIZE;
188     auto *newClass = static_cast<JSHClass *>(heap_->AllocateNonMovableOrHugeObject(hclass, classSize));
189     newClass->Initialize(thread_, size, type, inlinedProps);
190 
191     return JSHandle<JSHClass>(thread_, newClass);
192 }
193 
NewEcmaReadOnlyHClass(JSHClass * hclass,uint32_t size,JSType type,uint32_t inlinedProps)194 JSHandle<JSHClass> ObjectFactory::NewEcmaReadOnlyHClass(JSHClass *hclass, uint32_t size, JSType type,
195                                                           uint32_t inlinedProps)
196 {
197     NewObjectHook();
198     uint32_t classSize = JSHClass::SIZE;
199     auto *newClass = static_cast<JSHClass *>(heap_->AllocateReadOnlyOrHugeObject(hclass, classSize));
200     newClass->Initialize(thread_, size, type, inlinedProps);
201 
202     return JSHandle<JSHClass>(thread_, newClass);
203 }
204 
NewEcmaHClass(uint32_t size,JSType type,uint32_t inlinedProps)205 JSHandle<JSHClass> ObjectFactory::NewEcmaHClass(uint32_t size, JSType type, uint32_t inlinedProps)
206 {
207     return NewEcmaHClass(JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()),
208                            size, type, inlinedProps);
209 }
210 
InitObjectFields(const TaggedObject * object)211 void ObjectFactory::InitObjectFields(const TaggedObject *object)
212 {
213     auto *klass = object->GetClass();
214     auto objBodySize = klass->GetObjectSize() - TaggedObject::TaggedObjectSize();
215     ASSERT(objBodySize % JSTaggedValue::TaggedTypeSize() == 0);
216     uint32_t numOfFields = objBodySize / JSTaggedValue::TaggedTypeSize();
217     size_t addr = reinterpret_cast<uintptr_t>(object) + TaggedObject::TaggedObjectSize();
218     for (uint32_t i = 0; i < numOfFields; i++) {
219         auto *fieldAddr = reinterpret_cast<JSTaggedType *>(addr + i * JSTaggedValue::TaggedTypeSize());
220         *fieldAddr = JSTaggedValue::Undefined().GetRawData();
221     }
222 }
223 
NewJSArrayBufferData(const JSHandle<JSArrayBuffer> & array,int32_t length)224 void ObjectFactory::NewJSArrayBufferData(const JSHandle<JSArrayBuffer> &array, int32_t length)
225 {
226     if (length == 0) {
227         return;
228     }
229 
230     JSTaggedValue data = array->GetArrayBufferData();
231     size_t size = static_cast<size_t>(length) * sizeof(uint8_t);
232     if (data != JSTaggedValue::Undefined()) {
233         auto *pointer = JSNativePointer::Cast(data.GetTaggedObject());
234         auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
235         if (memset_s(newData, length, 0, length) != EOK) {
236             LOG_FULL(FATAL) << "memset_s failed";
237             UNREACHABLE();
238         }
239         pointer->ResetExternalPointer(newData);
240         return;
241     }
242 
243     auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
244     if (memset_s(newData, length, 0, length) != EOK) {
245         LOG_FULL(FATAL) << "memset_s failed";
246         UNREACHABLE();
247     }
248     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newData, NativeAreaAllocator::FreeBufferFunc,
249                                                            vm_->GetNativeAreaAllocator(), false, size);
250     array->SetArrayBufferData(thread_, pointer);
251 }
252 
NewJSSharedArrayBufferData(const JSHandle<JSArrayBuffer> & array,int32_t length)253 void ObjectFactory::NewJSSharedArrayBufferData(const JSHandle<JSArrayBuffer> &array, int32_t length)
254 {
255     if (length == 0) {
256         return;
257     }
258     void *newData = nullptr;
259     size_t size =
260         JSSharedMemoryManager::GetInstance()->CreateOrLoad(&newData, length) ? static_cast<size_t>(length) : 0U;
261     if (memset_s(newData, length, 0, length) != EOK) {
262         LOG_FULL(FATAL) << "memset_s failed";
263         UNREACHABLE();
264     }
265     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newData, JSSharedMemoryManager::RemoveSharedMemory,
266                                                            JSSharedMemoryManager::GetInstance(), false, size);
267     array->SetArrayBufferData(thread_, pointer);
268 }
269 
NewJSArrayBuffer(int32_t length)270 JSHandle<JSArrayBuffer> ObjectFactory::NewJSArrayBuffer(int32_t length)
271 {
272     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
273 
274     JSHandle<JSFunction> constructor(env->GetArrayBufferFunction());
275     JSHandle<JSArrayBuffer> arrayBuffer(NewJSObjectByConstructor(constructor));
276     arrayBuffer->SetArrayBufferByteLength(length);
277     if (length > 0) {
278         auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(length);
279         if (memset_s(newData, length, 0, length) != EOK) {
280             LOG_FULL(FATAL) << "memset_s failed";
281             UNREACHABLE();
282         }
283         JSHandle<JSNativePointer> pointer = NewJSNativePointer(newData, NativeAreaAllocator::FreeBufferFunc,
284                                                                vm_->GetNativeAreaAllocator(), false, length);
285         arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue());
286         arrayBuffer->ClearBitField();
287     }
288     return arrayBuffer;
289 }
290 
NewJSArrayBuffer(void * buffer,int32_t length,const DeleteEntryPoint & deleter,void * data,bool share)291 JSHandle<JSArrayBuffer> ObjectFactory::NewJSArrayBuffer(void *buffer, int32_t length, const DeleteEntryPoint &deleter,
292                                                         void *data, bool share)
293 {
294     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
295 
296     JSHandle<JSFunction> constructor(env->GetArrayBufferFunction());
297     JSHandle<JSArrayBuffer> arrayBuffer(NewJSObjectByConstructor(constructor));
298     length = buffer == nullptr ? 0 : length;
299     arrayBuffer->SetArrayBufferByteLength(length);
300     if (length > 0) {
301         JSHandle<JSNativePointer> pointer = NewJSNativePointer(buffer, deleter, data, false, length);
302         arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue());
303         arrayBuffer->SetShared(share);
304     }
305     return arrayBuffer;
306 }
307 
NewJSDataView(JSHandle<JSArrayBuffer> buffer,uint32_t offset,uint32_t length)308 JSHandle<JSDataView> ObjectFactory::NewJSDataView(JSHandle<JSArrayBuffer> buffer, uint32_t offset, uint32_t length)
309 {
310     uint32_t arrayLength = buffer->GetArrayBufferByteLength();
311     if (arrayLength - offset < length) {
312         THROW_TYPE_ERROR_AND_RETURN(thread_, "offset or length error",
313                                     JSHandle<JSDataView>(thread_, JSTaggedValue::Undefined()));
314     }
315     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
316 
317     JSHandle<JSFunction> constructor(env->GetDataViewFunction());
318     JSHandle<JSDataView> arrayBuffer(NewJSObjectByConstructor(constructor));
319     arrayBuffer->SetDataView(thread_, JSTaggedValue::True());
320     arrayBuffer->SetViewedArrayBuffer(thread_, buffer.GetTaggedValue());
321     arrayBuffer->SetByteLength(length);
322     arrayBuffer->SetByteOffset(offset);
323     return arrayBuffer;
324 }
325 
NewJSSharedArrayBuffer(int32_t length)326 JSHandle<JSArrayBuffer> ObjectFactory::NewJSSharedArrayBuffer(int32_t length)
327 {
328     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
329 
330     JSHandle<JSFunction> constructor(env->GetSharedArrayBufferFunction());
331     JSHandle<JSArrayBuffer> sharedArrayBuffer(NewJSObjectByConstructor(constructor));
332     sharedArrayBuffer->SetArrayBufferByteLength(length);
333     if (length > 0) {
334         NewJSSharedArrayBufferData(sharedArrayBuffer, length);
335         sharedArrayBuffer->SetShared(true);
336     }
337     return sharedArrayBuffer;
338 }
339 
NewJSSharedArrayBuffer(void * buffer,int32_t length)340 JSHandle<JSArrayBuffer> ObjectFactory::NewJSSharedArrayBuffer(void *buffer, int32_t length)
341 {
342     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
343 
344     JSHandle<JSFunction> constructor(env->GetSharedArrayBufferFunction());
345     JSHandle<JSArrayBuffer> sharedArrayBuffer(NewJSObjectByConstructor(constructor));
346     length = buffer == nullptr ? 0 : length;
347     sharedArrayBuffer->SetArrayBufferByteLength(length);
348     if (length > 0) {
349         JSHandle<JSNativePointer> pointer = NewJSNativePointer(buffer, JSSharedMemoryManager::RemoveSharedMemory,
350                                                                JSSharedMemoryManager::GetInstance(), false, length);
351         sharedArrayBuffer->SetArrayBufferData(thread_, pointer);
352         sharedArrayBuffer->SetShared(true);
353     }
354     return sharedArrayBuffer;
355 }
356 
NewJSRegExpByteCodeData(const JSHandle<JSRegExp> & regexp,void * buffer,size_t size)357 void ObjectFactory::NewJSRegExpByteCodeData(const JSHandle<JSRegExp> &regexp, void *buffer, size_t size)
358 {
359     if (buffer == nullptr) {
360         return;
361     }
362 
363     auto newBuffer = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
364     if (memcpy_s(newBuffer, size, buffer, size) != EOK) {
365         LOG_FULL(FATAL) << "memcpy_s failed";
366         UNREACHABLE();
367     }
368     JSTaggedValue data = regexp->GetByteCodeBuffer();
369     if (data != JSTaggedValue::Undefined()) {
370         JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject());
371         native->ResetExternalPointer(newBuffer);
372         return;
373     }
374     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newBuffer, NativeAreaAllocator::FreeBufferFunc,
375                                                            vm_->GetNativeAreaAllocator(), false, size);
376     regexp->SetByteCodeBuffer(thread_, pointer.GetTaggedValue());
377     regexp->SetLength(static_cast<uint32_t>(size));
378 }
379 
NewEcmaHClass(uint32_t size,JSType type,const JSHandle<JSTaggedValue> & prototype)380 JSHandle<JSHClass> ObjectFactory::NewEcmaHClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype)
381 {
382     JSHandle<JSHClass> newClass = NewEcmaHClass(size, type);
383     newClass->SetPrototype(thread_, prototype.GetTaggedValue());
384     return newClass;
385 }
386 
NewJSObject(const JSHandle<JSHClass> & jshclass)387 JSHandle<JSObject> ObjectFactory::NewJSObject(const JSHandle<JSHClass> &jshclass)
388 {
389     JSHandle<JSObject> obj(thread_, JSObject::Cast(NewObject(jshclass)));
390     JSHandle<TaggedArray> emptyArray = EmptyArray();
391     obj->InitializeHash();
392     obj->SetElements(thread_, emptyArray, SKIP_BARRIER);
393     obj->SetProperties(thread_, emptyArray, SKIP_BARRIER);
394     return obj;
395 }
396 
CloneProperties(const JSHandle<TaggedArray> & old)397 JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray> &old)
398 {
399     uint32_t newLength = old->GetLength();
400     if (newLength == 0) {
401         return EmptyArray();
402     }
403     NewObjectHook();
404     auto klass = old->GetClass();
405     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
406     auto header = heap_->AllocateYoungOrHugeObject(klass, size);
407     JSHandle<TaggedArray> newArray(thread_, header);
408     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
409     for (uint32_t i = 0; i < newLength; i++) {
410         JSTaggedValue value = old->Get(i);
411         newArray->Set(thread_, i, value);
412     }
413     return newArray;
414 }
415 
CloneObjectLiteral(JSHandle<JSObject> object)416 JSHandle<JSObject> ObjectFactory::CloneObjectLiteral(JSHandle<JSObject> object)
417 {
418     NewObjectHook();
419     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
420 
421     JSHandle<JSObject> cloneObject = NewJSObject(klass);
422 
423     JSHandle<TaggedArray> elements(thread_, object->GetElements());
424     auto newElements = CloneProperties(elements);
425     cloneObject->SetElements(thread_, newElements.GetTaggedValue());
426 
427     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
428     auto newProperties = CloneProperties(properties);
429     cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
430 
431     for (uint32_t i = 0; i < klass->GetInlinedProperties(); i++) {
432         cloneObject->SetPropertyInlinedProps(thread_, i, object->GetPropertyInlinedProps(i));
433     }
434     return cloneObject;
435 }
436 
CloneArrayLiteral(JSHandle<JSArray> object)437 JSHandle<JSArray> ObjectFactory::CloneArrayLiteral(JSHandle<JSArray> object)
438 {
439     NewObjectHook();
440     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
441 
442     JSHandle<JSArray> cloneObject(NewJSObject(klass));
443     cloneObject->SetArrayLength(thread_, object->GetArrayLength());
444 
445     JSHandle<TaggedArray> elements(thread_, object->GetElements());
446     static constexpr uint8_t MAX_READ_ONLY_ARRAY_LENGTH = 10;
447     uint32_t elementsLength = elements->GetLength();
448     MemSpaceType type = elementsLength > MAX_READ_ONLY_ARRAY_LENGTH ?
449         MemSpaceType::SEMI_SPACE : MemSpaceType::NON_MOVABLE;
450 
451 #if !defined ENABLE_COW_ARRAY
452     type = MemSpaceType::SEMI_SPACE;
453 #endif
454 
455     if (type == MemSpaceType::NON_MOVABLE && elements.GetTaggedValue().IsCOWArray()) {
456         // share the same elements array in nonmovable space.
457         cloneObject->SetElements(thread_, elements.GetTaggedValue());
458     } else {
459         auto newElements = CopyArray(elements, elementsLength, elementsLength, JSTaggedValue::Hole(), type);
460         cloneObject->SetElements(thread_, newElements.GetTaggedValue());
461     }
462 
463     if (type == MemSpaceType::NON_MOVABLE && !object->GetElements().IsCOWArray()) {
464         ASSERT(!Region::ObjectAddressToRange(object->GetElements().GetTaggedObject())->InNonMovableSpace());
465         // Set the first shared elements into the old object.
466         object->SetElements(thread_, cloneObject->GetElements());
467     }
468 
469     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
470     uint32_t propertiesLength = properties->GetLength();
471     type = propertiesLength > MAX_READ_ONLY_ARRAY_LENGTH ?
472         MemSpaceType::SEMI_SPACE : MemSpaceType::NON_MOVABLE;
473 
474 #if !defined ENABLE_COW_ARRAY
475     type = MemSpaceType::SEMI_SPACE;
476 #endif
477 
478     if (type == MemSpaceType::NON_MOVABLE && properties.GetTaggedValue().IsCOWArray()) {
479         // share the same properties array in nonmovable space.
480         cloneObject->SetProperties(thread_, properties.GetTaggedValue());
481     } else {
482         auto newProperties = CopyArray(properties, propertiesLength, propertiesLength, JSTaggedValue::Hole(), type);
483         cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
484     }
485 
486     if (type == MemSpaceType::NON_MOVABLE && !object->GetProperties().IsCOWArray()) {
487         ASSERT(!Region::ObjectAddressToRange(object->GetProperties().GetTaggedObject())->InNonMovableSpace());
488         // Set the first shared properties into the old object.
489         object->SetProperties(thread_, cloneObject->GetProperties());
490     }
491 
492     for (uint32_t i = 0; i < klass->GetInlinedProperties(); i++) {
493         cloneObject->SetPropertyInlinedProps(thread_, i, object->GetPropertyInlinedProps(i));
494     }
495     return cloneObject;
496 }
497 
CloneProperties(const JSHandle<TaggedArray> & old,const JSHandle<JSTaggedValue> & env,const JSHandle<JSObject> & obj)498 JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray> &old,
499                                                      const JSHandle<JSTaggedValue> &env, const JSHandle<JSObject> &obj)
500 {
501     uint32_t newLength = old->GetLength();
502     if (newLength == 0) {
503         return EmptyArray();
504     }
505     NewObjectHook();
506     auto klass = old->GetClass();
507     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
508     auto header = heap_->AllocateYoungOrHugeObject(klass, size);
509     JSHandle<TaggedArray> newArray(thread_, header);
510     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
511 
512     for (uint32_t i = 0; i < newLength; i++) {
513         JSTaggedValue value = old->Get(i);
514         if (!value.IsJSFunction()) {
515             newArray->Set(thread_, i, value);
516         } else {
517             JSHandle<JSFunction> valueHandle(thread_, value);
518             JSHandle<JSFunction> newFunc = CloneJSFuction(valueHandle);
519             newFunc->SetLexicalEnv(thread_, env);
520             newFunc->SetHomeObject(thread_, obj);
521             newArray->Set(thread_, i, newFunc);
522         }
523     }
524     return newArray;
525 }
526 
CloneObjectLiteral(JSHandle<JSObject> object,const JSHandle<JSTaggedValue> & env,bool canShareHClass)527 JSHandle<JSObject> ObjectFactory::CloneObjectLiteral(JSHandle<JSObject> object, const JSHandle<JSTaggedValue> &env,
528                                                      bool canShareHClass)
529 {
530     NewObjectHook();
531     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
532 
533     if (!canShareHClass) {
534         klass = JSHClass::Clone(thread_, klass);
535     }
536 
537     JSHandle<JSObject> cloneObject = NewJSObject(klass);
538 
539     JSHandle<TaggedArray> elements(thread_, object->GetElements());
540     auto newElements = CloneProperties(elements, env, cloneObject);
541     cloneObject->SetElements(thread_, newElements.GetTaggedValue());
542 
543     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
544     auto newProperties = CloneProperties(properties, env, cloneObject);
545     cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
546 
547     for (uint32_t i = 0; i < klass->GetInlinedProperties(); i++) {
548         JSTaggedValue value = object->GetPropertyInlinedProps(i);
549         if (!value.IsJSFunction()) {
550             cloneObject->SetPropertyInlinedProps(thread_, i, value);
551         } else {
552             JSHandle<JSFunction> valueHandle(thread_, value);
553             JSHandle<JSFunction> newFunc = CloneJSFuction(valueHandle);
554             newFunc->SetLexicalEnv(thread_, env);
555             newFunc->SetHomeObject(thread_, cloneObject);
556             cloneObject->SetPropertyInlinedProps(thread_, i, newFunc.GetTaggedValue());
557         }
558     }
559     return cloneObject;
560 }
561 
CloneJSFuction(JSHandle<JSFunction> func)562 JSHandle<JSFunction> ObjectFactory::CloneJSFuction(JSHandle<JSFunction> func)
563 {
564     JSHandle<JSHClass> jshclass(thread_, func->GetJSHClass());
565     JSHandle<Method> method(thread_, func->GetMethod());
566     JSHandle<JSFunction> cloneFunc = NewJSFunctionByHClass(method, jshclass);
567 
568     JSTaggedValue length = func->GetPropertyInlinedProps(JSFunction::LENGTH_INLINE_PROPERTY_INDEX);
569     cloneFunc->SetPropertyInlinedProps(thread_, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length);
570     cloneFunc->SetModule(thread_, func->GetModule());
571     return cloneFunc;
572 }
573 
CloneClassCtor(JSHandle<JSFunction> ctor,const JSHandle<JSTaggedValue> & lexenv,bool canShareHClass)574 JSHandle<JSFunction> ObjectFactory::CloneClassCtor(JSHandle<JSFunction> ctor, const JSHandle<JSTaggedValue> &lexenv,
575                                                    bool canShareHClass)
576 {
577     NewObjectHook();
578     JSHandle<JSHClass> hclass(thread_, ctor->GetClass());
579 
580     if (!canShareHClass) {
581         hclass = JSHClass::Clone(thread_, hclass);
582     }
583 
584     JSHandle<Method> method(thread_, ctor->GetMethod());
585     ASSERT_PRINT(method->GetFunctionKind() == FunctionKind::CLASS_CONSTRUCTOR ||
586                  method->GetFunctionKind() == FunctionKind::DERIVED_CONSTRUCTOR,
587                  "cloned function is not class");
588     JSHandle<JSFunction> cloneCtor = NewJSFunctionByHClass(method, hclass);
589 
590     for (uint32_t i = 0; i < hclass->GetInlinedProperties(); i++) {
591         JSTaggedValue value = ctor->GetPropertyInlinedProps(i);
592         if (!value.IsJSFunction()) {
593             cloneCtor->SetPropertyInlinedProps(thread_, i, value);
594         } else {
595             JSHandle<JSFunction> valueHandle(thread_, value);
596             JSHandle<JSFunction> newFunc = CloneJSFuction(valueHandle);
597             newFunc->SetLexicalEnv(thread_, lexenv);
598             newFunc->SetHomeObject(thread_, cloneCtor);
599             cloneCtor->SetPropertyInlinedProps(thread_, i, newFunc.GetTaggedValue());
600         }
601     }
602 
603     JSHandle<TaggedArray> elements(thread_, ctor->GetElements());
604     auto newElements = CloneProperties(elements, lexenv, JSHandle<JSObject>(cloneCtor));
605     cloneCtor->SetElements(thread_, newElements.GetTaggedValue());
606 
607     JSHandle<TaggedArray> properties(thread_, ctor->GetProperties());
608     auto newProperties = CloneProperties(properties, lexenv, JSHandle<JSObject>(cloneCtor));
609     cloneCtor->SetProperties(thread_, newProperties.GetTaggedValue());
610 
611     return cloneCtor;
612 }
613 
NewNonMovableJSObject(const JSHandle<JSHClass> & jshclass)614 JSHandle<JSObject> ObjectFactory::NewNonMovableJSObject(const JSHandle<JSHClass> &jshclass)
615 {
616     JSHandle<JSObject> obj(thread_,
617                            JSObject::Cast(NewNonMovableObject(jshclass, jshclass->GetInlinedProperties())));
618     obj->InitializeHash();
619     obj->SetElements(thread_, EmptyArray(), SKIP_BARRIER);
620     obj->SetProperties(thread_, EmptyArray(), SKIP_BARRIER);
621     return obj;
622 }
623 
NewJSPrimitiveRef(const JSHandle<JSHClass> & hclass,const JSHandle<JSTaggedValue> & object)624 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(const JSHandle<JSHClass> &hclass,
625                                                           const JSHandle<JSTaggedValue> &object)
626 {
627     JSHandle<JSPrimitiveRef> obj = JSHandle<JSPrimitiveRef>::Cast(NewJSObject(hclass));
628     obj->SetValue(thread_, object);
629     return obj;
630 }
631 
NewJSArray()632 JSHandle<JSArray> ObjectFactory::NewJSArray()
633 {
634     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
635     JSHandle<JSFunction> function(env->GetArrayFunction());
636     return JSHandle<JSArray>(NewJSObjectByConstructor(function));
637 }
638 
NewJSForinIterator(const JSHandle<JSTaggedValue> & obj)639 JSHandle<JSForInIterator> ObjectFactory::NewJSForinIterator(const JSHandle<JSTaggedValue> &obj)
640 {
641     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
642     JSHandle<JSHClass> hclass(env->GetForinIteratorClass());
643 
644     JSHandle<JSForInIterator> it = JSHandle<JSForInIterator>::Cast(NewJSObject(hclass));
645     it->SetObject(thread_, obj);
646     it->SetVisitedKeys(thread_, thread_->GlobalConstants()->GetEmptyTaggedQueue());
647     it->SetRemainingKeys(thread_, thread_->GlobalConstants()->GetEmptyTaggedQueue());
648     it->ClearBitField();
649     return it;
650 }
651 
CreateJSRegExpInstanceClass(JSHandle<JSTaggedValue> proto)652 JSHandle<JSHClass> ObjectFactory::CreateJSRegExpInstanceClass(JSHandle<JSTaggedValue> proto)
653 {
654     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
655     JSHandle<JSHClass> regexpClass = NewEcmaHClass(JSRegExp::SIZE, JSType::JS_REG_EXP, proto);
656 
657     uint32_t fieldOrder = 0;
658     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(1);
659     {
660         PropertyAttributes attributes = PropertyAttributes::Default(true, false, false);
661         attributes.SetIsInlinedProps(true);
662         attributes.SetRepresentation(Representation::MIXED);
663         attributes.SetOffset(fieldOrder++);
664         layoutInfoHandle->AddKey(thread_, 0, globalConst->GetLastIndexString(), attributes);
665     }
666 
667     {
668         regexpClass->SetLayout(thread_, layoutInfoHandle);
669         regexpClass->SetNumberOfProps(fieldOrder);
670     }
671 
672     return regexpClass;
673 }
674 
CreateJSArrayInstanceClass(JSHandle<JSTaggedValue> proto)675 JSHandle<JSHClass> ObjectFactory::CreateJSArrayInstanceClass(JSHandle<JSTaggedValue> proto)
676 {
677     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
678     JSHandle<JSHClass> arrayClass = NewEcmaHClass(JSArray::SIZE, JSType::JS_ARRAY, proto);
679 
680     uint32_t fieldOrder = 0;
681     ASSERT(JSArray::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
682     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(1);
683     {
684         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(true, false, false);
685         attributes.SetIsInlinedProps(true);
686         attributes.SetRepresentation(Representation::MIXED);
687         attributes.SetOffset(fieldOrder++);
688         layoutInfoHandle->AddKey(thread_, 0, globalConst->GetLengthString(), attributes);
689     }
690 
691     {
692         arrayClass->SetLayout(thread_, layoutInfoHandle);
693         arrayClass->SetNumberOfProps(fieldOrder);
694     }
695     arrayClass->SetIsStableElements(true);
696     arrayClass->SetHasConstructor(false);
697 
698     return arrayClass;
699 }
700 
CreateJSArguments()701 JSHandle<JSHClass> ObjectFactory::CreateJSArguments()
702 {
703     JSHandle<GlobalEnv> env = thread_->GetEcmaVM()->GetGlobalEnv();
704     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
705     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
706 
707     JSHandle<JSHClass> argumentsClass = NewEcmaHClass(JSArguments::SIZE, JSType::JS_ARGUMENTS, proto);
708 
709     uint32_t fieldOrder = 0;
710     ASSERT(JSArguments::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
711     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(JSArguments::LENGTH_OF_INLINE_PROPERTIES);
712     {
713         PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);
714         attributes.SetIsInlinedProps(true);
715         attributes.SetRepresentation(Representation::MIXED);
716         attributes.SetOffset(fieldOrder++);
717         layoutInfoHandle->AddKey(thread_, JSArguments::LENGTH_INLINE_PROPERTY_INDEX, globalConst->GetLengthString(),
718                                  attributes);
719     }
720 
721     ASSERT(JSArguments::ITERATOR_INLINE_PROPERTY_INDEX == fieldOrder);
722     {
723         PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);
724         attributes.SetIsInlinedProps(true);
725         attributes.SetRepresentation(Representation::MIXED);
726         attributes.SetOffset(fieldOrder++);
727         layoutInfoHandle->AddKey(thread_, JSArguments::ITERATOR_INLINE_PROPERTY_INDEX,
728                                  env->GetIteratorSymbol().GetTaggedValue(), attributes);
729     }
730 
731     {
732         ASSERT(JSArguments::CALLER_INLINE_PROPERTY_INDEX == fieldOrder);
733         PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
734         attributes.SetIsInlinedProps(true);
735         attributes.SetIsAccessor(true);
736         attributes.SetRepresentation(Representation::MIXED);
737         attributes.SetOffset(fieldOrder++);
738         layoutInfoHandle->AddKey(thread_, JSArguments::CALLER_INLINE_PROPERTY_INDEX,
739                                  thread_->GlobalConstants()->GetHandledCallerString().GetTaggedValue(), attributes);
740     }
741 
742     {
743         ASSERT(JSArguments::CALLEE_INLINE_PROPERTY_INDEX == fieldOrder);
744         PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
745         attributes.SetIsInlinedProps(true);
746         attributes.SetIsAccessor(true);
747         attributes.SetRepresentation(Representation::MIXED);
748         attributes.SetOffset(fieldOrder++);
749         layoutInfoHandle->AddKey(thread_, JSArguments::CALLEE_INLINE_PROPERTY_INDEX,
750                                  thread_->GlobalConstants()->GetHandledCalleeString().GetTaggedValue(), attributes);
751     }
752 
753     {
754         argumentsClass->SetLayout(thread_, layoutInfoHandle);
755         argumentsClass->SetNumberOfProps(fieldOrder);
756     }
757     argumentsClass->SetIsStableElements(true);
758     return argumentsClass;
759 }
760 
NewJSArguments()761 JSHandle<JSArguments> ObjectFactory::NewJSArguments()
762 {
763     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
764     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetArgumentsClass());
765     JSHandle<JSArguments> obj = JSHandle<JSArguments>::Cast(NewJSObject(hclass));
766     return obj;
767 }
768 
GetJSError(const ErrorType & errorType,const char * data,bool needCheckStack)769 JSHandle<JSObject> ObjectFactory::GetJSError(const ErrorType &errorType, const char *data, bool needCheckStack)
770 {
771     ASSERT_PRINT(errorType == ErrorType::ERROR || errorType == ErrorType::EVAL_ERROR ||
772                      errorType == ErrorType::RANGE_ERROR || errorType == ErrorType::REFERENCE_ERROR ||
773                      errorType == ErrorType::SYNTAX_ERROR || errorType == ErrorType::TYPE_ERROR ||
774                      errorType == ErrorType::URI_ERROR || errorType == ErrorType::OOM_ERROR,
775                  "The error type is not in the valid range.");
776     if (data != nullptr) {
777         JSHandle<EcmaString> handleMsg = NewFromUtf8(data);
778         return NewJSError(errorType, handleMsg, needCheckStack);
779     }
780     JSHandle<EcmaString> emptyString(thread_->GlobalConstants()->GetHandledEmptyString());
781     return NewJSError(errorType, emptyString, needCheckStack);
782 }
783 
NewJSError(const ErrorType & errorType,const JSHandle<EcmaString> & message,bool needCheckStack)784 JSHandle<JSObject> ObjectFactory::NewJSError(const ErrorType &errorType, const JSHandle<EcmaString> &message,
785     bool needCheckStack)
786 {
787     // if there have exception in thread, then return current exception, no need to new js error.
788     if (thread_->HasPendingException()) {
789         JSHandle<JSObject> obj(thread_, thread_->GetException());
790         return obj;
791     }
792 
793     // current frame may be entry frame, exception happened in JSFunction::Call and JSFunction::Construct,
794     // in this case sp = the prev frame (interpreter frame).
795     if (!thread_->IsAsmInterpreter()) {
796         FrameHandler frameHandler(thread_);
797         if (frameHandler.IsInterpretedEntryFrame()) {
798             thread_->SetCurrentSPFrame(frameHandler.GetPrevJSFrame());
799         }
800     }
801 
802     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
803     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
804     JSHandle<JSTaggedValue> nativeConstructor;
805     switch (errorType) {
806         case ErrorType::RANGE_ERROR:
807             nativeConstructor = env->GetRangeErrorFunction();
808             break;
809         case ErrorType::EVAL_ERROR:
810             nativeConstructor = env->GetEvalErrorFunction();
811             break;
812         case ErrorType::REFERENCE_ERROR:
813             nativeConstructor = env->GetReferenceErrorFunction();
814             break;
815         case ErrorType::TYPE_ERROR:
816             nativeConstructor = env->GetTypeErrorFunction();
817             break;
818         case ErrorType::URI_ERROR:
819             nativeConstructor = env->GetURIErrorFunction();
820             break;
821         case ErrorType::SYNTAX_ERROR:
822             nativeConstructor = env->GetSyntaxErrorFunction();
823             break;
824         case ErrorType::OOM_ERROR:
825             nativeConstructor = env->GetOOMErrorFunction();
826             break;
827         default:
828             nativeConstructor = env->GetErrorFunction();
829             break;
830     }
831     JSHandle<JSFunction> nativeFunc = JSHandle<JSFunction>::Cast(nativeConstructor);
832     JSHandle<JSTaggedValue> nativePrototype(thread_, nativeFunc->GetFunctionPrototype());
833     JSHandle<JSTaggedValue> ctorKey = globalConst->GetHandledConstructorString();
834     JSHandle<JSTaggedValue> ctor(JSTaggedValue::GetProperty(thread_, nativePrototype, ctorKey).GetValue());
835     JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
836     EcmaRuntimeCallInfo *info =
837         EcmaInterpreter::NewRuntimeCallInfo(thread_, ctor, nativePrototype, undefined, 1, needCheckStack);
838     info->SetCallArg(message.GetTaggedValue());
839     Method *method = JSHandle<ECMAObject>::Cast(ctor)->GetCallTarget();
840     JSTaggedValue obj = reinterpret_cast<EcmaEntrypoint>(const_cast<void *>(method->GetNativePointer()))(info);
841     JSHandle<JSObject> handleNativeInstanceObj(thread_, obj);
842     auto sp = const_cast<JSTaggedType *>(thread_->GetCurrentSPFrame());
843     ASSERT(FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_ENTRY_FRAME);
844     auto prevEntry = InterpretedEntryFrame::GetFrameFromSp(sp)->GetPrevFrameFp();
845     thread_->SetCurrentSPFrame(prevEntry);
846     return handleNativeInstanceObj;
847 }
848 
NewJSAggregateError()849 JSHandle<JSObject> ObjectFactory::NewJSAggregateError()
850 {
851     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
852     JSHandle<JSFunction> constructor(env->GetAggregateErrorFunction());
853     return NewJSObjectByConstructor(constructor);
854 }
855 
NewJSObjectByConstructor(const JSHandle<JSFunction> & constructor)856 JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor)
857 {
858     if (!constructor->HasFunctionPrototype() ||
859         (constructor->GetProtoOrHClass().IsHeapObject() && constructor->GetFunctionPrototype().IsECMAObject())) {
860         JSHandle<JSHClass> jshclass = JSFunction::GetInstanceJSHClass(thread_, constructor,
861                                                                       JSHandle<JSTaggedValue>(constructor));
862         return NewJSObjectWithInit(jshclass);
863     }
864     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
865     JSHandle<JSObject> result =
866         NewJSObjectByConstructor(JSHandle<JSFunction>(env->GetObjectFunction()), JSHandle<JSTaggedValue>(constructor));
867     if (thread_->HasPendingException()) {
868         LOG_FULL(FATAL) << "NewJSObjectByConstructor should not throw Exception! ";
869     }
870     return result;
871 }
872 
NewJSObjectByConstructor(const JSHandle<JSFunction> & constructor,const JSHandle<JSTaggedValue> & newTarget)873 JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor,
874                                                            const JSHandle<JSTaggedValue> &newTarget)
875 {
876     JSHandle<JSHClass> jshclass;
877     if (!constructor->HasFunctionPrototype() ||
878         (constructor->GetProtoOrHClass().IsHeapObject() && constructor->GetFunctionPrototype().IsECMAObject())) {
879         jshclass = JSFunction::GetInstanceJSHClass(thread_, constructor, newTarget);
880     } else {
881         JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
882         jshclass = JSFunction::GetInstanceJSHClass(thread_, JSHandle<JSFunction>(env->GetObjectFunction()), newTarget);
883     }
884     // Check this exception elsewhere
885     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread_);
886     return NewJSObjectWithInit(jshclass);
887 }
888 
NewJSObjectWithInit(const JSHandle<JSHClass> & jshclass)889 JSHandle<JSObject> ObjectFactory::NewJSObjectWithInit(const JSHandle<JSHClass> &jshclass)
890 {
891     JSHandle<JSObject> obj = NewJSObject(jshclass);
892     InitializeJSObject(obj, jshclass);
893     return obj;
894 }
895 
InitializeJSObject(const JSHandle<JSObject> & obj,const JSHandle<JSHClass> & jshclass)896 void ObjectFactory::InitializeJSObject(const JSHandle<JSObject> &obj, const JSHandle<JSHClass> &jshclass)
897 {
898     JSType type = jshclass->GetObjectType();
899     switch (type) {
900         case JSType::JS_OBJECT:
901         case JSType::JS_ERROR:
902         case JSType::JS_EVAL_ERROR:
903         case JSType::JS_RANGE_ERROR:
904         case JSType::JS_REFERENCE_ERROR:
905         case JSType::JS_TYPE_ERROR:
906         case JSType::JS_AGGREGATE_ERROR:
907         case JSType::JS_URI_ERROR:
908         case JSType::JS_SYNTAX_ERROR:
909         case JSType::JS_OOM_ERROR:
910         case JSType::JS_ASYNCITERATOR:
911         case JSType::JS_ITERATOR: {
912             break;
913         }
914         case JSType::JS_INTL: {
915             JSIntl::Cast(*obj)->SetFallbackSymbol(thread_, JSTaggedValue::Undefined());
916             JSHandle<JSSymbol> jsSymbol = NewPublicSymbolWithChar("IntlLegacyConstructedSymbol");
917             JSIntl::Cast(*obj)->SetFallbackSymbol(thread_, jsSymbol);
918             break;
919         }
920         case JSType::JS_LOCALE: {
921             JSLocale::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
922             break;
923         }
924         case JSType::JS_DATE_TIME_FORMAT: {
925             JSDateTimeFormat::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
926             JSDateTimeFormat::Cast(*obj)->SetCalendar(thread_, JSTaggedValue::Undefined());
927             JSDateTimeFormat::Cast(*obj)->SetNumberingSystem(thread_, JSTaggedValue::Undefined());
928             JSDateTimeFormat::Cast(*obj)->SetTimeZone(thread_, JSTaggedValue::Undefined());
929             JSDateTimeFormat::Cast(*obj)->SetLocaleIcu(thread_, JSTaggedValue::Undefined());
930             JSDateTimeFormat::Cast(*obj)->SetSimpleDateTimeFormatIcu(thread_, JSTaggedValue::Undefined());
931             JSDateTimeFormat::Cast(*obj)->SetIso8601(thread_, JSTaggedValue::Undefined());
932             JSDateTimeFormat::Cast(*obj)->SetBoundFormat(thread_, JSTaggedValue::Undefined());
933             JSDateTimeFormat::Cast(*obj)->SetHourCycle(HourCycleOption::EXCEPTION);
934             JSDateTimeFormat::Cast(*obj)->SetDateStyle(DateTimeStyleOption::EXCEPTION);
935             JSDateTimeFormat::Cast(*obj)->SetTimeStyle(DateTimeStyleOption::EXCEPTION);
936             break;
937         }
938         case JSType::JS_NUMBER_FORMAT: {
939             JSNumberFormat::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
940             JSNumberFormat::Cast(*obj)->SetNumberingSystem(thread_, JSTaggedValue::Undefined());
941             JSNumberFormat::Cast(*obj)->SetCurrency(thread_, JSTaggedValue::Undefined());
942             JSNumberFormat::Cast(*obj)->SetUnit(thread_, JSTaggedValue::Undefined());
943             JSNumberFormat::Cast(*obj)->SetMinimumIntegerDigits(thread_, JSTaggedValue::Undefined());
944             JSNumberFormat::Cast(*obj)->SetMinimumFractionDigits(thread_, JSTaggedValue::Undefined());
945             JSNumberFormat::Cast(*obj)->SetMaximumFractionDigits(thread_, JSTaggedValue::Undefined());
946             JSNumberFormat::Cast(*obj)->SetMinimumSignificantDigits(thread_, JSTaggedValue::Undefined());
947             JSNumberFormat::Cast(*obj)->SetMaximumSignificantDigits(thread_, JSTaggedValue::Undefined());
948             JSNumberFormat::Cast(*obj)->SetUseGrouping(thread_, JSTaggedValue::Undefined());
949             JSNumberFormat::Cast(*obj)->SetBoundFormat(thread_, JSTaggedValue::Undefined());
950             JSNumberFormat::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
951             JSNumberFormat::Cast(*obj)->SetStyle(StyleOption::EXCEPTION);
952             JSNumberFormat::Cast(*obj)->SetCurrencySign(CurrencySignOption::EXCEPTION);
953             JSNumberFormat::Cast(*obj)->SetCurrencyDisplay(CurrencyDisplayOption::EXCEPTION);
954             JSNumberFormat::Cast(*obj)->SetUnitDisplay(UnitDisplayOption::EXCEPTION);
955             JSNumberFormat::Cast(*obj)->SetSignDisplay(SignDisplayOption::EXCEPTION);
956             JSNumberFormat::Cast(*obj)->SetCompactDisplay(CompactDisplayOption::EXCEPTION);
957             JSNumberFormat::Cast(*obj)->SetNotation(NotationOption::EXCEPTION);
958             JSNumberFormat::Cast(*obj)->SetRoundingType(RoundingType::EXCEPTION);
959             break;
960         }
961         case JSType::JS_RELATIVE_TIME_FORMAT: {
962             JSRelativeTimeFormat::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
963             JSRelativeTimeFormat::Cast(*obj)->SetNumberingSystem(thread_, JSTaggedValue::Undefined());
964             JSRelativeTimeFormat::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
965             JSRelativeTimeFormat::Cast(*obj)->SetStyle(RelativeStyleOption::EXCEPTION);
966             JSRelativeTimeFormat::Cast(*obj)->SetNumeric(NumericOption::EXCEPTION);
967             break;
968         }
969         case JSType::JS_COLLATOR: {
970             JSCollator::Cast(*obj)->SetIcuField(thread_, JSTaggedValue::Undefined());
971             JSCollator::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
972             JSCollator::Cast(*obj)->SetCollation(thread_, JSTaggedValue::Undefined());
973             JSCollator::Cast(*obj)->SetBoundCompare(thread_, JSTaggedValue::Undefined());
974             JSCollator::Cast(*obj)->SetUsage(UsageOption::EXCEPTION);
975             JSCollator::Cast(*obj)->SetCaseFirst(CaseFirstOption::EXCEPTION);
976             JSCollator::Cast(*obj)->SetSensitivity(SensitivityOption::EXCEPTION);
977             JSCollator::Cast(*obj)->SetIgnorePunctuation(false);
978             JSCollator::Cast(*obj)->SetNumeric(false);
979             break;
980         }
981         case JSType::JS_PLURAL_RULES: {
982             JSPluralRules::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
983             JSPluralRules::Cast(*obj)->SetMinimumIntegerDigits(thread_, JSTaggedValue::Undefined());
984             JSPluralRules::Cast(*obj)->SetMinimumFractionDigits(thread_, JSTaggedValue::Undefined());
985             JSPluralRules::Cast(*obj)->SetMaximumFractionDigits(thread_, JSTaggedValue::Undefined());
986             JSPluralRules::Cast(*obj)->SetMinimumSignificantDigits(thread_, JSTaggedValue::Undefined());
987             JSPluralRules::Cast(*obj)->SetMaximumSignificantDigits(thread_, JSTaggedValue::Undefined());
988             JSPluralRules::Cast(*obj)->SetIcuPR(thread_, JSTaggedValue::Undefined());
989             JSPluralRules::Cast(*obj)->SetIcuNF(thread_, JSTaggedValue::Undefined());
990             JSPluralRules::Cast(*obj)->SetRoundingType(RoundingType::EXCEPTION);
991             JSPluralRules::Cast(*obj)->SetType(TypeOption::EXCEPTION);
992             break;
993         }
994         case JSType::JS_DISPLAYNAMES: {
995             JSDisplayNames::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
996             JSDisplayNames::Cast(*obj)->SetType(TypednsOption::EXCEPTION);
997             JSDisplayNames::Cast(*obj)->SetStyle(StyOption::EXCEPTION);
998             JSDisplayNames::Cast(*obj)->SetFallback(FallbackOption::EXCEPTION);
999             JSDisplayNames::Cast(*obj)->SetIcuLDN(thread_, JSTaggedValue::Undefined());
1000             break;
1001         }
1002         case JSType::JS_LIST_FORMAT: {
1003             JSListFormat::Cast(*obj)->SetLocale(thread_, JSTaggedValue::Undefined());
1004             JSListFormat::Cast(*obj)->SetType(ListTypeOption::EXCEPTION);
1005             JSListFormat::Cast(*obj)->SetStyle(ListStyleOption::EXCEPTION);
1006             JSListFormat::Cast(*obj)->SetIcuLF(thread_, JSTaggedValue::Undefined());
1007             break;
1008         }
1009         case JSType::JS_ARRAY: {
1010             JSArray::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
1011             ASSERT(!obj->GetJSHClass()->IsDictionaryMode());
1012             auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
1013             JSArray::Cast(*obj)->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
1014             break;
1015         }
1016         case JSType::JS_DATE:
1017             JSDate::Cast(*obj)->SetTimeValue(thread_, JSTaggedValue(0.0));
1018             JSDate::Cast(*obj)->SetLocalOffset(thread_, JSTaggedValue(JSDate::MAX_DOUBLE));
1019             break;
1020         case JSType::JS_TYPED_ARRAY:
1021         case JSType::JS_INT8_ARRAY:
1022         case JSType::JS_UINT8_ARRAY:
1023         case JSType::JS_UINT8_CLAMPED_ARRAY:
1024         case JSType::JS_INT16_ARRAY:
1025         case JSType::JS_UINT16_ARRAY:
1026         case JSType::JS_INT32_ARRAY:
1027         case JSType::JS_UINT32_ARRAY:
1028         case JSType::JS_FLOAT32_ARRAY:
1029         case JSType::JS_FLOAT64_ARRAY:
1030         case JSType::JS_BIGINT64_ARRAY:
1031         case JSType::JS_BIGUINT64_ARRAY:
1032             JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined());
1033             JSTypedArray::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined());
1034             JSTypedArray::Cast(*obj)->SetByteLength(0);
1035             JSTypedArray::Cast(*obj)->SetByteOffset(0);
1036             JSTypedArray::Cast(*obj)->SetArrayLength(0);
1037             JSTypedArray::Cast(*obj)->SetContentType(ContentType::None);
1038             break;
1039         case JSType::JS_REG_EXP:
1040             JSRegExp::Cast(*obj)->SetByteCodeBuffer(thread_, JSTaggedValue::Undefined());
1041             JSRegExp::Cast(*obj)->SetOriginalSource(thread_, JSTaggedValue::Undefined());
1042             JSRegExp::Cast(*obj)->SetOriginalFlags(thread_, JSTaggedValue(0));
1043             JSRegExp::Cast(*obj)->SetGroupName(thread_, JSTaggedValue::Undefined());
1044             JSRegExp::Cast(*obj)->SetLength(0);
1045             break;
1046         case JSType::JS_PRIMITIVE_REF:
1047             JSPrimitiveRef::Cast(*obj)->SetValue(thread_, JSTaggedValue::Undefined());
1048             break;
1049         case JSType::JS_SET:
1050             JSSet::Cast(*obj)->SetLinkedSet(thread_, JSTaggedValue::Undefined());
1051             break;
1052         case JSType::JS_MAP:
1053             JSMap::Cast(*obj)->SetLinkedMap(thread_, JSTaggedValue::Undefined());
1054             break;
1055         case JSType::JS_WEAK_MAP:
1056             JSWeakMap::Cast(*obj)->SetLinkedMap(thread_, JSTaggedValue::Undefined());
1057             break;
1058         case JSType::JS_WEAK_SET:
1059             JSWeakSet::Cast(*obj)->SetLinkedSet(thread_, JSTaggedValue::Undefined());
1060             break;
1061         case JSType::JS_WEAK_REF:
1062             JSWeakRef::Cast(*obj)->SetWeakObject(thread_, JSTaggedValue::Undefined());
1063             break;
1064         case JSType::JS_FINALIZATION_REGISTRY:
1065             JSFinalizationRegistry::Cast(*obj)->SetCleanupCallback(thread_, JSTaggedValue::Undefined());
1066             JSFinalizationRegistry::Cast(*obj)->SetNoUnregister(thread_, JSTaggedValue::Undefined());
1067             JSFinalizationRegistry::Cast(*obj)->SetMaybeUnregister(thread_, JSTaggedValue::Undefined());
1068             JSFinalizationRegistry::Cast(*obj)->SetNext(thread_, JSTaggedValue::Null());
1069             JSFinalizationRegistry::Cast(*obj)->SetPrev(thread_, JSTaggedValue::Null());
1070             break;
1071         case JSType::JS_GENERATOR_OBJECT:
1072             JSGeneratorObject::Cast(*obj)->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
1073             JSGeneratorObject::Cast(*obj)->SetResumeResult(thread_, JSTaggedValue::Undefined());
1074             JSGeneratorObject::Cast(*obj)->SetGeneratorState(JSGeneratorState::UNDEFINED);
1075             JSGeneratorObject::Cast(*obj)->SetResumeMode(GeneratorResumeMode::UNDEFINED);
1076             break;
1077         case JSType::JS_ASYNC_GENERATOR_OBJECT:
1078             JSAsyncGeneratorObject::Cast(*obj)->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
1079             JSAsyncGeneratorObject::Cast(*obj)->SetAsyncGeneratorQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1080             JSAsyncGeneratorObject::Cast(*obj)->SetGeneratorBrand(thread_, JSTaggedValue::Undefined());
1081             JSAsyncGeneratorObject::Cast(*obj)->SetResumeResult(thread_, JSTaggedValue::Undefined());
1082             JSAsyncGeneratorObject::Cast(*obj)->SetAsyncGeneratorState(JSAsyncGeneratorState::UNDEFINED);
1083             JSAsyncGeneratorObject::Cast(*obj)->SetResumeMode(AsyncGeneratorResumeMode::UNDEFINED);
1084             break;
1085         case JSType::JS_STRING_ITERATOR:
1086             JSStringIterator::Cast(*obj)->SetStringIteratorNextIndex(0);
1087             JSStringIterator::Cast(*obj)->SetIteratedString(thread_, JSTaggedValue::Undefined());
1088             break;
1089         case JSType::JS_ASYNC_FROM_SYNC_ITERATOR:
1090             JSAsyncFromSyncIterator::Cast(*obj)->SetSyncIteratorRecord(thread_, JSTaggedValue::Undefined());
1091             break;
1092         case JSType::JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION:
1093             JSAsyncFromSyncIterUnwarpFunction::Cast(*obj)->SetDone(thread_, JSTaggedValue::Undefined());
1094             break;
1095         case JSType::JS_ARRAY_BUFFER:
1096             JSArrayBuffer::Cast(*obj)->SetArrayBufferData(thread_, JSTaggedValue::Undefined());
1097             JSArrayBuffer::Cast(*obj)->SetArrayBufferByteLength(0);
1098             JSArrayBuffer::Cast(*obj)->ClearBitField();
1099             break;
1100         case JSType::JS_SHARED_ARRAY_BUFFER:
1101             JSArrayBuffer::Cast(*obj)->SetArrayBufferData(thread_, JSTaggedValue::Undefined());
1102             JSArrayBuffer::Cast(*obj)->SetArrayBufferByteLength(0);
1103             JSArrayBuffer::Cast(*obj)->SetShared(true);
1104             break;
1105         case JSType::JS_PROMISE:
1106             JSPromise::Cast(*obj)->SetPromiseState(PromiseState::PENDING);
1107             JSPromise::Cast(*obj)->SetPromiseResult(thread_, JSTaggedValue::Undefined());
1108             JSPromise::Cast(*obj)->SetPromiseRejectReactions(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1109             JSPromise::Cast(*obj)->SetPromiseFulfillReactions(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1110 
1111             JSPromise::Cast(*obj)->SetPromiseIsHandled(false);
1112             break;
1113         case JSType::JS_DATA_VIEW:
1114             JSDataView::Cast(*obj)->SetDataView(thread_, JSTaggedValue(false));
1115             JSDataView::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined());
1116             JSDataView::Cast(*obj)->SetByteLength(0);
1117             JSDataView::Cast(*obj)->SetByteOffset(0);
1118             break;
1119         // non ECMA standard jsapi container
1120         case JSType::JS_API_ARRAY_LIST: {
1121             JSAPIArrayList::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
1122             break;
1123         }
1124         case JSType::JS_API_HASH_MAP: {
1125             JSAPIHashMap::Cast(*obj)->SetSize(0);
1126             JSAPIHashMap::Cast(*obj)->SetTable(thread_, JSTaggedValue::Undefined());
1127             break;
1128         }
1129         case JSType::JS_API_HASH_SET: {
1130             JSAPIHashSet::Cast(*obj)->SetSize(0);
1131             JSAPIHashSet::Cast(*obj)->SetTable(thread_, JSTaggedValue::Undefined());
1132             break;
1133         }
1134         case JSType::JS_API_TREE_MAP: {
1135             JSAPITreeMap::Cast(*obj)->SetTreeMap(thread_, JSTaggedValue::Undefined());
1136             break;
1137         }
1138         case JSType::JS_API_TREE_SET: {
1139             JSAPITreeSet::Cast(*obj)->SetTreeSet(thread_, JSTaggedValue::Undefined());
1140             break;
1141         }
1142         case JSType::JS_API_QUEUE: {
1143             JSAPIQueue::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
1144             JSAPIQueue::Cast(*obj)->SetFront(0);
1145             JSAPIQueue::Cast(*obj)->SetTail(0);
1146             break;
1147         }
1148         case JSType::JS_API_PLAIN_ARRAY: {
1149             JSAPIPlainArray::Cast(*obj)->SetLength(0);
1150             JSAPIPlainArray::Cast(*obj)->SetValues(thread_, JSTaggedValue(0));
1151             JSAPIPlainArray::Cast(*obj)->SetKeys(thread_, JSTaggedValue(0));
1152             break;
1153         }
1154         case JSType::JS_API_STACK: {
1155             JSAPIStack::Cast(*obj)->SetTop(0);
1156             break;
1157         }
1158         case JSType::JS_API_DEQUE: {
1159             JSAPIDeque::Cast(*obj)->SetFirst(0);
1160             JSAPIDeque::Cast(*obj)->SetLast(0);
1161             break;
1162         }
1163         case JSType::JS_API_LIGHT_WEIGHT_MAP: {
1164             JSAPILightWeightMap::Cast(*obj)->SetLength(0);
1165             JSAPILightWeightMap::Cast(*obj)->SetHashes(thread_, JSTaggedValue::Undefined());
1166             JSAPILightWeightMap::Cast(*obj)->SetKeys(thread_, JSTaggedValue::Undefined());
1167             JSAPILightWeightMap::Cast(*obj)->SetValues(thread_, JSTaggedValue::Undefined());
1168             break;
1169         }
1170         case JSType::JS_API_LIGHT_WEIGHT_SET: {
1171             JSAPILightWeightSet::Cast(*obj)->SetLength(0);
1172             JSAPILightWeightSet::Cast(*obj)->SetHashes(thread_, JSTaggedValue::Undefined());
1173             JSAPILightWeightSet::Cast(*obj)->SetValues(thread_, JSTaggedValue::Undefined());
1174             break;
1175         }
1176         case JSType::JS_API_VECTOR: {
1177             JSAPIVector::Cast(*obj)->SetLength(0);
1178             break;
1179         }
1180         case JSType::JS_API_LIST: {
1181             JSAPIList::Cast(*obj)->SetSingleList(thread_, JSTaggedValue::Undefined());
1182             break;
1183         }
1184         case JSType::JS_API_LINKED_LIST: {
1185             JSAPILinkedList::Cast(*obj)->SetDoubleList(thread_, JSTaggedValue::Undefined());
1186             break;
1187         }
1188         case JSType::JS_ASYNC_FUNC_OBJECT:
1189             JSAsyncFuncObject::Cast(*obj)->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
1190             JSAsyncFuncObject::Cast(*obj)->SetResumeResult(thread_, JSTaggedValue::Undefined());
1191             JSAsyncFuncObject::Cast(*obj)->SetPromise(thread_, JSTaggedValue::Undefined());
1192             break;
1193         case JSType::JS_FUNCTION:
1194         case JSType::JS_GENERATOR_FUNCTION:
1195             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1196             break;
1197         case JSType::JS_ASYNC_GENERATOR_FUNCTION:
1198             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1199             break;
1200         case JSType::JS_PROXY_REVOC_FUNCTION:
1201             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1202             JSProxyRevocFunction::Cast(*obj)->SetRevocableProxy(thread_, JSTaggedValue::Undefined());
1203             break;
1204         case JSType::JS_PROMISE_REACTIONS_FUNCTION:
1205             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1206             JSPromiseReactionsFunction::Cast(*obj)->SetPromise(thread_, JSTaggedValue::Undefined());
1207             JSPromiseReactionsFunction::Cast(*obj)->SetAlreadyResolved(thread_, JSTaggedValue::Undefined());
1208             break;
1209         case JSType::JS_PROMISE_EXECUTOR_FUNCTION:
1210             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1211             JSPromiseExecutorFunction::Cast(*obj)->SetCapability(thread_, JSTaggedValue::Undefined());
1212             break;
1213         case JSType::JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN:
1214             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1215             JSAsyncGeneratorResNextRetProRstFtn::Cast(*obj)->SetAsyncGeneratorObject(thread_,
1216                                                                                      JSTaggedValue::Undefined());
1217             break;
1218         case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION:
1219             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1220             JSPromiseAllResolveElementFunction::Cast(*obj)->SetIndex(thread_, JSTaggedValue::Undefined());
1221             JSPromiseAllResolveElementFunction::Cast(*obj)->SetValues(thread_, JSTaggedValue::Undefined());
1222             JSPromiseAllResolveElementFunction::Cast(*obj)->SetCapabilities(thread_, JSTaggedValue::Undefined());
1223             JSPromiseAllResolveElementFunction::Cast(*obj)->SetRemainingElements(thread_, JSTaggedValue::Undefined());
1224             JSPromiseAllResolveElementFunction::Cast(*obj)->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
1225             break;
1226         case JSType::JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION:
1227             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1228             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetIndex(0);
1229             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetErrors(thread_, JSTaggedValue::Undefined());
1230             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetCapability(thread_, JSTaggedValue::Undefined());
1231             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetRemainingElements(thread_, JSTaggedValue::Undefined());
1232             JSPromiseAnyRejectElementFunction::Cast(*obj)->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
1233             break;
1234         case JSType::JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION:
1235             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1236             JSPromiseAllSettledElementFunction::Cast(*obj)->SetIndex(0);
1237             JSPromiseAllSettledElementFunction::Cast(*obj)->SetValues(thread_, JSTaggedValue::Undefined());
1238             JSPromiseAllSettledElementFunction::Cast(*obj)->SetCapability(thread_, JSTaggedValue::Undefined());
1239             JSPromiseAllSettledElementFunction::Cast(*obj)->SetRemainingElements(thread_, JSTaggedValue::Undefined());
1240             JSPromiseAllSettledElementFunction::Cast(*obj)->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
1241             break;
1242         case JSType::JS_PROMISE_FINALLY_FUNCTION:
1243             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1244             JSPromiseFinallyFunction::Cast(*obj)->SetOnFinally(thread_, JSTaggedValue::Undefined());
1245             JSPromiseFinallyFunction::Cast(*obj)->SetConstructor(thread_, JSTaggedValue::Undefined());
1246             break;
1247         case JSType::JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION:
1248             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1249             JSPromiseValueThunkOrThrowerFunction::Cast(*obj)->SetResult(thread_, JSTaggedValue::Undefined());
1250             break;
1251         case JSType::JS_INTL_BOUND_FUNCTION:
1252             JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>(obj));
1253             JSIntlBoundFunction::Cast(*obj)->SetNumberFormat(thread_, JSTaggedValue::Undefined());
1254             JSIntlBoundFunction::Cast(*obj)->SetDateTimeFormat(thread_, JSTaggedValue::Undefined());
1255             JSIntlBoundFunction::Cast(*obj)->SetCollator(thread_, JSTaggedValue::Undefined());
1256             break;
1257         case JSType::JS_BOUND_FUNCTION:
1258             JSBoundFunction::Cast(*obj)->SetMethod(thread_, JSTaggedValue::Undefined());
1259             JSBoundFunction::Cast(*obj)->SetBoundTarget(thread_, JSTaggedValue::Undefined());
1260             JSBoundFunction::Cast(*obj)->SetBoundThis(thread_, JSTaggedValue::Undefined());
1261             JSBoundFunction::Cast(*obj)->SetBoundArguments(thread_, JSTaggedValue::Undefined());
1262             break;
1263         case JSType::JS_ARGUMENTS:
1264             break;
1265         case JSType::JS_FORIN_ITERATOR:
1266         case JSType::JS_MAP_ITERATOR:
1267         case JSType::JS_SET_ITERATOR:
1268         case JSType::JS_REG_EXP_ITERATOR:
1269         case JSType::JS_API_ARRAYLIST_ITERATOR:
1270         case JSType::JS_API_TREEMAP_ITERATOR:
1271         case JSType::JS_API_TREESET_ITERATOR:
1272         case JSType::JS_API_QUEUE_ITERATOR:
1273         case JSType::JS_API_DEQUE_ITERATOR:
1274         case JSType::JS_API_LIGHT_WEIGHT_MAP_ITERATOR:
1275         case JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR:
1276         case JSType::JS_API_STACK_ITERATOR:
1277         case JSType::JS_API_VECTOR_ITERATOR:
1278         case JSType::JS_API_HASHMAP_ITERATOR:
1279         case JSType::JS_API_HASHSET_ITERATOR:
1280         case JSType::JS_ARRAY_ITERATOR:
1281         case JSType::JS_API_PLAIN_ARRAY_ITERATOR:
1282             break;
1283         case JSType::JS_CJS_MODULE:
1284             CjsModule::Cast(*obj)->SetId(thread_, JSTaggedValue::Undefined());
1285             CjsModule::Cast(*obj)->SetExports(thread_, JSTaggedValue::Undefined());
1286             CjsModule::Cast(*obj)->SetPath(thread_, JSTaggedValue::Undefined());
1287             CjsModule::Cast(*obj)->SetFilename(thread_, JSTaggedValue::Undefined());
1288             CjsModule::Cast(*obj)->SetStatus(CjsModuleStatus::UNLOAD);
1289             break;
1290         case JSType::JS_CJS_EXPORTS:
1291             CjsExports::Cast(*obj)->SetExports(thread_, JSTaggedValue::Undefined());
1292             break;
1293         case JSType::JS_CJS_REQUIRE:
1294             CjsRequire::Cast(*obj)->SetCache(thread_, JSTaggedValue::Undefined());
1295             CjsRequire::Cast(*obj)->SetParent(thread_, JSTaggedValue::Undefined());
1296             break;
1297         default:
1298             UNREACHABLE();
1299     }
1300 }
1301 
FillFreeObject(uintptr_t address,size_t size,RemoveSlots removeSlots,uintptr_t hugeObjectHead)1302 FreeObject *ObjectFactory::FillFreeObject(uintptr_t address, size_t size, RemoveSlots removeSlots,
1303                                           uintptr_t hugeObjectHead)
1304 {
1305     FreeObject *object = nullptr;
1306     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1307     if (size >= FreeObject::SIZE_OFFSET && size < FreeObject::SIZE) {
1308         object = reinterpret_cast<FreeObject *>(address);
1309         object->SetClassWithoutBarrier(JSHClass::Cast(globalConst->GetFreeObjectWithOneFieldClass().GetTaggedObject()));
1310         object->SetNext(INVALID_OBJECT);
1311     } else if (size >= FreeObject::SIZE) {
1312         object = reinterpret_cast<FreeObject *>(address);
1313         if (!vm_->IsGlobalConstInitialized()) {
1314             object->SetClassWithoutBarrier(nullptr);
1315         } else {
1316             object->SetClassWithoutBarrier(
1317                 JSHClass::Cast(globalConst->GetFreeObjectWithTwoFieldClass().GetTaggedObject()));
1318         }
1319         object->SetAvailable(size);
1320         object->SetNext(INVALID_OBJECT);
1321     } else if (size == FreeObject::NEXT_OFFSET) {
1322         object = reinterpret_cast<FreeObject *>(address);
1323         object->SetClassWithoutBarrier(
1324             JSHClass::Cast(globalConst->GetFreeObjectWithNoneFieldClass().GetTaggedObject()));
1325     } else {
1326         LOG_ECMA(DEBUG) << "Fill free object size is smaller";
1327     }
1328 
1329     if (removeSlots == RemoveSlots::YES) {
1330         // For huge object, the region of `object` might not be its 1st region. Use `hugeObjectHead` instead.
1331         Region *region = Region::ObjectAddressToRange(hugeObjectHead == 0 ? object :
1332                                                       reinterpret_cast<TaggedObject *>(hugeObjectHead));
1333         if (!region->InYoungSpace()) {
1334             heap_->ClearSlotsRange(region, address, address + size);
1335         }
1336     }
1337     return object;
1338 }
1339 
NewObject(const JSHandle<JSHClass> & hclass)1340 TaggedObject *ObjectFactory::NewObject(const JSHandle<JSHClass> &hclass)
1341 {
1342     NewObjectHook();
1343     TaggedObject *header = heap_->AllocateYoungOrHugeObject(*hclass);
1344     uint32_t inobjPropCount = hclass->GetInlinedProperties();
1345     if (inobjPropCount > 0) {
1346         InitializeExtraProperties(hclass, header, inobjPropCount);
1347     }
1348     return header;
1349 }
1350 
NewNonMovableObject(const JSHandle<JSHClass> & hclass,uint32_t inobjPropCount)1351 TaggedObject *ObjectFactory::NewNonMovableObject(const JSHandle<JSHClass> &hclass, uint32_t inobjPropCount)
1352 {
1353     NewObjectHook();
1354     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(*hclass);
1355     if (inobjPropCount > 0) {
1356         InitializeExtraProperties(hclass, header, inobjPropCount);
1357     }
1358     return header;
1359 }
1360 
InitializeExtraProperties(const JSHandle<JSHClass> & hclass,TaggedObject * obj,uint32_t inobjPropCount)1361 void ObjectFactory::InitializeExtraProperties(const JSHandle<JSHClass> &hclass, TaggedObject *obj,
1362                                               uint32_t inobjPropCount)
1363 {
1364     ASSERT(inobjPropCount * JSTaggedValue::TaggedTypeSize() < hclass->GetObjectSize());
1365     auto paddr = reinterpret_cast<uintptr_t>(obj) + hclass->GetObjectSize();
1366     // The object which created by AOT speculative hclass, should be initialized as hole, means does not exist,
1367     // to follow ECMA spec.
1368     JSTaggedType initVal = hclass->IsTS() ? JSTaggedValue::VALUE_HOLE : JSTaggedValue::VALUE_UNDEFINED;
1369     for (uint32_t i = 0; i < inobjPropCount; ++i) {
1370         paddr -= JSTaggedValue::TaggedTypeSize();
1371         *reinterpret_cast<JSTaggedType *>(paddr) = initVal;
1372     }
1373 }
1374 
OrdinaryNewJSObjectCreate(const JSHandle<JSTaggedValue> & proto)1375 JSHandle<JSObject> ObjectFactory::OrdinaryNewJSObjectCreate(const JSHandle<JSTaggedValue> &proto)
1376 {
1377     JSHandle<JSTaggedValue> protoValue(proto);
1378     JSHandle<JSHClass> hclass(thread_, thread_->GlobalConstants()->GetObjectClass().GetTaggedObject());
1379     JSHandle<JSHClass> newClass = JSHClass::TransProtoWithoutLayout(thread_, hclass, protoValue);
1380     JSHandle<JSObject> newObj = NewJSObject(newClass);
1381     newObj->GetJSHClass()->SetExtensible(true);
1382     return newObj;
1383 }
1384 
NewJSFunction(const JSHandle<GlobalEnv> & env,const void * nativeFunc,FunctionKind kind,kungfu::BuiltinsStubCSigns::ID builtinId)1385 JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc,
1386                                                   FunctionKind kind, kungfu::BuiltinsStubCSigns::ID builtinId)
1387 {
1388     JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, kind, builtinId);
1389     return NewJSFunction(env, target);
1390 }
1391 
NewJSFunction(const JSHandle<GlobalEnv> & env,const JSHandle<Method> & method)1392 JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<GlobalEnv> &env,
1393                                                   const JSHandle<Method> &method)
1394 {
1395     FunctionKind kind = method->GetFunctionKind();
1396     JSHandle<JSHClass> hclass;
1397     if (kind == FunctionKind::BASE_CONSTRUCTOR) {
1398         hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
1399     } else if (JSFunction::IsConstructorKind(kind)) {
1400         hclass = JSHandle<JSHClass>::Cast(env->GetConstructorFunctionClass());
1401     } else if (kind == FunctionKind::CONCURRENT_FUNCTION) {
1402         hclass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
1403     } else {
1404         hclass = JSHandle<JSHClass>::Cast(env->GetNormalFunctionClass());
1405     }
1406 
1407     return NewJSFunctionByHClass(method, hclass);
1408 }
1409 
CreateFunctionClass(FunctionKind kind,uint32_t size,JSType type,const JSHandle<JSTaggedValue> & prototype)1410 JSHandle<JSHClass> ObjectFactory::CreateFunctionClass(FunctionKind kind, uint32_t size, JSType type,
1411                                                       const JSHandle<JSTaggedValue> &prototype)
1412 {
1413     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1414     JSHandle<JSHClass> functionClass = NewEcmaHClass(size, type, prototype);
1415     {
1416         functionClass->SetCallable(true);
1417         // FunctionKind = BASE_CONSTRUCTOR
1418         if (JSFunction::IsConstructorKind(kind)) {
1419             functionClass->SetConstructor(true);
1420         }
1421         functionClass->SetExtensible(true);
1422     }
1423 
1424     uint32_t fieldOrder = 0;
1425     ASSERT(JSFunction::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
1426     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(JSFunction::LENGTH_OF_INLINE_PROPERTIES);
1427     {
1428         PropertyAttributes attributes = PropertyAttributes::Default(false, false, true);
1429         attributes.SetIsInlinedProps(true);
1430         attributes.SetRepresentation(Representation::MIXED);
1431         attributes.SetOffset(fieldOrder);
1432         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetLengthString(), attributes);
1433         fieldOrder++;
1434     }
1435 
1436     ASSERT(JSFunction::NAME_INLINE_PROPERTY_INDEX == fieldOrder);
1437     // not set name in-object property on class which may have a name() method
1438     if (!JSFunction::IsClassConstructor(kind)) {
1439         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true);
1440         attributes.SetIsInlinedProps(true);
1441         attributes.SetRepresentation(Representation::MIXED);
1442         attributes.SetOffset(fieldOrder);
1443         layoutInfoHandle->AddKey(thread_, fieldOrder,
1444                                  thread_->GlobalConstants()->GetHandledNameString().GetTaggedValue(), attributes);
1445         fieldOrder++;
1446     }
1447 
1448     if (JSFunction::HasPrototype(kind) && !JSFunction::IsClassConstructor(kind)) {
1449         ASSERT(JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX == fieldOrder);
1450         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(true, false, false);
1451         attributes.SetIsInlinedProps(true);
1452         attributes.SetRepresentation(Representation::MIXED);
1453         attributes.SetOffset(fieldOrder);
1454         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetPrototypeString(), attributes);
1455         fieldOrder++;
1456     } else if (JSFunction::IsClassConstructor(kind)) {
1457         ASSERT(JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX == fieldOrder);
1458         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, false);
1459         attributes.SetIsInlinedProps(true);
1460         attributes.SetRepresentation(Representation::MIXED);
1461         attributes.SetOffset(fieldOrder);
1462         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetPrototypeString(), attributes);
1463         fieldOrder++;
1464     }
1465 
1466     {
1467         functionClass->SetLayout(thread_, layoutInfoHandle);
1468         functionClass->SetNumberOfProps(fieldOrder);
1469     }
1470     return functionClass;
1471 }
1472 
CreateDefaultClassPrototypeHClass(JSHClass * hclass)1473 JSHandle<JSHClass> ObjectFactory::CreateDefaultClassPrototypeHClass(JSHClass *hclass)
1474 {
1475     uint32_t size = ClassInfoExtractor::NON_STATIC_RESERVED_LENGTH;
1476     JSHandle<LayoutInfo> layout = CreateLayoutInfo(size, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
1477     PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);  // non-enumerable
1478 
1479     attributes.SetIsInlinedProps(true);
1480     attributes.SetRepresentation(Representation::MIXED);
1481     attributes.SetOffset(ClassInfoExtractor::CONSTRUCTOR_INDEX);
1482     layout->AddKey(thread_, ClassInfoExtractor::CONSTRUCTOR_INDEX,
1483         thread_->GlobalConstants()->GetConstructorString(), attributes);
1484 
1485     JSHandle<JSHClass> defaultHclass = NewEcmaHClass(hclass, JSObject::SIZE, JSType::JS_OBJECT, size);
1486     defaultHclass->SetLayout(thread_, layout);
1487     defaultHclass->SetNumberOfProps(size);
1488     defaultHclass->SetClassPrototype(true);
1489     defaultHclass->SetIsPrototype(true);
1490     return defaultHclass;
1491 }
1492 
CreateDefaultClassConstructorHClass(JSHClass * hclass)1493 JSHandle<JSHClass> ObjectFactory::CreateDefaultClassConstructorHClass(JSHClass *hclass)
1494 {
1495     uint32_t size = ClassInfoExtractor::STATIC_RESERVED_LENGTH;
1496     JSHandle<LayoutInfo> layout = CreateLayoutInfo(size, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
1497 
1498     JSHandle<TaggedArray> array = NewTaggedArray(size);
1499     array->Set(thread_, ClassInfoExtractor::LENGTH_INDEX, thread_->GlobalConstants()->GetLengthString());
1500     array->Set(thread_, ClassInfoExtractor::NAME_INDEX, thread_->GlobalConstants()->GetNameString());
1501     array->Set(thread_, ClassInfoExtractor::PROTOTYPE_INDEX, thread_->GlobalConstants()->GetPrototypeString());
1502     for (uint32_t index = ClassInfoExtractor::LENGTH_INDEX; index < size; index++) {
1503         PropertyAttributes attributes;
1504         if (index == ClassInfoExtractor::PROTOTYPE_INDEX) {
1505             attributes = PropertyAttributes::DefaultAccessor(false, false, false);
1506         } else {
1507             attributes = PropertyAttributes::Default(false, false, true);
1508         }
1509         attributes.SetIsInlinedProps(true);
1510         attributes.SetRepresentation(Representation::MIXED);
1511         attributes.SetOffset(index);
1512         layout->AddKey(thread_, index, array->Get(index), attributes);
1513     }
1514 
1515     JSHandle<JSHClass> defaultHclass = NewEcmaHClass(hclass, JSFunction::SIZE, JSType::JS_FUNCTION, size);
1516     defaultHclass->SetLayout(thread_, layout);
1517     defaultHclass->SetNumberOfProps(size);
1518     defaultHclass->SetClassConstructor(true);
1519     defaultHclass->SetConstructor(true);
1520     return defaultHclass;
1521 }
1522 
NewJSFunctionByHClass(const JSHandle<Method> & method,const JSHandle<JSHClass> & clazz,MemSpaceType type)1523 JSHandle<JSFunction> ObjectFactory::NewJSFunctionByHClass(const JSHandle<Method> &method,
1524                                                           const JSHandle<JSHClass> &clazz,
1525                                                           MemSpaceType type)
1526 {
1527     JSHandle<JSFunction> function;
1528     switch (type) {
1529         case MemSpaceType::SEMI_SPACE:
1530             function = JSHandle<JSFunction>::Cast(NewJSObject(clazz));
1531             break;
1532         case MemSpaceType::OLD_SPACE:
1533             function = JSHandle<JSFunction>::Cast(NewOldSpaceJSObject(clazz));
1534             break;
1535         case MemSpaceType::NON_MOVABLE:
1536             function = JSHandle<JSFunction>::Cast(NewNonMovableJSObject(clazz));
1537             break;
1538         default:
1539             UNREACHABLE();
1540     }
1541     clazz->SetCallable(true);
1542     clazz->SetExtensible(true);
1543     JSFunction::InitializeJSFunction(thread_, function, method->GetFunctionKind());
1544     function->SetMethod(thread_, method);
1545     return function;
1546 }
1547 
NewJSFunctionByHClass(const void * func,const JSHandle<JSHClass> & clazz,FunctionKind kind)1548 JSHandle<JSFunction> ObjectFactory::NewJSFunctionByHClass(const void *func, const JSHandle<JSHClass> &clazz,
1549                                                           FunctionKind kind)
1550 {
1551     JSHandle<Method> method = NewMethodForNativeFunction(func, kind);
1552     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(NewJSObject(clazz));
1553     clazz->SetCallable(true);
1554     clazz->SetExtensible(true);
1555     JSFunction::InitializeJSFunction(thread_, function, kind);
1556     function->SetMethod(thread_, method);
1557     return function;
1558 }
1559 
NewMethod(const MethodLiteral * methodLiteral)1560 JSHandle<Method> ObjectFactory::NewMethod(const MethodLiteral *methodLiteral)
1561 {
1562     NewObjectHook();
1563     TaggedObject *header = heap_->AllocateOldOrHugeObject(
1564         JSHClass::Cast(thread_->GlobalConstants()->GetMethodClass().GetTaggedObject()));
1565     JSHandle<Method> method(thread_, header);
1566     if (methodLiteral != nullptr) {
1567         method->SetCallField(methodLiteral->GetCallField());
1568         method->SetLiteralInfo(methodLiteral->GetLiteralInfo());
1569         method->SetNativePointerOrBytecodeArray(const_cast<void *>(methodLiteral->GetNativePointer()));
1570         method->SetExtraLiteralInfo(methodLiteral->GetExtraLiteralInfo());
1571     } else {
1572         method->SetCallField(0ULL);
1573         method->SetLiteralInfo(0ULL);
1574         method->SetNativePointerOrBytecodeArray(nullptr);
1575         method->SetExtraLiteralInfo(0ULL);
1576     }
1577     method->SetCodeEntryOrLiteral(reinterpret_cast<uintptr_t>(methodLiteral));
1578     method->SetConstantPool(thread_, JSTaggedValue::Undefined());
1579     method->SetProfileTypeInfo(thread_, JSTaggedValue::Undefined());
1580     return method;
1581 }
1582 
NewJSNativeErrorFunction(const JSHandle<GlobalEnv> & env,const void * nativeFunc)1583 JSHandle<JSFunction> ObjectFactory::NewJSNativeErrorFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc)
1584 {
1585     JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, FunctionKind::BUILTIN_CONSTRUCTOR);
1586     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetNativeErrorFunctionClass());
1587     return NewJSFunctionByHClass(target, hclass);
1588 }
1589 
NewSpecificTypedArrayFunction(const JSHandle<GlobalEnv> & env,const void * nativeFunc)1590 JSHandle<JSFunction> ObjectFactory::NewSpecificTypedArrayFunction(const JSHandle<GlobalEnv> &env,
1591                                                                   const void *nativeFunc)
1592 {
1593     JSHandle<Method> target = NewMethodForNativeFunction(nativeFunc, FunctionKind::BUILTIN_CONSTRUCTOR);
1594     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSpecificTypedArrayFunctionClass());
1595     return NewJSFunctionByHClass(target, hclass);
1596 }
1597 
NewAotFunction(uint32_t numArgs,uintptr_t codeEntry)1598 JSHandle<JSFunction> ObjectFactory::NewAotFunction(uint32_t numArgs, uintptr_t codeEntry)
1599 {
1600     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1601     JSHandle<Method> method = NewMethodForNativeFunction(reinterpret_cast<void *>(codeEntry));
1602     method->SetAotCodeBit(true);
1603     method->SetNativeBit(false);
1604     method->SetNumArgsWithCallField(numArgs);
1605     method->SetCodeEntryOrLiteral(codeEntry);
1606     JSHandle<JSFunction> jsfunc = NewJSFunction(env, method);
1607     return jsfunc;
1608 }
1609 
NewJSBoundFunction(const JSHandle<JSFunctionBase> & target,const JSHandle<JSTaggedValue> & boundThis,const JSHandle<TaggedArray> & args)1610 JSHandle<JSBoundFunction> ObjectFactory::NewJSBoundFunction(const JSHandle<JSFunctionBase> &target,
1611                                                             const JSHandle<JSTaggedValue> &boundThis,
1612                                                             const JSHandle<TaggedArray> &args)
1613 {
1614     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1615     JSHandle<JSTaggedValue> proto = env->GetFunctionPrototype();
1616     JSHandle<JSHClass> hclass = NewEcmaHClass(JSBoundFunction::SIZE, JSType::JS_BOUND_FUNCTION, proto);
1617 
1618     JSHandle<JSBoundFunction> bundleFunction = JSHandle<JSBoundFunction>::Cast(NewJSObject(hclass));
1619     bundleFunction->SetBoundTarget(thread_, target);
1620     bundleFunction->SetBoundThis(thread_, boundThis);
1621     bundleFunction->SetBoundArguments(thread_, args);
1622     hclass->SetCallable(true);
1623     if (target.GetTaggedValue().IsConstructor()) {
1624         bundleFunction->SetConstructor(true);
1625     }
1626     bundleFunction->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_GLOBAL_CALL_JS_BOUND_FUNCTION));
1627     return bundleFunction;
1628 }
1629 
NewJSIntlBoundFunction(MethodIndex idx,int functionLength)1630 JSHandle<JSIntlBoundFunction> ObjectFactory::NewJSIntlBoundFunction(MethodIndex idx, int functionLength)
1631 {
1632     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1633     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetJSIntlBoundFunctionClass());
1634 
1635     JSHandle<JSIntlBoundFunction> intlBoundFunc = JSHandle<JSIntlBoundFunction>::Cast(NewJSObject(hclass));
1636     intlBoundFunc->SetNumberFormat(thread_, JSTaggedValue::Undefined());
1637     intlBoundFunc->SetDateTimeFormat(thread_, JSTaggedValue::Undefined());
1638     intlBoundFunc->SetCollator(thread_, JSTaggedValue::Undefined());
1639     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(intlBoundFunc);
1640     JSFunction::InitializeJSFunction(thread_, function);
1641     function->SetMethod(thread_, vm_->GetMethodByIndex(idx));
1642     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(functionLength));
1643     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1644     JSHandle<JSTaggedValue> emptyString = globalConst->GetHandledEmptyString();
1645     JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
1646     PropertyDescriptor nameDesc(thread_, emptyString, false, false, true);
1647     JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>::Cast(function), nameKey, nameDesc);
1648     return intlBoundFunc;
1649 }
1650 
NewJSProxyRevocFunction(const JSHandle<JSProxy> & proxy)1651 JSHandle<JSProxyRevocFunction> ObjectFactory::NewJSProxyRevocFunction(const JSHandle<JSProxy> &proxy)
1652 {
1653     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1654     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1655     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetProxyRevocFunctionClass());
1656 
1657     JSHandle<JSProxyRevocFunction> revocFunction = JSHandle<JSProxyRevocFunction>::Cast(NewJSObject(hclass));
1658     revocFunction->SetRevocableProxy(thread_, JSTaggedValue::Undefined());
1659     revocFunction->SetRevocableProxy(thread_, proxy);
1660     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(revocFunction);
1661     JSFunction::InitializeJSFunction(thread_, function);
1662     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROXY_INVALIDATE_PROXY_FUNCTION));
1663     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(0));
1664     JSHandle<JSTaggedValue> emptyString = globalConst->GetHandledEmptyString();
1665     JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
1666     PropertyDescriptor nameDesc(thread_, emptyString, false, false, true);
1667     JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>::Cast(function), nameKey, nameDesc);
1668     return revocFunction;
1669 }
1670 
NewJSAsyncAwaitStatusFunction(MethodIndex idx)1671 JSHandle<JSAsyncAwaitStatusFunction> ObjectFactory::NewJSAsyncAwaitStatusFunction(MethodIndex idx)
1672 {
1673     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1674     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetAsyncAwaitStatusFunctionClass());
1675 
1676     JSHandle<JSAsyncAwaitStatusFunction> awaitFunction =
1677         JSHandle<JSAsyncAwaitStatusFunction>::Cast(NewJSObject(hclass));
1678     awaitFunction->SetAsyncContext(thread_, JSTaggedValue::Undefined());
1679     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(awaitFunction));
1680     awaitFunction->SetMethod(thread_, vm_->GetMethodByIndex(idx));
1681     return awaitFunction;
1682 }
1683 
NewJSGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)1684 JSHandle<JSGeneratorObject> ObjectFactory::NewJSGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)
1685 {
1686     JSHandle<JSTaggedValue> proto(thread_, JSHandle<JSFunction>::Cast(generatorFunction)->GetProtoOrHClass());
1687     if (!proto->IsECMAObject()) {
1688         JSHandle<GlobalEnv> realmHandle = JSObject::GetFunctionRealm(thread_, generatorFunction);
1689         proto = realmHandle->GetGeneratorPrototype();
1690     }
1691     JSHandle<JSHClass> hclass = NewEcmaHClass(JSGeneratorObject::SIZE, JSType::JS_GENERATOR_OBJECT, proto);
1692     JSHandle<JSGeneratorObject> generatorObject = JSHandle<JSGeneratorObject>::Cast(NewJSObject(hclass));
1693     generatorObject->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
1694     generatorObject->SetResumeResult(thread_, JSTaggedValue::Undefined());
1695     return generatorObject;
1696 }
1697 
NewJSAsyncGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)1698 JSHandle<JSAsyncGeneratorObject> ObjectFactory::NewJSAsyncGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)
1699 {
1700     JSHandle<JSTaggedValue> proto(thread_, JSHandle<JSFunction>::Cast(generatorFunction)->GetProtoOrHClass());
1701     if (!proto->IsECMAObject()) {
1702         JSHandle<GlobalEnv> realmHandle = JSObject::GetFunctionRealm(thread_, generatorFunction);
1703         proto = realmHandle->GetAsyncGeneratorPrototype();
1704     }
1705     JSHandle<JSHClass> hclass = NewEcmaHClass(JSAsyncGeneratorObject::SIZE,
1706                                                   JSType::JS_ASYNC_GENERATOR_OBJECT, proto);
1707     JSHandle<JSAsyncGeneratorObject> generatorObject =
1708         JSHandle<JSAsyncGeneratorObject>::Cast(NewJSObjectWithInit(hclass));
1709     return generatorObject;
1710 }
1711 
NewJSAsyncFuncObject()1712 JSHandle<JSAsyncFuncObject> ObjectFactory::NewJSAsyncFuncObject()
1713 {
1714     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1715     JSHandle<JSTaggedValue> proto = env->GetInitialGenerator();
1716     JSHandle<JSHClass> hclass = NewEcmaHClass(JSAsyncFuncObject::SIZE, JSType::JS_ASYNC_FUNC_OBJECT, proto);
1717     JSHandle<JSAsyncFuncObject> asyncFuncObject = JSHandle<JSAsyncFuncObject>::Cast(NewJSObjectWithInit(hclass));
1718     return asyncFuncObject;
1719 }
1720 
NewCompletionRecord(CompletionRecordType type,JSHandle<JSTaggedValue> value)1721 JSHandle<CompletionRecord> ObjectFactory::NewCompletionRecord(CompletionRecordType type, JSHandle<JSTaggedValue> value)
1722 {
1723     NewObjectHook();
1724     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1725         JSHClass::Cast(thread_->GlobalConstants()->GetCompletionRecordClass().GetTaggedObject()));
1726     JSHandle<CompletionRecord> obj(thread_, header);
1727     obj->SetType(type);
1728     obj->SetValue(thread_, value);
1729     return obj;
1730 }
1731 
NewGeneratorContext()1732 JSHandle<GeneratorContext> ObjectFactory::NewGeneratorContext()
1733 {
1734     NewObjectHook();
1735     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1736         JSHClass::Cast(thread_->GlobalConstants()->GetGeneratorContextClass().GetTaggedObject()));
1737     JSHandle<GeneratorContext> obj(thread_, header);
1738     obj->SetRegsArray(thread_, JSTaggedValue::Undefined());
1739     obj->SetMethod(thread_, JSTaggedValue::Undefined());
1740     obj->SetThis(thread_, JSTaggedValue::Undefined());
1741     obj->SetAcc(thread_, JSTaggedValue::Undefined());
1742     obj->SetGeneratorObject(thread_, JSTaggedValue::Undefined());
1743     obj->SetLexicalEnv(thread_, JSTaggedValue::Undefined());
1744     obj->SetNRegs(0);
1745     obj->SetBCOffset(0);
1746     return obj;
1747 }
1748 
NewJSPrimitiveRef(const JSHandle<JSFunction> & function,const JSHandle<JSTaggedValue> & object)1749 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(const JSHandle<JSFunction> &function,
1750                                                           const JSHandle<JSTaggedValue> &object)
1751 {
1752     JSHandle<JSPrimitiveRef> obj(NewJSObjectByConstructor(function));
1753     obj->SetValue(thread_, object);
1754 
1755     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1756     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1757     if (function.GetTaggedValue() == env->GetStringFunction().GetTaggedValue()) {
1758         JSHandle<JSTaggedValue> lengthStr = globalConst->GetHandledLengthString();
1759         uint32_t length = EcmaStringAccessor(object.GetTaggedValue()).GetLength();
1760         PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>(thread_, JSTaggedValue(length)), false, false, false);
1761         JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>(obj), lengthStr, desc);
1762     }
1763 
1764     return obj;
1765 }
1766 
NewJSPrimitiveRef(PrimitiveType type,const JSHandle<JSTaggedValue> & object)1767 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(PrimitiveType type, const JSHandle<JSTaggedValue> &object)
1768 {
1769     ObjectFactory *factory = vm_->GetFactory();
1770     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1771     JSHandle<JSTaggedValue> function;
1772     switch (type) {
1773         case PrimitiveType::PRIMITIVE_NUMBER:
1774             function = env->GetNumberFunction();
1775             break;
1776         case PrimitiveType::PRIMITIVE_STRING:
1777             function = env->GetStringFunction();
1778             break;
1779         case PrimitiveType::PRIMITIVE_SYMBOL:
1780             function = env->GetSymbolFunction();
1781             break;
1782         case PrimitiveType::PRIMITIVE_BOOLEAN:
1783             function = env->GetBooleanFunction();
1784             break;
1785         case PrimitiveType::PRIMITIVE_BIGINT:
1786             function = env->GetBigIntFunction();
1787             break;
1788         default:
1789             break;
1790     }
1791     JSHandle<JSFunction> funcHandle(function);
1792     return factory->NewJSPrimitiveRef(funcHandle, object);
1793 }
1794 
NewJSString(const JSHandle<JSTaggedValue> & str)1795 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSString(const JSHandle<JSTaggedValue> &str)
1796 {
1797     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1798     JSHandle<JSFunction> stringFunc(env->GetStringFunction());
1799     JSHandle<JSPrimitiveRef> obj = JSHandle<JSPrimitiveRef>::Cast(NewJSObjectByConstructor(stringFunc));
1800     obj->SetValue(thread_, str);
1801     return obj;
1802 }
1803 
NewGlobalEnv(JSHClass * globalEnvClass)1804 JSHandle<GlobalEnv> ObjectFactory::NewGlobalEnv(JSHClass *globalEnvClass)
1805 {
1806     NewObjectHook();
1807     // Note: Global env must be allocated in non-movable heap, since its getters will directly return
1808     //       the offsets of the properties as the address of Handles.
1809     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(globalEnvClass);
1810     InitObjectFields(header);
1811     return JSHandle<GlobalEnv>(thread_, GlobalEnv::Cast(header));
1812 }
1813 
NewLexicalEnv(int numSlots)1814 JSHandle<LexicalEnv> ObjectFactory::NewLexicalEnv(int numSlots)
1815 {
1816     NewObjectHook();
1817     size_t size = LexicalEnv::ComputeSize(numSlots);
1818     auto header = heap_->AllocateYoungOrHugeObject(
1819         JSHClass::Cast(thread_->GlobalConstants()->GetEnvClass().GetTaggedObject()), size);
1820     JSHandle<LexicalEnv> array(thread_, header);
1821     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), numSlots + LexicalEnv::RESERVED_ENV_LENGTH);
1822     return array;
1823 }
1824 
NewJSSymbol()1825 JSHandle<JSSymbol> ObjectFactory::NewJSSymbol()
1826 {
1827     NewObjectHook();
1828     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1829         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
1830     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
1831     obj->SetDescription(thread_, JSTaggedValue::Undefined());
1832     obj->SetFlags(0);
1833     obj->SetHashField(SymbolTable::Hash(obj.GetTaggedValue()));
1834     return obj;
1835 }
1836 
NewPrivateSymbol()1837 JSHandle<JSSymbol> ObjectFactory::NewPrivateSymbol()
1838 {
1839     JSHandle<JSSymbol> obj = NewJSSymbol();
1840     obj->SetPrivate();
1841     return obj;
1842 }
1843 
NewPrivateNameSymbol(const JSHandle<JSTaggedValue> & name)1844 JSHandle<JSSymbol> ObjectFactory::NewPrivateNameSymbol(const JSHandle<JSTaggedValue> &name)
1845 {
1846     NewObjectHook();
1847     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1848         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
1849     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
1850     obj->SetFlags(0);
1851     obj->SetPrivateNameSymbol();
1852     obj->SetDescription(thread_, name);
1853     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
1854     return obj;
1855 }
1856 
NewWellKnownSymbol(const JSHandle<JSTaggedValue> & name)1857 JSHandle<JSSymbol> ObjectFactory::NewWellKnownSymbol(const JSHandle<JSTaggedValue> &name)
1858 {
1859     NewObjectHook();
1860     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1861         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
1862     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
1863     obj->SetFlags(0);
1864     obj->SetWellKnownSymbol();
1865     obj->SetDescription(thread_, name);
1866     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
1867     return obj;
1868 }
1869 
NewPublicSymbol(const JSHandle<JSTaggedValue> & name)1870 JSHandle<JSSymbol> ObjectFactory::NewPublicSymbol(const JSHandle<JSTaggedValue> &name)
1871 {
1872     NewObjectHook();
1873     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1874         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
1875     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
1876     obj->SetFlags(0);
1877     obj->SetDescription(thread_, name);
1878     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
1879     return obj;
1880 }
1881 
NewSymbolWithTable(const JSHandle<JSTaggedValue> & name)1882 JSHandle<JSSymbol> ObjectFactory::NewSymbolWithTable(const JSHandle<JSTaggedValue> &name)
1883 {
1884     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1885     JSHandle<SymbolTable> tableHandle(env->GetRegisterSymbols());
1886     if (tableHandle->ContainsKey(name.GetTaggedValue())) {
1887         JSTaggedValue objValue = tableHandle->GetSymbol(name.GetTaggedValue());
1888         return JSHandle<JSSymbol>(thread_, objValue);
1889     }
1890 
1891     JSHandle<JSSymbol> obj = NewPublicSymbol(name);
1892     JSHandle<JSTaggedValue> valueHandle(obj);
1893     JSHandle<JSTaggedValue> keyHandle(name);
1894     JSHandle<SymbolTable> table = SymbolTable::Insert(thread_, tableHandle, keyHandle, valueHandle);
1895     env->SetRegisterSymbols(thread_, table);
1896     return obj;
1897 }
1898 
NewPrivateNameSymbolWithChar(const char * description)1899 JSHandle<JSSymbol> ObjectFactory::NewPrivateNameSymbolWithChar(const char *description)
1900 {
1901     JSHandle<EcmaString> string = NewFromUtf8(description);
1902     return NewPrivateNameSymbol(JSHandle<JSTaggedValue>(string));
1903 }
1904 
NewWellKnownSymbolWithChar(const char * description)1905 JSHandle<JSSymbol> ObjectFactory::NewWellKnownSymbolWithChar(const char *description)
1906 {
1907     JSHandle<EcmaString> string = NewFromUtf8(description);
1908     return NewWellKnownSymbol(JSHandle<JSTaggedValue>(string));
1909 }
1910 
NewPublicSymbolWithChar(const char * description)1911 JSHandle<JSSymbol> ObjectFactory::NewPublicSymbolWithChar(const char *description)
1912 {
1913     JSHandle<EcmaString> string = NewFromUtf8(description);
1914     return NewPublicSymbol(JSHandle<JSTaggedValue>(string));
1915 }
1916 
NewSymbolWithTableWithChar(const char * description)1917 JSHandle<JSSymbol> ObjectFactory::NewSymbolWithTableWithChar(const char *description)
1918 {
1919     JSHandle<EcmaString> string = NewFromUtf8(description);
1920     return NewSymbolWithTable(JSHandle<JSTaggedValue>(string));
1921 }
1922 
NewAccessorData()1923 JSHandle<AccessorData> ObjectFactory::NewAccessorData()
1924 {
1925     NewObjectHook();
1926     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1927         JSHClass::Cast(thread_->GlobalConstants()->GetAccessorDataClass().GetTaggedObject()));
1928     JSHandle<AccessorData> acc(thread_, AccessorData::Cast(header));
1929     acc->SetGetter(thread_, JSTaggedValue::Undefined());
1930     acc->SetSetter(thread_, JSTaggedValue::Undefined());
1931     return acc;
1932 }
1933 
NewInternalAccessor(void * setter,void * getter)1934 JSHandle<AccessorData> ObjectFactory::NewInternalAccessor(void *setter, void *getter)
1935 {
1936     NewObjectHook();
1937     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(
1938         JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject()));
1939     JSHandle<AccessorData> obj(thread_, AccessorData::Cast(header));
1940     obj->SetGetter(thread_, JSTaggedValue::Undefined());
1941     obj->SetSetter(thread_, JSTaggedValue::Undefined());
1942     if (setter != nullptr) {
1943         JSHandle<JSNativePointer> setFunc = NewJSNativePointer(setter, nullptr, nullptr, true);
1944         obj->SetSetter(thread_, setFunc.GetTaggedValue());
1945     } else {
1946         JSTaggedValue setFunc = JSTaggedValue::Undefined();
1947         obj->SetSetter(thread_, setFunc);
1948         ASSERT(!obj->HasSetter());
1949     }
1950     JSHandle<JSNativePointer> getFunc = NewJSNativePointer(getter, nullptr, nullptr, true);
1951     obj->SetGetter(thread_, getFunc);
1952     return obj;
1953 }
1954 
NewPromiseCapability()1955 JSHandle<PromiseCapability> ObjectFactory::NewPromiseCapability()
1956 {
1957     NewObjectHook();
1958     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1959         JSHClass::Cast(thread_->GlobalConstants()->GetCapabilityRecordClass().GetTaggedObject()));
1960     JSHandle<PromiseCapability> obj(thread_, header);
1961     obj->SetPromise(thread_, JSTaggedValue::Undefined());
1962     obj->SetResolve(thread_, JSTaggedValue::Undefined());
1963     obj->SetReject(thread_, JSTaggedValue::Undefined());
1964     return obj;
1965 }
1966 
NewPromiseReaction()1967 JSHandle<PromiseReaction> ObjectFactory::NewPromiseReaction()
1968 {
1969     NewObjectHook();
1970     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1971         JSHClass::Cast(thread_->GlobalConstants()->GetReactionsRecordClass().GetTaggedObject()));
1972     JSHandle<PromiseReaction> obj(thread_, header);
1973     obj->SetPromiseCapability(thread_, JSTaggedValue::Undefined());
1974     obj->SetHandler(thread_, JSTaggedValue::Undefined());
1975     obj->SetType(PromiseType::RESOLVE);
1976     return obj;
1977 }
1978 
NewPromiseIteratorRecord(const JSHandle<JSTaggedValue> & itor,bool done)1979 JSHandle<PromiseIteratorRecord> ObjectFactory::NewPromiseIteratorRecord(const JSHandle<JSTaggedValue> &itor, bool done)
1980 {
1981     NewObjectHook();
1982     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1983         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseIteratorRecordClass().GetTaggedObject()));
1984     JSHandle<PromiseIteratorRecord> obj(thread_, header);
1985     obj->SetIterator(thread_, itor.GetTaggedValue());
1986     obj->SetDone(done);
1987     return obj;
1988 }
1989 
NewMicroJobQueue()1990 JSHandle<job::MicroJobQueue> ObjectFactory::NewMicroJobQueue()
1991 {
1992     NewObjectHook();
1993     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(
1994         JSHClass::Cast(thread_->GlobalConstants()->GetMicroJobQueueClass().GetTaggedObject()));
1995     JSHandle<job::MicroJobQueue> obj(thread_, header);
1996     obj->SetPromiseJobQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1997     obj->SetScriptJobQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1998     return obj;
1999 }
2000 
NewPendingJob(const JSHandle<JSFunction> & func,const JSHandle<TaggedArray> & argv)2001 JSHandle<job::PendingJob> ObjectFactory::NewPendingJob(const JSHandle<JSFunction> &func,
2002                                                        const JSHandle<TaggedArray> &argv)
2003 {
2004     NewObjectHook();
2005     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2006         JSHClass::Cast(thread_->GlobalConstants()->GetPendingJobClass().GetTaggedObject()));
2007     JSHandle<job::PendingJob> obj(thread_, header);
2008     obj->SetJob(thread_, func.GetTaggedValue());
2009     obj->SetArguments(thread_, argv.GetTaggedValue());
2010 #if defined(ENABLE_HITRACE)
2011     obj->SetChainId(0);
2012     obj->SetSpanId(0);
2013     obj->SetParentSpanId(0);
2014     obj->SetFlags(0);
2015 #endif
2016     return obj;
2017 }
2018 
NewJSProxy(const JSHandle<JSTaggedValue> & target,const JSHandle<JSTaggedValue> & handler)2019 JSHandle<JSProxy> ObjectFactory::NewJSProxy(const JSHandle<JSTaggedValue> &target,
2020                                             const JSHandle<JSTaggedValue> &handler)
2021 {
2022     NewObjectHook();
2023     TaggedObject *header = nullptr;
2024     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2025 
2026     if (target->IsCallable()) {
2027         auto jsProxyCallableClass = JSHClass::Cast(globalConst->GetJSProxyCallableClass().GetTaggedObject());
2028         auto jsProxyConstructClass = JSHClass::Cast(globalConst->GetJSProxyConstructClass().GetTaggedObject());
2029         header = target->IsConstructor() ? heap_->AllocateYoungOrHugeObject(jsProxyConstructClass)
2030                                          : heap_->AllocateYoungOrHugeObject(jsProxyCallableClass);
2031     } else {
2032         header = heap_->AllocateYoungOrHugeObject(
2033             JSHClass::Cast(thread_->GlobalConstants()->GetJSProxyOrdinaryClass().GetTaggedObject()));
2034     }
2035 
2036     JSHandle<JSProxy> proxy(thread_, header);
2037     proxy->InitializeHash();
2038     proxy->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_GLOBAL_CALL_JS_PROXY));
2039     proxy->SetTarget(thread_, target.GetTaggedValue());
2040     proxy->SetHandler(thread_, handler.GetTaggedValue());
2041     return proxy;
2042 }
2043 
NewJSRealm()2044 JSHandle<JSRealm> ObjectFactory::NewJSRealm()
2045 {
2046     JSHandle<JSHClass> hClassHandle = NewEcmaHClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS);
2047     JSHClass *hclass = reinterpret_cast<JSHClass *>(hClassHandle.GetTaggedValue().GetTaggedObject());
2048     hclass->SetClass(hclass);
2049     JSHandle<JSHClass> realmEnvClass = NewEcmaHClass(*hClassHandle, GlobalEnv::SIZE, JSType::GLOBAL_ENV);
2050     JSHandle<GlobalEnv> realmEnvHandle = NewGlobalEnv(*realmEnvClass);
2051 
2052     auto result = TemplateMap::Create(thread_);
2053     realmEnvHandle->SetTemplateMap(thread_, result);
2054 
2055     Builtins builtins;
2056     builtins.Initialize(realmEnvHandle, thread_);
2057     JSHandle<JSTaggedValue> protoValue = thread_->GlobalConstants()->GetHandledJSRealmClass();
2058     JSHandle<JSHClass> hclassHandle = NewEcmaHClass(JSRealm::SIZE, JSType::JS_REALM, protoValue);
2059     JSHandle<JSRealm> realm(NewJSObject(hclassHandle));
2060     realm->SetGlobalEnv(thread_, realmEnvHandle.GetTaggedValue());
2061     realm->SetValue(thread_, JSTaggedValue::Undefined());
2062 
2063     JSHandle<JSTaggedValue> realmObj = realmEnvHandle->GetJSGlobalObject();
2064     JSHandle<JSTaggedValue> realmkey(thread_->GlobalConstants()->GetHandledGlobalString());
2065     PropertyDescriptor realmDesc(thread_, JSHandle<JSTaggedValue>::Cast(realmObj), true, false, true);
2066     [[maybe_unused]] bool status =
2067         JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(realm), realmkey, realmDesc);
2068     ASSERT_PRINT(status == true, "Realm defineOwnProperty failed");
2069 
2070     return realm;
2071 }
2072 
NewEmptyArray()2073 JSHandle<TaggedArray> ObjectFactory::NewEmptyArray()
2074 {
2075     NewObjectHook();
2076     auto header = heap_->AllocateReadOnlyOrHugeObject(
2077         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), TaggedArray::SIZE);
2078     JSHandle<TaggedArray> array(thread_, header);
2079     array->SetLength(0);
2080     array->SetExtraLength(0);
2081     return array;
2082 }
2083 
NewTaggedArray(uint32_t length,JSTaggedValue initVal,bool nonMovable)2084 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal, bool nonMovable)
2085 {
2086     if (nonMovable) {
2087         return NewTaggedArray(length, initVal, MemSpaceType::NON_MOVABLE);
2088     }
2089     return NewTaggedArray(length, initVal, MemSpaceType::SEMI_SPACE);
2090 }
2091 
NewTaggedArray(uint32_t length,JSTaggedValue initVal,MemSpaceType spaceType)2092 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType)
2093 {
2094     NewObjectHook();
2095     if (length == 0) {
2096         return EmptyArray();
2097     }
2098 
2099     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2100     TaggedObject *header = nullptr;
2101     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2102     switch (spaceType) {
2103         case MemSpaceType::SEMI_SPACE:
2104             header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
2105             break;
2106         case MemSpaceType::OLD_SPACE:
2107             header = heap_->AllocateOldOrHugeObject(arrayClass, size);
2108             break;
2109         case MemSpaceType::NON_MOVABLE:
2110             header = heap_->AllocateNonMovableOrHugeObject(arrayClass, size);
2111             break;
2112         default:
2113             UNREACHABLE();
2114     }
2115 
2116     JSHandle<TaggedArray> array(thread_, header);
2117     array->InitializeWithSpecialValue(initVal, length);
2118     return array;
2119 }
2120 
RemoveElementByIndex(JSHandle<TaggedArray> & srcArray,uint32_t index,uint32_t effectiveLength)2121 void ObjectFactory::RemoveElementByIndex(JSHandle<TaggedArray> &srcArray,
2122                                          uint32_t index,
2123                                          uint32_t effectiveLength)
2124 {
2125     ASSERT(0 <= index || index < effectiveLength);
2126     Region *region = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*srcArray));
2127     if (region->InYoungSpace() && !region->IsMarking()) {
2128         size_t taggedTypeSize = JSTaggedValue::TaggedTypeSize();
2129         size_t offset = taggedTypeSize * index;
2130         auto *addr = reinterpret_cast<JSTaggedType *>(ToUintPtr(srcArray->GetData()) + offset);
2131         while (index < effectiveLength - 1) {
2132             *addr = *(addr + 1);
2133             addr++;
2134             index++;
2135         }
2136     } else {
2137         while (index < effectiveLength - 1) {
2138             srcArray->Set(thread_, index, srcArray->Get(index + 1));
2139             index++;
2140         }
2141     }
2142     srcArray->Set(thread_, effectiveLength - 1, JSTaggedValue::Hole());
2143 }
2144 
InsertElementByIndex(JSHandle<TaggedArray> & srcArray,const JSHandle<JSTaggedValue> & value,uint32_t index,uint32_t effectiveLength)2145 JSHandle<TaggedArray> ObjectFactory::InsertElementByIndex(JSHandle<TaggedArray> &srcArray,
2146                                                           const JSHandle<JSTaggedValue> &value,
2147                                                           uint32_t index,
2148                                                           uint32_t effectiveLength)
2149 {
2150     ASSERT(0 <= index || index <= effectiveLength);
2151     Region *region = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*srcArray));
2152     if (region->InYoungSpace() && !region->IsMarking()) {
2153         size_t taggedTypeSize = JSTaggedValue::TaggedTypeSize();
2154         size_t offset = taggedTypeSize * effectiveLength;
2155         auto *addr = reinterpret_cast<JSTaggedType *>(ToUintPtr(srcArray->GetData()) + offset);
2156         while (effectiveLength != index && effectiveLength > 0) {
2157             *addr = *(addr - 1);
2158             addr--;
2159             effectiveLength--;
2160         }
2161     } else {
2162         while (effectiveLength != index && effectiveLength > 0) {
2163             JSTaggedValue oldValue = srcArray->Get(effectiveLength - 1);
2164             srcArray->Set(thread_, effectiveLength, oldValue);
2165             effectiveLength--;
2166         }
2167     }
2168     srcArray->Set(thread_, index, value.GetTaggedValue());
2169     return srcArray;
2170 }
2171 
NewAndCopyTaggedArray(JSHandle<TaggedArray> & srcElements,uint32_t newLength,uint32_t oldLength)2172 JSHandle<TaggedArray> ObjectFactory::NewAndCopyTaggedArray(JSHandle<TaggedArray> &srcElements,
2173                                                            uint32_t newLength,
2174                                                            uint32_t oldLength)
2175 {
2176     ASSERT(oldLength <= newLength);
2177     MemSpaceType spaceType = newLength < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
2178     JSHandle<TaggedArray> dstElements = NewTaggedArrayWithoutInit(newLength, spaceType);
2179     if (newLength == 0) {
2180         return dstElements;
2181     }
2182     Region *region = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*dstElements));
2183     if (region->InYoungSpace() && !region->IsMarking()) {
2184         size_t size = oldLength * sizeof(JSTaggedType);
2185         if (memcpy_s(reinterpret_cast<void *>(dstElements->GetData()), size,
2186             reinterpret_cast<void *>(srcElements->GetData()), size) != EOK) {
2187             LOG_FULL(FATAL) << "memcpy_s failed";
2188         }
2189     } else {
2190         for (uint32_t i = 0; i < oldLength; i++) {
2191             dstElements->Set(thread_, i, srcElements->Get(i));
2192         }
2193     }
2194     for (uint32_t i = oldLength; i < newLength; i++) {
2195         dstElements->Set(thread_, i, JSTaggedValue::Hole());
2196     }
2197     return dstElements;
2198 }
2199 
CopyTaggedArrayElement(JSHandle<TaggedArray> & srcElements,JSHandle<TaggedArray> & dstElements,uint32_t effectiveLength)2200 void ObjectFactory::CopyTaggedArrayElement(JSHandle<TaggedArray> &srcElements,
2201                                            JSHandle<TaggedArray> &dstElements,
2202                                            uint32_t effectiveLength)
2203 {
2204     ASSERT(effectiveLength <= srcElements->GetLength());
2205     ASSERT(effectiveLength <= dstElements->GetLength());
2206     Region *region = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*dstElements));
2207     if (region->InYoungSpace() && !region->IsMarking()) {
2208         size_t size = effectiveLength * sizeof(JSTaggedType);
2209         if (memcpy_s(reinterpret_cast<void *>(dstElements->GetData()), size,
2210             reinterpret_cast<void *>(srcElements->GetData()), size) != EOK) {
2211             LOG_FULL(FATAL) << "memcpy_s failed" << " size: " << size;
2212         }
2213     } else {
2214         for (uint32_t i = 0; i < effectiveLength; i++) {
2215             dstElements->Set(thread_, i, srcElements->Get(i));
2216         }
2217     }
2218 }
2219 
2220 // private
NewTaggedArrayWithoutInit(uint32_t length,MemSpaceType spaceType)2221 JSHandle<TaggedArray> ObjectFactory::NewTaggedArrayWithoutInit(uint32_t length, MemSpaceType spaceType)
2222 {
2223     NewObjectHook();
2224     if (length == 0) {
2225         return EmptyArray();
2226     }
2227 
2228     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2229     TaggedObject *header = nullptr;
2230     auto arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2231     switch (spaceType) {
2232         case MemSpaceType::SEMI_SPACE:
2233             header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
2234             break;
2235         case MemSpaceType::OLD_SPACE:
2236             header = heap_->AllocateOldOrHugeObject(arrayClass, size);
2237             break;
2238         default:
2239             UNREACHABLE();
2240     }
2241     JSHandle<TaggedArray> array(thread_, header);
2242     array->SetLength(length);
2243     return array;
2244 }
2245 
NewTaggedArray(uint32_t length,JSTaggedValue initVal)2246 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal)
2247 {
2248     NewObjectHook();
2249     if (length == 0) {
2250         return EmptyArray();
2251     }
2252     MemSpaceType spaceType = length < LENGTH_THRESHOLD ? MemSpaceType::SEMI_SPACE : MemSpaceType::OLD_SPACE;
2253     JSHandle<TaggedArray> array = NewTaggedArrayWithoutInit(length, spaceType);
2254     array->InitializeWithSpecialValue(initVal, length);
2255     return array;
2256 }
2257 
NewCOWTaggedArray(uint32_t length,JSTaggedValue initVal)2258 JSHandle<COWTaggedArray> ObjectFactory::NewCOWTaggedArray(uint32_t length, JSTaggedValue initVal)
2259 {
2260     NewObjectHook();
2261     ASSERT(length > 0);
2262 
2263     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2264     auto header = heap_->AllocateNonMovableOrHugeObject(
2265         JSHClass::Cast(thread_->GlobalConstants()->GetCOWArrayClass().GetTaggedObject()), size);
2266     JSHandle<COWTaggedArray> cowArray(thread_, header);
2267     cowArray->InitializeWithSpecialValue(initVal, length);
2268     return cowArray;
2269 }
2270 
NewTaggedHashArray(uint32_t length)2271 JSHandle<TaggedHashArray> ObjectFactory::NewTaggedHashArray(uint32_t length)
2272 {
2273     if (length == 0) {
2274         return JSHandle<TaggedHashArray>::Cast(EmptyArray());
2275     }
2276 
2277     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2278     auto header = heap_->AllocateYoungOrHugeObject(
2279         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
2280     JSHandle<TaggedHashArray> array(thread_, header);
2281     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), length);
2282     return array;
2283 }
2284 
NewByteArray(uint32_t length,uint32_t size)2285 JSHandle<ByteArray> ObjectFactory::NewByteArray(uint32_t length, uint32_t size)
2286 {
2287     size_t byteSize = ByteArray::ComputeSize(size, length);
2288     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetByteArrayClass().GetTaggedObject());
2289     TaggedObject *header = heap_->AllocateYoungOrHugeObject(arrayClass, byteSize);
2290     JSHandle<ByteArray> array(thread_, header);
2291 
2292     void *data = array->GetData();
2293     if (memset_s(data, length * size, 0, length * size) != EOK) {
2294         LOG_FULL(FATAL) << "memset_s failed";
2295         UNREACHABLE();
2296     }
2297 
2298     array->SetLength(length);
2299     array->SetSize(size);
2300     return array;
2301 }
2302 
NewLinkedNode(int hash,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value,const JSHandle<LinkedNode> & next)2303 JSHandle<LinkedNode> ObjectFactory::NewLinkedNode(int hash, const JSHandle<JSTaggedValue> &key,
2304                                                   const JSHandle<JSTaggedValue> &value,
2305                                                   const JSHandle<LinkedNode> &next)
2306 {
2307     NewObjectHook();
2308     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2309     auto header = heap_->AllocateYoungOrHugeObject(
2310         JSHClass::Cast(globalConst->GetLinkedNode().GetTaggedObject()), LinkedNode::SIZE);
2311     JSHandle<LinkedNode> node(thread_, header);
2312     node->InitLinkedNode(thread_, hash, key, value, next);
2313 
2314     return node;
2315 }
2316 
NewTreeNode(int hash,const JSHandle<JSTaggedValue> & key,const JSHandle<JSTaggedValue> & value)2317 JSHandle<RBTreeNode> ObjectFactory::NewTreeNode(int hash, const JSHandle<JSTaggedValue> &key,
2318                                                 const JSHandle<JSTaggedValue> &value)
2319 {
2320     NewObjectHook();
2321     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2322     auto header = heap_->AllocateYoungOrHugeObject(
2323         JSHClass::Cast(globalConst->GetRBTreeNode().GetTaggedObject()), RBTreeNode::SIZE);
2324     JSHandle<RBTreeNode> treenode(thread_, header);
2325     treenode->InitRBTreeNode(thread_, hash, key, value, 1);
2326     return treenode;
2327 }
2328 
NewDictionaryArray(uint32_t length)2329 JSHandle<TaggedArray> ObjectFactory::NewDictionaryArray(uint32_t length)
2330 {
2331     NewObjectHook();
2332     ASSERT(length > 0);
2333 
2334     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2335     auto header = heap_->AllocateYoungOrHugeObject(
2336         JSHClass::Cast(thread_->GlobalConstants()->GetDictionaryClass().GetTaggedObject()), size);
2337     JSHandle<TaggedArray> array(thread_, header);
2338     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
2339 
2340     return array;
2341 }
2342 
ExtendArray(const JSHandle<TaggedArray> & old,uint32_t length,JSTaggedValue initVal,MemSpaceType type)2343 JSHandle<TaggedArray> ObjectFactory::ExtendArray(const JSHandle<TaggedArray> &old, uint32_t length,
2344                                                  JSTaggedValue initVal, MemSpaceType type)
2345 {
2346     ASSERT(length > old->GetLength());
2347     NewObjectHook();
2348     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2349     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2350     TaggedObject *header = AllocObjectWithSpaceType(size, arrayClass, type);
2351     JSHandle<TaggedArray> newArray(thread_, header);
2352     newArray->SetLength(length);
2353     newArray->SetExtraLength(old->GetExtraLength());
2354 
2355     uint32_t oldLength = old->GetLength();
2356     for (uint32_t i = 0; i < oldLength; i++) {
2357         JSTaggedValue value = old->Get(i);
2358         newArray->Set(thread_, i, value);
2359     }
2360 
2361     for (uint32_t i = oldLength; i < length; i++) {
2362         newArray->Set(thread_, i, initVal);
2363     }
2364 
2365     return newArray;
2366 }
2367 
CopyPartArray(const JSHandle<TaggedArray> & old,uint32_t start,uint32_t end)2368 JSHandle<TaggedArray> ObjectFactory::CopyPartArray(const JSHandle<TaggedArray> &old, uint32_t start,
2369                                                    uint32_t end)
2370 {
2371     ASSERT(start <= end);
2372     ASSERT(end <= old->GetLength());
2373 
2374     uint32_t newLength = end - start;
2375     if (newLength == 0) {
2376         return EmptyArray();
2377     }
2378 
2379     NewObjectHook();
2380     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
2381     auto header = heap_->AllocateYoungOrHugeObject(
2382         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
2383     JSHandle<TaggedArray> newArray(thread_, header);
2384     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
2385 
2386     for (uint32_t i = 0; i < newLength; i++) {
2387         JSTaggedValue value = old->Get(i + start);
2388         if (value.IsHole()) {
2389             break;
2390         }
2391         newArray->Set(thread_, i, value);
2392     }
2393     return newArray;
2394 }
2395 
CopyArray(const JSHandle<TaggedArray> & old,uint32_t oldLength,uint32_t newLength,JSTaggedValue initVal,MemSpaceType type)2396 JSHandle<TaggedArray> ObjectFactory::CopyArray(const JSHandle<TaggedArray> &old, uint32_t oldLength, uint32_t newLength,
2397                                                JSTaggedValue initVal, MemSpaceType type)
2398 {
2399     if (newLength == 0) {
2400         return EmptyArray();
2401     }
2402     if (newLength > oldLength) {
2403         return ExtendArray(old, newLength, initVal, type);
2404     }
2405     NewObjectHook();
2406     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
2407     TaggedObject *header = nullptr;
2408     if (type == MemSpaceType::NON_MOVABLE) {
2409         // COW array is shared in nonmovable space.
2410         JSHClass *cowArrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetCOWArrayClass().GetTaggedObject());
2411         header = AllocObjectWithSpaceType(size, cowArrayClass, type);
2412     } else {
2413         JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2414         header = AllocObjectWithSpaceType(size, arrayClass, type);
2415     }
2416 
2417     JSHandle<TaggedArray> newArray(thread_, header);
2418     newArray->SetLength(newLength);
2419     newArray->SetExtraLength(old->GetExtraLength());
2420 
2421     for (uint32_t i = 0; i < newLength; i++) {
2422         JSTaggedValue value = old->Get(i);
2423         newArray->Set(thread_, i, value);
2424     }
2425 
2426     return newArray;
2427 }
2428 
CreateLayoutInfo(int properties,MemSpaceType type,GrowMode mode,JSTaggedValue initVal)2429 JSHandle<LayoutInfo> ObjectFactory::CreateLayoutInfo(int properties, MemSpaceType type,
2430     GrowMode mode, JSTaggedValue initVal)
2431 {
2432     int growLength =
2433         mode == GrowMode::GROW ? static_cast<int>(LayoutInfo::ComputeGrowCapacity(properties)) : properties;
2434     uint32_t arrayLength = LayoutInfo::ComputeArrayLength(growLength);
2435     JSHandle<LayoutInfo> layoutInfoHandle = JSHandle<LayoutInfo>::Cast(NewTaggedArray(arrayLength, initVal, type));
2436     layoutInfoHandle->SetNumberOfElements(thread_, 0);
2437     return layoutInfoHandle;
2438 }
2439 
ExtendLayoutInfo(const JSHandle<LayoutInfo> & old,int properties,JSTaggedValue initVal)2440 JSHandle<LayoutInfo> ObjectFactory::ExtendLayoutInfo(const JSHandle<LayoutInfo> &old, int properties,
2441                                                      JSTaggedValue initVal)
2442 {
2443     ASSERT(properties >= old->NumberOfElements());
2444     uint32_t arrayLength = LayoutInfo::ComputeArrayLength(LayoutInfo::ComputeGrowCapacity(properties));
2445     return JSHandle<LayoutInfo>(ExtendArray(JSHandle<TaggedArray>(old), arrayLength, initVal));
2446 }
2447 
CopyLayoutInfo(const JSHandle<LayoutInfo> & old)2448 JSHandle<LayoutInfo> ObjectFactory::CopyLayoutInfo(const JSHandle<LayoutInfo> &old)
2449 {
2450     uint32_t newLength = old->GetLength();
2451     return JSHandle<LayoutInfo>(CopyArray(JSHandle<TaggedArray>::Cast(old), newLength, newLength));
2452 }
2453 
CopyAndReSort(const JSHandle<LayoutInfo> & old,int end,int capacity)2454 JSHandle<LayoutInfo> ObjectFactory::CopyAndReSort(const JSHandle<LayoutInfo> &old, int end, int capacity)
2455 {
2456     ASSERT(capacity >= end);
2457     JSHandle<LayoutInfo> newArr = CreateLayoutInfo(capacity);
2458     Span<struct Properties> sp(old->GetProperties(), end);
2459     int i = 0;
2460     for (; i < end; i++) {
2461         newArr->AddKey(thread_, i, sp[i].key_, PropertyAttributes(sp[i].attr_));
2462     }
2463 
2464     return newArr;
2465 }
2466 
NewConstantPool(uint32_t capacity)2467 JSHandle<ConstantPool> ObjectFactory::NewConstantPool(uint32_t capacity)
2468 {
2469     NewObjectHook();
2470     size_t size = ConstantPool::ComputeSize(capacity);
2471     auto header = heap_->AllocateOldOrHugeObject(
2472         JSHClass::Cast(thread_->GlobalConstants()->GetConstantPoolClass().GetTaggedObject()), size);
2473     JSHandle<ConstantPool> array(thread_, header);
2474     array->InitializeWithSpecialValue(JSTaggedValue::Hole(), capacity);
2475     return array;
2476 }
2477 
NewProgram()2478 JSHandle<Program> ObjectFactory::NewProgram()
2479 {
2480     NewObjectHook();
2481     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2482         JSHClass::Cast(thread_->GlobalConstants()->GetProgramClass().GetTaggedObject()));
2483     JSHandle<Program> p(thread_, header);
2484     p->InitializeHash();
2485     p->SetMainFunction(thread_, JSTaggedValue::Undefined());
2486     return p;
2487 }
2488 
NewModuleNamespace()2489 JSHandle<ModuleNamespace> ObjectFactory::NewModuleNamespace()
2490 {
2491     NewObjectHook();
2492     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2493     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetModuleNamespaceClass());
2494     JSHandle<JSObject> obj = NewJSObject(hclass);
2495 
2496     JSHandle<ModuleNamespace> moduleNamespace = JSHandle<ModuleNamespace>::Cast(obj);
2497     moduleNamespace->SetModule(thread_, JSTaggedValue::Undefined());
2498     moduleNamespace->SetExports(thread_, JSTaggedValue::Undefined());
2499     return moduleNamespace;
2500 }
2501 
NewCjsModule()2502 JSHandle<CjsModule> ObjectFactory::NewCjsModule()
2503 {
2504     NewObjectHook();
2505     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2506     JSHandle<JSFunction> moduleObj(env->GetCjsModuleFunction());
2507     JSHandle<CjsModule> cjsModule = JSHandle<CjsModule>(NewJSObjectByConstructor(moduleObj));
2508     return cjsModule;
2509 }
2510 
NewCjsExports()2511 JSHandle<CjsExports> ObjectFactory::NewCjsExports()
2512 {
2513     NewObjectHook();
2514     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2515     JSHandle<JSFunction> exportsObj(env->GetCjsExportsFunction());
2516     JSHandle<CjsExports> cjsExports = JSHandle<CjsExports>(NewJSObjectByConstructor(exportsObj));
2517     return cjsExports;
2518 }
2519 
NewCjsRequire()2520 JSHandle<CjsRequire> ObjectFactory::NewCjsRequire()
2521 {
2522     NewObjectHook();
2523     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2524     JSHandle<JSFunction> requireObj(env->GetCjsRequireFunction());
2525     JSHandle<CjsRequire> cjsRequire = JSHandle<CjsRequire>(NewJSObjectByConstructor(requireObj));
2526     return cjsRequire;
2527 }
2528 
GetEmptyString() const2529 JSHandle<EcmaString> ObjectFactory::GetEmptyString() const
2530 {
2531     return JSHandle<EcmaString>(thread_->GlobalConstants()->GetHandledEmptyString());
2532 }
2533 
EmptyArray() const2534 JSHandle<TaggedArray> ObjectFactory::EmptyArray() const
2535 {
2536     return JSHandle<TaggedArray>(thread_->GlobalConstants()->GetHandledEmptyArray());
2537 }
2538 
GetStringFromStringTable(const uint8_t * utf8Data,uint32_t utf8Len,bool canBeCompress) const2539 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const uint8_t *utf8Data, uint32_t utf8Len,
2540                                                              bool canBeCompress) const
2541 {
2542     NewObjectHook();
2543     if (utf8Len == 0) {
2544         return GetEmptyString();
2545     }
2546     auto stringTable = vm_->GetEcmaStringTable();
2547     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(utf8Data, utf8Len, canBeCompress));
2548 }
2549 
GetStringFromStringTableNonMovable(const uint8_t * utf8Data,uint32_t utf8Len) const2550 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTableNonMovable(const uint8_t *utf8Data, uint32_t utf8Len) const
2551 {
2552     NewObjectHook();
2553     if (utf8Len == 0) {
2554         return GetEmptyString();
2555     }
2556     auto stringTable = vm_->GetEcmaStringTable();
2557     return JSHandle<EcmaString>(thread_, stringTable->CreateAndInternStringNonMovable(utf8Data, utf8Len));
2558 }
2559 
GetStringFromStringTable(const uint16_t * utf16Data,uint32_t utf16Len,bool canBeCompress) const2560 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len,
2561                                                              bool canBeCompress) const
2562 {
2563     NewObjectHook();
2564     if (utf16Len == 0) {
2565         return GetEmptyString();
2566     }
2567     auto stringTable = vm_->GetEcmaStringTable();
2568     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(utf16Data, utf16Len, canBeCompress));
2569 }
2570 
GetStringFromStringTable(EcmaString * string) const2571 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(EcmaString *string) const
2572 {
2573     ASSERT(string != nullptr);
2574     if (EcmaStringAccessor(string).GetLength() == 0) {
2575         return GetEmptyString();
2576     }
2577     auto stringTable = vm_->GetEcmaStringTable();
2578     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(string));
2579 }
2580 
2581 // NB! don't do special case for C0 80, it means '\u0000', so don't convert to UTF-8
GetRawStringFromStringTable(const uint8_t * mutf8Data,uint32_t utf16Len,bool canBeCompressed,MemSpaceType type) const2582 EcmaString *ObjectFactory::GetRawStringFromStringTable(const uint8_t *mutf8Data, uint32_t utf16Len,
2583                                                        bool canBeCompressed, MemSpaceType type) const
2584 {
2585     NewObjectHook();
2586     if (UNLIKELY(utf16Len == 0)) {
2587         return *GetEmptyString();
2588     }
2589 
2590     if (canBeCompressed) {
2591         return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceType(mutf8Data, utf16Len, true, type);
2592     }
2593 
2594     CVector<uint16_t> utf16Data(utf16Len);
2595     auto len = utf::ConvertRegionMUtf8ToUtf16(mutf8Data, utf16Data.data(), utf::Mutf8Size(mutf8Data), utf16Len, 0);
2596     return vm_->GetEcmaStringTable()->GetOrInternStringWithSpaceType(utf16Data.data(), len, false, type);
2597 }
2598 
NewPropertyBox(const JSHandle<JSTaggedValue> & value)2599 JSHandle<PropertyBox> ObjectFactory::NewPropertyBox(const JSHandle<JSTaggedValue> &value)
2600 {
2601     NewObjectHook();
2602     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2603         JSHClass::Cast(thread_->GlobalConstants()->GetPropertyBoxClass().GetTaggedObject()));
2604     JSHandle<PropertyBox> box(thread_, header);
2605     box->SetValue(thread_, value);
2606     return box;
2607 }
2608 
NewProtoChangeMarker()2609 JSHandle<ProtoChangeMarker> ObjectFactory::NewProtoChangeMarker()
2610 {
2611     NewObjectHook();
2612     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2613         JSHClass::Cast(thread_->GlobalConstants()->GetProtoChangeMarkerClass().GetTaggedObject()));
2614     JSHandle<ProtoChangeMarker> marker(thread_, header);
2615     marker->ClearBitField();
2616     return marker;
2617 }
2618 
NewProtoChangeDetails()2619 JSHandle<ProtoChangeDetails> ObjectFactory::NewProtoChangeDetails()
2620 {
2621     NewObjectHook();
2622     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2623         JSHClass::Cast(thread_->GlobalConstants()->GetProtoChangeDetailsClass().GetTaggedObject()));
2624     JSHandle<ProtoChangeDetails> protoInfo(thread_, header);
2625     protoInfo->SetChangeListener(thread_, JSTaggedValue::Undefined());
2626     protoInfo->SetRegisterIndex(ProtoChangeDetails::UNREGISTERED);
2627     return protoInfo;
2628 }
2629 
NewProfileTypeInfo(uint32_t length)2630 JSHandle<ProfileTypeInfo> ObjectFactory::NewProfileTypeInfo(uint32_t length)
2631 {
2632     NewObjectHook();
2633     ASSERT(length > 0);
2634 
2635     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2636     auto header = heap_->AllocateYoungOrHugeObject(
2637         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
2638     JSHandle<ProfileTypeInfo> array(thread_, header);
2639     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
2640 
2641     return array;
2642 }
2643 
NewBigInt(uint32_t length)2644 JSHandle<BigInt> ObjectFactory::NewBigInt(uint32_t length)
2645 {
2646     NewObjectHook();
2647     ASSERT(length > 0);
2648     size_t size = BigInt::ComputeSize(length);
2649     auto header = heap_->AllocateYoungOrHugeObject(
2650         JSHClass::Cast(thread_->GlobalConstants()->GetBigIntClass().GetTaggedObject()), size);
2651     JSHandle<BigInt> bigint(thread_, header);
2652     bigint->SetLength(length);
2653     bigint->SetSign(false);
2654     bigint->InitializationZero();
2655     return bigint;
2656 }
2657 
2658 // static
NewObjectHook() const2659 void ObjectFactory::NewObjectHook() const
2660 {
2661 #ifndef NDEBUG
2662     if (vm_->GetJSOptions().EnableForceGC() && vm_->IsInitialized()) {
2663         if (vm_->GetJSOptions().ForceFullGC()) {
2664             vm_->CollectGarbage(TriggerGCType::YOUNG_GC);
2665             vm_->CollectGarbage(TriggerGCType::OLD_GC);
2666             vm_->CollectGarbage(TriggerGCType::FULL_GC);
2667         } else {
2668             vm_->CollectGarbage(TriggerGCType::YOUNG_GC);
2669             vm_->CollectGarbage(TriggerGCType::OLD_GC);
2670         }
2671     }
2672 #endif
2673 }
2674 
NewTaggedQueue(uint32_t length)2675 JSHandle<TaggedQueue> ObjectFactory::NewTaggedQueue(uint32_t length)
2676 {
2677     uint32_t queueLength = TaggedQueue::QueueToArrayIndex(length);
2678     auto queue = JSHandle<TaggedQueue>::Cast(NewTaggedArray(queueLength, JSTaggedValue::Hole()));
2679     queue->SetStart(thread_, JSTaggedValue(0));  // equal to 0 when add 1.
2680     queue->SetEnd(thread_, JSTaggedValue(0));
2681     queue->SetCapacity(thread_, JSTaggedValue(length));
2682 
2683     return queue;
2684 }
2685 
GetEmptyTaggedQueue() const2686 JSHandle<TaggedQueue> ObjectFactory::GetEmptyTaggedQueue() const
2687 {
2688     return JSHandle<TaggedQueue>(thread_->GlobalConstants()->GetHandledEmptyTaggedQueue());
2689 }
2690 
NewJSSetIterator(const JSHandle<JSSet> & set,IterationKind kind)2691 JSHandle<JSSetIterator> ObjectFactory::NewJSSetIterator(const JSHandle<JSSet> &set, IterationKind kind)
2692 {
2693     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2694     JSHandle<JSTaggedValue> protoValue = env->GetSetIteratorPrototype();
2695     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2696     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSSetIteratorClass());
2697     hclassHandle->SetPrototype(thread_, protoValue);
2698     JSHandle<JSSetIterator> iter(NewJSObject(hclassHandle));
2699     iter->GetJSHClass()->SetExtensible(true);
2700     iter->SetIteratedSet(thread_, set->GetLinkedSet());
2701     iter->SetNextIndex(0);
2702     iter->SetIterationKind(kind);
2703     return iter;
2704 }
2705 
NewJSRegExpIterator(const JSHandle<JSTaggedValue> & matcher,const JSHandle<EcmaString> & inputStr,bool global,bool fullUnicode)2706 JSHandle<JSRegExpIterator> ObjectFactory::NewJSRegExpIterator(const JSHandle<JSTaggedValue> &matcher,
2707                                                               const JSHandle<EcmaString> &inputStr, bool global,
2708                                                               bool fullUnicode)
2709 {
2710     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2711     JSHandle<JSTaggedValue> protoValue = env->GetRegExpIteratorPrototype();
2712     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2713     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSRegExpIteratorClass());
2714     hclassHandle->SetPrototype(thread_, protoValue);
2715     JSHandle<JSRegExpIterator> iter(NewJSObject(hclassHandle));
2716     iter->GetJSHClass()->SetExtensible(true);
2717     iter->SetIteratingRegExp(thread_, matcher.GetTaggedValue());
2718     iter->SetIteratedString(thread_, inputStr.GetTaggedValue());
2719     iter->SetGlobal(global);
2720     iter->SetUnicode(fullUnicode);
2721     iter->SetDone(false);
2722     return iter;
2723 }
2724 
NewJSMapIterator(const JSHandle<JSMap> & map,IterationKind kind)2725 JSHandle<JSMapIterator> ObjectFactory::NewJSMapIterator(const JSHandle<JSMap> &map, IterationKind kind)
2726 {
2727     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2728     JSHandle<JSTaggedValue> protoValue = env->GetMapIteratorPrototype();
2729     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2730     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSMapIteratorClass());
2731     hclassHandle->SetPrototype(thread_, protoValue);
2732     JSHandle<JSMapIterator> iter(NewJSObject(hclassHandle));
2733     iter->GetJSHClass()->SetExtensible(true);
2734     iter->SetIteratedMap(thread_, map->GetLinkedMap());
2735     iter->SetNextIndex(0);
2736     iter->SetIterationKind(kind);
2737     return iter;
2738 }
2739 
NewJSAPIHashMapIterator(const JSHandle<JSAPIHashMap> & hashMap,IterationKind kind)2740 JSHandle<JSAPIHashMapIterator> ObjectFactory::NewJSAPIHashMapIterator(const JSHandle<JSAPIHashMap> &hashMap,
2741                                                                       IterationKind kind)
2742 {
2743     NewObjectHook();
2744     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2745     JSHandle<JSTaggedValue> undefinedHandle = globalConst->GetHandledUndefined();
2746     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetHashMapIteratorPrototype());
2747     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIHashMapIteratorClass());
2748     hclassHandle->SetPrototype(thread_, proto);
2749     JSHandle<JSAPIHashMapIterator> iter(NewJSObject(hclassHandle));
2750     iter->GetJSHClass()->SetExtensible(true);
2751     iter->SetCurrentNodeResult(thread_, undefinedHandle);
2752     iter->SetIteratedHashMap(thread_, hashMap);
2753     iter->SetNextIndex(0);
2754     iter->SetTaggedQueue(thread_, JSTaggedValue::Undefined());
2755     JSHandle<TaggedQueue> queue = NewTaggedQueue(0);
2756     iter->SetTaggedQueue(thread_, queue);
2757     iter->SetIterationKind(kind);
2758     return iter;
2759 }
2760 
NewJSAPIHashSetIterator(const JSHandle<JSAPIHashSet> & hashSet,IterationKind kind)2761 JSHandle<JSAPIHashSetIterator> ObjectFactory::NewJSAPIHashSetIterator(const JSHandle<JSAPIHashSet> &hashSet,
2762                                                                       IterationKind kind)
2763 {
2764     NewObjectHook();
2765     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2766     JSHandle<JSTaggedValue> undefinedHandle = globalConst->GetHandledUndefined();
2767     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetHashSetIteratorPrototype());
2768     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIHashSetIteratorClass());
2769     hclassHandle->SetPrototype(thread_, proto);
2770     JSHandle<JSAPIHashSetIterator> iter(NewJSObject(hclassHandle));
2771     iter->GetJSHClass()->SetExtensible(true);
2772     iter->SetCurrentNodeResult(thread_, undefinedHandle);
2773     iter->SetIteratedHashSet(thread_, hashSet);
2774     iter->SetNextIndex(0);
2775     iter->SetTableIndex(0);
2776     iter->SetTaggedQueue(thread_, JSTaggedValue::Undefined());
2777     JSHandle<TaggedQueue> queue = NewTaggedQueue(0);
2778     iter->SetTaggedQueue(thread_, queue);
2779     iter->SetIterationKind(kind);
2780     return iter;
2781 }
2782 
NewJSArrayIterator(const JSHandle<JSObject> & array,IterationKind kind)2783 JSHandle<JSArrayIterator> ObjectFactory::NewJSArrayIterator(const JSHandle<JSObject> &array, IterationKind kind)
2784 {
2785     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2786     JSHandle<JSTaggedValue> protoValue = env->GetArrayIteratorPrototype();
2787     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
2788     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSArrayIteratorClass());
2789     hclassHandle->SetPrototype(thread_, protoValue);
2790     JSHandle<JSArrayIterator> iter(NewJSObject(hclassHandle));
2791     iter->GetJSHClass()->SetExtensible(true);
2792     iter->SetIteratedArray(thread_, array);
2793     iter->SetNextIndex(0);
2794     iter->SetIterationKind(kind);
2795     return iter;
2796 }
2797 
CreateJSPromiseReactionsFunction(MethodIndex idx)2798 JSHandle<JSPromiseReactionsFunction> ObjectFactory::CreateJSPromiseReactionsFunction(MethodIndex idx)
2799 {
2800     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2801     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseReactionFunctionClass());
2802 
2803     JSHandle<JSPromiseReactionsFunction> reactionsFunction =
2804         JSHandle<JSPromiseReactionsFunction>::Cast(NewJSObject(hclass));
2805     reactionsFunction->SetPromise(thread_, JSTaggedValue::Hole());
2806     reactionsFunction->SetAlreadyResolved(thread_, JSTaggedValue::Hole());
2807     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(reactionsFunction);
2808     JSFunction::InitializeJSFunction(thread_, function);
2809     reactionsFunction->SetMethod(thread_, vm_->GetMethodByIndex(idx));
2810     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(1));
2811     return reactionsFunction;
2812 }
2813 
CreateJSPromiseExecutorFunction()2814 JSHandle<JSPromiseExecutorFunction> ObjectFactory::CreateJSPromiseExecutorFunction()
2815 {
2816     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2817     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseExecutorFunctionClass());
2818     JSHandle<JSPromiseExecutorFunction> executorFunction =
2819         JSHandle<JSPromiseExecutorFunction>::Cast(NewJSObject(hclass));
2820     executorFunction->SetCapability(thread_, JSTaggedValue::Hole());
2821     executorFunction->SetCapability(thread_, JSTaggedValue::Undefined());
2822     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(executorFunction);
2823     JSFunction::InitializeJSFunction(thread_, function);
2824     executorFunction->SetMethod(
2825         thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_EXECUTOR));
2826     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(FunctionLength::TWO));
2827     return executorFunction;
2828 }
2829 
NewJSPromiseAllResolveElementFunction()2830 JSHandle<JSPromiseAllResolveElementFunction> ObjectFactory::NewJSPromiseAllResolveElementFunction()
2831 {
2832     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2833     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseAllResolveElementFunctionClass());
2834     JSHandle<JSPromiseAllResolveElementFunction> function =
2835         JSHandle<JSPromiseAllResolveElementFunction>::Cast(NewJSObject(hclass));
2836     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2837     function->SetMethod(
2838         thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_RESOLVE_ELEMENT_FUNCTION));
2839     function->SetIndex(thread_, JSTaggedValue::Undefined());
2840     function->SetValues(thread_, JSTaggedValue::Undefined());
2841     function->SetCapabilities(thread_, JSTaggedValue::Undefined());
2842     function->SetRemainingElements(thread_, JSTaggedValue::Undefined());
2843     function->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
2844     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2845     return function;
2846 }
2847 
NewJSPromiseAnyRejectElementFunction()2848 JSHandle<JSPromiseAnyRejectElementFunction> ObjectFactory::NewJSPromiseAnyRejectElementFunction()
2849 {
2850     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2851     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseAnyRejectElementFunctionClass());
2852     JSHandle<JSPromiseAnyRejectElementFunction> function =
2853         JSHandle<JSPromiseAnyRejectElementFunction>::Cast(NewJSObject(hclass));
2854     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2855     function->SetMethod(
2856         thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_ANY_REJECT_ELEMENT_FUNCTION));
2857     function->SetIndex(0);
2858     function->SetErrors(thread_, JSTaggedValue::Undefined());
2859     function->SetCapability(thread_, JSTaggedValue::Undefined());
2860     function->SetRemainingElements(thread_, JSTaggedValue::Undefined());
2861     function->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
2862     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2863     return function;
2864 }
2865 
NewJSPromiseAllSettledResolveElementFunction()2866 JSHandle<JSPromiseAllSettledElementFunction> ObjectFactory::NewJSPromiseAllSettledResolveElementFunction()
2867 {
2868     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2869     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseAllSettledElementFunctionClass());
2870     JSHandle<JSPromiseAllSettledElementFunction> function =
2871         JSHandle<JSPromiseAllSettledElementFunction>::Cast(NewJSObject(hclass));
2872     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2873     function->SetMethod(thread_,
2874         vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_ALL_SETTLED_RESOLVE_ELEMENT_FUNCTION));
2875     function->SetIndex(0);
2876     function->SetValues(thread_, JSTaggedValue::Undefined());
2877     function->SetCapability(thread_, JSTaggedValue::Undefined());
2878     function->SetRemainingElements(thread_, JSTaggedValue::Undefined());
2879     function->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
2880     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2881     return function;
2882 }
2883 
NewJSPromiseAllSettledRejectElementFunction()2884 JSHandle<JSPromiseAllSettledElementFunction> ObjectFactory::NewJSPromiseAllSettledRejectElementFunction()
2885 {
2886     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2887     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseAllSettledElementFunctionClass());
2888     JSHandle<JSPromiseAllSettledElementFunction> function =
2889         JSHandle<JSPromiseAllSettledElementFunction>::Cast(NewJSObject(hclass));
2890     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2891     function->SetMethod(thread_,
2892         vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_ALL_SETTLED_REJECT_ELEMENT_FUNCTION));
2893     function->SetIndex(0);
2894     function->SetValues(thread_, JSTaggedValue::Undefined());
2895     function->SetCapability(thread_, JSTaggedValue::Undefined());
2896     function->SetRemainingElements(thread_, JSTaggedValue::Undefined());
2897     function->SetAlreadyCalled(thread_, JSTaggedValue::Undefined());
2898     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2899     return function;
2900 }
2901 
NewJSPromiseThenFinallyFunction()2902 JSHandle<JSPromiseFinallyFunction> ObjectFactory::NewJSPromiseThenFinallyFunction()
2903 {
2904     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2905     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseFinallyFunctionClass());
2906     JSHandle<JSPromiseFinallyFunction> function =
2907         JSHandle<JSPromiseFinallyFunction>::Cast(NewJSObject(hclass));
2908     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2909     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_THEN_FINALLY_FUNCTION));
2910     function->SetConstructor(thread_, JSTaggedValue::Undefined());
2911     function->SetOnFinally(thread_, JSTaggedValue::Undefined());
2912     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2913     return function;
2914 }
2915 
NewJSPromiseCatchFinallyFunction()2916 JSHandle<JSPromiseFinallyFunction> ObjectFactory::NewJSPromiseCatchFinallyFunction()
2917 {
2918     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2919     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseFinallyFunctionClass());
2920     JSHandle<JSPromiseFinallyFunction> function =
2921         JSHandle<JSPromiseFinallyFunction>::Cast(NewJSObject(hclass));
2922     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2923     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_CATCH_FINALLY_FUNCTION));
2924     function->SetConstructor(thread_, JSTaggedValue::Undefined());
2925     function->SetOnFinally(thread_, JSTaggedValue::Undefined());
2926     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2927     return function;
2928 }
2929 
NewJSAsyGenResNextRetProRstFulfilledFtn()2930 JSHandle<JSAsyncGeneratorResNextRetProRstFtn> ObjectFactory::NewJSAsyGenResNextRetProRstFulfilledFtn()
2931 {
2932     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2933     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(
2934         env->GetAsyncGeneratorResNextRetProRstFtnClass());
2935     JSHandle<JSAsyncGeneratorResNextRetProRstFtn> function =
2936         JSHandle<JSAsyncGeneratorResNextRetProRstFtn>::Cast(NewJSObject(hclass));
2937     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2938     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_ASYNC_GENERATOR_NEXT_FULFILLED_FUNCTION));
2939     function->SetAsyncGeneratorObject(thread_, JSTaggedValue::Undefined());
2940     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2941     return function;
2942 }
2943 
NewJSAsyncFromSyncIterUnwarpFunction()2944 JSHandle<JSAsyncFromSyncIterUnwarpFunction> ObjectFactory::NewJSAsyncFromSyncIterUnwarpFunction()
2945 {
2946     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2947     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetAsyncFromSyncIterUnwarpClass());
2948     JSHandle<JSAsyncFromSyncIterUnwarpFunction> function =
2949         JSHandle<JSAsyncFromSyncIterUnwarpFunction>::Cast(NewJSObject(hclass));
2950     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2951     JSTaggedValue debugVaule =  vm_->GetMethodByIndex(MethodIndex::BUILTINS_ASYNC_FROM_SYNC_ITERATOR_FUNCTION);
2952     function->SetMethod(thread_, debugVaule);
2953     function->SetDone(thread_, JSTaggedValue::Undefined());
2954     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2955     return function;
2956 }
2957 
NewJSAsyGenResNextRetProRstRejectedFtn()2958 JSHandle<JSAsyncGeneratorResNextRetProRstFtn> ObjectFactory::NewJSAsyGenResNextRetProRstRejectedFtn()
2959 {
2960     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2961     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(
2962         env->GetAsyncGeneratorResNextRetProRstFtnClass());
2963     JSHandle<JSAsyncGeneratorResNextRetProRstFtn> function =
2964         JSHandle<JSAsyncGeneratorResNextRetProRstFtn>::Cast(NewJSObject(hclass));
2965     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2966     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_ASYNC_GENERATOR_NEXT_REJECTED_FUNCTION));
2967     function->SetAsyncGeneratorObject(thread_, JSTaggedValue::Undefined());
2968     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
2969     return function;
2970 }
2971 
NewJSPromiseValueThunkFunction()2972 JSHandle<JSPromiseValueThunkOrThrowerFunction> ObjectFactory::NewJSPromiseValueThunkFunction()
2973 {
2974     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2975     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseValueThunkOrThrowerFunctionClass());
2976     JSHandle<JSPromiseValueThunkOrThrowerFunction> function =
2977         JSHandle<JSPromiseValueThunkOrThrowerFunction>::Cast(NewJSObject(hclass));
2978     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2979     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_VALUE_THUNK_FUNCTION));
2980     function->SetResult(thread_, JSTaggedValue::Undefined());
2981     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(0));
2982     return function;
2983 }
2984 
NewJSPromiseThrowerFunction()2985 JSHandle<JSPromiseValueThunkOrThrowerFunction> ObjectFactory::NewJSPromiseThrowerFunction()
2986 {
2987     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2988     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetPromiseValueThunkOrThrowerFunctionClass());
2989     JSHandle<JSPromiseValueThunkOrThrowerFunction> function =
2990         JSHandle<JSPromiseValueThunkOrThrowerFunction>::Cast(NewJSObject(hclass));
2991     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
2992     function->SetMethod(thread_, vm_->GetMethodByIndex(MethodIndex::BUILTINS_PROMISE_HANDLER_THROWER_FUNCTION));
2993     function->SetResult(thread_, JSTaggedValue::Undefined());
2994     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(0));
2995     return function;
2996 }
2997 
InternString(const JSHandle<JSTaggedValue> & key)2998 EcmaString *ObjectFactory::InternString(const JSHandle<JSTaggedValue> &key)
2999 {
3000     EcmaString *str = EcmaString::Cast(key->GetTaggedObject());
3001     if (EcmaStringAccessor(str).IsInternString()) {
3002         return str;
3003     }
3004 
3005     EcmaStringTable *stringTable = vm_->GetEcmaStringTable();
3006     return stringTable->GetOrInternString(str);
3007 }
3008 
NewTransitionHandler()3009 JSHandle<TransitionHandler> ObjectFactory::NewTransitionHandler()
3010 {
3011     NewObjectHook();
3012     TransitionHandler *handler =
3013         TransitionHandler::Cast(heap_->AllocateYoungOrHugeObject(
3014             JSHClass::Cast(thread_->GlobalConstants()->GetTransitionHandlerClass().GetTaggedObject())));
3015     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
3016     handler->SetTransitionHClass(thread_, JSTaggedValue::Undefined());
3017     return JSHandle<TransitionHandler>(thread_, handler);
3018 }
3019 
NewPrototypeHandler()3020 JSHandle<PrototypeHandler> ObjectFactory::NewPrototypeHandler()
3021 {
3022     NewObjectHook();
3023     PrototypeHandler *header =
3024         PrototypeHandler::Cast(heap_->AllocateYoungOrHugeObject(
3025             JSHClass::Cast(thread_->GlobalConstants()->GetPrototypeHandlerClass().GetTaggedObject())));
3026     JSHandle<PrototypeHandler> handler(thread_, header);
3027     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
3028     handler->SetProtoCell(thread_, JSTaggedValue::Undefined());
3029     handler->SetHolder(thread_, JSTaggedValue::Undefined());
3030     return handler;
3031 }
3032 
NewTransWithProtoHandler()3033 JSHandle<TransWithProtoHandler> ObjectFactory::NewTransWithProtoHandler()
3034 {
3035     NewObjectHook();
3036     TransWithProtoHandler *header =
3037         TransWithProtoHandler::Cast(heap_->AllocateYoungOrHugeObject(
3038             JSHClass::Cast(thread_->GlobalConstants()->GetTransWithProtoHandlerClass().GetTaggedObject())));
3039     JSHandle<TransWithProtoHandler> handler(thread_, header);
3040     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
3041     handler->SetProtoCell(thread_, JSTaggedValue::Undefined());
3042     handler->SetTransitionHClass(thread_, JSTaggedValue::Undefined());
3043     return handler;
3044 }
3045 
NewStoreTSHandler()3046 JSHandle<StoreTSHandler> ObjectFactory::NewStoreTSHandler()
3047 {
3048     NewObjectHook();
3049     StoreTSHandler *header =
3050         StoreTSHandler::Cast(heap_->AllocateYoungOrHugeObject(
3051             JSHClass::Cast(thread_->GlobalConstants()->GetStoreTSHandlerClass().GetTaggedObject())));
3052     JSHandle<StoreTSHandler> handler(thread_, header);
3053     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
3054     handler->SetProtoCell(thread_, JSTaggedValue::Undefined());
3055     handler->SetHolder(thread_, JSTaggedValue::Undefined());
3056     return handler;
3057 }
3058 
NewPromiseRecord()3059 JSHandle<PromiseRecord> ObjectFactory::NewPromiseRecord()
3060 {
3061     NewObjectHook();
3062     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3063         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseRecordClass().GetTaggedObject()));
3064     JSHandle<PromiseRecord> obj(thread_, header);
3065     obj->SetValue(thread_, JSTaggedValue::Undefined());
3066     return obj;
3067 }
3068 
NewResolvingFunctionsRecord()3069 JSHandle<ResolvingFunctionsRecord> ObjectFactory::NewResolvingFunctionsRecord()
3070 {
3071     NewObjectHook();
3072     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3073         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseResolvingFunctionsRecordClass().GetTaggedObject()));
3074     JSHandle<ResolvingFunctionsRecord> obj(thread_, header);
3075     obj->SetResolveFunction(thread_, JSTaggedValue::Undefined());
3076     obj->SetRejectFunction(thread_, JSTaggedValue::Undefined());
3077     return obj;
3078 }
3079 
CreateObjectClass(const JSHandle<TaggedArray> & properties,size_t length)3080 JSHandle<JSHClass> ObjectFactory::CreateObjectClass(const JSHandle<TaggedArray> &properties, size_t length)
3081 {
3082     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3083     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
3084 
3085     uint32_t fieldOrder = 0;
3086     JSMutableHandle<JSTaggedValue> key(thread_, JSTaggedValue::Undefined());
3087     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(length);
3088     while (fieldOrder < length) {
3089         key.Update(properties->Get(fieldOrder * 2));  // 2: Meaning to double
3090         ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
3091         PropertyAttributes attributes = PropertyAttributes::Default();
3092 
3093         if (properties->Get(fieldOrder * 2 + 1).IsAccessor()) {  // 2: Meaning to double
3094             attributes.SetIsAccessor(true);
3095         }
3096 
3097         attributes.SetIsInlinedProps(true);
3098         attributes.SetRepresentation(Representation::MIXED);
3099         attributes.SetOffset(fieldOrder);
3100         layoutInfoHandle->AddKey(thread_, fieldOrder, key.GetTaggedValue(), attributes);
3101         fieldOrder++;
3102     }
3103     ASSERT(fieldOrder <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
3104     JSHandle<JSHClass> objClass = NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, fieldOrder);
3105     objClass->SetPrototype(thread_, proto.GetTaggedValue());
3106     {
3107         objClass->SetExtensible(true);
3108         objClass->SetIsLiteral(true);
3109         objClass->SetLayout(thread_, layoutInfoHandle);
3110         objClass->SetNumberOfProps(fieldOrder);
3111     }
3112     return objClass;
3113 }
3114 
SetLayoutInObjHClass(const JSHandle<TaggedArray> & properties,size_t length,const JSHandle<JSHClass> & objClass)3115 JSHandle<JSHClass> ObjectFactory::SetLayoutInObjHClass(const JSHandle<TaggedArray> &properties, size_t length,
3116                                                        const JSHandle<JSHClass> &objClass)
3117 {
3118     JSMutableHandle<JSTaggedValue> key(thread_, JSTaggedValue::Undefined());
3119     JSHandle<JSHClass> newObjHclass(objClass);
3120 
3121     for (size_t fieldOffset = 0; fieldOffset < length; fieldOffset++) {
3122         key.Update(properties->Get(fieldOffset * 2)); // 2 : pair of key and value
3123         ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
3124         PropertyAttributes attributes = PropertyAttributes::Default();
3125         if (properties->Get(fieldOffset * 2 + 1).IsAccessor()) {  // 2: Meaning to double
3126             attributes.SetIsAccessor(true);
3127         }
3128         attributes.SetIsInlinedProps(true);
3129         attributes.SetRepresentation(Representation::MIXED);
3130         attributes.SetOffset(fieldOffset);
3131         newObjHclass = JSHClass::SetPropertyOfObjHClass(thread_, newObjHclass, key, attributes);
3132     }
3133     return newObjHclass;
3134 }
3135 
GetObjectLiteralHClass(const JSHandle<TaggedArray> & properties,size_t length)3136 JSHandle<JSHClass> ObjectFactory::GetObjectLiteralHClass(const JSHandle<TaggedArray> &properties, size_t length)
3137 {
3138     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3139     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
3140 
3141     // 64 : If object literal gets too many properties, create hclass directly.
3142     const int HCLASS_CACHE_SIZE = 64;
3143     if (length >= HCLASS_CACHE_SIZE) {
3144         return CreateObjectClass(properties, length);
3145     }
3146     JSHandle<JSTaggedValue> maybeCache = env->GetObjectLiteralHClassCache();
3147     if (maybeCache->IsHole()) {
3148         JSHandle<TaggedArray> cacheArr = NewTaggedArray(HCLASS_CACHE_SIZE);
3149         env->SetObjectLiteralHClassCache(thread_, cacheArr.GetTaggedValue());
3150     }
3151     JSHandle<JSTaggedValue> hclassCache = env->GetObjectLiteralHClassCache();
3152     JSHandle<TaggedArray> hclassCacheArr = JSHandle<TaggedArray>::Cast(hclassCache);
3153     JSTaggedValue maybeHClass = hclassCacheArr->Get(length);
3154     if (maybeHClass.IsHole()) {
3155         JSHandle<JSHClass> objHClass = NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, length);
3156         objHClass->SetPrototype(thread_, proto.GetTaggedValue());
3157         {
3158             objHClass->SetNumberOfProps(0);
3159             objHClass->SetExtensible(true);
3160             objHClass->SetIsLiteral(true);
3161         }
3162         hclassCacheArr->Set(thread_, length, objHClass);
3163         return SetLayoutInObjHClass(properties, length, objHClass);
3164     }
3165     return SetLayoutInObjHClass(properties, length, JSHandle<JSHClass>(thread_, maybeHClass));
3166 }
3167 
NewOldSpaceObjLiteralByHClass(const JSHandle<TaggedArray> & properties,size_t length)3168 JSHandle<JSObject> ObjectFactory::NewOldSpaceObjLiteralByHClass(const JSHandle<TaggedArray> &properties, size_t length)
3169 {
3170     JSHandle<JSHClass> hclass = GetObjectLiteralHClass(properties, length);
3171     JSHandle<JSObject> obj = NewOldSpaceJSObject(hclass);
3172     InitializeJSObject(obj, hclass);
3173     return obj;
3174 }
3175 
NewEmptyJSObject()3176 JSHandle<JSObject> ObjectFactory::NewEmptyJSObject()
3177 {
3178     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
3179     JSHandle<JSFunction> builtinObj(env->GetObjectFunction());
3180     return NewJSObjectByConstructor(builtinObj);
3181 }
3182 
CreateNullJSObject()3183 JSHandle<JSObject> ObjectFactory::CreateNullJSObject()
3184 {
3185     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3186     JSHandle<JSTaggedValue> nullValue = globalConst->GetHandledNull();
3187     return OrdinaryNewJSObjectCreate(nullValue);
3188 }
3189 
NewSpaceBySnapshotAllocator(size_t size)3190 uintptr_t ObjectFactory::NewSpaceBySnapshotAllocator(size_t size)
3191 {
3192     NewObjectHook();
3193     return heap_->AllocateSnapshotSpace(size);
3194 }
3195 
NewMachineCodeObject(size_t length,const uint8_t * data)3196 JSHandle<MachineCode> ObjectFactory::NewMachineCodeObject(size_t length, const uint8_t *data)
3197 {
3198     NewObjectHook();
3199     TaggedObject *obj = heap_->AllocateMachineCodeObject(JSHClass::Cast(
3200         thread_->GlobalConstants()->GetMachineCodeClass().GetTaggedObject()), length + MachineCode::SIZE);
3201     MachineCode *code = MachineCode::Cast(obj);
3202     if (code == nullptr) {
3203         LOG_FULL(FATAL) << "machine code cast failed";
3204         UNREACHABLE();
3205     }
3206     code->SetInstructionSizeInBytes(static_cast<uint32_t>(length));
3207     if (data != nullptr) {
3208         code->SetData(data, length);
3209     }
3210     JSHandle<MachineCode> codeObj(thread_, code);
3211     return codeObj;
3212 }
3213 
NewClassInfoExtractor(JSHandle<JSTaggedValue> method)3214 JSHandle<ClassInfoExtractor> ObjectFactory::NewClassInfoExtractor(JSHandle<JSTaggedValue> method)
3215 {
3216     NewObjectHook();
3217     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3218         JSHClass::Cast(thread_->GlobalConstants()->GetClassInfoExtractorHClass().GetTaggedObject()));
3219     JSHandle<ClassInfoExtractor> obj(thread_, header);
3220     obj->ClearBitField();
3221     obj->SetConstructorMethod(thread_, method.GetTaggedValue());
3222     JSHandle<TaggedArray> emptyArray = EmptyArray();
3223     obj->SetNonStaticKeys(thread_, emptyArray, SKIP_BARRIER);
3224     obj->SetNonStaticProperties(thread_, emptyArray, SKIP_BARRIER);
3225     obj->SetNonStaticElements(thread_, emptyArray, SKIP_BARRIER);
3226     obj->SetStaticKeys(thread_, emptyArray, SKIP_BARRIER);
3227     obj->SetStaticProperties(thread_, emptyArray, SKIP_BARRIER);
3228     obj->SetStaticElements(thread_, emptyArray, SKIP_BARRIER);
3229     return obj;
3230 }
3231 
3232 // ----------------------------------- new TSType ----------------------------------------
CreateTSObjLayoutInfo(int propNum,JSTaggedValue initVal)3233 JSHandle<TSObjLayoutInfo> ObjectFactory::CreateTSObjLayoutInfo(int propNum, JSTaggedValue initVal)
3234 {
3235     uint32_t arrayLength = TSObjLayoutInfo::ComputeArrayLength(propNum);
3236     JSHandle<TSObjLayoutInfo> tsPropInfoHandle = JSHandle<TSObjLayoutInfo>::Cast(NewTaggedArray(arrayLength, initVal));
3237     tsPropInfoHandle->SetNumOfProperties(thread_, 0);
3238     return tsPropInfoHandle;
3239 }
3240 
NewTSObjectType(uint32_t numOfKeys)3241 JSHandle<TSObjectType> ObjectFactory::NewTSObjectType(uint32_t numOfKeys)
3242 {
3243     NewObjectHook();
3244 
3245     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3246         JSHClass::Cast(thread_->GlobalConstants()->GetTSObjectTypeClass().GetTaggedObject()));
3247     JSHandle<TSObjectType> objectType(thread_, header);
3248     objectType->SetHClass(thread_, JSTaggedValue::Undefined());
3249     objectType->SetObjLayoutInfo(thread_, JSTaggedValue::Undefined());
3250     objectType->SetGT(GlobalTSTypeRef::Default());
3251 
3252     JSHandle<TSObjLayoutInfo> tsPropInfo = CreateTSObjLayoutInfo(numOfKeys);
3253     objectType->SetObjLayoutInfo(thread_, tsPropInfo);
3254     return objectType;
3255 }
3256 
NewTSClassType()3257 JSHandle<TSClassType> ObjectFactory::NewTSClassType()
3258 {
3259     NewObjectHook();
3260 
3261     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3262         JSHClass::Cast(thread_->GlobalConstants()->GetTSClassTypeClass().GetTaggedObject()));
3263     JSHandle<TSClassType> classType(thread_, header);
3264 
3265     classType->SetGT(GlobalTSTypeRef::Default());
3266     classType->SetInstanceType(thread_, JSTaggedValue::Undefined());
3267     classType->SetConstructorType(thread_, JSTaggedValue::Undefined());
3268     classType->SetPrototypeType(thread_, JSTaggedValue::Undefined());
3269     classType->SetName(thread_, JSTaggedValue::Undefined());
3270     classType->SetExtensionGT(GlobalTSTypeRef::Default());
3271     classType->SetHasLinked(false);
3272 
3273     return classType;
3274 }
3275 
NewTSInterfaceType()3276 JSHandle<TSInterfaceType> ObjectFactory::NewTSInterfaceType()
3277 {
3278     NewObjectHook();
3279 
3280     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3281         JSHClass::Cast(thread_->GlobalConstants()->GetTSInterfaceTypeClass().GetTaggedObject()));
3282     JSHandle<TSInterfaceType> interfaceType(thread_, header);
3283 
3284     JSHandle<TaggedArray> extends = EmptyArray();
3285     interfaceType->SetGT(GlobalTSTypeRef::Default());
3286     interfaceType->SetExtends(thread_, extends);
3287     interfaceType->SetFields(thread_, JSTaggedValue::Undefined());
3288 
3289     return interfaceType;
3290 }
3291 
3292 
NewTSUnionType(uint32_t length)3293 JSHandle<TSUnionType> ObjectFactory::NewTSUnionType(uint32_t length)
3294 {
3295     NewObjectHook();
3296     ASSERT(length > 0);
3297 
3298     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3299         JSHClass::Cast(thread_->GlobalConstants()->GetTSUnionTypeClass().GetTaggedObject()));
3300     JSHandle<TSUnionType> unionType(thread_, header);
3301 
3302     unionType->SetGT(GlobalTSTypeRef::Default());
3303     unionType->SetComponents(thread_, JSTaggedValue::Undefined());
3304     JSHandle<TaggedArray> componentTypes = NewTaggedArray(length, JSTaggedValue::Undefined());
3305     unionType->SetComponents(thread_, componentTypes);
3306 
3307     return unionType;
3308 }
3309 
NewTSClassInstanceType()3310 JSHandle<TSClassInstanceType> ObjectFactory::NewTSClassInstanceType()
3311 {
3312     NewObjectHook();
3313 
3314     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3315         JSHClass::Cast(thread_->GlobalConstants()->GetTSClassInstanceTypeClass().GetTaggedObject()));
3316     JSHandle<TSClassInstanceType> classInstanceType(thread_, header);
3317 
3318     classInstanceType->SetGT(GlobalTSTypeRef::Default());
3319     classInstanceType->SetClassGT(GlobalTSTypeRef::Default());
3320 
3321     return classInstanceType;
3322 }
3323 
NewTSFunctionType(uint32_t length)3324 JSHandle<TSFunctionType> ObjectFactory::NewTSFunctionType(uint32_t length)
3325 {
3326     NewObjectHook();
3327 
3328     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3329         JSHClass::Cast(thread_->GlobalConstants()->GetTSFunctionTypeClass().GetTaggedObject()));
3330     JSHandle<TSFunctionType> functionType(thread_, header);
3331 
3332     functionType->SetGT(GlobalTSTypeRef::Default());
3333     functionType->SetName(thread_, JSTaggedValue::Undefined());
3334     functionType->SetParameterTypes(thread_, JSTaggedValue::Undefined());
3335     functionType->SetReturnGT(GlobalTSTypeRef::Default());
3336     functionType->SetThisGT(GlobalTSTypeRef::Default());
3337     functionType->ClearBitField();
3338 
3339     JSHandle<TaggedArray> parameterTypes = NewTaggedArray(length, JSTaggedValue::Undefined());
3340     functionType->SetParameterTypes(thread_, parameterTypes);
3341 
3342     return functionType;
3343 }
3344 
NewTSArrayType()3345 JSHandle<TSArrayType> ObjectFactory::NewTSArrayType()
3346 {
3347     NewObjectHook();
3348 
3349     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3350         JSHClass::Cast(thread_->GlobalConstants()->GetTSArrayTypeClass().GetTaggedObject()));
3351 
3352     JSHandle<TSArrayType> arrayType(thread_, header);
3353     arrayType->SetElementGT(GlobalTSTypeRef::Default());
3354 
3355     return arrayType;
3356 }
3357 
NewTSTypeTable(uint32_t length)3358 JSHandle<TSTypeTable> ObjectFactory::NewTSTypeTable(uint32_t length)
3359 {
3360     NewObjectHook();
3361 
3362     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length + TSTypeTable::RESERVE_TABLE_LENGTH);
3363     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
3364     auto header = heap_->AllocateOldOrHugeObject(arrayClass, size);
3365 
3366     JSHandle<TSTypeTable> table(thread_, header);
3367     table->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length + TSTypeTable::RESERVE_TABLE_LENGTH);
3368     table->SetNumberOfTypes(thread_);
3369 
3370     return table;
3371 }
3372 
NewTSModuleTable(uint32_t length)3373 JSHandle<TSModuleTable> ObjectFactory::NewTSModuleTable(uint32_t length)
3374 {
3375     NewObjectHook();
3376     ASSERT(length > 0);
3377 
3378     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
3379     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
3380     auto header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
3381     JSHandle<TSModuleTable> array(thread_, header);
3382     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
3383     array->SetNumberOfTSTypeTables(thread_, 0);
3384 
3385     return array;
3386 }
3387 
NewTSIteratorInstanceType()3388 JSHandle<TSIteratorInstanceType> ObjectFactory::NewTSIteratorInstanceType()
3389 {
3390     NewObjectHook();
3391 
3392     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3393         JSHClass::Cast(thread_->GlobalConstants()->GetTSIteratorInstanceTypeClass().GetTaggedObject()));
3394     JSHandle<TSIteratorInstanceType> iteratorInstanceType(thread_, header);
3395 
3396     iteratorInstanceType->SetGT(GlobalTSTypeRef::Default());
3397     iteratorInstanceType->SetKindGT(GlobalTSTypeRef::Default());
3398     iteratorInstanceType->SetElementGT(GlobalTSTypeRef::Default());
3399 
3400     return iteratorInstanceType;
3401 }
3402 // ----------------------------------- new string ----------------------------------------
NewFromASCII(const CString & data)3403 JSHandle<EcmaString> ObjectFactory::NewFromASCII(const CString &data)
3404 {
3405     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
3406     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, data.length()));
3407     return GetStringFromStringTable(utf8Data, data.length(), true);
3408 }
3409 
NewFromASCIINonMovable(const CString & data)3410 JSHandle<EcmaString> ObjectFactory::NewFromASCIINonMovable(const CString &data)
3411 {
3412     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
3413     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, data.length()));
3414     return GetStringFromStringTableNonMovable(utf8Data, data.length());
3415 }
3416 
NewFromUtf8(const CString & data)3417 JSHandle<EcmaString> ObjectFactory::NewFromUtf8(const CString &data)
3418 {
3419     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
3420     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, data.length());
3421     return GetStringFromStringTable(utf8Data, data.length(), canBeCompress);
3422 }
3423 
NewFromStdString(const std::string & data)3424 JSHandle<EcmaString> ObjectFactory::NewFromStdString(const std::string &data)
3425 {
3426     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
3427     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, data.length());
3428     return GetStringFromStringTable(utf8Data, data.size(), canBeCompress);
3429 }
3430 
NewFromUtf8(const uint8_t * utf8Data,uint32_t utf8Len)3431 JSHandle<EcmaString> ObjectFactory::NewFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len)
3432 {
3433     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, utf8Len);
3434     return GetStringFromStringTable(utf8Data, utf8Len, canBeCompress);
3435 }
3436 
NewFromUtf16(const uint16_t * utf16Data,uint32_t utf16Len)3437 JSHandle<EcmaString> ObjectFactory::NewFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len)
3438 {
3439     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len);
3440     return GetStringFromStringTable(utf16Data, utf16Len, canBeCompress);
3441 }
3442 
NewFromUtf16Compress(const uint16_t * utf16Data,uint32_t utf16Len)3443 JSHandle<EcmaString> ObjectFactory::NewFromUtf16Compress(const uint16_t *utf16Data, uint32_t utf16Len)
3444 {
3445     ASSERT(EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len));
3446     return GetStringFromStringTable(utf16Data, utf16Len, true);
3447 }
3448 
NewFromUtf16NotCompress(const uint16_t * utf16Data,uint32_t utf16Len)3449 JSHandle<EcmaString> ObjectFactory::NewFromUtf16NotCompress(const uint16_t *utf16Data, uint32_t utf16Len)
3450 {
3451     ASSERT(!EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len));
3452     return GetStringFromStringTable(utf16Data, utf16Len, false);
3453 }
3454 
NewFromUtf8Literal(const uint8_t * utf8Data,uint32_t utf8Len)3455 JSHandle<EcmaString> ObjectFactory::NewFromUtf8Literal(const uint8_t *utf8Data, uint32_t utf8Len)
3456 {
3457     NewObjectHook();
3458     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf8Data, utf8Len);
3459     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress));
3460 }
3461 
NewFromUtf8LiteralCompress(const uint8_t * utf8Data,uint32_t utf8Len)3462 JSHandle<EcmaString> ObjectFactory::NewFromUtf8LiteralCompress(const uint8_t *utf8Data, uint32_t utf8Len)
3463 {
3464     NewObjectHook();
3465     ASSERT(EcmaStringAccessor::CanBeCompressed(utf8Data, utf8Len));
3466     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, true));
3467 }
3468 
NewFromUtf16Literal(const uint16_t * utf16Data,uint32_t utf16Len)3469 JSHandle<EcmaString> ObjectFactory::NewFromUtf16Literal(const uint16_t *utf16Data, uint32_t utf16Len)
3470 {
3471     NewObjectHook();
3472     bool canBeCompress = EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len);
3473     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, canBeCompress));
3474 }
3475 
NewFromUtf16LiteralCompress(const uint16_t * utf16Data,uint32_t utf16Len)3476 JSHandle<EcmaString> ObjectFactory::NewFromUtf16LiteralCompress(const uint16_t *utf16Data, uint32_t utf16Len)
3477 {
3478     NewObjectHook();
3479     ASSERT(EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len));
3480     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, true));
3481 }
3482 
NewFromUtf16LiteralNotCompress(const uint16_t * utf16Data,uint32_t utf16Len)3483 JSHandle<EcmaString> ObjectFactory::NewFromUtf16LiteralNotCompress(const uint16_t *utf16Data, uint32_t utf16Len)
3484 {
3485     NewObjectHook();
3486     ASSERT(!EcmaStringAccessor::CanBeCompressed(utf16Data, utf16Len));
3487     return JSHandle<EcmaString>(thread_, EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, false));
3488 }
3489 
ConcatFromString(const JSHandle<EcmaString> & firstString,const JSHandle<EcmaString> & secondString)3490 JSHandle<EcmaString> ObjectFactory::ConcatFromString(const JSHandle<EcmaString> &firstString,
3491                                                      const JSHandle<EcmaString> &secondString)
3492 {
3493     if (EcmaStringAccessor(firstString).GetLength() == 0) {
3494         return secondString;
3495     }
3496     if (EcmaStringAccessor(secondString).GetLength() == 0) {
3497         return firstString;
3498     }
3499     return GetStringFromStringTable(firstString, secondString);
3500 }
3501 
GetStringFromStringTable(const JSHandle<EcmaString> & firstString,const JSHandle<EcmaString> & secondString)3502 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const JSHandle<EcmaString> &firstString,
3503                                                              const JSHandle<EcmaString> &secondString)
3504 {
3505     auto stringTable = vm_->GetEcmaStringTable();
3506     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(firstString, secondString));
3507 }
3508 
NewJSAPIArrayList(uint32_t capacity)3509 JSHandle<JSAPIArrayList> ObjectFactory::NewJSAPIArrayList(uint32_t capacity)
3510 {
3511     NewObjectHook();
3512     JSHandle<JSFunction> builtinObj(thread_, thread_->GlobalConstants()->GetArrayListFunction());
3513     JSHandle<JSAPIArrayList> obj = JSHandle<JSAPIArrayList>(NewJSObjectByConstructor(builtinObj));
3514     ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory();
3515     JSHandle<TaggedArray> elements = factory->NewTaggedArray(capacity);
3516     obj->SetElements(thread_, elements);
3517 
3518     return obj;
3519 }
3520 
NewJSAPIArrayListIterator(const JSHandle<JSAPIArrayList> & arrayList)3521 JSHandle<JSAPIArrayListIterator> ObjectFactory::NewJSAPIArrayListIterator(const JSHandle<JSAPIArrayList> &arrayList)
3522 {
3523     NewObjectHook();
3524     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3525     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetArrayListIteratorPrototype());
3526     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIArrayListIteratorClass());
3527     hclassHandle->SetPrototype(thread_, protoValue);
3528     JSHandle<JSAPIArrayListIterator> iter(NewJSObject(hclassHandle));
3529     iter->GetJSHClass()->SetExtensible(true);
3530     iter->SetIteratedArrayList(thread_, arrayList);
3531     iter->SetNextIndex(0);
3532     return iter;
3533 }
3534 
NewJSAPILightWeightMapIterator(const JSHandle<JSAPILightWeightMap> & obj,IterationKind kind)3535 JSHandle<JSAPILightWeightMapIterator> ObjectFactory::NewJSAPILightWeightMapIterator(
3536     const JSHandle<JSAPILightWeightMap> &obj, IterationKind kind)
3537 {
3538     NewObjectHook();
3539     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3540     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetLightWeightMapIteratorPrototype());
3541     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPILightWeightMapIteratorClass());
3542     hclassHandle->SetPrototype(thread_, protoValue);
3543     JSHandle<JSAPILightWeightMapIterator> iter(NewJSObject(hclassHandle));
3544     iter->GetJSHClass()->SetExtensible(true);
3545     iter->SetIteratedLightWeightMap(thread_, obj);
3546     iter->SetNextIndex(0);
3547     iter->SetIterationKind(kind);
3548     return iter;
3549 }
3550 
NewJSAPILightWeightSetIterator(const JSHandle<JSAPILightWeightSet> & obj,IterationKind kind)3551 JSHandle<JSAPILightWeightSetIterator> ObjectFactory::NewJSAPILightWeightSetIterator(
3552     const JSHandle<JSAPILightWeightSet> &obj, IterationKind kind)
3553 {
3554     NewObjectHook();
3555     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3556     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetLightWeightSetIteratorPrototype());
3557     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPILightWeightSetIteratorClass());
3558     hclassHandle->SetPrototype(thread_, protoValue);
3559     JSHandle<JSAPILightWeightSetIterator> iter(NewJSObject(hclassHandle));
3560     iter->GetJSHClass()->SetExtensible(true);
3561     iter->SetIteratedLightWeightSet(thread_, obj);
3562     iter->SetNextIndex(0);
3563     iter->SetIterationKind(kind);
3564     return iter;
3565 }
3566 
NewJSAPIPlainArray(uint32_t capacity)3567 JSHandle<JSAPIPlainArray> ObjectFactory::NewJSAPIPlainArray(uint32_t capacity)
3568 {
3569     NewObjectHook();
3570     JSHandle<JSFunction> builtinObj(thread_, thread_->GlobalConstants()->GetPlainArrayFunction());
3571     JSHandle<JSAPIPlainArray> obj = JSHandle<JSAPIPlainArray>(NewJSObjectByConstructor(builtinObj));
3572     ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory();
3573     JSHandle<TaggedArray> keyArray = factory->NewTaggedArray(capacity);
3574     JSHandle<TaggedArray> valueArray = factory->NewTaggedArray(capacity);
3575     obj->SetKeys(thread_, keyArray);
3576     obj->SetValues(thread_, valueArray);
3577 
3578     return obj;
3579 }
3580 
NewJSAPIPlainArrayIterator(const JSHandle<JSAPIPlainArray> & plainarray,IterationKind kind)3581 JSHandle<JSAPIPlainArrayIterator> ObjectFactory::NewJSAPIPlainArrayIterator(const JSHandle<JSAPIPlainArray> &plainarray,
3582                                                                             IterationKind kind)
3583 {
3584     NewObjectHook();
3585     JSHandle<JSTaggedValue> protoValue(thread_, thread_->GlobalConstants()->GetPlainArrayIteratorPrototype());
3586     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3587     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIPlainArrayIteratorClass());
3588     hclassHandle->SetPrototype(thread_, protoValue);
3589     JSHandle<JSAPIPlainArrayIterator> iter(NewJSObject(hclassHandle));
3590     iter->GetJSHClass()->SetExtensible(true);
3591     iter->SetIteratedPlainArray(thread_, plainarray);
3592     iter->SetNextIndex(0);
3593     iter->SetIterationKind(kind);
3594     return iter;
3595 }
3596 
NewJSAPIStackIterator(const JSHandle<JSAPIStack> & stack)3597 JSHandle<JSAPIStackIterator> ObjectFactory::NewJSAPIStackIterator(const JSHandle<JSAPIStack> &stack)
3598 {
3599     NewObjectHook();
3600     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3601     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetStackIteratorPrototype());
3602     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIStackIteratorClass());
3603     hclassHandle->SetPrototype(thread_, protoValue);
3604     JSHandle<JSAPIStackIterator> iter(NewJSObject(hclassHandle));
3605     iter->GetJSHClass()->SetExtensible(true);
3606     iter->SetIteratedStack(thread_, stack);
3607     iter->SetNextIndex(0);
3608     return iter;
3609 }
3610 
CopyDeque(const JSHandle<TaggedArray> & old,uint32_t newLength,uint32_t oldLength,uint32_t first,uint32_t last)3611 JSHandle<TaggedArray> ObjectFactory::CopyDeque(const JSHandle<TaggedArray> &old, uint32_t newLength,
3612                                                [[maybe_unused]] uint32_t oldLength, uint32_t first, uint32_t last)
3613 {
3614     NewObjectHook();
3615     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
3616     auto header = heap_->AllocateYoungOrHugeObject(
3617         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
3618     JSHandle<TaggedArray> newArray(thread_, header);
3619     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
3620 
3621     uint32_t curIndex = first;
3622     // newIndex use in new TaggedArray, 0 : New TaggedArray index
3623     uint32_t newIndex = 0;
3624     uint32_t oldCapacity = old->GetLength();
3625     while (curIndex != last) {
3626         JSTaggedValue value = old->Get(curIndex);
3627         newArray->Set(thread_, newIndex, value);
3628         ASSERT(oldCapacity != 0);
3629         curIndex = (curIndex + 1) % oldCapacity;
3630         newIndex = newIndex + 1;
3631     }
3632     return newArray;
3633 }
3634 
NewJSAPIDequeIterator(const JSHandle<JSAPIDeque> & deque)3635 JSHandle<JSAPIDequeIterator> ObjectFactory::NewJSAPIDequeIterator(const JSHandle<JSAPIDeque> &deque)
3636 {
3637     NewObjectHook();
3638     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3639     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetDequeIteratorPrototype());
3640     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIDequeIteratorClass());
3641     hclassHandle->SetPrototype(thread_, protoValue);
3642     JSHandle<JSAPIDequeIterator> iter(NewJSObject(hclassHandle));
3643     iter->GetJSHClass()->SetExtensible(true);
3644     iter->SetIteratedDeque(thread_, deque);
3645     iter->SetNextIndex(deque->GetFirst());
3646     return iter;
3647 }
3648 
CopyQueue(const JSHandle<TaggedArray> & old,uint32_t newLength,uint32_t front,uint32_t tail)3649 JSHandle<TaggedArray> ObjectFactory::CopyQueue(const JSHandle<TaggedArray> &old, uint32_t newLength,
3650                                                uint32_t front, uint32_t tail)
3651 {
3652     NewObjectHook();
3653     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
3654     auto header = heap_->AllocateYoungOrHugeObject(
3655         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
3656     JSHandle<TaggedArray> newArray(thread_, header);
3657     newArray->InitializeWithSpecialValue(JSTaggedValue::Hole(), newLength, old->GetExtraLength());
3658 
3659     uint32_t curIndex = front;
3660     // newIndex use in new TaggedArray, 0 : New TaggedArray index
3661     uint32_t newIndex = 0;
3662     uint32_t oldCapacity = old->GetLength();
3663     while (curIndex != tail) {
3664         JSTaggedValue value = old->Get(curIndex);
3665         newArray->Set(thread_, newIndex, value);
3666         ASSERT(oldCapacity != 0);
3667         curIndex = (curIndex + 1) % oldCapacity;
3668         newIndex = newIndex + 1;
3669     }
3670     return newArray;
3671 }
3672 
NewJSAPIQueueIterator(const JSHandle<JSAPIQueue> & queue)3673 JSHandle<JSAPIQueueIterator> ObjectFactory::NewJSAPIQueueIterator(const JSHandle<JSAPIQueue> &queue)
3674 {
3675     NewObjectHook();
3676     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3677     JSHandle<JSTaggedValue> protoValue(thread_, globalConst->GetQueueIteratorPrototype());
3678     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIQueueIteratorClass());
3679     hclassHandle->SetPrototype(thread_, protoValue);
3680     JSHandle<JSAPIQueueIterator> iter(NewJSObject(hclassHandle));
3681     iter->GetJSHClass()->SetExtensible(true);
3682     iter->SetIteratedQueue(thread_, queue); // IteratedQueue
3683     iter->SetNextIndex(0);
3684     return iter;
3685 }
3686 
NewJSAPITreeMapIterator(const JSHandle<JSAPITreeMap> & map,IterationKind kind)3687 JSHandle<JSAPITreeMapIterator> ObjectFactory::NewJSAPITreeMapIterator(const JSHandle<JSAPITreeMap> &map,
3688                                                                       IterationKind kind)
3689 {
3690     NewObjectHook();
3691     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3692     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetTreeMapIteratorPrototype());
3693     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPITreeMapIteratorClass());
3694     hclassHandle->SetPrototype(thread_, proto);
3695     JSHandle<JSAPITreeMapIterator> iter(NewJSObject(hclassHandle));
3696     iter->GetJSHClass()->SetExtensible(true);
3697     iter->SetIteratedMap(thread_, map);
3698     iter->SetNextIndex(0);
3699     iter->SetEntries(thread_, JSTaggedValue::Hole());
3700     iter->SetIterationKind(kind);
3701     return iter;
3702 }
3703 
NewJSAPITreeSetIterator(const JSHandle<JSAPITreeSet> & set,IterationKind kind)3704 JSHandle<JSAPITreeSetIterator> ObjectFactory::NewJSAPITreeSetIterator(const JSHandle<JSAPITreeSet> &set,
3705                                                                       IterationKind kind)
3706 {
3707     NewObjectHook();
3708     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3709     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetTreeSetIteratorPrototype());
3710     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPITreeSetIteratorClass());
3711     hclassHandle->SetPrototype(thread_, proto);
3712     JSHandle<JSAPITreeSetIterator> iter(NewJSObject(hclassHandle));
3713     iter->GetJSHClass()->SetExtensible(true);
3714     iter->SetIteratedSet(thread_, set);
3715     iter->SetNextIndex(0);
3716     iter->SetEntries(thread_, JSTaggedValue::Hole());
3717     iter->SetIterationKind(kind);
3718     return iter;
3719 }
3720 
NewJSAPIVector(uint32_t capacity)3721 JSHandle<JSAPIVector> ObjectFactory::NewJSAPIVector(uint32_t capacity)
3722 {
3723     NewObjectHook();
3724     JSHandle<JSFunction> builtinObj(thread_, thread_->GlobalConstants()->GetVectorFunction());
3725     JSHandle<JSAPIVector> obj = JSHandle<JSAPIVector>(NewJSObjectByConstructor(builtinObj));
3726     JSHandle<TaggedArray> newVector = NewTaggedArray(capacity);
3727     obj->SetElements(thread_, newVector);
3728 
3729     return obj;
3730 }
3731 
NewJSAPIVectorIterator(const JSHandle<JSAPIVector> & vector)3732 JSHandle<JSAPIVectorIterator> ObjectFactory::NewJSAPIVectorIterator(const JSHandle<JSAPIVector> &vector)
3733 {
3734     NewObjectHook();
3735     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3736     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetVectorIteratorPrototype());
3737     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIVectorIteratorClass());
3738     hclassHandle->SetPrototype(thread_, proto);
3739     JSHandle<JSAPIVectorIterator> iter(NewJSObject(hclassHandle));
3740     iter->GetJSHClass()->SetExtensible(true);
3741     iter->SetIteratedVector(thread_, vector);
3742     iter->SetNextIndex(0);
3743     return iter;
3744 }
3745 
NewJSAPILinkedListIterator(const JSHandle<JSAPILinkedList> & linkedList)3746 JSHandle<JSAPILinkedListIterator> ObjectFactory::NewJSAPILinkedListIterator(const JSHandle<JSAPILinkedList> &linkedList)
3747 {
3748     NewObjectHook();
3749     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3750     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetLinkedListIteratorPrototype());
3751     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPILinkedListIteratorClass());
3752     hclassHandle->SetPrototype(thread_, proto);
3753     JSHandle<JSAPILinkedListIterator> iter(NewJSObject(hclassHandle));
3754     iter->GetJSHClass()->SetExtensible(true);
3755     iter->SetIteratedLinkedList(thread_, linkedList->GetDoubleList());
3756     iter->SetNextIndex(0);
3757     const uint32_t linkedListElementStartIndex = 4;
3758     iter->SetDataIndex(linkedListElementStartIndex);
3759     return iter;
3760 }
3761 
NewJSAPIListIterator(const JSHandle<JSAPIList> & List)3762 JSHandle<JSAPIListIterator> ObjectFactory::NewJSAPIListIterator(const JSHandle<JSAPIList> &List)
3763 {
3764     NewObjectHook();
3765     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
3766     JSHandle<JSTaggedValue> proto(thread_, globalConst->GetListIteratorPrototype());
3767     JSHandle<JSHClass> hclassHandle(globalConst->GetHandledJSAPIListIteratorClass());
3768     hclassHandle->SetPrototype(thread_, proto);
3769     JSHandle<JSAPIListIterator> iter(NewJSObject(hclassHandle));
3770     iter->GetJSHClass()->SetExtensible(true);
3771     iter->SetIteratedList(thread_, List->GetSingleList());
3772     iter->SetNextIndex(0);
3773     const uint32_t linkedListElementStartIndex = 4;
3774     iter->SetDataIndex(linkedListElementStartIndex);
3775     return iter;
3776 }
3777 
NewJSAPIList()3778 JSHandle<JSAPIList> ObjectFactory::NewJSAPIList()
3779 {
3780     NewObjectHook();
3781     JSHandle<JSFunction> function(thread_, thread_->GlobalConstants()->GetListFunction());
3782     return JSHandle<JSAPIList>::Cast(NewJSObjectByConstructor(function));
3783 }
3784 
NewJSAPILinkedList()3785 JSHandle<JSAPILinkedList> ObjectFactory::NewJSAPILinkedList()
3786 {
3787     NewObjectHook();
3788     JSHandle<JSFunction> function(thread_, thread_->GlobalConstants()->GetLinkedListFunction());
3789     return JSHandle<JSAPILinkedList>::Cast(NewJSObjectByConstructor(function));
3790 }
3791 
NewImportEntry()3792 JSHandle<ImportEntry> ObjectFactory::NewImportEntry()
3793 {
3794     JSHandle<JSTaggedValue> defautValue = thread_->GlobalConstants()->GetHandledUndefined();
3795     return NewImportEntry(defautValue, defautValue, defautValue);
3796 }
3797 
NewImportEntry(const JSHandle<JSTaggedValue> & moduleRequest,const JSHandle<JSTaggedValue> & importName,const JSHandle<JSTaggedValue> & localName)3798 JSHandle<ImportEntry> ObjectFactory::NewImportEntry(const JSHandle<JSTaggedValue> &moduleRequest,
3799                                                     const JSHandle<JSTaggedValue> &importName,
3800                                                     const JSHandle<JSTaggedValue> &localName)
3801 {
3802     NewObjectHook();
3803     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3804         JSHClass::Cast(thread_->GlobalConstants()->GetImportEntryClass().GetTaggedObject()));
3805     JSHandle<ImportEntry> obj(thread_, header);
3806     obj->SetModuleRequest(thread_, moduleRequest);
3807     obj->SetImportName(thread_, importName);
3808     obj->SetLocalName(thread_, localName);
3809     return obj;
3810 }
3811 
NewLocalExportEntry()3812 JSHandle<LocalExportEntry> ObjectFactory::NewLocalExportEntry()
3813 {
3814     JSHandle<JSTaggedValue> defautValue = thread_->GlobalConstants()->GetHandledUndefined();
3815     return NewLocalExportEntry(defautValue, defautValue);
3816 }
3817 
NewLocalExportEntry(const JSHandle<JSTaggedValue> & exportName,const JSHandle<JSTaggedValue> & localName)3818 JSHandle<LocalExportEntry> ObjectFactory::NewLocalExportEntry(const JSHandle<JSTaggedValue> &exportName,
3819                                                               const JSHandle<JSTaggedValue> &localName)
3820 {
3821     NewObjectHook();
3822     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3823         JSHClass::Cast(thread_->GlobalConstants()->GetLocalExportEntryClass().GetTaggedObject()));
3824     JSHandle<LocalExportEntry> obj(thread_, header);
3825     obj->SetExportName(thread_, exportName);
3826     obj->SetLocalName(thread_, localName);
3827     return obj;
3828 }
3829 
NewIndirectExportEntry()3830 JSHandle<IndirectExportEntry> ObjectFactory::NewIndirectExportEntry()
3831 {
3832     JSHandle<JSTaggedValue> defautValue = thread_->GlobalConstants()->GetHandledUndefined();
3833     return NewIndirectExportEntry(defautValue, defautValue, defautValue);
3834 }
3835 
NewIndirectExportEntry(const JSHandle<JSTaggedValue> & exportName,const JSHandle<JSTaggedValue> & moduleRequest,const JSHandle<JSTaggedValue> & importName)3836 JSHandle<IndirectExportEntry> ObjectFactory::NewIndirectExportEntry(const JSHandle<JSTaggedValue> &exportName,
3837                                                                     const JSHandle<JSTaggedValue> &moduleRequest,
3838                                                                     const JSHandle<JSTaggedValue> &importName)
3839 {
3840     NewObjectHook();
3841     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3842         JSHClass::Cast(thread_->GlobalConstants()->GetIndirectExportEntryClass().GetTaggedObject()));
3843     JSHandle<IndirectExportEntry> obj(thread_, header);
3844     obj->SetExportName(thread_, exportName);
3845     obj->SetModuleRequest(thread_, moduleRequest);
3846     obj->SetImportName(thread_, importName);
3847     return obj;
3848 }
3849 
NewStarExportEntry()3850 JSHandle<StarExportEntry> ObjectFactory::NewStarExportEntry()
3851 {
3852     JSHandle<JSTaggedValue> defautValue = thread_->GlobalConstants()->GetHandledUndefined();
3853     return NewStarExportEntry(defautValue);
3854 }
3855 
NewStarExportEntry(const JSHandle<JSTaggedValue> & moduleRequest)3856 JSHandle<StarExportEntry> ObjectFactory::NewStarExportEntry(const JSHandle<JSTaggedValue> &moduleRequest)
3857 {
3858     NewObjectHook();
3859     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3860         JSHClass::Cast(thread_->GlobalConstants()->GetStarExportEntryClass().GetTaggedObject()));
3861     JSHandle<StarExportEntry> obj(thread_, header);
3862     obj->SetModuleRequest(thread_, moduleRequest);
3863     return obj;
3864 }
3865 
NewSourceTextModule()3866 JSHandle<SourceTextModule> ObjectFactory::NewSourceTextModule()
3867 {
3868     NewObjectHook();
3869     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3870         JSHClass::Cast(thread_->GlobalConstants()->GetSourceTextModuleClass().GetTaggedObject()));
3871     JSHandle<SourceTextModule> obj(thread_, header);
3872     JSTaggedValue undefinedValue = thread_->GlobalConstants()->GetUndefined();
3873     obj->SetEnvironment(thread_, undefinedValue);
3874     obj->SetNamespace(thread_, undefinedValue);
3875     obj->SetEcmaModuleFilename(thread_, undefinedValue);
3876     obj->SetEcmaModuleRecordName(thread_, undefinedValue);
3877     obj->SetRequestedModules(thread_, undefinedValue);
3878     obj->SetImportEntries(thread_, undefinedValue);
3879     obj->SetLocalExportEntries(thread_, undefinedValue);
3880     obj->SetIndirectExportEntries(thread_, undefinedValue);
3881     obj->SetStarExportEntries(thread_, undefinedValue);
3882     obj->SetNameDictionary(thread_, undefinedValue);
3883     obj->SetDFSIndex(SourceTextModule::UNDEFINED_INDEX);
3884     obj->SetDFSAncestorIndex(SourceTextModule::UNDEFINED_INDEX);
3885     obj->SetEvaluationError(SourceTextModule::UNDEFINED_INDEX);
3886     obj->SetStatus(ModuleStatus::UNINSTANTIATED);
3887     obj->SetTypes(ModuleTypes::UNKNOWN);
3888     obj->SetIsNewBcVersion(false);
3889     return obj;
3890 }
3891 
NewResolvedBindingRecord()3892 JSHandle<ResolvedBinding> ObjectFactory::NewResolvedBindingRecord()
3893 {
3894     JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
3895     JSHandle<SourceTextModule> ecmaModule(undefinedValue);
3896     JSHandle<JSTaggedValue> bindingName(undefinedValue);
3897     return NewResolvedBindingRecord(ecmaModule, bindingName);
3898 }
3899 
NewResolvedBindingRecord(const JSHandle<SourceTextModule> & module,const JSHandle<JSTaggedValue> & bindingName)3900 JSHandle<ResolvedBinding> ObjectFactory::NewResolvedBindingRecord(const JSHandle<SourceTextModule> &module,
3901                                                                   const JSHandle<JSTaggedValue> &bindingName)
3902 {
3903     NewObjectHook();
3904     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3905         JSHClass::Cast(thread_->GlobalConstants()->GetResolvedBindingClass().GetTaggedObject()));
3906     JSHandle<ResolvedBinding> obj(thread_, header);
3907     obj->SetModule(thread_, module);
3908     obj->SetBindingName(thread_, bindingName);
3909     return obj;
3910 }
3911 
NewResolvedIndexBindingRecord()3912 JSHandle<ResolvedIndexBinding> ObjectFactory::NewResolvedIndexBindingRecord()
3913 {
3914     JSHandle<JSTaggedValue> undefinedValue = thread_->GlobalConstants()->GetHandledUndefined();
3915     JSHandle<SourceTextModule> ecmaModule(undefinedValue);
3916     int32_t index = 0;
3917     return NewResolvedIndexBindingRecord(ecmaModule, index);
3918 }
3919 
NewResolvedIndexBindingRecord(const JSHandle<SourceTextModule> & module,int32_t index)3920 JSHandle<ResolvedIndexBinding> ObjectFactory::NewResolvedIndexBindingRecord(const JSHandle<SourceTextModule> &module,
3921                                                                             int32_t index)
3922 {
3923     NewObjectHook();
3924     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3925         JSHClass::Cast(thread_->GlobalConstants()->GetResolvedIndexBindingClass().GetTaggedObject()));
3926     JSHandle<ResolvedIndexBinding> obj(thread_, header);
3927     obj->SetModule(thread_, module);
3928     obj->SetIndex(index);
3929     return obj;
3930 }
3931 
NewCellRecord()3932 JSHandle<CellRecord> ObjectFactory::NewCellRecord()
3933 {
3934     NewObjectHook();
3935     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
3936         JSHClass::Cast(thread_->GlobalConstants()->GetCellRecordClass().GetTaggedObject()));
3937     JSHandle<CellRecord> obj(thread_, header);
3938     obj->SetWeakRefTarget(thread_, JSTaggedValue::Undefined());
3939     obj->SetHeldValue(thread_, JSTaggedValue::Undefined());
3940     return obj;
3941 }
3942 
CreateIteratorResultInstanceClass()3943 JSHandle<JSHClass> ObjectFactory::CreateIteratorResultInstanceClass()
3944 {
3945     auto globalConst = thread_->GlobalConstants();
3946     JSHandle<JSTaggedValue> proto = vm_->GetGlobalEnv()->GetObjectFunctionPrototype();
3947     JSHandle<JSHClass> iterResultClass = NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, proto);
3948 
3949     uint32_t fieldOrder = 0;
3950     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(2); // 2 means two field
3951     {
3952         ASSERT(JSIterator::VALUE_INLINE_PROPERTY_INDEX == fieldOrder);
3953         PropertyAttributes attributes = PropertyAttributes::Default();
3954         attributes.SetIsInlinedProps(true);
3955         attributes.SetRepresentation(Representation::MIXED);
3956         attributes.SetOffset(fieldOrder);
3957         layoutInfoHandle->AddKey(thread_, fieldOrder++, globalConst->GetValueString(), attributes);
3958     }
3959     {
3960         ASSERT(JSIterator::DONE_INLINE_PROPERTY_INDEX == fieldOrder);
3961         PropertyAttributes attributes = PropertyAttributes::Default();
3962         attributes.SetIsInlinedProps(true);
3963         attributes.SetRepresentation(Representation::MIXED);
3964         attributes.SetOffset(fieldOrder);
3965         layoutInfoHandle->AddKey(thread_, fieldOrder++, globalConst->GetDoneString(), attributes);
3966     }
3967 
3968     {
3969         iterResultClass->SetLayout(thread_, layoutInfoHandle);
3970         iterResultClass->SetNumberOfProps(fieldOrder);
3971     }
3972     return iterResultClass;
3973 }
3974 
NewOldSpaceObject(const JSHandle<JSHClass> & hclass)3975 TaggedObject *ObjectFactory::NewOldSpaceObject(const JSHandle<JSHClass> &hclass)
3976 {
3977     NewObjectHook();
3978     TaggedObject *header = heap_->AllocateOldOrHugeObject(*hclass);
3979     uint32_t inobjPropCount = hclass->GetInlinedProperties();
3980     if (inobjPropCount > 0) {
3981         InitializeExtraProperties(hclass, header, inobjPropCount);
3982     }
3983     return header;
3984 }
3985 
NewOldSpaceJSObject(const JSHandle<JSHClass> & jshclass)3986 JSHandle<JSObject> ObjectFactory::NewOldSpaceJSObject(const JSHandle<JSHClass> &jshclass)
3987 {
3988     JSHandle<JSObject> obj(thread_, JSObject::Cast(NewOldSpaceObject(jshclass)));
3989     JSHandle<TaggedArray> emptyArray = EmptyArray();
3990     obj->InitializeHash();
3991     obj->SetElements(thread_, emptyArray);
3992     obj->SetProperties(thread_, emptyArray);
3993     return obj;
3994 }
3995 
NewOldSpaceTaggedArray(uint32_t length,JSTaggedValue initVal)3996 JSHandle<TaggedArray> ObjectFactory::NewOldSpaceTaggedArray(uint32_t length, JSTaggedValue initVal)
3997 {
3998     return NewTaggedArray(length, initVal, MemSpaceType::OLD_SPACE);
3999 }
4000 
NewJSStableArrayWithElements(const JSHandle<TaggedArray> & elements)4001 JSHandle<JSArray> ObjectFactory::NewJSStableArrayWithElements(const JSHandle<TaggedArray> &elements)
4002 {
4003     JSHandle<JSHClass> cls(thread_,
4004                            JSHandle<JSFunction>::Cast(vm_->GetGlobalEnv()->GetArrayFunction())->GetProtoOrHClass());
4005     JSHandle<JSArray> array = JSHandle<JSArray>::Cast(NewJSObject(cls));
4006     array->SetElements(thread_, elements);
4007 
4008     array->SetLength(thread_, JSTaggedValue(elements->GetLength()));
4009     auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
4010     array->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
4011     return array;
4012 }
4013 
NewJSAsyncGeneratorFunction(const JSHandle<Method> & method)4014 JSHandle<JSFunction> ObjectFactory::NewJSAsyncGeneratorFunction(const JSHandle<Method> &method)
4015 {
4016     NewObjectHook();
4017     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
4018 
4019     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetAsyncGeneratorFunctionClass());
4020     JSHandle<JSFunction> asyncGeneratorFunc = JSHandle<JSFunction>::Cast(NewJSObject(hclass));
4021     JSFunction::InitializeJSFunction(thread_, asyncGeneratorFunc, FunctionKind::ASYNC_GENERATOR_FUNCTION);
4022     asyncGeneratorFunc->SetMethod(thread_, method);
4023     return asyncGeneratorFunc;
4024 }
4025 
NewAsyncGeneratorRequest()4026 JSHandle<AsyncGeneratorRequest> ObjectFactory::NewAsyncGeneratorRequest()
4027 {
4028     NewObjectHook();
4029     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4030         JSHClass::Cast(thread_->GlobalConstants()->GetAsyncGeneratorRequestRecordClass().GetTaggedObject()));
4031     JSHandle<AsyncGeneratorRequest> obj(thread_, header);
4032     obj->SetCompletion(thread_, JSTaggedValue::Undefined());
4033     obj->SetCapability(thread_, JSTaggedValue::Undefined());
4034     return obj;
4035 }
4036 
NewAsyncIteratorRecord(const JSHandle<JSTaggedValue> & itor,const JSHandle<JSTaggedValue> & next,bool done)4037 JSHandle<AsyncIteratorRecord> ObjectFactory::NewAsyncIteratorRecord(const JSHandle<JSTaggedValue> &itor,
4038                                                                     const JSHandle<JSTaggedValue> &next, bool done)
4039 {
4040     NewObjectHook();
4041     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4042         JSHClass::Cast(thread_->GlobalConstants()->GetAsyncIteratorRecordClass().GetTaggedObject()));
4043     JSHandle<AsyncIteratorRecord> obj(thread_, header);
4044     obj->SetIterator(thread_, itor.GetTaggedValue());
4045     obj->SetNextMethod(thread_, next.GetTaggedValue());
4046     obj->SetDone(done);
4047     return obj;
4048 }
4049 
NewAOTLiteralInfo(uint32_t length,JSTaggedValue initVal)4050 JSHandle<AOTLiteralInfo> ObjectFactory::NewAOTLiteralInfo(uint32_t length, JSTaggedValue initVal)
4051 {
4052     NewObjectHook();
4053     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
4054     auto header = heap_->AllocateYoungOrHugeObject(
4055         JSHClass::Cast(thread_->GlobalConstants()->GetAOTLiteralInfoClass().GetTaggedObject()), size);
4056 
4057     JSHandle<AOTLiteralInfo> aotLiteralInfo(thread_, header);
4058     aotLiteralInfo->InitializeWithSpecialValue(initVal, length);
4059     return aotLiteralInfo;
4060 }
4061 
NewClassLiteral()4062 JSHandle<ClassLiteral> ObjectFactory::NewClassLiteral()
4063 {
4064     NewObjectHook();
4065 
4066     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
4067         JSHClass::Cast(thread_->GlobalConstants()->GetClassLiteralClass().GetTaggedObject()));
4068     JSHandle<TaggedArray> emptyArray = EmptyArray();
4069 
4070     JSHandle<ClassLiteral> classLiteral(thread_, header);
4071     classLiteral->SetArray(thread_, emptyArray);
4072     classLiteral->SetIsAOTUsed(false);
4073 
4074     return classLiteral;
4075 }
4076 }  // namespace panda::ecmascript
4077