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