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