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