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