• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "ecma_string_table.h"
17 #include "ecma_vm.h"
18 #include "ecmascript/accessor_data.h"
19 #include "ecmascript/base/error_helper.h"
20 #include "ecmascript/builtins.h"
21 #include "ecmascript/builtins/builtins_errors.h"
22 #include "ecmascript/builtins/builtins_global.h"
23 #include "ecmascript/class_info_extractor.h"
24 #include "ecmascript/jspandafile/program_object.h"
25 #include "ecmascript/ecma_macros.h"
26 #include "ecmascript/ecma_module.h"
27 #include "ecmascript/free_object.h"
28 #include "ecmascript/global_env.h"
29 #include "ecmascript/global_env_constants-inl.h"
30 #include "ecmascript/global_env_constants.h"
31 #include "ecmascript/ic/ic_handler.h"
32 #include "ecmascript/ic/profile_type_info.h"
33 #include "ecmascript/ic/property_box.h"
34 #include "ecmascript/ic/proto_change_details.h"
35 #include "ecmascript/internal_call_params.h"
36 #include "ecmascript/interpreter/frame_handler.h"
37 #include "ecmascript/jobs/micro_job_queue.h"
38 #include "ecmascript/jobs/pending_job.h"
39 #include "ecmascript/js_api_tree_map.h"
40 #include "ecmascript/js_api_tree_map_iterator.h"
41 #include "ecmascript/js_api_tree_set.h"
42 #include "ecmascript/js_api_tree_set_iterator.h"
43 #include "ecmascript/js_arguments.h"
44 #include "ecmascript/js_array.h"
45 #include "ecmascript/js_array_iterator.h"
46 #include "ecmascript/js_arraybuffer.h"
47 #include "ecmascript/js_api_arraylist.h"
48 #include "ecmascript/js_api_arraylist_iterator.h"
49 #include "ecmascript/js_async_function.h"
50 #include "ecmascript/js_bigint.h"
51 #include "ecmascript/js_dataview.h"
52 #include "ecmascript/js_date.h"
53 #include "ecmascript/js_for_in_iterator.h"
54 #include "ecmascript/js_generator_object.h"
55 #include "ecmascript/js_hclass-inl.h"
56 #include "ecmascript/js_hclass.h"
57 #include "ecmascript/js_iterator.h"
58 #include "ecmascript/js_map.h"
59 #include "ecmascript/js_map_iterator.h"
60 #include "ecmascript/js_object-inl.h"
61 #include "ecmascript/js_primitive_ref.h"
62 #include "ecmascript/js_promise.h"
63 #include "ecmascript/js_proxy.h"
64 #include "ecmascript/js_realm.h"
65 #include "ecmascript/js_regexp.h"
66 #include "ecmascript/js_set.h"
67 #include "ecmascript/js_set_iterator.h"
68 #include "ecmascript/js_string_iterator.h"
69 #include "ecmascript/js_symbol.h"
70 #include "ecmascript/js_tagged_value-inl.h"
71 #include "ecmascript/js_thread.h"
72 #include "ecmascript/js_typed_array.h"
73 #include "ecmascript/js_weak_container.h"
74 #include "ecmascript/layout_info-inl.h"
75 #include "ecmascript/linked_hash_table-inl.h"
76 #include "ecmascript/mem/heap-inl.h"
77 #include "ecmascript/mem/space.h"
78 #include "ecmascript/record.h"
79 #include "ecmascript/symbol_table-inl.h"
80 #include "ecmascript/tagged_tree-inl.h"
81 #include "ecmascript/template_map.h"
82 #include "ecmascript/template_map.h"
83 #include "ecmascript/ts_types/ts_obj_layout_info-inl.h"
84 #include "ecmascript/ts_types/ts_type.h"
85 #include "ecmascript/ts_types/ts_type_table.h"
86 
87 
88 namespace panda::ecmascript {
89 using Error = builtins::BuiltinsError;
90 using RangeError = builtins::BuiltinsRangeError;
91 using ReferenceError = builtins::BuiltinsReferenceError;
92 using TypeError = builtins::BuiltinsTypeError;
93 using URIError = builtins::BuiltinsURIError;
94 using SyntaxError = builtins::BuiltinsSyntaxError;
95 using EvalError = builtins::BuiltinsEvalError;
96 using ErrorType = base::ErrorType;
97 using ErrorHelper = base::ErrorHelper;
98 
ObjectFactory(JSThread * thread,Heap * heap)99 ObjectFactory::ObjectFactory(JSThread *thread, Heap *heap)
100     : thread_(thread), vm_(thread->GetEcmaVM()), heap_(heap)
101 {
102 }
103 
NewEcmaDynClassClass(JSHClass * hclass,uint32_t size,JSType type)104 JSHandle<JSHClass> ObjectFactory::NewEcmaDynClassClass(JSHClass *hclass, uint32_t size, JSType type)
105 {
106     NewObjectHook();
107     uint32_t classSize = JSHClass::SIZE;
108     auto *newClass = static_cast<JSHClass *>(heap_->AllocateDynClassClass(hclass, classSize));
109     newClass->Initialize(thread_, size, type, 0);
110 
111     return JSHandle<JSHClass>(thread_, newClass);
112 }
113 
NewEcmaDynClass(JSHClass * hclass,uint32_t size,JSType type,uint32_t inlinedProps)114 JSHandle<JSHClass> ObjectFactory::NewEcmaDynClass(JSHClass *hclass, uint32_t size, JSType type, uint32_t inlinedProps)
115 {
116     NewObjectHook();
117     uint32_t classSize = JSHClass::SIZE;
118     auto *newClass = static_cast<JSHClass *>(heap_->AllocateNonMovableOrHugeObject(hclass, classSize));
119     newClass->Initialize(thread_, size, type, inlinedProps);
120 
121     return JSHandle<JSHClass>(thread_, newClass);
122 }
123 
NewEcmaDynClass(uint32_t size,JSType type,uint32_t inlinedProps)124 JSHandle<JSHClass> ObjectFactory::NewEcmaDynClass(uint32_t size, JSType type, uint32_t inlinedProps)
125 {
126     return NewEcmaDynClass(JSHClass::Cast(thread_->GlobalConstants()->GetHClassClass().GetTaggedObject()),
127                            size, type, inlinedProps);
128 }
129 
InitObjectFields(const TaggedObject * object)130 void ObjectFactory::InitObjectFields(const TaggedObject *object)
131 {
132     auto *klass = object->GetClass();
133     auto objBodySize = klass->GetObjectSize() - TaggedObject::TaggedObjectSize();
134     ASSERT(objBodySize % JSTaggedValue::TaggedTypeSize() == 0);
135     int numOfFields = static_cast<int>(objBodySize / JSTaggedValue::TaggedTypeSize());
136     size_t addr = reinterpret_cast<uintptr_t>(object) + TaggedObject::TaggedObjectSize();
137     for (int i = 0; i < numOfFields; i++) {
138         auto *fieldAddr = reinterpret_cast<JSTaggedType *>(addr + i * JSTaggedValue::TaggedTypeSize());
139         *fieldAddr = JSTaggedValue::Undefined().GetRawData();
140     }
141 }
142 
NewJSArrayBufferData(const JSHandle<JSArrayBuffer> & array,int32_t length)143 void ObjectFactory::NewJSArrayBufferData(const JSHandle<JSArrayBuffer> &array, int32_t length)
144 {
145     if (length == 0) {
146         return;
147     }
148 
149     JSTaggedValue data = array->GetArrayBufferData();
150     if (data != JSTaggedValue::Undefined()) {
151         auto *pointer = JSNativePointer::Cast(data.GetTaggedObject());
152         auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(length * sizeof(uint8_t));
153         if (memset_s(newData, length, 0, length) != EOK) {
154             LOG_ECMA(FATAL) << "memset_s failed";
155             UNREACHABLE();
156         }
157         pointer->ResetExternalPointer(newData);
158         return;
159     }
160 
161     auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(length * sizeof(uint8_t));
162     if (memset_s(newData, length, 0, length) != EOK) {
163         LOG_ECMA(FATAL) << "memset_s failed";
164         UNREACHABLE();
165     }
166     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newData, NativeAreaAllocator::FreeBufferFunc,
167                                                            vm_->GetNativeAreaAllocator());
168     array->SetArrayBufferData(thread_, pointer.GetTaggedValue());
169     vm_->PushToArrayDataList(*pointer);
170 }
171 
NewJSArrayBuffer(int32_t length)172 JSHandle<JSArrayBuffer> ObjectFactory::NewJSArrayBuffer(int32_t length)
173 {
174     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
175 
176     JSHandle<JSFunction> constructor(env->GetArrayBufferFunction());
177     JSHandle<JSTaggedValue> newTarget(constructor);
178     JSHandle<JSArrayBuffer> arrayBuffer(NewJSObjectByConstructor(constructor, newTarget));
179     arrayBuffer->SetArrayBufferByteLength(length);
180     if (length > 0) {
181         auto newData = vm_->GetNativeAreaAllocator()->AllocateBuffer(length);
182         if (memset_s(newData, length, 0, length) != EOK) {
183             LOG_ECMA(FATAL) << "memset_s failed";
184             UNREACHABLE();
185         }
186         JSHandle<JSNativePointer> pointer = NewJSNativePointer(newData, NativeAreaAllocator::FreeBufferFunc,
187                                                                vm_->GetNativeAreaAllocator());
188         arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue());
189         arrayBuffer->ClearBitField();
190         vm_->PushToArrayDataList(*pointer);
191     }
192     return arrayBuffer;
193 }
194 
NewJSArrayBuffer(void * buffer,int32_t length,const DeleteEntryPoint & deleter,void * data,bool share)195 JSHandle<JSArrayBuffer> ObjectFactory::NewJSArrayBuffer(void *buffer, int32_t length, const DeleteEntryPoint &deleter,
196                                                         void *data, bool share)
197 {
198     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
199 
200     JSHandle<JSFunction> constructor(env->GetArrayBufferFunction());
201     JSHandle<JSTaggedValue> newTarget(constructor);
202     JSHandle<JSArrayBuffer> arrayBuffer(NewJSObjectByConstructor(constructor, newTarget));
203     length = buffer == nullptr ? 0 : length;
204     arrayBuffer->SetArrayBufferByteLength(length);
205     if (length > 0) {
206         JSHandle<JSNativePointer> pointer = NewJSNativePointer(buffer, deleter, data);
207         arrayBuffer->SetArrayBufferData(thread_, pointer.GetTaggedValue());
208         arrayBuffer->SetShared(share);
209         vm_->PushToArrayDataList(*pointer);
210     }
211     return arrayBuffer;
212 }
213 
NewJSDataView(JSHandle<JSArrayBuffer> buffer,uint32_t offset,uint32_t length)214 JSHandle<JSDataView> ObjectFactory::NewJSDataView(JSHandle<JSArrayBuffer> buffer, uint32_t offset, uint32_t length)
215 {
216     uint32_t arrayLength = buffer->GetArrayBufferByteLength();
217     if (arrayLength - offset < length) {
218         THROW_TYPE_ERROR_AND_RETURN(thread_, "offset or length error",
219                                     JSHandle<JSDataView>(thread_, JSTaggedValue::Undefined()));
220     }
221     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
222 
223     JSHandle<JSFunction> constructor(env->GetDataViewFunction());
224     JSHandle<JSTaggedValue> newTarget(constructor);
225     JSHandle<JSDataView> arrayBuffer(NewJSObjectByConstructor(constructor, newTarget));
226     arrayBuffer->SetDataView(thread_, JSTaggedValue::True());
227     arrayBuffer->SetViewedArrayBuffer(thread_, buffer.GetTaggedValue());
228     arrayBuffer->SetByteLength(length);
229     arrayBuffer->SetByteOffset(offset);
230     return arrayBuffer;
231 }
232 
NewJSRegExpByteCodeData(const JSHandle<JSRegExp> & regexp,void * buffer,size_t size)233 void ObjectFactory::NewJSRegExpByteCodeData(const JSHandle<JSRegExp> &regexp, void *buffer, size_t size)
234 {
235     if (buffer == nullptr) {
236         return;
237     }
238 
239     auto newBuffer = vm_->GetNativeAreaAllocator()->AllocateBuffer(size);
240     if (memcpy_s(newBuffer, size, buffer, size) != EOK) {
241         LOG_ECMA(FATAL) << "memcpy_s failed";
242         UNREACHABLE();
243     }
244     JSTaggedValue data = regexp->GetByteCodeBuffer();
245     if (data != JSTaggedValue::Undefined()) {
246         JSNativePointer *native = JSNativePointer::Cast(data.GetTaggedObject());
247         native->ResetExternalPointer(newBuffer);
248         return;
249     }
250     JSHandle<JSNativePointer> pointer = NewJSNativePointer(newBuffer, NativeAreaAllocator::FreeBufferFunc,
251                                                            vm_->GetNativeAreaAllocator());
252     regexp->SetByteCodeBuffer(thread_, pointer.GetTaggedValue());
253     regexp->SetLength(static_cast<uint32_t>(size));
254 
255     // push uint8_t* to ecma array_data_list
256     vm_->PushToArrayDataList(*pointer);
257 }
258 
NewEcmaDynClass(uint32_t size,JSType type,const JSHandle<JSTaggedValue> & prototype)259 JSHandle<JSHClass> ObjectFactory::NewEcmaDynClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype)
260 {
261     JSHandle<JSHClass> newClass = NewEcmaDynClass(size, type);
262     newClass->SetPrototype(thread_, prototype.GetTaggedValue());
263     return newClass;
264 }
265 
NewJSObject(const JSHandle<JSHClass> & jshclass)266 JSHandle<JSObject> ObjectFactory::NewJSObject(const JSHandle<JSHClass> &jshclass)
267 {
268     JSHandle<JSObject> obj(thread_, JSObject::Cast(NewDynObject(jshclass)));
269     JSHandle<TaggedArray> emptyArray = EmptyArray();
270     obj->InitializeHash();
271     obj->SetElements(thread_, emptyArray, SKIP_BARRIER);
272     obj->SetProperties(thread_, emptyArray, SKIP_BARRIER);
273     return obj;
274 }
275 
CloneProperties(const JSHandle<TaggedArray> & old)276 JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray> &old)
277 {
278     uint32_t newLength = old->GetLength();
279     if (newLength == 0) {
280         return EmptyArray();
281     }
282     NewObjectHook();
283     auto klass = old->GetClass();
284     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
285     auto header = heap_->AllocateYoungOrHugeObject(klass, size);
286     JSHandle<TaggedArray> newArray(thread_, header);
287     newArray->SetLength(newLength);
288 
289     for (uint32_t i = 0; i < newLength; i++) {
290         JSTaggedValue value = old->Get(i);
291         newArray->Set(thread_, i, value);
292     }
293     return newArray;
294 }
295 
CloneObjectLiteral(JSHandle<JSObject> object)296 JSHandle<JSObject> ObjectFactory::CloneObjectLiteral(JSHandle<JSObject> object)
297 {
298     NewObjectHook();
299     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
300 
301     JSHandle<JSObject> cloneObject = NewJSObject(klass);
302 
303     JSHandle<TaggedArray> elements(thread_, object->GetElements());
304     auto newElements = CloneProperties(elements);
305     cloneObject->SetElements(thread_, newElements.GetTaggedValue());
306 
307     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
308     auto newProperties = CloneProperties(properties);
309     cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
310 
311     for (uint32_t i = 0; i < klass->GetInlinedProperties(); i++) {
312         cloneObject->SetPropertyInlinedProps(thread_, i, object->GetPropertyInlinedProps(i));
313     }
314     return cloneObject;
315 }
316 
CloneArrayLiteral(JSHandle<JSArray> object)317 JSHandle<JSArray> ObjectFactory::CloneArrayLiteral(JSHandle<JSArray> object)
318 {
319     NewObjectHook();
320     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
321 
322     JSHandle<JSArray> cloneObject(NewJSObject(klass));
323     cloneObject->SetArrayLength(thread_, object->GetArrayLength());
324 
325     JSHandle<TaggedArray> elements(thread_, object->GetElements());
326     auto newElements = CopyArray(elements, elements->GetLength(), elements->GetLength());
327     cloneObject->SetElements(thread_, newElements.GetTaggedValue());
328 
329     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
330     auto newProperties = CopyArray(properties, properties->GetLength(), properties->GetLength());
331     cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
332 
333     for (uint32_t i = 0; i < klass->GetInlinedProperties(); i++) {
334         cloneObject->SetPropertyInlinedProps(thread_, i, object->GetPropertyInlinedProps(i));
335     }
336     return cloneObject;
337 }
338 
CloneProperties(const JSHandle<TaggedArray> & old,const JSHandle<JSTaggedValue> & env,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & constpool)339 JSHandle<TaggedArray> ObjectFactory::CloneProperties(const JSHandle<TaggedArray> &old,
340                                                      const JSHandle<JSTaggedValue> &env, const JSHandle<JSObject> &obj,
341                                                      const JSHandle<JSTaggedValue> &constpool)
342 {
343     uint32_t newLength = old->GetLength();
344     if (newLength == 0) {
345         return EmptyArray();
346     }
347     NewObjectHook();
348     auto klass = old->GetClass();
349     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
350     auto header = heap_->AllocateYoungOrHugeObject(klass, size);
351     JSHandle<TaggedArray> newArray(thread_, header);
352     newArray->SetLength(newLength);
353 
354     for (uint32_t i = 0; i < newLength; i++) {
355         JSTaggedValue value = old->Get(i);
356         if (!value.IsJSFunction()) {
357             newArray->Set(thread_, i, value);
358         } else {
359             JSHandle<JSFunction> valueHandle(thread_, value);
360             JSHandle<JSFunction> newFunc = CloneJSFuction(valueHandle, valueHandle->GetFunctionKind());
361             newFunc->SetLexicalEnv(thread_, env);
362             newFunc->SetHomeObject(thread_, obj);
363             newFunc->SetConstantPool(thread_, constpool);
364             newArray->Set(thread_, i, newFunc);
365         }
366     }
367     return newArray;
368 }
369 
CloneObjectLiteral(JSHandle<JSObject> object,const JSHandle<JSTaggedValue> & env,const JSHandle<JSTaggedValue> & constpool,bool canShareHClass)370 JSHandle<JSObject> ObjectFactory::CloneObjectLiteral(JSHandle<JSObject> object, const JSHandle<JSTaggedValue> &env,
371                                                      const JSHandle<JSTaggedValue> &constpool, bool canShareHClass)
372 {
373     NewObjectHook();
374     auto klass = JSHandle<JSHClass>(thread_, object->GetClass());
375 
376     if (!canShareHClass) {
377         klass = JSHClass::Clone(thread_, klass);
378     }
379 
380     JSHandle<JSObject> cloneObject = NewJSObject(klass);
381 
382     JSHandle<TaggedArray> elements(thread_, object->GetElements());
383     auto newElements = CloneProperties(elements, env, cloneObject, constpool);
384     cloneObject->SetElements(thread_, newElements.GetTaggedValue());
385 
386     JSHandle<TaggedArray> properties(thread_, object->GetProperties());
387     auto newProperties = CloneProperties(properties, env, cloneObject, constpool);
388     cloneObject->SetProperties(thread_, newProperties.GetTaggedValue());
389 
390     for (uint32_t i = 0; i < klass->GetInlinedProperties(); i++) {
391         JSTaggedValue value = object->GetPropertyInlinedProps(i);
392         if (!value.IsJSFunction()) {
393             cloneObject->SetPropertyInlinedProps(thread_, i, value);
394         } else {
395             JSHandle<JSFunction> valueHandle(thread_, value);
396             JSHandle<JSFunction> newFunc = CloneJSFuction(valueHandle, valueHandle->GetFunctionKind());
397             newFunc->SetLexicalEnv(thread_, env);
398             newFunc->SetHomeObject(thread_, cloneObject);
399             newFunc->SetConstantPool(thread_, constpool);
400             cloneObject->SetPropertyInlinedProps(thread_, i, newFunc.GetTaggedValue());
401         }
402     }
403     return cloneObject;
404 }
405 
CloneJSFuction(JSHandle<JSFunction> obj,FunctionKind kind)406 JSHandle<JSFunction> ObjectFactory::CloneJSFuction(JSHandle<JSFunction> obj, FunctionKind kind)
407 {
408     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
409     JSHandle<JSHClass> jshclass(thread_, obj->GetJSHClass());
410     JSHandle<JSFunction> cloneFunc = NewJSFunctionByDynClass(obj->GetCallTarget(), jshclass, kind);
411     if (kind == FunctionKind::GENERATOR_FUNCTION) {
412         JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
413         JSHandle<JSObject> initialGeneratorFuncPrototype =
414             NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
415         JSObject::SetPrototype(thread_, initialGeneratorFuncPrototype, env->GetGeneratorPrototype());
416         cloneFunc->SetProtoOrDynClass(thread_, initialGeneratorFuncPrototype);
417     }
418 
419     JSTaggedValue length = obj->GetPropertyInlinedProps(JSFunction::LENGTH_INLINE_PROPERTY_INDEX);
420     cloneFunc->SetPropertyInlinedProps(thread_, JSFunction::LENGTH_INLINE_PROPERTY_INDEX, length);
421     return cloneFunc;
422 }
423 
CloneClassCtor(JSHandle<JSFunction> ctor,const JSHandle<JSTaggedValue> & lexenv,bool canShareHClass)424 JSHandle<JSFunction> ObjectFactory::CloneClassCtor(JSHandle<JSFunction> ctor, const JSHandle<JSTaggedValue> &lexenv,
425                                                    bool canShareHClass)
426 {
427     NewObjectHook();
428     JSHandle<JSTaggedValue> constpool(thread_, ctor->GetConstantPool());
429     JSHandle<JSHClass> hclass(thread_, ctor->GetClass());
430 
431     if (!canShareHClass) {
432         hclass = JSHClass::Clone(thread_, hclass);
433     }
434 
435     FunctionKind kind = ctor->GetFunctionKind();
436     ASSERT_PRINT(kind == FunctionKind::CLASS_CONSTRUCTOR || kind == FunctionKind::DERIVED_CONSTRUCTOR,
437                  "cloned function is not class");
438     JSHandle<JSFunction> cloneCtor = NewJSFunctionByDynClass(ctor->GetCallTarget(), hclass, kind);
439 
440     for (uint32_t i = 0; i < hclass->GetInlinedProperties(); i++) {
441         JSTaggedValue value = ctor->GetPropertyInlinedProps(i);
442         if (!value.IsJSFunction()) {
443             cloneCtor->SetPropertyInlinedProps(thread_, i, value);
444         } else {
445             JSHandle<JSFunction> valueHandle(thread_, value);
446             JSHandle<JSFunction> newFunc = CloneJSFuction(valueHandle, valueHandle->GetFunctionKind());
447             newFunc->SetLexicalEnv(thread_, lexenv);
448             newFunc->SetHomeObject(thread_, cloneCtor);
449             newFunc->SetConstantPool(thread_, constpool);
450             cloneCtor->SetPropertyInlinedProps(thread_, i, newFunc.GetTaggedValue());
451         }
452     }
453 
454     JSHandle<TaggedArray> elements(thread_, ctor->GetElements());
455     auto newElements = CloneProperties(elements, lexenv, JSHandle<JSObject>(cloneCtor), constpool);
456     cloneCtor->SetElements(thread_, newElements.GetTaggedValue());
457 
458     JSHandle<TaggedArray> properties(thread_, ctor->GetProperties());
459     auto newProperties = CloneProperties(properties, lexenv, JSHandle<JSObject>(cloneCtor), constpool);
460     cloneCtor->SetProperties(thread_, newProperties.GetTaggedValue());
461 
462     cloneCtor->SetConstantPool(thread_, constpool);
463 
464     return cloneCtor;
465 }
466 
NewNonMovableJSObject(const JSHandle<JSHClass> & jshclass)467 JSHandle<JSObject> ObjectFactory::NewNonMovableJSObject(const JSHandle<JSHClass> &jshclass)
468 {
469     JSHandle<JSObject> obj(thread_,
470                            JSObject::Cast(NewNonMovableDynObject(jshclass, jshclass->GetInlinedProperties())));
471     obj->SetElements(thread_, EmptyArray(), SKIP_BARRIER);
472     obj->SetProperties(thread_, EmptyArray(), SKIP_BARRIER);
473     return obj;
474 }
475 
NewJSPrimitiveRef(const JSHandle<JSHClass> & dynKlass,const JSHandle<JSTaggedValue> & object)476 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(const JSHandle<JSHClass> &dynKlass,
477                                                           const JSHandle<JSTaggedValue> &object)
478 {
479     JSHandle<JSPrimitiveRef> obj = JSHandle<JSPrimitiveRef>::Cast(NewJSObject(dynKlass));
480     obj->SetValue(thread_, object);
481     return obj;
482 }
483 
NewJSArray()484 JSHandle<JSArray> ObjectFactory::NewJSArray()
485 {
486     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
487     JSHandle<JSTaggedValue> function = env->GetArrayFunction();
488 
489     return JSHandle<JSArray>(NewJSObjectByConstructor(JSHandle<JSFunction>(function), function));
490 }
491 
NewJSForinIterator(const JSHandle<JSTaggedValue> & obj)492 JSHandle<JSForInIterator> ObjectFactory::NewJSForinIterator(const JSHandle<JSTaggedValue> &obj)
493 {
494     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
495     JSHandle<JSHClass> dynclass(env->GetForinIteratorClass());
496 
497     JSHandle<JSForInIterator> it = JSHandle<JSForInIterator>::Cast(NewJSObject(dynclass));
498     it->SetObject(thread_, obj);
499     it->SetVisitedKeys(thread_, env->GetEmptyTaggedQueue());
500     it->SetRemainingKeys(thread_, env->GetEmptyTaggedQueue());
501     it->ClearBitField();
502     return it;
503 }
504 
CreateJSRegExpInstanceClass(JSHandle<JSTaggedValue> proto)505 JSHandle<JSHClass> ObjectFactory::CreateJSRegExpInstanceClass(JSHandle<JSTaggedValue> proto)
506 {
507     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
508     JSHandle<JSHClass> regexpDynclass = NewEcmaDynClass(JSRegExp::SIZE, JSType::JS_REG_EXP, proto);
509 
510     uint32_t fieldOrder = 0;
511     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(1);
512     {
513         PropertyAttributes attributes = PropertyAttributes::Default(true, false, false);
514         attributes.SetIsInlinedProps(true);
515         attributes.SetRepresentation(Representation::MIXED);
516         attributes.SetOffset(fieldOrder++);
517         layoutInfoHandle->AddKey(thread_, 0, globalConst->GetLastIndexString(), attributes);
518     }
519 
520     {
521         regexpDynclass->SetLayout(thread_, layoutInfoHandle);
522         regexpDynclass->SetNumberOfProps(fieldOrder);
523     }
524 
525     return regexpDynclass;
526 }
527 
CreateJSArrayInstanceClass(JSHandle<JSTaggedValue> proto)528 JSHandle<JSHClass> ObjectFactory::CreateJSArrayInstanceClass(JSHandle<JSTaggedValue> proto)
529 {
530     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
531     JSHandle<JSHClass> arrayDynclass = NewEcmaDynClass(JSArray::SIZE, JSType::JS_ARRAY, proto);
532 
533     uint32_t fieldOrder = 0;
534     ASSERT(JSArray::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
535     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(1);
536     {
537         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(true, false, false);
538         attributes.SetIsInlinedProps(true);
539         attributes.SetRepresentation(Representation::MIXED);
540         attributes.SetOffset(fieldOrder++);
541         layoutInfoHandle->AddKey(thread_, 0, globalConst->GetLengthString(), attributes);
542     }
543 
544     {
545         arrayDynclass->SetLayout(thread_, layoutInfoHandle);
546         arrayDynclass->SetNumberOfProps(fieldOrder);
547     }
548     arrayDynclass->SetIsStableElements(true);
549     arrayDynclass->SetHasConstructor(false);
550 
551     return arrayDynclass;
552 }
553 
CreateJSArguments()554 JSHandle<JSHClass> ObjectFactory::CreateJSArguments()
555 {
556     JSHandle<GlobalEnv> env = thread_->GetEcmaVM()->GetGlobalEnv();
557     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
558     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
559 
560     JSHandle<JSHClass> argumentsDynclass = NewEcmaDynClass(JSArguments::SIZE, JSType::JS_ARGUMENTS, proto);
561 
562     uint32_t fieldOrder = 0;
563     ASSERT(JSArguments::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
564     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(JSArguments::LENGTH_OF_INLINE_PROPERTIES);
565     {
566         PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);
567         attributes.SetIsInlinedProps(true);
568         attributes.SetRepresentation(Representation::MIXED);
569         attributes.SetOffset(fieldOrder++);
570         layoutInfoHandle->AddKey(thread_, JSArguments::LENGTH_INLINE_PROPERTY_INDEX, globalConst->GetLengthString(),
571                                  attributes);
572     }
573 
574     ASSERT(JSArguments::ITERATOR_INLINE_PROPERTY_INDEX == fieldOrder);
575     {
576         PropertyAttributes attributes = PropertyAttributes::Default(true, false, true);
577         attributes.SetIsInlinedProps(true);
578         attributes.SetRepresentation(Representation::MIXED);
579         attributes.SetOffset(fieldOrder++);
580         layoutInfoHandle->AddKey(thread_, JSArguments::ITERATOR_INLINE_PROPERTY_INDEX,
581                                  env->GetIteratorSymbol().GetTaggedValue(), attributes);
582     }
583 
584     {
585         ASSERT(JSArguments::CALLER_INLINE_PROPERTY_INDEX == fieldOrder);
586         PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
587         attributes.SetIsInlinedProps(true);
588         attributes.SetIsAccessor(true);
589         attributes.SetRepresentation(Representation::MIXED);
590         attributes.SetOffset(fieldOrder++);
591         layoutInfoHandle->AddKey(thread_, JSArguments::CALLER_INLINE_PROPERTY_INDEX,
592                                  thread_->GlobalConstants()->GetHandledCallerString().GetTaggedValue(), attributes);
593     }
594 
595     {
596         ASSERT(JSArguments::CALLEE_INLINE_PROPERTY_INDEX == fieldOrder);
597         PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
598         attributes.SetIsInlinedProps(true);
599         attributes.SetIsAccessor(true);
600         attributes.SetRepresentation(Representation::MIXED);
601         attributes.SetOffset(fieldOrder++);
602         layoutInfoHandle->AddKey(thread_, JSArguments::CALLEE_INLINE_PROPERTY_INDEX,
603                                  thread_->GlobalConstants()->GetHandledCalleeString().GetTaggedValue(), attributes);
604     }
605 
606     {
607         argumentsDynclass->SetLayout(thread_, layoutInfoHandle);
608         argumentsDynclass->SetNumberOfProps(fieldOrder);
609     }
610     argumentsDynclass->SetIsStableElements(true);
611     return argumentsDynclass;
612 }
613 
NewJSArguments()614 JSHandle<JSArguments> ObjectFactory::NewJSArguments()
615 {
616     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
617     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetArgumentsClass());
618     JSHandle<JSArguments> obj = JSHandle<JSArguments>::Cast(NewJSObject(dynclass));
619     return obj;
620 }
621 
GetJSError(const ErrorType & errorType,const char * data)622 JSHandle<JSObject> ObjectFactory::GetJSError(const ErrorType &errorType, const char *data)
623 {
624     ASSERT_PRINT(errorType == ErrorType::ERROR || errorType == ErrorType::EVAL_ERROR ||
625                      errorType == ErrorType::RANGE_ERROR || errorType == ErrorType::REFERENCE_ERROR ||
626                      errorType == ErrorType::SYNTAX_ERROR || errorType == ErrorType::TYPE_ERROR ||
627                      errorType == ErrorType::URI_ERROR,
628                  "The error type is not in the valid range.");
629     if (data != nullptr) {
630         JSHandle<EcmaString> handleMsg = NewFromString(data);
631         return NewJSError(errorType, handleMsg);
632     }
633     JSHandle<EcmaString> emptyString(thread_->GlobalConstants()->GetHandledEmptyString());
634     return NewJSError(errorType, emptyString);
635 }
636 
NewJSError(const ErrorType & errorType,const JSHandle<EcmaString> & message)637 JSHandle<JSObject> ObjectFactory::NewJSError(const ErrorType &errorType, const JSHandle<EcmaString> &message)
638 {
639     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
640     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
641     JSHandle<JSTaggedValue> nativeConstructor;
642     switch (errorType) {
643         case ErrorType::RANGE_ERROR:
644             nativeConstructor = env->GetRangeErrorFunction();
645             break;
646         case ErrorType::EVAL_ERROR:
647             nativeConstructor = env->GetEvalErrorFunction();
648             break;
649         case ErrorType::REFERENCE_ERROR:
650             nativeConstructor = env->GetReferenceErrorFunction();
651             break;
652         case ErrorType::TYPE_ERROR:
653             nativeConstructor = env->GetTypeErrorFunction();
654             break;
655         case ErrorType::URI_ERROR:
656             nativeConstructor = env->GetURIErrorFunction();
657             break;
658         case ErrorType::SYNTAX_ERROR:
659             nativeConstructor = env->GetSyntaxErrorFunction();
660             break;
661         default:
662             nativeConstructor = env->GetErrorFunction();
663             break;
664     }
665     JSHandle<JSFunction> nativeFunc = JSHandle<JSFunction>::Cast(nativeConstructor);
666     JSHandle<JSTaggedValue> nativePrototype(thread_, nativeFunc->GetFunctionPrototype());
667     JSHandle<JSTaggedValue> ctorKey = globalConst->GetHandledConstructorString();
668 
669     InternalCallParams *arguments = thread_->GetInternalCallParams();
670     arguments->MakeArgv(message.GetTaggedValue());
671     JSTaggedValue obj = JSFunction::Invoke(thread_, nativePrototype, ctorKey, 1, arguments->GetArgv());
672     JSHandle<JSObject> handleNativeInstanceObj(thread_, obj);
673     return handleNativeInstanceObj;
674 }
675 
NewJSObjectByConstructor(const JSHandle<JSFunction> & constructor,const JSHandle<JSTaggedValue> & newTarget)676 JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor,
677                                                            const JSHandle<JSTaggedValue> &newTarget)
678 {
679     JSHandle<JSHClass> jshclass;
680     if (!constructor->HasFunctionPrototype() ||
681         (constructor->GetProtoOrDynClass().IsHeapObject() && constructor->GetFunctionPrototype().IsECMAObject())) {
682         jshclass = JSFunction::GetInstanceJSHClass(thread_, constructor, newTarget);
683     } else {
684         JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
685         jshclass = JSFunction::GetInstanceJSHClass(thread_, JSHandle<JSFunction>(env->GetObjectFunction()), newTarget);
686     }
687     // Check this exception elsewhere
688     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread_);
689 
690     JSHandle<JSObject> obj = NewJSObject(jshclass);
691     {
692         JSType type = jshclass->GetObjectType();
693         switch (type) {
694             case JSType::JS_OBJECT:
695             case JSType::JS_ERROR:
696             case JSType::JS_EVAL_ERROR:
697             case JSType::JS_RANGE_ERROR:
698             case JSType::JS_REFERENCE_ERROR:
699             case JSType::JS_TYPE_ERROR:
700             case JSType::JS_URI_ERROR:
701             case JSType::JS_SYNTAX_ERROR:
702             case JSType::JS_ITERATOR:
703             case JSType::JS_INTL:
704             case JSType::JS_LOCALE:
705             case JSType::JS_DATE_TIME_FORMAT:
706             case JSType::JS_NUMBER_FORMAT:
707             case JSType::JS_RELATIVE_TIME_FORMAT:
708             case JSType::JS_COLLATOR:
709             case JSType::JS_PLURAL_RULES:
710                 break;
711             case JSType::JS_ARRAY: {
712                 JSArray::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
713                 auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
714                 JSArray::Cast(*obj)->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
715                 break;
716             }
717             case JSType::JS_DATE:
718                 JSDate::Cast(*obj)->SetTimeValue(thread_, JSTaggedValue(0.0));
719                 JSDate::Cast(*obj)->SetLocalOffset(thread_, JSTaggedValue(JSDate::MAX_DOUBLE));
720                 break;
721             case JSType::JS_INT8_ARRAY:
722             case JSType::JS_UINT8_ARRAY:
723             case JSType::JS_UINT8_CLAMPED_ARRAY:
724             case JSType::JS_INT16_ARRAY:
725             case JSType::JS_UINT16_ARRAY:
726             case JSType::JS_INT32_ARRAY:
727             case JSType::JS_UINT32_ARRAY:
728             case JSType::JS_FLOAT32_ARRAY:
729             case JSType::JS_FLOAT64_ARRAY:
730                 JSTypedArray::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined());
731                 JSTypedArray::Cast(*obj)->SetTypedArrayName(thread_, JSTaggedValue::Undefined());
732                 JSTypedArray::Cast(*obj)->SetByteLength(thread_, JSTaggedValue(0));
733                 JSTypedArray::Cast(*obj)->SetByteOffset(thread_, JSTaggedValue(0));
734                 JSTypedArray::Cast(*obj)->SetArrayLength(thread_, JSTaggedValue(0));
735                 break;
736             case JSType::JS_REG_EXP:
737                 JSRegExp::Cast(*obj)->SetByteCodeBuffer(thread_, JSTaggedValue::Undefined());
738                 JSRegExp::Cast(*obj)->SetOriginalSource(thread_, JSTaggedValue::Undefined());
739                 JSRegExp::Cast(*obj)->SetOriginalFlags(thread_, JSTaggedValue(0));
740                 JSRegExp::Cast(*obj)->SetLength(0);
741                 break;
742             case JSType::JS_PRIMITIVE_REF:
743                 JSPrimitiveRef::Cast(*obj)->SetValue(thread_, JSTaggedValue::Undefined());
744                 break;
745             case JSType::JS_SET:
746                 JSSet::Cast(*obj)->SetLinkedSet(thread_, JSTaggedValue::Undefined());
747                 break;
748             case JSType::JS_MAP:
749                 JSMap::Cast(*obj)->SetLinkedMap(thread_, JSTaggedValue::Undefined());
750                 break;
751             case JSType::JS_WEAK_MAP:
752                 JSWeakMap::Cast(*obj)->SetLinkedMap(thread_, JSTaggedValue::Undefined());
753                 break;
754             case JSType::JS_WEAK_SET:
755                 JSWeakSet::Cast(*obj)->SetLinkedSet(thread_, JSTaggedValue::Undefined());
756                 break;
757             case JSType::JS_GENERATOR_OBJECT:
758                 JSGeneratorObject::Cast(*obj)->SetGeneratorContext(thread_, JSTaggedValue::Undefined());
759                 JSGeneratorObject::Cast(*obj)->SetResumeResult(thread_, JSTaggedValue::Undefined());
760                 JSGeneratorObject::Cast(*obj)->SetGeneratorState(JSGeneratorState::UNDEFINED);
761                 JSGeneratorObject::Cast(*obj)->SetResumeMode(GeneratorResumeMode::UNDEFINED);
762                 break;
763             case JSType::JS_STRING_ITERATOR:
764                 JSStringIterator::Cast(*obj)->SetStringIteratorNextIndex(0);
765                 JSStringIterator::Cast(*obj)->SetIteratedString(thread_, JSTaggedValue::Undefined());
766                 break;
767             case JSType::JS_ARRAY_BUFFER:
768                 JSArrayBuffer::Cast(*obj)->SetArrayBufferData(thread_, JSTaggedValue::Undefined());
769                 JSArrayBuffer::Cast(*obj)->SetArrayBufferByteLength(0);
770                 JSArrayBuffer::Cast(*obj)->ClearBitField();
771                 break;
772             case JSType::JS_PROMISE:
773                 JSPromise::Cast(*obj)->SetPromiseState(PromiseState::PENDING);
774                 JSPromise::Cast(*obj)->SetPromiseResult(thread_, JSTaggedValue::Undefined());
775                 JSPromise::Cast(*obj)->SetPromiseRejectReactions(thread_, GetEmptyTaggedQueue().GetTaggedValue());
776                 JSPromise::Cast(*obj)->SetPromiseFulfillReactions(thread_, GetEmptyTaggedQueue().GetTaggedValue());
777 
778                 JSPromise::Cast(*obj)->SetPromiseIsHandled(false);
779                 break;
780             case JSType::JS_DATA_VIEW:
781                 JSDataView::Cast(*obj)->SetDataView(thread_, JSTaggedValue(false));
782                 JSDataView::Cast(*obj)->SetViewedArrayBuffer(thread_, JSTaggedValue::Undefined());
783                 JSDataView::Cast(*obj)->SetByteLength(0);
784                 JSDataView::Cast(*obj)->SetByteOffset(0);
785                 break;
786             // non ECMA standard jsapi container
787             case JSType::JS_API_ARRAY_LIST:
788                 JSAPIArrayList::Cast(*obj)->SetLength(thread_, JSTaggedValue(0));
789                 break;
790             case JSType::JS_API_TREE_MAP:
791                 JSAPITreeMap::Cast(*obj)->SetTreeMap(thread_, JSTaggedValue::Undefined());
792                 break;
793             case JSType::JS_API_TREE_SET:
794                 JSAPITreeSet::Cast(*obj)->SetTreeSet(thread_, JSTaggedValue::Undefined());
795                 break;
796             case JSType::JS_FUNCTION:
797             case JSType::JS_GENERATOR_FUNCTION:
798             case JSType::JS_FORIN_ITERATOR:
799             case JSType::JS_MAP_ITERATOR:
800             case JSType::JS_SET_ITERATOR:
801             case JSType::JS_API_ARRAYLIST_ITERATOR:
802             case JSType::JS_API_TREEMAP_ITERATOR:
803             case JSType::JS_API_TREESET_ITERATOR:
804             case JSType::JS_ARRAY_ITERATOR:
805             default:
806                 UNREACHABLE();
807         }
808     }
809     return obj;
810 }
811 
FillFreeObject(uintptr_t address,size_t size,RemoveSlots removeSlots)812 FreeObject *ObjectFactory::FillFreeObject(uintptr_t address, size_t size, RemoveSlots removeSlots)
813 {
814     FreeObject *object = nullptr;
815     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
816     if (size >= FreeObject::SIZE_OFFSET && size < FreeObject::SIZE) {
817         object = reinterpret_cast<FreeObject *>(address);
818         object->SetClassWithoutBarrier(JSHClass::Cast(globalConst->GetFreeObjectWithOneFieldClass().GetTaggedObject()));
819         object->SetNext(nullptr);
820     } else if (size >= FreeObject::SIZE) {
821         object = reinterpret_cast<FreeObject *>(address);
822         bool firstHClassLoaded = false;
823         if (!firstHClassLoaded && !globalConst->GetFreeObjectWithTwoFieldClass().GetRawData()) {
824             object->SetClassWithoutBarrier(nullptr);
825             firstHClassLoaded = true;
826         } else {
827             object->SetClassWithoutBarrier(
828                 JSHClass::Cast(globalConst->GetFreeObjectWithTwoFieldClass().GetTaggedObject()));
829         }
830         object->SetAvailable(size);
831         object->SetNext(nullptr);
832     } else if (size == FreeObject::NEXT_OFFSET) {
833         object = reinterpret_cast<FreeObject *>(address);
834         object->SetClassWithoutBarrier(
835             JSHClass::Cast(globalConst->GetFreeObjectWithNoneFieldClass().GetTaggedObject()));
836     } else {
837         LOG_ECMA(DEBUG) << "Fill free object size is smaller";
838     }
839 
840     if (removeSlots == RemoveSlots::YES) {
841         Region *region = Region::ObjectAddressToRange(object);
842         if (!region->InYoungGeneration()) {
843             heap_->ClearSlotsRange(region, address, address + size);
844         }
845     }
846     return object;
847 }
848 
NewDynObject(const JSHandle<JSHClass> & dynclass)849 TaggedObject *ObjectFactory::NewDynObject(const JSHandle<JSHClass> &dynclass)
850 {
851     NewObjectHook();
852     TaggedObject *header = heap_->AllocateYoungOrHugeObject(*dynclass);
853     uint32_t inobjPropCount = dynclass->GetInlinedProperties();
854     if (inobjPropCount > 0) {
855         InitializeExtraProperties(dynclass, header, inobjPropCount);
856     }
857     return header;
858 }
859 
NewNonMovableDynObject(const JSHandle<JSHClass> & dynclass,int inobjPropCount)860 TaggedObject *ObjectFactory::NewNonMovableDynObject(const JSHandle<JSHClass> &dynclass, int inobjPropCount)
861 {
862     NewObjectHook();
863     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(*dynclass);
864     if (inobjPropCount > 0) {
865         InitializeExtraProperties(dynclass, header, inobjPropCount);
866     }
867     return header;
868 }
869 
InitializeExtraProperties(const JSHandle<JSHClass> & dynclass,TaggedObject * obj,int inobjPropCount)870 void ObjectFactory::InitializeExtraProperties(const JSHandle<JSHClass> &dynclass, TaggedObject *obj, int inobjPropCount)
871 {
872     ASSERT(inobjPropCount * JSTaggedValue::TaggedTypeSize() < dynclass->GetObjectSize());
873     auto paddr = reinterpret_cast<uintptr_t>(obj) + dynclass->GetObjectSize();
874     JSTaggedType initVal = JSTaggedValue::Undefined().GetRawData();
875     for (int i = 0; i < inobjPropCount; ++i) {
876         paddr -= JSTaggedValue::TaggedTypeSize();
877         *reinterpret_cast<JSTaggedType *>(paddr) = initVal;
878     }
879 }
880 
OrdinaryNewJSObjectCreate(const JSHandle<JSTaggedValue> & proto)881 JSHandle<JSObject> ObjectFactory::OrdinaryNewJSObjectCreate(const JSHandle<JSTaggedValue> &proto)
882 {
883     JSHandle<JSTaggedValue> protoValue(proto);
884     JSHandle<JSHClass> protoDyn = NewEcmaDynClass(JSObject::SIZE, JSType::JS_OBJECT, protoValue);
885     JSHandle<JSObject> newObj = NewJSObject(protoDyn);
886     newObj->GetJSHClass()->SetExtensible(true);
887     return newObj;
888 }
889 
NewJSFunction(const JSHandle<GlobalEnv> & env,const void * nativeFunc,FunctionKind kind)890 JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc,
891                                                   FunctionKind kind)
892 {
893     JSMethod *target = vm_->GetMethodForNativeFunction(nativeFunc);
894     return NewJSFunction(env, target, kind);
895 }
896 
NewJSFunction(const JSHandle<GlobalEnv> & env,JSMethod * method,FunctionKind kind)897 JSHandle<JSFunction> ObjectFactory::NewJSFunction(const JSHandle<GlobalEnv> &env, JSMethod *method, FunctionKind kind)
898 {
899     JSHandle<JSHClass> dynclass;
900     if (kind == FunctionKind::BASE_CONSTRUCTOR) {
901         dynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithProto());
902     } else if (JSFunction::IsConstructorKind(kind)) {
903         dynclass = JSHandle<JSHClass>::Cast(env->GetConstructorFunctionClass());
904     } else {
905         dynclass = JSHandle<JSHClass>::Cast(env->GetNormalFunctionClass());
906     }
907 
908     return NewJSFunctionByDynClass(method, dynclass, kind);
909 }
910 
CreateFunctionClass(FunctionKind kind,uint32_t size,JSType type,const JSHandle<JSTaggedValue> & prototype)911 JSHandle<JSHClass> ObjectFactory::CreateFunctionClass(FunctionKind kind, uint32_t size, JSType type,
912                                                       const JSHandle<JSTaggedValue> &prototype)
913 {
914     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
915     JSHandle<JSHClass> functionClass = NewEcmaDynClass(size, type, prototype);
916     {
917         functionClass->SetCallable(true);
918         // FunctionKind = BASE_CONSTRUCTOR
919         if (JSFunction::IsConstructorKind(kind)) {
920             functionClass->SetConstructor(true);
921         }
922         functionClass->SetExtensible(true);
923     }
924 
925     uint32_t fieldOrder = 0;
926     ASSERT(JSFunction::LENGTH_INLINE_PROPERTY_INDEX == fieldOrder);
927     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(JSFunction::LENGTH_OF_INLINE_PROPERTIES);
928     {
929         PropertyAttributes attributes = PropertyAttributes::Default(false, false, true);
930         attributes.SetIsInlinedProps(true);
931         attributes.SetRepresentation(Representation::MIXED);
932         attributes.SetOffset(fieldOrder);
933         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetLengthString(), attributes);
934         fieldOrder++;
935     }
936 
937     ASSERT(JSFunction::NAME_INLINE_PROPERTY_INDEX == fieldOrder);
938     // not set name in-object property on class which may have a name() method
939     if (!JSFunction::IsClassConstructor(kind)) {
940         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, true);
941         attributes.SetIsInlinedProps(true);
942         attributes.SetRepresentation(Representation::MIXED);
943         attributes.SetOffset(fieldOrder);
944         layoutInfoHandle->AddKey(thread_, fieldOrder,
945                                  thread_->GlobalConstants()->GetHandledNameString().GetTaggedValue(), attributes);
946         fieldOrder++;
947     }
948 
949     if (JSFunction::HasPrototype(kind) && !JSFunction::IsClassConstructor(kind)) {
950         ASSERT(JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX == fieldOrder);
951         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(true, false, false);
952         attributes.SetIsInlinedProps(true);
953         attributes.SetRepresentation(Representation::MIXED);
954         attributes.SetOffset(fieldOrder);
955         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetPrototypeString(), attributes);
956         fieldOrder++;
957     } else if (JSFunction::IsClassConstructor(kind)) {
958         ASSERT(JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX == fieldOrder);
959         PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(false, false, false);
960         attributes.SetIsInlinedProps(true);
961         attributes.SetRepresentation(Representation::MIXED);
962         attributes.SetOffset(fieldOrder);
963         layoutInfoHandle->AddKey(thread_, fieldOrder, globalConst->GetPrototypeString(), attributes);
964         fieldOrder++;
965     }
966 
967     {
968         functionClass->SetLayout(thread_, layoutInfoHandle);
969         functionClass->SetNumberOfProps(fieldOrder);
970     }
971     return functionClass;
972 }
973 
NewJSFunctionByDynClass(JSMethod * method,const JSHandle<JSHClass> & clazz,FunctionKind kind)974 JSHandle<JSFunction> ObjectFactory::NewJSFunctionByDynClass(JSMethod *method, const JSHandle<JSHClass> &clazz,
975                                                             FunctionKind kind)
976 {
977     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(NewJSObject(clazz));
978     clazz->SetCallable(true);
979     clazz->SetExtensible(true);
980     JSFunction::InitializeJSFunction(thread_, function, kind);
981     function->SetCallTarget(thread_, method);
982     return function;
983 }
984 
NewJSNativeErrorFunction(const JSHandle<GlobalEnv> & env,const void * nativeFunc)985 JSHandle<JSFunction> ObjectFactory::NewJSNativeErrorFunction(const JSHandle<GlobalEnv> &env, const void *nativeFunc)
986 {
987     JSMethod *target = vm_->GetMethodForNativeFunction(nativeFunc);
988     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetNativeErrorFunctionClass());
989     return NewJSFunctionByDynClass(target, dynclass, FunctionKind::BUILTIN_CONSTRUCTOR);
990 }
991 
NewSpecificTypedArrayFunction(const JSHandle<GlobalEnv> & env,const void * nativeFunc)992 JSHandle<JSFunction> ObjectFactory::NewSpecificTypedArrayFunction(const JSHandle<GlobalEnv> &env,
993                                                                   const void *nativeFunc)
994 {
995     JSMethod *target = vm_->GetMethodForNativeFunction(nativeFunc);
996     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetSpecificTypedArrayFunctionClass());
997     return NewJSFunctionByDynClass(target, dynclass, FunctionKind::BUILTIN_CONSTRUCTOR);
998 }
999 
NewJSBoundFunction(const JSHandle<JSFunctionBase> & target,const JSHandle<JSTaggedValue> & boundThis,const JSHandle<TaggedArray> & args)1000 JSHandle<JSBoundFunction> ObjectFactory::NewJSBoundFunction(const JSHandle<JSFunctionBase> &target,
1001                                                             const JSHandle<JSTaggedValue> &boundThis,
1002                                                             const JSHandle<TaggedArray> &args)
1003 {
1004     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1005     JSHandle<JSTaggedValue> proto = env->GetFunctionPrototype();
1006     JSHandle<JSHClass> dynclass = NewEcmaDynClass(JSBoundFunction::SIZE, JSType::JS_BOUND_FUNCTION, proto);
1007 
1008     JSHandle<JSBoundFunction> bundleFunction = JSHandle<JSBoundFunction>::Cast(NewJSObject(dynclass));
1009     bundleFunction->SetBoundTarget(thread_, target);
1010     bundleFunction->SetBoundThis(thread_, boundThis);
1011     bundleFunction->SetBoundArguments(thread_, args);
1012     dynclass->SetCallable(true);
1013     if (target.GetTaggedValue().IsConstructor()) {
1014         bundleFunction->SetConstructor(true);
1015     }
1016     JSMethod *method =
1017         vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(builtins::BuiltinsGlobal::CallJsBoundFunction));
1018     bundleFunction->SetCallTarget(thread_, method);
1019     return bundleFunction;
1020 }
1021 
NewJSIntlBoundFunction(const void * nativeFunc,int functionLength)1022 JSHandle<JSIntlBoundFunction> ObjectFactory::NewJSIntlBoundFunction(const void *nativeFunc, int functionLength)
1023 {
1024     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1025     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetJSIntlBoundFunctionClass());
1026 
1027     JSHandle<JSIntlBoundFunction> intlBoundFunc = JSHandle<JSIntlBoundFunction>::Cast(NewJSObject(dynclass));
1028     JSMethod *method = vm_->GetMethodForNativeFunction(nativeFunc);
1029     intlBoundFunc->SetCallTarget(thread_, method);
1030     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(intlBoundFunc);
1031     JSFunction::InitializeJSFunction(thread_, function, FunctionKind::NORMAL_FUNCTION);
1032     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(functionLength));
1033     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1034     JSHandle<JSTaggedValue> emptyString = globalConst->GetHandledEmptyString();
1035     JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
1036     PropertyDescriptor nameDesc(thread_, emptyString, false, false, true);
1037     JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>::Cast(function), nameKey, nameDesc);
1038     return intlBoundFunc;
1039 }
1040 
NewJSProxyRevocFunction(const JSHandle<JSProxy> & proxy,const void * nativeFunc)1041 JSHandle<JSProxyRevocFunction> ObjectFactory::NewJSProxyRevocFunction(const JSHandle<JSProxy> &proxy,
1042                                                                       const void *nativeFunc)
1043 {
1044     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1045     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1046     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetProxyRevocFunctionClass());
1047 
1048     JSHandle<JSProxyRevocFunction> revocFunction = JSHandle<JSProxyRevocFunction>::Cast(NewJSObject(dynclass));
1049     revocFunction->SetRevocableProxy(thread_, proxy);
1050 
1051     JSMethod *target = vm_->GetMethodForNativeFunction(nativeFunc);
1052     revocFunction->SetCallTarget(thread_, target);
1053     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(revocFunction);
1054     JSFunction::InitializeJSFunction(thread_, function, FunctionKind::NORMAL_FUNCTION);
1055     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(0));
1056     JSHandle<JSTaggedValue> emptyString = globalConst->GetHandledEmptyString();
1057     JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
1058     PropertyDescriptor nameDesc(thread_, emptyString, false, false, true);
1059     JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>::Cast(function), nameKey, nameDesc);
1060     return revocFunction;
1061 }
1062 
NewJSAsyncAwaitStatusFunction(const void * nativeFunc)1063 JSHandle<JSAsyncAwaitStatusFunction> ObjectFactory::NewJSAsyncAwaitStatusFunction(const void *nativeFunc)
1064 {
1065     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1066     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetAsyncAwaitStatusFunctionClass());
1067 
1068     JSHandle<JSAsyncAwaitStatusFunction> awaitFunction =
1069         JSHandle<JSAsyncAwaitStatusFunction>::Cast(NewJSObject(dynclass));
1070 
1071     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(awaitFunction));
1072     JSMethod *target = vm_->GetMethodForNativeFunction(nativeFunc);
1073     awaitFunction->SetCallTarget(thread_, target);
1074     return awaitFunction;
1075 }
1076 
NewJSGeneratorFunction(JSMethod * method)1077 JSHandle<JSFunction> ObjectFactory::NewJSGeneratorFunction(JSMethod *method)
1078 {
1079     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1080 
1081     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
1082     JSHandle<JSFunction> generatorFunc = JSHandle<JSFunction>::Cast(NewJSObject(dynclass));
1083     JSFunction::InitializeJSFunction(thread_, generatorFunc, FunctionKind::GENERATOR_FUNCTION);
1084     generatorFunc->SetCallTarget(thread_, method);
1085     return generatorFunc;
1086 }
1087 
NewJSGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)1088 JSHandle<JSGeneratorObject> ObjectFactory::NewJSGeneratorObject(JSHandle<JSTaggedValue> generatorFunction)
1089 {
1090     JSHandle<JSTaggedValue> proto(thread_, JSHandle<JSFunction>::Cast(generatorFunction)->GetProtoOrDynClass());
1091     if (!proto->IsECMAObject()) {
1092         JSHandle<GlobalEnv> realmHandle = JSObject::GetFunctionRealm(thread_, generatorFunction);
1093         proto = realmHandle->GetGeneratorPrototype();
1094     }
1095     JSHandle<JSHClass> dynclass = NewEcmaDynClass(JSGeneratorObject::SIZE, JSType::JS_GENERATOR_OBJECT, proto);
1096     JSHandle<JSGeneratorObject> generatorObject = JSHandle<JSGeneratorObject>::Cast(NewJSObject(dynclass));
1097     return generatorObject;
1098 }
1099 
NewAsyncFunction(JSMethod * method)1100 JSHandle<JSAsyncFunction> ObjectFactory::NewAsyncFunction(JSMethod *method)
1101 {
1102     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1103     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
1104     JSHandle<JSAsyncFunction> asyncFunction = JSHandle<JSAsyncFunction>::Cast(NewJSObject(dynclass));
1105     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(asyncFunction));
1106     asyncFunction->SetCallTarget(thread_, method);
1107     return asyncFunction;
1108 }
1109 
NewJSAsyncFuncObject()1110 JSHandle<JSAsyncFuncObject> ObjectFactory::NewJSAsyncFuncObject()
1111 {
1112     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1113     JSHandle<JSTaggedValue> proto = env->GetInitialGenerator();
1114     JSHandle<JSHClass> dynclass = NewEcmaDynClass(JSAsyncFuncObject::SIZE, JSType::JS_ASYNC_FUNC_OBJECT, proto);
1115     JSHandle<JSAsyncFuncObject> asyncFuncObject = JSHandle<JSAsyncFuncObject>::Cast(NewJSObject(dynclass));
1116     return asyncFuncObject;
1117 }
1118 
NewCompletionRecord(CompletionRecordType type,JSHandle<JSTaggedValue> value)1119 JSHandle<CompletionRecord> ObjectFactory::NewCompletionRecord(CompletionRecordType type, JSHandle<JSTaggedValue> value)
1120 {
1121     NewObjectHook();
1122     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1123         JSHClass::Cast(thread_->GlobalConstants()->GetCompletionRecordClass().GetTaggedObject()));
1124     JSHandle<CompletionRecord> obj(thread_, header);
1125     obj->SetType(type);
1126     obj->SetValue(thread_, value);
1127     return obj;
1128 }
1129 
NewGeneratorContext()1130 JSHandle<GeneratorContext> ObjectFactory::NewGeneratorContext()
1131 {
1132     NewObjectHook();
1133     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1134         JSHClass::Cast(thread_->GlobalConstants()->GetGeneratorContextClass().GetTaggedObject()));
1135     JSHandle<GeneratorContext> obj(thread_, header);
1136     obj->SetRegsArray(thread_, JSTaggedValue::Undefined());
1137     obj->SetMethod(thread_, JSTaggedValue::Undefined());
1138     obj->SetAcc(thread_, JSTaggedValue::Undefined());
1139     obj->SetGeneratorObject(thread_, JSTaggedValue::Undefined());
1140     obj->SetLexicalEnv(thread_, JSTaggedValue::Undefined());
1141     obj->SetNRegs(0);
1142     obj->SetBCOffset(0);
1143     return obj;
1144 }
1145 
NewJSPrimitiveRef(const JSHandle<JSFunction> & function,const JSHandle<JSTaggedValue> & object)1146 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(const JSHandle<JSFunction> &function,
1147                                                           const JSHandle<JSTaggedValue> &object)
1148 {
1149     JSHandle<JSPrimitiveRef> obj(NewJSObjectByConstructor(function, JSHandle<JSTaggedValue>(function)));
1150     obj->SetValue(thread_, object);
1151 
1152     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1153     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1154     if (function.GetTaggedValue() == env->GetStringFunction().GetTaggedValue()) {
1155         JSHandle<JSTaggedValue> lengthStr = globalConst->GetHandledLengthString();
1156 
1157         int32_t length = EcmaString::Cast(object.GetTaggedValue().GetTaggedObject())->GetLength();
1158         PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>(thread_, JSTaggedValue(length)), false, false, false);
1159         JSTaggedValue::DefinePropertyOrThrow(thread_, JSHandle<JSTaggedValue>(obj), lengthStr, desc);
1160     }
1161 
1162     return obj;
1163 }
1164 
NewJSPrimitiveRef(PrimitiveType type,const JSHandle<JSTaggedValue> & object)1165 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSPrimitiveRef(PrimitiveType type, const JSHandle<JSTaggedValue> &object)
1166 {
1167     ObjectFactory *factory = vm_->GetFactory();
1168     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1169     JSHandle<JSTaggedValue> function;
1170     switch (type) {
1171         case PrimitiveType::PRIMITIVE_NUMBER:
1172             function = env->GetNumberFunction();
1173             break;
1174         case PrimitiveType::PRIMITIVE_STRING:
1175             function = env->GetStringFunction();
1176             break;
1177         case PrimitiveType::PRIMITIVE_SYMBOL:
1178             function = env->GetSymbolFunction();
1179             break;
1180         case PrimitiveType::PRIMITIVE_BOOLEAN:
1181             function = env->GetBooleanFunction();
1182             break;
1183         case PrimitiveType::PRIMITIVE_BIGINT:
1184             function = env->GetBigIntFunction();
1185             break;
1186         default:
1187             break;
1188     }
1189     JSHandle<JSFunction> funcHandle(function);
1190     return factory->NewJSPrimitiveRef(funcHandle, object);
1191 }
1192 
NewJSString(const JSHandle<JSTaggedValue> & str)1193 JSHandle<JSPrimitiveRef> ObjectFactory::NewJSString(const JSHandle<JSTaggedValue> &str)
1194 {
1195     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1196     JSHandle<JSTaggedValue> stringFunc = env->GetStringFunction();
1197 
1198     JSHandle<JSPrimitiveRef> obj =
1199         JSHandle<JSPrimitiveRef>::Cast(NewJSObjectByConstructor(JSHandle<JSFunction>(stringFunc), stringFunc));
1200     obj->SetValue(thread_, str);
1201     return obj;
1202 }
1203 
NewGlobalEnv(JSHClass * globalEnvClass)1204 JSHandle<GlobalEnv> ObjectFactory::NewGlobalEnv(JSHClass *globalEnvClass)
1205 {
1206     NewObjectHook();
1207     // Note: Global env must be allocated in non-movable heap, since its getters will directly return
1208     //       the offsets of the properties as the address of Handles.
1209     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(globalEnvClass);
1210     InitObjectFields(header);
1211     return JSHandle<GlobalEnv>(thread_, GlobalEnv::Cast(header));
1212 }
1213 
NewLexicalEnv(int numSlots)1214 JSHandle<LexicalEnv> ObjectFactory::NewLexicalEnv(int numSlots)
1215 {
1216     NewObjectHook();
1217     size_t size = LexicalEnv::ComputeSize(numSlots);
1218     auto header = heap_->AllocateYoungOrHugeObject(
1219         JSHClass::Cast(thread_->GlobalConstants()->GetEnvClass().GetTaggedObject()), size);
1220     JSHandle<LexicalEnv> array(thread_, header);
1221     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), numSlots + LexicalEnv::RESERVED_ENV_LENGTH);
1222     return array;
1223 }
1224 
NewJSSymbol()1225 JSHandle<JSSymbol> ObjectFactory::NewJSSymbol()
1226 {
1227     NewObjectHook();
1228     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1229         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
1230     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
1231     obj->SetDescription(thread_, JSTaggedValue::Undefined());
1232     obj->SetFlags(0);
1233     obj->SetHashField(SymbolTable::Hash(obj.GetTaggedValue()));
1234     return obj;
1235 }
1236 
NewPrivateSymbol()1237 JSHandle<JSSymbol> ObjectFactory::NewPrivateSymbol()
1238 {
1239     JSHandle<JSSymbol> obj = NewJSSymbol();
1240     obj->SetPrivate(thread_);
1241     return obj;
1242 }
1243 
NewPrivateNameSymbol(const JSHandle<JSTaggedValue> & name)1244 JSHandle<JSSymbol> ObjectFactory::NewPrivateNameSymbol(const JSHandle<JSTaggedValue> &name)
1245 {
1246     NewObjectHook();
1247     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1248         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
1249     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
1250     obj->SetFlags(0);
1251     obj->SetPrivateNameSymbol(thread_);
1252     obj->SetDescription(thread_, name);
1253     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
1254     return obj;
1255 }
1256 
NewWellKnownSymbol(const JSHandle<JSTaggedValue> & name)1257 JSHandle<JSSymbol> ObjectFactory::NewWellKnownSymbol(const JSHandle<JSTaggedValue> &name)
1258 {
1259     NewObjectHook();
1260     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1261         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
1262     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
1263     obj->SetFlags(0);
1264     obj->SetWellKnownSymbol(thread_);
1265     obj->SetDescription(thread_, name);
1266     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
1267     return obj;
1268 }
1269 
NewPublicSymbol(const JSHandle<JSTaggedValue> & name)1270 JSHandle<JSSymbol> ObjectFactory::NewPublicSymbol(const JSHandle<JSTaggedValue> &name)
1271 {
1272     NewObjectHook();
1273     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1274         JSHClass::Cast(thread_->GlobalConstants()->GetSymbolClass().GetTaggedObject()));
1275     JSHandle<JSSymbol> obj(thread_, JSSymbol::Cast(header));
1276     obj->SetFlags(0);
1277     obj->SetDescription(thread_, name);
1278     obj->SetHashField(SymbolTable::Hash(name.GetTaggedValue()));
1279     return obj;
1280 }
1281 
NewSymbolWithTable(const JSHandle<JSTaggedValue> & name)1282 JSHandle<JSSymbol> ObjectFactory::NewSymbolWithTable(const JSHandle<JSTaggedValue> &name)
1283 {
1284     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1285     JSHandle<SymbolTable> tableHandle(env->GetRegisterSymbols());
1286     if (tableHandle->ContainsKey(thread_, name.GetTaggedValue())) {
1287         JSTaggedValue objValue = tableHandle->GetSymbol(name.GetTaggedValue());
1288         return JSHandle<JSSymbol>(thread_, objValue);
1289     }
1290 
1291     JSHandle<JSSymbol> obj = NewPublicSymbol(name);
1292     JSHandle<JSTaggedValue> valueHandle(obj);
1293     JSHandle<JSTaggedValue> keyHandle(name);
1294     JSHandle<SymbolTable> table = SymbolTable::Insert(thread_, tableHandle, keyHandle, valueHandle);
1295     env->SetRegisterSymbols(thread_, table);
1296     return obj;
1297 }
1298 
NewPrivateNameSymbolWithChar(const char * description)1299 JSHandle<JSSymbol> ObjectFactory::NewPrivateNameSymbolWithChar(const char *description)
1300 {
1301     JSHandle<EcmaString> string = NewFromString(description);
1302     return NewPrivateNameSymbol(JSHandle<JSTaggedValue>(string));
1303 }
1304 
NewWellKnownSymbolWithChar(const char * description)1305 JSHandle<JSSymbol> ObjectFactory::NewWellKnownSymbolWithChar(const char *description)
1306 {
1307     JSHandle<EcmaString> string = NewFromString(description);
1308     return NewWellKnownSymbol(JSHandle<JSTaggedValue>(string));
1309 }
1310 
NewPublicSymbolWithChar(const char * description)1311 JSHandle<JSSymbol> ObjectFactory::NewPublicSymbolWithChar(const char *description)
1312 {
1313     JSHandle<EcmaString> string = NewFromString(description);
1314     return NewPublicSymbol(JSHandle<JSTaggedValue>(string));
1315 }
1316 
NewSymbolWithTableWithChar(const char * description)1317 JSHandle<JSSymbol> ObjectFactory::NewSymbolWithTableWithChar(const char *description)
1318 {
1319     JSHandle<EcmaString> string = NewFromString(description);
1320     return NewSymbolWithTable(JSHandle<JSTaggedValue>(string));
1321 }
1322 
NewAccessorData()1323 JSHandle<AccessorData> ObjectFactory::NewAccessorData()
1324 {
1325     NewObjectHook();
1326     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1327         JSHClass::Cast(thread_->GlobalConstants()->GetAccessorDataClass().GetTaggedObject()));
1328     JSHandle<AccessorData> acc(thread_, AccessorData::Cast(header));
1329     acc->SetGetter(thread_, JSTaggedValue::Undefined());
1330     acc->SetSetter(thread_, JSTaggedValue::Undefined());
1331     return acc;
1332 }
1333 
NewInternalAccessor(void * setter,void * getter)1334 JSHandle<AccessorData> ObjectFactory::NewInternalAccessor(void *setter, void *getter)
1335 {
1336     NewObjectHook();
1337     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(
1338         JSHClass::Cast(thread_->GlobalConstants()->GetInternalAccessorClass().GetTaggedObject()));
1339     JSHandle<AccessorData> obj(thread_, AccessorData::Cast(header));
1340     if (setter != nullptr) {
1341         JSHandle<JSNativePointer> setFunc = NewJSNativePointer(setter, nullptr, nullptr, true);
1342         obj->SetSetter(thread_, setFunc.GetTaggedValue());
1343     } else {
1344         JSTaggedValue setFunc = JSTaggedValue::Undefined();
1345         obj->SetSetter(thread_, setFunc);
1346         ASSERT(!obj->HasSetter());
1347     }
1348     JSHandle<JSNativePointer> getFunc = NewJSNativePointer(getter, nullptr, nullptr, true);
1349     obj->SetGetter(thread_, getFunc);
1350     return obj;
1351 }
1352 
NewPromiseCapability()1353 JSHandle<PromiseCapability> ObjectFactory::NewPromiseCapability()
1354 {
1355     NewObjectHook();
1356     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1357         JSHClass::Cast(thread_->GlobalConstants()->GetCapabilityRecordClass().GetTaggedObject()));
1358     JSHandle<PromiseCapability> obj(thread_, header);
1359     obj->SetPromise(thread_, JSTaggedValue::Undefined());
1360     obj->SetResolve(thread_, JSTaggedValue::Undefined());
1361     obj->SetReject(thread_, JSTaggedValue::Undefined());
1362     return obj;
1363 }
1364 
NewPromiseReaction()1365 JSHandle<PromiseReaction> ObjectFactory::NewPromiseReaction()
1366 {
1367     NewObjectHook();
1368     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1369         JSHClass::Cast(thread_->GlobalConstants()->GetReactionsRecordClass().GetTaggedObject()));
1370     JSHandle<PromiseReaction> obj(thread_, header);
1371     obj->SetPromiseCapability(thread_, JSTaggedValue::Undefined());
1372     obj->SetHandler(thread_, JSTaggedValue::Undefined());
1373     obj->SetType(PromiseType::RESOLVE);
1374     return obj;
1375 }
1376 
NewPromiseIteratorRecord(const JSHandle<JSTaggedValue> & itor,bool done)1377 JSHandle<PromiseIteratorRecord> ObjectFactory::NewPromiseIteratorRecord(const JSHandle<JSTaggedValue> &itor, bool done)
1378 {
1379     NewObjectHook();
1380     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1381         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseIteratorRecordClass().GetTaggedObject()));
1382     JSHandle<PromiseIteratorRecord> obj(thread_, header);
1383     obj->SetIterator(thread_, itor.GetTaggedValue());
1384     obj->SetDone(done);
1385     return obj;
1386 }
1387 
NewMicroJobQueue()1388 JSHandle<job::MicroJobQueue> ObjectFactory::NewMicroJobQueue()
1389 {
1390     NewObjectHook();
1391     TaggedObject *header = heap_->AllocateNonMovableOrHugeObject(
1392         JSHClass::Cast(thread_->GlobalConstants()->GetMicroJobQueueClass().GetTaggedObject()));
1393     JSHandle<job::MicroJobQueue> obj(thread_, header);
1394     obj->SetPromiseJobQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1395     obj->SetScriptJobQueue(thread_, GetEmptyTaggedQueue().GetTaggedValue());
1396     return obj;
1397 }
1398 
NewPendingJob(const JSHandle<JSFunction> & func,const JSHandle<TaggedArray> & argv)1399 JSHandle<job::PendingJob> ObjectFactory::NewPendingJob(const JSHandle<JSFunction> &func,
1400                                                        const JSHandle<TaggedArray> &argv)
1401 {
1402     NewObjectHook();
1403     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1404         JSHClass::Cast(thread_->GlobalConstants()->GetPendingJobClass().GetTaggedObject()));
1405     JSHandle<job::PendingJob> obj(thread_, header);
1406     obj->SetJob(thread_, func.GetTaggedValue());
1407     obj->SetArguments(thread_, argv.GetTaggedValue());
1408     obj->SetChainId(0);
1409     obj->SetSpanId(0);
1410     obj->SetParentSpanId(0);
1411     obj->SetFlags(0);
1412     return obj;
1413 }
1414 
NewJSProxy(const JSHandle<JSTaggedValue> & target,const JSHandle<JSTaggedValue> & handler)1415 JSHandle<JSProxy> ObjectFactory::NewJSProxy(const JSHandle<JSTaggedValue> &target,
1416                                             const JSHandle<JSTaggedValue> &handler)
1417 {
1418     NewObjectHook();
1419     TaggedObject *header = nullptr;
1420     const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1421 
1422     if (target->IsCallable()) {
1423         auto jsProxyCallableClass = JSHClass::Cast(globalConst->GetJSProxyCallableClass().GetTaggedObject());
1424         auto jsProxyConstructClass = JSHClass::Cast(globalConst->GetJSProxyConstructClass().GetTaggedObject());
1425         header = target->IsConstructor() ? heap_->AllocateYoungOrHugeObject(jsProxyConstructClass)
1426                                          : heap_->AllocateYoungOrHugeObject(jsProxyCallableClass);
1427     } else {
1428         header = heap_->AllocateYoungOrHugeObject(
1429             JSHClass::Cast(thread_->GlobalConstants()->GetJSProxyOrdinaryClass().GetTaggedObject()));
1430     }
1431 
1432     JSHandle<JSProxy> proxy(thread_, header);
1433     JSMethod *method = nullptr;
1434     if (target->IsCallable()) {
1435         JSMethod *nativeMethod =
1436             vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(builtins::BuiltinsGlobal::CallJsProxy));
1437         proxy->SetCallTarget(thread_, nativeMethod);
1438     }
1439     proxy->SetMethod(method);
1440 
1441     proxy->SetTarget(thread_, target.GetTaggedValue());
1442     proxy->SetHandler(thread_, handler.GetTaggedValue());
1443     return proxy;
1444 }
1445 
NewJSRealm()1446 JSHandle<JSRealm> ObjectFactory::NewJSRealm()
1447 {
1448     JSHandle<JSHClass> dynClassClassHandle = NewEcmaDynClassClass(nullptr, JSHClass::SIZE, JSType::HCLASS);
1449     JSHClass *dynclass = reinterpret_cast<JSHClass *>(dynClassClassHandle.GetTaggedValue().GetTaggedObject());
1450     dynclass->SetClass(dynclass);
1451     JSHandle<JSHClass> realmEnvClass = NewEcmaDynClass(*dynClassClassHandle, GlobalEnv::SIZE, JSType::GLOBAL_ENV);
1452     JSHandle<GlobalEnv> realmEnvHandle = NewGlobalEnv(*realmEnvClass);
1453 
1454     realmEnvHandle->SetEmptyArray(thread_, NewEmptyArray());
1455     realmEnvHandle->SetEmptyTaggedQueue(thread_, NewTaggedQueue(0));
1456     auto result = TemplateMap::Create(thread_);
1457     realmEnvHandle->SetTemplateMap(thread_, result);
1458 
1459     Builtins builtins;
1460     builtins.Initialize(realmEnvHandle, thread_);
1461     JSHandle<JSTaggedValue> protoValue = thread_->GlobalConstants()->GetHandledJSRealmClass();
1462     JSHandle<JSHClass> dynHandle = NewEcmaDynClass(JSRealm::SIZE, JSType::JS_REALM, protoValue);
1463     JSHandle<JSRealm> realm(NewJSObject(dynHandle));
1464     realm->SetGlobalEnv(thread_, realmEnvHandle.GetTaggedValue());
1465 
1466     JSHandle<JSTaggedValue> realmObj = realmEnvHandle->GetJSGlobalObject();
1467     JSHandle<JSTaggedValue> realmkey(thread_->GlobalConstants()->GetHandledGlobalString());
1468     PropertyDescriptor realmDesc(thread_, JSHandle<JSTaggedValue>::Cast(realmObj), true, false, true);
1469     [[maybe_unused]] bool status =
1470         JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>::Cast(realm), realmkey, realmDesc);
1471     ASSERT_PRINT(status == true, "Realm defineOwnProperty failed");
1472 
1473     return realm;
1474 }
1475 
NewEmptyArray()1476 JSHandle<TaggedArray> ObjectFactory::NewEmptyArray()
1477 {
1478     NewObjectHook();
1479     auto header = heap_->AllocateNonMovableOrHugeObject(
1480         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), TaggedArray::SIZE);
1481     JSHandle<TaggedArray> array(thread_, header);
1482     array->SetLength(0);
1483     return array;
1484 }
1485 
NewTaggedArray(uint32_t length,JSTaggedValue initVal,bool nonMovable)1486 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal, bool nonMovable)
1487 {
1488     if (nonMovable) {
1489         return NewTaggedArray(length, initVal, MemSpaceType::NON_MOVABLE);
1490     }
1491     return NewTaggedArray(length, initVal, MemSpaceType::SEMI_SPACE);
1492 }
1493 
NewTaggedArray(uint32_t length,JSTaggedValue initVal,MemSpaceType spaceType)1494 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal, MemSpaceType spaceType)
1495 {
1496     NewObjectHook();
1497     if (length == 0) {
1498         return EmptyArray();
1499     }
1500 
1501     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
1502     TaggedObject *header = nullptr;
1503     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
1504     switch (spaceType) {
1505         case MemSpaceType::SEMI_SPACE:
1506             header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
1507             break;
1508         case MemSpaceType::OLD_SPACE:
1509             header = heap_->AllocateOldOrHugeObject(arrayClass, size);
1510             break;
1511         case MemSpaceType::NON_MOVABLE:
1512             header = heap_->AllocateNonMovableOrHugeObject(arrayClass, size);
1513             break;
1514         default:
1515             UNREACHABLE();
1516     }
1517 
1518     JSHandle<TaggedArray> array(thread_, header);
1519     array->InitializeWithSpecialValue(initVal, length);
1520     return array;
1521 }
1522 
NewTaggedArray(uint32_t length,JSTaggedValue initVal)1523 JSHandle<TaggedArray> ObjectFactory::NewTaggedArray(uint32_t length, JSTaggedValue initVal)
1524 {
1525     NewObjectHook();
1526     if (length == 0) {
1527         return EmptyArray();
1528     }
1529 
1530     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
1531     auto header = heap_->AllocateYoungOrHugeObject(
1532         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
1533     JSHandle<TaggedArray> array(thread_, header);
1534     array->InitializeWithSpecialValue(initVal, length);
1535     return array;
1536 }
1537 
NewDictionaryArray(uint32_t length)1538 JSHandle<TaggedArray> ObjectFactory::NewDictionaryArray(uint32_t length)
1539 {
1540     NewObjectHook();
1541     ASSERT(length > 0);
1542 
1543     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
1544     auto header = heap_->AllocateYoungOrHugeObject(
1545         JSHClass::Cast(thread_->GlobalConstants()->GetDictionaryClass().GetTaggedObject()), size);
1546     JSHandle<TaggedArray> array(thread_, header);
1547     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
1548 
1549     return array;
1550 }
1551 
ExtendArray(const JSHandle<TaggedArray> & old,uint32_t length,JSTaggedValue initVal)1552 JSHandle<TaggedArray> ObjectFactory::ExtendArray(const JSHandle<TaggedArray> &old, uint32_t length,
1553                                                  JSTaggedValue initVal)
1554 {
1555     ASSERT(length > old->GetLength());
1556     NewObjectHook();
1557     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
1558     auto header = heap_->AllocateYoungOrHugeObject(
1559         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
1560     JSHandle<TaggedArray> newArray(thread_, header);
1561     newArray->SetLength(length);
1562 
1563     uint32_t oldLength = old->GetLength();
1564     for (uint32_t i = 0; i < oldLength; i++) {
1565         JSTaggedValue value = old->Get(i);
1566         newArray->Set(thread_, i, value);
1567     }
1568 
1569     for (uint32_t i = oldLength; i < length; i++) {
1570         newArray->Set(thread_, i, initVal);
1571     }
1572 
1573     return newArray;
1574 }
1575 
CopyPartArray(const JSHandle<TaggedArray> & old,uint32_t start,uint32_t end)1576 JSHandle<TaggedArray> ObjectFactory::CopyPartArray(const JSHandle<TaggedArray> &old, uint32_t start,
1577                                                    uint32_t end)
1578 {
1579     ASSERT(start <= end);
1580     ASSERT(end <= old->GetLength());
1581 
1582     uint32_t newLength = end - start;
1583     if (newLength == 0) {
1584         return EmptyArray();
1585     }
1586 
1587     NewObjectHook();
1588     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
1589     auto header = heap_->AllocateYoungOrHugeObject(
1590         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
1591     JSHandle<TaggedArray> newArray(thread_, header);
1592     newArray->SetLength(newLength);
1593 
1594     for (uint32_t i = 0; i < newLength; i++) {
1595         JSTaggedValue value = old->Get(i + start);
1596         if (value.IsHole()) {
1597             break;
1598         }
1599         newArray->Set(thread_, i, value);
1600     }
1601     return newArray;
1602 }
1603 
CopyArray(const JSHandle<TaggedArray> & old,uint32_t oldLength,uint32_t newLength,JSTaggedValue initVal)1604 JSHandle<TaggedArray> ObjectFactory::CopyArray(const JSHandle<TaggedArray> &old,
1605                                                [[maybe_unused]] uint32_t oldLength, uint32_t newLength,
1606                                                JSTaggedValue initVal)
1607 {
1608     if (newLength == 0) {
1609         return EmptyArray();
1610     }
1611     if (newLength > oldLength) {
1612         return ExtendArray(old, newLength, initVal);
1613     }
1614 
1615     NewObjectHook();
1616     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), newLength);
1617     auto header = heap_->AllocateYoungOrHugeObject(
1618         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
1619     JSHandle<TaggedArray> newArray(thread_, header);
1620     newArray->SetLength(newLength);
1621 
1622     for (uint32_t i = 0; i < newLength; i++) {
1623         JSTaggedValue value = old->Get(i);
1624         newArray->Set(thread_, i, value);
1625     }
1626 
1627     return newArray;
1628 }
1629 
CreateLayoutInfo(int properties,JSTaggedValue initVal)1630 JSHandle<LayoutInfo> ObjectFactory::CreateLayoutInfo(int properties, JSTaggedValue initVal)
1631 {
1632     int arrayLength = LayoutInfo::ComputeArrayLength(LayoutInfo::ComputeGrowCapacity(properties));
1633     JSHandle<LayoutInfo> layoutInfoHandle = JSHandle<LayoutInfo>::Cast(NewTaggedArray(arrayLength, initVal));
1634     layoutInfoHandle->SetNumberOfElements(thread_, 0);
1635     return layoutInfoHandle;
1636 }
1637 
ExtendLayoutInfo(const JSHandle<LayoutInfo> & old,int properties,JSTaggedValue initVal)1638 JSHandle<LayoutInfo> ObjectFactory::ExtendLayoutInfo(const JSHandle<LayoutInfo> &old, int properties,
1639                                                      JSTaggedValue initVal)
1640 {
1641     ASSERT(properties > old->NumberOfElements());
1642     int arrayLength = LayoutInfo::ComputeArrayLength(LayoutInfo::ComputeGrowCapacity(properties));
1643     return JSHandle<LayoutInfo>(ExtendArray(JSHandle<TaggedArray>(old), arrayLength, initVal));
1644 }
1645 
CopyLayoutInfo(const JSHandle<LayoutInfo> & old)1646 JSHandle<LayoutInfo> ObjectFactory::CopyLayoutInfo(const JSHandle<LayoutInfo> &old)
1647 {
1648     int newLength = old->GetLength();
1649     return JSHandle<LayoutInfo>(CopyArray(JSHandle<TaggedArray>::Cast(old), newLength, newLength));
1650 }
1651 
CopyAndReSort(const JSHandle<LayoutInfo> & old,int end,int capacity)1652 JSHandle<LayoutInfo> ObjectFactory::CopyAndReSort(const JSHandle<LayoutInfo> &old, int end, int capacity)
1653 {
1654     ASSERT(capacity >= end);
1655     JSHandle<LayoutInfo> newArr = CreateLayoutInfo(capacity);
1656     Span<struct Properties> sp(old->GetProperties(), end);
1657     int i = 0;
1658     for (; i < end; i++) {
1659         newArr->AddKey(thread_, i, sp[i].key_, PropertyAttributes(sp[i].attr_));
1660     }
1661 
1662     return newArr;
1663 }
1664 
NewConstantPool(uint32_t capacity)1665 JSHandle<ConstantPool> ObjectFactory::NewConstantPool(uint32_t capacity)
1666 {
1667     NewObjectHook();
1668     if (capacity == 0) {
1669         return JSHandle<ConstantPool>::Cast(EmptyArray());
1670     }
1671     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), capacity);
1672     auto header = heap_->AllocateNonMovableOrHugeObject(
1673         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
1674     JSHandle<ConstantPool> array(thread_, header);
1675     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), capacity);
1676     return array;
1677 }
1678 
NewProgram()1679 JSHandle<Program> ObjectFactory::NewProgram()
1680 {
1681     NewObjectHook();
1682     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1683         JSHClass::Cast(thread_->GlobalConstants()->GetProgramClass().GetTaggedObject()));
1684     JSHandle<Program> p(thread_, header);
1685     p->SetMainFunction(thread_, JSTaggedValue::Undefined());
1686     return p;
1687 }
1688 
NewEmptyEcmaModule()1689 JSHandle<EcmaModule> ObjectFactory::NewEmptyEcmaModule()
1690 {
1691     NewObjectHook();
1692     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1693         JSHClass::Cast(thread_->GlobalConstants()->GetEcmaModuleClass().GetTaggedObject()));
1694     JSHandle<EcmaModule> module(thread_, header);
1695     module->SetNameDictionary(thread_, JSTaggedValue::Undefined());
1696     return module;
1697 }
1698 
GetEmptyString() const1699 JSHandle<EcmaString> ObjectFactory::GetEmptyString() const
1700 {
1701     return JSHandle<EcmaString>(thread_->GlobalConstants()->GetHandledEmptyString());
1702 }
1703 
EmptyArray() const1704 JSHandle<TaggedArray> ObjectFactory::EmptyArray() const
1705 {
1706     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1707     return JSHandle<TaggedArray>(env->GetEmptyArray());
1708 }
1709 
GetStringFromStringTable(const uint8_t * utf8Data,uint32_t utf8Len,bool canBeCompress) const1710 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const uint8_t *utf8Data, uint32_t utf8Len,
1711                                                              bool canBeCompress) const
1712 {
1713     NewObjectHook();
1714     if (utf8Len == 0) {
1715         return GetEmptyString();
1716     }
1717     auto stringTable = vm_->GetEcmaStringTable();
1718     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(utf8Data, utf8Len, canBeCompress));
1719 }
1720 
GetStringFromStringTable(const uint16_t * utf16Data,uint32_t utf16Len,bool canBeCompress) const1721 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const uint16_t *utf16Data, uint32_t utf16Len,
1722                                                              bool canBeCompress) const
1723 {
1724     NewObjectHook();
1725     if (utf16Len == 0) {
1726         return GetEmptyString();
1727     }
1728     auto stringTable = vm_->GetEcmaStringTable();
1729     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(utf16Data, utf16Len, canBeCompress));
1730 }
1731 
GetStringFromStringTable(EcmaString * string) const1732 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(EcmaString *string) const
1733 {
1734     ASSERT(string != nullptr);
1735     if (string->GetLength() == 0) {
1736         return GetEmptyString();
1737     }
1738     auto stringTable = vm_->GetEcmaStringTable();
1739     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(string));
1740 }
1741 
1742 // NB! don't do special case for C0 80, it means '\u0000', so don't convert to UTF-8
GetRawStringFromStringTable(const uint8_t * mutf8Data,uint32_t utf16Len,bool canBeCompressed) const1743 EcmaString *ObjectFactory::GetRawStringFromStringTable(const uint8_t *mutf8Data,
1744                                                        uint32_t utf16Len, bool canBeCompressed) const
1745 {
1746     NewObjectHook();
1747     if (UNLIKELY(utf16Len == 0)) {
1748         return *GetEmptyString();
1749     }
1750 
1751     if (canBeCompressed) {
1752         return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(mutf8Data, utf16Len, true));
1753     }
1754 
1755     CVector<uint16_t> utf16Data(utf16Len);
1756     auto len = utf::ConvertRegionMUtf8ToUtf16(mutf8Data, utf16Data.data(), utf::Mutf8Size(mutf8Data), utf16Len, 0);
1757     return EcmaString::Cast(vm_->GetEcmaStringTable()->GetOrInternString(utf16Data.data(), len, false));
1758 }
1759 
NewPropertyBox(const JSHandle<JSTaggedValue> & value)1760 JSHandle<PropertyBox> ObjectFactory::NewPropertyBox(const JSHandle<JSTaggedValue> &value)
1761 {
1762     NewObjectHook();
1763     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1764         JSHClass::Cast(thread_->GlobalConstants()->GetPropertyBoxClass().GetTaggedObject()));
1765     JSHandle<PropertyBox> box(thread_, header);
1766     box->SetValue(thread_, value);
1767     return box;
1768 }
1769 
NewProtoChangeMarker()1770 JSHandle<ProtoChangeMarker> ObjectFactory::NewProtoChangeMarker()
1771 {
1772     NewObjectHook();
1773     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1774         JSHClass::Cast(thread_->GlobalConstants()->GetProtoChangeMarkerClass().GetTaggedObject()));
1775     JSHandle<ProtoChangeMarker> marker(thread_, header);
1776     marker->ClearBitField();
1777     return marker;
1778 }
1779 
NewProtoChangeDetails()1780 JSHandle<ProtoChangeDetails> ObjectFactory::NewProtoChangeDetails()
1781 {
1782     NewObjectHook();
1783     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1784         JSHClass::Cast(thread_->GlobalConstants()->GetProtoChangeDetailsClass().GetTaggedObject()));
1785     JSHandle<ProtoChangeDetails> protoInfo(thread_, header);
1786     protoInfo->SetChangeListener(thread_, JSTaggedValue::Undefined());
1787     protoInfo->SetRegisterIndex(ProtoChangeDetails::UNREGISTERED);
1788     return protoInfo;
1789 }
1790 
NewProfileTypeInfo(uint32_t length)1791 JSHandle<ProfileTypeInfo> ObjectFactory::NewProfileTypeInfo(uint32_t length)
1792 {
1793     NewObjectHook();
1794     ASSERT(length > 0);
1795 
1796     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
1797     auto header = heap_->AllocateYoungOrHugeObject(
1798         JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject()), size);
1799     JSHandle<ProfileTypeInfo> array(thread_, header);
1800     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
1801 
1802     return array;
1803 }
1804 
NewBigInt()1805 JSHandle<BigInt> ObjectFactory::NewBigInt()
1806 {
1807     NewObjectHook();
1808     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1809         JSHClass::Cast(thread_->GlobalConstants()->GetBigIntClass().GetTaggedObject()));
1810     JSHandle<BigInt> obj(thread_, BigInt::Cast(header));
1811     obj->SetData(thread_, JSTaggedValue::Undefined());
1812     obj->SetSign(false);
1813     return obj;
1814 }
1815 
1816 // static
NewObjectHook() const1817 void ObjectFactory::NewObjectHook() const
1818 {
1819 #ifndef NDEBUG
1820     if (vm_->GetJSOptions().IsEnableForceGC() && vm_->IsInitialized()) {
1821         if (vm_->GetJSOptions().IsForceFullGC()) {
1822             vm_->CollectGarbage(TriggerGCType::SEMI_GC);
1823             vm_->CollectGarbage(TriggerGCType::OLD_GC);
1824             vm_->CollectGarbage(TriggerGCType::FULL_GC);
1825         } else {
1826             vm_->CollectGarbage(TriggerGCType::SEMI_GC);
1827             vm_->CollectGarbage(TriggerGCType::OLD_GC);
1828         }
1829     }
1830 #endif
1831 }
1832 
NewTaggedQueue(uint32_t length)1833 JSHandle<TaggedQueue> ObjectFactory::NewTaggedQueue(uint32_t length)
1834 {
1835     uint32_t queueLength = TaggedQueue::QueueToArrayIndex(length);
1836     auto queue = JSHandle<TaggedQueue>::Cast(NewTaggedArray(queueLength, JSTaggedValue::Hole()));
1837     queue->SetStart(thread_, JSTaggedValue(0));  // equal to 0 when add 1.
1838     queue->SetEnd(thread_, JSTaggedValue(0));
1839     queue->SetCapacity(thread_, JSTaggedValue(length));
1840 
1841     return queue;
1842 }
1843 
GetEmptyTaggedQueue() const1844 JSHandle<TaggedQueue> ObjectFactory::GetEmptyTaggedQueue() const
1845 {
1846     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1847     return JSHandle<TaggedQueue>(env->GetEmptyTaggedQueue());
1848 }
1849 
NewJSSetIterator(const JSHandle<JSSet> & set,IterationKind kind)1850 JSHandle<JSSetIterator> ObjectFactory::NewJSSetIterator(const JSHandle<JSSet> &set, IterationKind kind)
1851 {
1852     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1853     JSHandle<JSTaggedValue> protoValue = env->GetSetIteratorPrototype();
1854     JSHandle<JSHClass> dynHandle = NewEcmaDynClass(JSSetIterator::SIZE, JSType::JS_SET_ITERATOR, protoValue);
1855     JSHandle<JSSetIterator> iter(NewJSObject(dynHandle));
1856     iter->GetJSHClass()->SetExtensible(true);
1857     iter->SetIteratedSet(thread_, set->GetLinkedSet());
1858     iter->SetNextIndex(0);
1859     iter->SetIterationKind(kind);
1860     return iter;
1861 }
1862 
NewJSMapIterator(const JSHandle<JSMap> & map,IterationKind kind)1863 JSHandle<JSMapIterator> ObjectFactory::NewJSMapIterator(const JSHandle<JSMap> &map, IterationKind kind)
1864 {
1865     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1866     JSHandle<JSTaggedValue> protoValue = env->GetMapIteratorPrototype();
1867     JSHandle<JSHClass> dynHandle = NewEcmaDynClass(JSMapIterator::SIZE, JSType::JS_MAP_ITERATOR, protoValue);
1868     JSHandle<JSMapIterator> iter(NewJSObject(dynHandle));
1869     iter->GetJSHClass()->SetExtensible(true);
1870     iter->SetIteratedMap(thread_, map->GetLinkedMap());
1871     iter->SetNextIndex(0);
1872     iter->SetIterationKind(kind);
1873     return iter;
1874 }
1875 
NewJSArrayIterator(const JSHandle<JSObject> & array,IterationKind kind)1876 JSHandle<JSArrayIterator> ObjectFactory::NewJSArrayIterator(const JSHandle<JSObject> &array, IterationKind kind)
1877 {
1878     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1879     JSHandle<JSTaggedValue> protoValue = env->GetArrayIteratorPrototype();
1880     JSHandle<JSHClass> dynHandle = NewEcmaDynClass(JSArrayIterator::SIZE, JSType::JS_ARRAY_ITERATOR, protoValue);
1881     JSHandle<JSArrayIterator> iter(NewJSObject(dynHandle));
1882     iter->GetJSHClass()->SetExtensible(true);
1883     iter->SetIteratedArray(thread_, array);
1884     iter->SetNextIndex(0);
1885     iter->SetIterationKind(kind);
1886     return iter;
1887 }
1888 
CreateJSPromiseReactionsFunction(const void * nativeFunc)1889 JSHandle<JSPromiseReactionsFunction> ObjectFactory::CreateJSPromiseReactionsFunction(const void *nativeFunc)
1890 {
1891     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1892     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetPromiseReactionFunctionClass());
1893 
1894     JSHandle<JSPromiseReactionsFunction> reactionsFunction =
1895         JSHandle<JSPromiseReactionsFunction>::Cast(NewJSObject(dynclass));
1896     reactionsFunction->SetPromise(thread_, JSTaggedValue::Hole());
1897     reactionsFunction->SetAlreadyResolved(thread_, JSTaggedValue::Hole());
1898     JSMethod *method = vm_->GetMethodForNativeFunction(nativeFunc);
1899     reactionsFunction->SetCallTarget(thread_, method);
1900     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(reactionsFunction);
1901     JSFunction::InitializeJSFunction(thread_, function);
1902     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(1));
1903     return reactionsFunction;
1904 }
1905 
CreateJSPromiseExecutorFunction(const void * nativeFunc)1906 JSHandle<JSPromiseExecutorFunction> ObjectFactory::CreateJSPromiseExecutorFunction(const void *nativeFunc)
1907 {
1908     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1909     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetPromiseExecutorFunctionClass());
1910     JSHandle<JSPromiseExecutorFunction> executorFunction =
1911         JSHandle<JSPromiseExecutorFunction>::Cast(NewJSObject(dynclass));
1912     executorFunction->SetCapability(thread_, JSTaggedValue::Hole());
1913     JSMethod *method = vm_->GetMethodForNativeFunction(nativeFunc);
1914     executorFunction->SetCallTarget(thread_, method);
1915     executorFunction->SetCapability(thread_, JSTaggedValue::Undefined());
1916     JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(executorFunction);
1917     JSFunction::InitializeJSFunction(thread_, function, FunctionKind::NORMAL_FUNCTION);
1918     JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(FunctionLength::TWO));
1919     return executorFunction;
1920 }
1921 
NewJSPromiseAllResolveElementFunction(const void * nativeFunc)1922 JSHandle<JSPromiseAllResolveElementFunction> ObjectFactory::NewJSPromiseAllResolveElementFunction(
1923     const void *nativeFunc)
1924 {
1925     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1926     JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetPromiseAllResolveElementFunctionClass());
1927     JSHandle<JSPromiseAllResolveElementFunction> function =
1928         JSHandle<JSPromiseAllResolveElementFunction>::Cast(NewJSObject(dynclass));
1929     JSFunction::InitializeJSFunction(thread_, JSHandle<JSFunction>::Cast(function));
1930     JSMethod *method = vm_->GetMethodForNativeFunction(nativeFunc);
1931     function->SetCallTarget(thread_, method);
1932     JSFunction::SetFunctionLength(thread_, JSHandle<JSFunction>::Cast(function), JSTaggedValue(1));
1933     return function;
1934 }
1935 
InternString(const JSHandle<JSTaggedValue> & key)1936 EcmaString *ObjectFactory::InternString(const JSHandle<JSTaggedValue> &key)
1937 {
1938     EcmaString *str = EcmaString::Cast(key->GetTaggedObject());
1939     if (str->IsInternString()) {
1940         return str;
1941     }
1942 
1943     EcmaStringTable *stringTable = vm_->GetEcmaStringTable();
1944     return stringTable->GetOrInternString(str);
1945 }
1946 
NewTransitionHandler()1947 JSHandle<TransitionHandler> ObjectFactory::NewTransitionHandler()
1948 {
1949     NewObjectHook();
1950     TransitionHandler *handler =
1951         TransitionHandler::Cast(heap_->AllocateYoungOrHugeObject(
1952             JSHClass::Cast(thread_->GlobalConstants()->GetTransitionHandlerClass().GetTaggedObject())));
1953     return JSHandle<TransitionHandler>(thread_, handler);
1954 }
1955 
NewPrototypeHandler()1956 JSHandle<PrototypeHandler> ObjectFactory::NewPrototypeHandler()
1957 {
1958     NewObjectHook();
1959     PrototypeHandler *header =
1960         PrototypeHandler::Cast(heap_->AllocateYoungOrHugeObject(
1961             JSHClass::Cast(thread_->GlobalConstants()->GetPrototypeHandlerClass().GetTaggedObject())));
1962     JSHandle<PrototypeHandler> handler(thread_, header);
1963     handler->SetHandlerInfo(thread_, JSTaggedValue::Undefined());
1964     handler->SetProtoCell(thread_, JSTaggedValue::Undefined());
1965     handler->SetHolder(thread_, JSTaggedValue::Undefined());
1966     return handler;
1967 }
1968 
NewPromiseRecord()1969 JSHandle<PromiseRecord> ObjectFactory::NewPromiseRecord()
1970 {
1971     NewObjectHook();
1972     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1973         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseRecordClass().GetTaggedObject()));
1974     JSHandle<PromiseRecord> obj(thread_, header);
1975     obj->SetValue(thread_, JSTaggedValue::Undefined());
1976     return obj;
1977 }
1978 
NewResolvingFunctionsRecord()1979 JSHandle<ResolvingFunctionsRecord> ObjectFactory::NewResolvingFunctionsRecord()
1980 {
1981     NewObjectHook();
1982     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
1983         JSHClass::Cast(thread_->GlobalConstants()->GetPromiseResolvingFunctionsRecordClass().GetTaggedObject()));
1984     JSHandle<ResolvingFunctionsRecord> obj(thread_, header);
1985     obj->SetResolveFunction(thread_, JSTaggedValue::Undefined());
1986     obj->SetRejectFunction(thread_, JSTaggedValue::Undefined());
1987     return obj;
1988 }
1989 
CreateObjectClass(const JSHandle<TaggedArray> & properties,size_t length)1990 JSHandle<JSHClass> ObjectFactory::CreateObjectClass(const JSHandle<TaggedArray> &properties, size_t length)
1991 {
1992     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
1993     JSHandle<JSTaggedValue> proto = env->GetObjectFunctionPrototype();
1994 
1995     uint32_t fieldOrder = 0;
1996     JSMutableHandle<JSTaggedValue> key(thread_, JSTaggedValue::Undefined());
1997     JSHandle<LayoutInfo> layoutInfoHandle = CreateLayoutInfo(length);
1998     while (fieldOrder < length) {
1999         key.Update(properties->Get(fieldOrder * 2));  // 2: Meaning to double
2000         ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
2001         PropertyAttributes attributes = PropertyAttributes::Default();
2002 
2003         if (properties->Get(fieldOrder * 2 + 1).IsAccessor()) {  // 2: Meaning to double
2004             attributes.SetIsAccessor(true);
2005         }
2006 
2007         attributes.SetIsInlinedProps(true);
2008         attributes.SetRepresentation(Representation::MIXED);
2009         attributes.SetOffset(fieldOrder);
2010         layoutInfoHandle->AddKey(thread_, fieldOrder, key.GetTaggedValue(), attributes);
2011         fieldOrder++;
2012     }
2013     ASSERT(fieldOrder <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
2014     JSHandle<JSHClass> objClass = NewEcmaDynClass(JSObject::SIZE, JSType::JS_OBJECT, fieldOrder);
2015     objClass->SetPrototype(thread_, proto.GetTaggedValue());
2016     {
2017         objClass->SetExtensible(true);
2018         objClass->SetIsLiteral(true);
2019         objClass->SetLayout(thread_, layoutInfoHandle);
2020         objClass->SetNumberOfProps(fieldOrder);
2021     }
2022     return objClass;
2023 }
2024 
NewJSObjectByClass(const JSHandle<TaggedArray> & properties,size_t length)2025 JSHandle<JSObject> ObjectFactory::NewJSObjectByClass(const JSHandle<TaggedArray> &properties, size_t length)
2026 {
2027     JSHandle<JSHClass> dynclass = CreateObjectClass(properties, length);
2028     JSHandle<JSObject> obj = NewJSObject(dynclass);
2029     return obj;
2030 }
2031 
NewEmptyJSObject()2032 JSHandle<JSObject> ObjectFactory::NewEmptyJSObject()
2033 {
2034     JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
2035     JSHandle<JSTaggedValue> builtinObj = env->GetObjectFunction();
2036     return NewJSObjectByConstructor(JSHandle<JSFunction>(builtinObj), builtinObj);
2037 }
2038 
ResolveString(uint32_t stringId)2039 EcmaString *ObjectFactory::ResolveString(uint32_t stringId)
2040 {
2041     JSMethod *caller = InterpretedFrameHandler(thread_).GetMethod();
2042     auto *pf = caller->GetPandaFile();
2043     auto id = panda_file::File::EntityId(stringId);
2044     auto foundStr = pf->GetStringData(id);
2045 
2046     return GetRawStringFromStringTable(foundStr.data, foundStr.utf16_length, foundStr.is_ascii);
2047 }
2048 
NewSpaceBySnapShotAllocator(size_t size)2049 uintptr_t ObjectFactory::NewSpaceBySnapShotAllocator(size_t size)
2050 {
2051     NewObjectHook();
2052     return heap_->AllocateSnapShotSpace(size);
2053 }
2054 
NewMachineCodeObject(size_t length,const uint8_t * data)2055 JSHandle<MachineCode> ObjectFactory::NewMachineCodeObject(size_t length, const uint8_t *data)
2056 {
2057     NewObjectHook();
2058     TaggedObject *obj = heap_->AllocateMachineCodeObject(JSHClass::Cast(
2059         thread_->GlobalConstants()->GetMachineCodeClass().GetTaggedObject()), length + MachineCode::SIZE);
2060     MachineCode *code = MachineCode::Cast(obj);
2061     code->SetInstructionSizeInBytes(static_cast<uint32_t>(length));
2062     if (data != nullptr) {
2063         code->SetData(data, length);
2064     }
2065     JSHandle<MachineCode> codeObj(thread_, code);
2066     return codeObj;
2067 }
2068 
NewClassInfoExtractor(JSMethod * ctorMethod)2069 JSHandle<ClassInfoExtractor> ObjectFactory::NewClassInfoExtractor(JSMethod *ctorMethod)
2070 {
2071     NewObjectHook();
2072     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2073         JSHClass::Cast(thread_->GlobalConstants()->GetClassInfoExtractorHClass().GetTaggedObject()));
2074     JSHandle<ClassInfoExtractor> obj(thread_, header);
2075     obj->ClearBitField();
2076     obj->SetConstructorMethod(ctorMethod);
2077     JSHandle<TaggedArray> emptyArray = EmptyArray();
2078     obj->SetPrototypeHClass(thread_, JSTaggedValue::Undefined());
2079     obj->SetNonStaticKeys(thread_, emptyArray, SKIP_BARRIER);
2080     obj->SetNonStaticProperties(thread_, emptyArray, SKIP_BARRIER);
2081     obj->SetNonStaticElements(thread_, emptyArray, SKIP_BARRIER);
2082     obj->SetConstructorHClass(thread_, JSTaggedValue::Undefined());
2083     obj->SetStaticKeys(thread_, emptyArray, SKIP_BARRIER);
2084     obj->SetStaticProperties(thread_, emptyArray, SKIP_BARRIER);
2085     obj->SetStaticElements(thread_, emptyArray, SKIP_BARRIER);
2086     return obj;
2087 }
2088 
2089 // ----------------------------------- new TSType ----------------------------------------
CreateTSObjLayoutInfo(int propNum,JSTaggedValue initVal)2090 JSHandle<TSObjLayoutInfo> ObjectFactory::CreateTSObjLayoutInfo(int propNum, JSTaggedValue initVal)
2091 {
2092     int arrayLength = TSObjLayoutInfo::ComputeArrayLength(propNum);
2093     JSHandle<TSObjLayoutInfo> tsPropInfoHandle = JSHandle<TSObjLayoutInfo>::Cast(NewTaggedArray(arrayLength, initVal));
2094     tsPropInfoHandle->SetNumberOfElements(thread_, 0);
2095     return tsPropInfoHandle;
2096 }
2097 
NewTSObjectType(uint32_t numOfKeys)2098 JSHandle<TSObjectType> ObjectFactory::NewTSObjectType(uint32_t numOfKeys)
2099 {
2100     NewObjectHook();
2101 
2102     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2103         JSHClass::Cast(thread_->GlobalConstants()->GetTSObjectTypeClass().GetTaggedObject()));
2104     JSHandle<TSObjectType> objectType(thread_, header);
2105 
2106     objectType->SetGTRef(GlobalTSTypeRef::Default());
2107 
2108     JSHandle<TSObjLayoutInfo> tsPropInfo = CreateTSObjLayoutInfo(numOfKeys);
2109     objectType->SetObjLayoutInfo(thread_, tsPropInfo);
2110 
2111     objectType->SetHClass(thread_, JSTaggedValue::Undefined());
2112 
2113     return objectType;
2114 }
2115 
NewTSClassType()2116 JSHandle<TSClassType> ObjectFactory::NewTSClassType()
2117 {
2118     NewObjectHook();
2119 
2120     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2121         JSHClass::Cast(thread_->GlobalConstants()->GetTSClassTypeClass().GetTaggedObject()));
2122     JSHandle<TSClassType> classType(thread_, header);
2123 
2124     classType->SetGTRef(GlobalTSTypeRef::Default());
2125     classType->SetInstanceType(thread_, JSTaggedValue::Undefined());
2126     classType->SetConstructorType(thread_, JSTaggedValue::Undefined());
2127     classType->SetPrototypeType(thread_, JSTaggedValue::Undefined());
2128     classType->SetExtensionType(thread_, JSTaggedValue::Undefined());
2129 
2130     return classType;
2131 }
2132 
NewTSInterfaceType()2133 JSHandle<TSInterfaceType> ObjectFactory::NewTSInterfaceType()
2134 {
2135     NewObjectHook();
2136 
2137     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2138         JSHClass::Cast(thread_->GlobalConstants()->GetTSInterfaceTypeClass().GetTaggedObject()));
2139     JSHandle<TSInterfaceType> interfaceType(thread_, header);
2140 
2141     JSHandle<TaggedArray> extends = EmptyArray();
2142     interfaceType->SetGTRef(GlobalTSTypeRef::Default());
2143     interfaceType->SetExtends(thread_, extends);
2144     interfaceType->SetFields(thread_, JSTaggedValue::Undefined());
2145 
2146     return interfaceType;
2147 }
2148 
2149 
NewTSUnionType(uint32_t length)2150 JSHandle<TSUnionType> ObjectFactory::NewTSUnionType(uint32_t length)
2151 {
2152     NewObjectHook();
2153     ASSERT(length > 0);
2154 
2155     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2156         JSHClass::Cast(thread_->GlobalConstants()->GetTSUnionTypeClass().GetTaggedObject()));
2157     JSHandle<TSUnionType> unionType(thread_, header);
2158 
2159     unionType->SetGTRef(GlobalTSTypeRef::Default());
2160     JSHandle<TaggedArray> componentTypes = NewTaggedArray(length, JSTaggedValue::Undefined());
2161     unionType->SetComponentTypes(thread_, componentTypes);
2162 
2163     return unionType;
2164 }
2165 
NewTSClassInstanceType()2166 JSHandle<TSClassInstanceType> ObjectFactory::NewTSClassInstanceType()
2167 {
2168     NewObjectHook();
2169 
2170     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2171         JSHClass::Cast(thread_->GlobalConstants()->GetTSClassInstanceTypeClass().GetTaggedObject()));
2172     JSHandle<TSClassInstanceType> classInstanceType(thread_, header);
2173 
2174     classInstanceType->SetGTRef(GlobalTSTypeRef::Default());
2175     classInstanceType->SetCreateClassType(JSTaggedValue::Undefined());
2176 
2177     return classInstanceType;
2178 }
2179 
NewTSImportType()2180 JSHandle<TSImportType> ObjectFactory::NewTSImportType()
2181 {
2182     NewObjectHook();
2183 
2184     TaggedObject *header = heap_->AllocateYoungOrHugeObject(
2185         JSHClass::Cast(thread_->GlobalConstants()->GetTSImportTypeClass().GetTaggedObject()));
2186     JSHandle<TSImportType> importType(thread_, header);
2187 
2188     importType->SetGTRef(GlobalTSTypeRef::Default());
2189     importType->SetTargetType(thread_, JSTaggedValue::Undefined());
2190     importType->SetImportPath(thread_, JSTaggedValue::Undefined());
2191 
2192     return importType;
2193 }
2194 
NewTSTypeTable(uint32_t length)2195 JSHandle<TSTypeTable> ObjectFactory::NewTSTypeTable(uint32_t length)
2196 {
2197     NewObjectHook();
2198     ASSERT(length > 0);
2199 
2200     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length + TSTypeTable::RESERVE_TABLE_LENGTH);
2201     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2202     auto header = heap_->AllocateOldOrHugeObject(arrayClass, size);
2203 
2204     JSHandle<TSTypeTable> table(thread_, header);
2205     table->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length + TSTypeTable::RESERVE_TABLE_LENGTH);
2206 
2207     return table;
2208 }
2209 
NewTSModuleTable(uint32_t length)2210 JSHandle<TSModuleTable> ObjectFactory::NewTSModuleTable(uint32_t length)
2211 {
2212     NewObjectHook();
2213     ASSERT(length > 0);
2214 
2215     size_t size = TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), length);
2216     JSHClass *arrayClass = JSHClass::Cast(thread_->GlobalConstants()->GetArrayClass().GetTaggedObject());
2217     auto header = heap_->AllocateYoungOrHugeObject(arrayClass, size);
2218     JSHandle<TSModuleTable> array(thread_, header);
2219     array->InitializeWithSpecialValue(JSTaggedValue::Undefined(), length);
2220     array->InitializeNumberOfTSTypeTable(thread_);
2221 
2222     return array;
2223 }
2224 // ----------------------------------- new string ----------------------------------------
NewFromString(const CString & data)2225 JSHandle<EcmaString> ObjectFactory::NewFromString(const CString &data)
2226 {
2227     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
2228     bool canBeCompress = EcmaString::CanBeCompressed(utf8Data, data.length());
2229     return GetStringFromStringTable(utf8Data, data.length(), canBeCompress);
2230 }
2231 
NewFromCanBeCompressString(const CString & data)2232 JSHandle<EcmaString> ObjectFactory::NewFromCanBeCompressString(const CString &data)
2233 {
2234     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
2235     ASSERT(EcmaString::CanBeCompressed(utf8Data, data.length()));
2236     return GetStringFromStringTable(utf8Data, data.length(), true);
2237 }
2238 
NewFromStdString(const std::string & data)2239 JSHandle<EcmaString> ObjectFactory::NewFromStdString(const std::string &data)
2240 {
2241     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
2242     bool canBeCompress = EcmaString::CanBeCompressed(utf8Data, data.length());
2243     return GetStringFromStringTable(utf8Data, data.size(), canBeCompress);
2244 }
2245 
NewFromStdStringUnCheck(const std::string & data,bool canBeCompress)2246 JSHandle<EcmaString> ObjectFactory::NewFromStdStringUnCheck(const std::string &data, bool canBeCompress)
2247 {
2248     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
2249     return GetStringFromStringTable(utf8Data, data.size(), canBeCompress);
2250 }
2251 
NewFromUtf8(const CString & data)2252 JSHandle<EcmaString> ObjectFactory::NewFromUtf8(const CString &data)
2253 {
2254     auto utf8Data = reinterpret_cast<const uint8_t *>(data.c_str());
2255     bool canBeCompress = EcmaString::CanBeCompressed(utf8Data, data.length());
2256     return GetStringFromStringTable(utf8Data, data.length(), canBeCompress);
2257 }
2258 
NewFromUtf8(const uint8_t * utf8Data,uint32_t utf8Len)2259 JSHandle<EcmaString> ObjectFactory::NewFromUtf8(const uint8_t *utf8Data, uint32_t utf8Len)
2260 {
2261     bool canBeCompress = EcmaString::CanBeCompressed(utf8Data, utf8Len);
2262     return GetStringFromStringTable(utf8Data, utf8Len, canBeCompress);
2263 }
2264 
NewFromUtf8UnCheck(const uint8_t * utf8Data,uint32_t utf8Len,bool canBeCompress)2265 JSHandle<EcmaString> ObjectFactory::NewFromUtf8UnCheck(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress)
2266 {
2267     return GetStringFromStringTable(utf8Data, utf8Len, canBeCompress);
2268 }
2269 
NewFromUtf16(const uint16_t * utf16Data,uint32_t utf16Len)2270 JSHandle<EcmaString> ObjectFactory::NewFromUtf16(const uint16_t *utf16Data, uint32_t utf16Len)
2271 {
2272     bool canBeCompress = EcmaString::CanBeCompressed(utf16Data, utf16Len);
2273     return GetStringFromStringTable(utf16Data, utf16Len, canBeCompress);
2274 }
2275 
NewFromUtf16UnCheck(const uint16_t * utf16Data,uint32_t utf16Len,bool canBeCompress)2276 JSHandle<EcmaString> ObjectFactory::NewFromUtf16UnCheck(const uint16_t *utf16Data, uint32_t utf16Len,
2277                                                         bool canBeCompress)
2278 {
2279     return GetStringFromStringTable(utf16Data, utf16Len, canBeCompress);
2280 }
2281 
NewFromUtf8Literal(const uint8_t * utf8Data,uint32_t utf8Len)2282 JSHandle<EcmaString> ObjectFactory::NewFromUtf8Literal(const uint8_t *utf8Data, uint32_t utf8Len)
2283 {
2284     NewObjectHook();
2285     bool canBeCompress = EcmaString::CanBeCompressed(utf8Data, utf8Len);
2286     return JSHandle<EcmaString>(thread_, EcmaString::CreateFromUtf8(utf8Data, utf8Len, vm_, canBeCompress));
2287 }
2288 
NewFromUtf8LiteralUnCheck(const uint8_t * utf8Data,uint32_t utf8Len,bool canBeCompress)2289 JSHandle<EcmaString> ObjectFactory::NewFromUtf8LiteralUnCheck(const uint8_t *utf8Data, uint32_t utf8Len,
2290                                                               bool canBeCompress)
2291 {
2292     NewObjectHook();
2293     return JSHandle<EcmaString>(thread_, EcmaString::CreateFromUtf8(utf8Data, utf8Len, vm_, canBeCompress));
2294 }
2295 
NewFromUtf16Literal(const uint16_t * utf16Data,uint32_t utf16Len)2296 JSHandle<EcmaString> ObjectFactory::NewFromUtf16Literal(const uint16_t *utf16Data, uint32_t utf16Len)
2297 {
2298     NewObjectHook();
2299     bool canBeCompress = EcmaString::CanBeCompressed(utf16Data, utf16Len);
2300     return JSHandle<EcmaString>(thread_, EcmaString::CreateFromUtf16(utf16Data, utf16Len, vm_, canBeCompress));
2301 }
2302 
NewFromUtf16LiteralUnCheck(const uint16_t * utf16Data,uint32_t utf16Len,bool canBeCompress)2303 JSHandle<EcmaString> ObjectFactory::NewFromUtf16LiteralUnCheck(const uint16_t *utf16Data, uint32_t utf16Len,
2304                                                                bool canBeCompress)
2305 {
2306     NewObjectHook();
2307     return JSHandle<EcmaString>(thread_, EcmaString::CreateFromUtf16(utf16Data, utf16Len, vm_, canBeCompress));
2308 }
2309 
NewFromString(EcmaString * str)2310 JSHandle<EcmaString> ObjectFactory::NewFromString(EcmaString *str)
2311 {
2312     return GetStringFromStringTable(str);
2313 }
2314 
ConcatFromString(const JSHandle<EcmaString> & firstString,const JSHandle<EcmaString> & secondString)2315 JSHandle<EcmaString> ObjectFactory::ConcatFromString(const JSHandle<EcmaString> &firstString,
2316                                                      const JSHandle<EcmaString> &secondString)
2317 {
2318     if (firstString->GetLength() == 0) {
2319         return secondString;
2320     }
2321     if (secondString->GetLength() == 0) {
2322         return firstString;
2323     }
2324     return GetStringFromStringTable(firstString, secondString);
2325 }
2326 
GetStringFromStringTable(const JSHandle<EcmaString> & firstString,const JSHandle<EcmaString> & secondString)2327 JSHandle<EcmaString> ObjectFactory::GetStringFromStringTable(const JSHandle<EcmaString> &firstString,
2328                                                              const JSHandle<EcmaString> &secondString)
2329 {
2330     auto stringTable = vm_->GetEcmaStringTable();
2331     return JSHandle<EcmaString>(thread_, stringTable->GetOrInternString(firstString, secondString));
2332 }
2333 
NewJSAPIArrayList(uint32_t capacity)2334 JSHandle<JSAPIArrayList> ObjectFactory::NewJSAPIArrayList(uint32_t capacity)
2335 {
2336     NewObjectHook();
2337     JSHandle<JSTaggedValue> builtinObj(thread_, thread_->GlobalConstants()->GetArrayListFunction());
2338     JSHandle<JSAPIArrayList> obj =
2339         JSHandle<JSAPIArrayList>(NewJSObjectByConstructor(JSHandle<JSFunction>(builtinObj), builtinObj));
2340     ObjectFactory *factory = thread_->GetEcmaVM()->GetFactory();
2341     obj->SetElements(thread_, factory->NewTaggedArray(capacity));
2342 
2343     return obj;
2344 }
2345 
NewJSAPIArrayListIterator(const JSHandle<JSAPIArrayList> & arrayList)2346 JSHandle<JSAPIArrayListIterator> ObjectFactory::NewJSAPIArrayListIterator(const JSHandle<JSAPIArrayList> &arrayList)
2347 {
2348     NewObjectHook();
2349     JSHandle<JSTaggedValue> protoValue(thread_, thread_->GlobalConstants()->GetArrayListIteratorPrototype());
2350     JSHandle<JSHClass> dynHandle =
2351         NewEcmaDynClass(JSAPIArrayListIterator::SIZE, JSType::JS_API_ARRAYLIST_ITERATOR, protoValue);
2352     JSHandle<JSAPIArrayListIterator> iter(NewJSObject(dynHandle));
2353     iter->GetJSHClass()->SetExtensible(true);
2354     iter->SetIteratedArrayList(thread_, arrayList);
2355     iter->SetNextIndex(thread_, JSTaggedValue(0));
2356     return iter;
2357 }
2358 
NewJSAPITreeMapIterator(const JSHandle<JSAPITreeMap> & map,IterationKind kind)2359 JSHandle<JSAPITreeMapIterator> ObjectFactory::NewJSAPITreeMapIterator(const JSHandle<JSAPITreeMap> &map,
2360                                                                       IterationKind kind)
2361 {
2362     NewObjectHook();
2363     JSHandle<JSTaggedValue> proto(thread_, thread_->GlobalConstants()->GetTreeMapIteratorPrototype());
2364     JSHandle<JSHClass> dynHandle = NewEcmaDynClass(JSAPITreeMapIterator::SIZE, JSType::JS_API_TREEMAP_ITERATOR, proto);
2365     JSHandle<JSAPITreeMapIterator> iter(NewJSObject(dynHandle));
2366     iter->GetJSHClass()->SetExtensible(true);
2367     iter->SetIteratedMap(thread_, map);
2368     iter->SetNextIndex(thread_, JSTaggedValue(0));
2369     iter->SetIterationKind(thread_, JSTaggedValue(static_cast<int>(kind)));
2370     JSHandle<TaggedTreeMap> tmap(thread_, map->GetTreeMap());
2371     JSHandle<TaggedArray> entries = TaggedTreeMap::GetArrayFromMap(thread_, tmap);
2372     iter->SetEntries(thread_, entries);
2373     return iter;
2374 }
2375 
NewJSAPITreeSetIterator(const JSHandle<JSAPITreeSet> & set,IterationKind kind)2376 JSHandle<JSAPITreeSetIterator> ObjectFactory::NewJSAPITreeSetIterator(const JSHandle<JSAPITreeSet> &set,
2377                                                                       IterationKind kind)
2378 {
2379     NewObjectHook();
2380     JSHandle<JSTaggedValue> proto(thread_, thread_->GlobalConstants()->GetTreeSetIteratorPrototype());
2381     JSHandle<JSHClass> dynHandle = NewEcmaDynClass(JSAPITreeSetIterator::SIZE, JSType::JS_API_TREESET_ITERATOR, proto);
2382     JSHandle<JSAPITreeSetIterator> iter(NewJSObject(dynHandle));
2383     iter->GetJSHClass()->SetExtensible(true);
2384     iter->SetIteratedSet(thread_, set);
2385     iter->SetNextIndex(thread_, JSTaggedValue(0));
2386     iter->SetIterationKind(thread_, JSTaggedValue(static_cast<int>(kind)));
2387     JSHandle<TaggedTreeSet> tset(thread_, set->GetTreeSet());
2388     JSHandle<TaggedArray> entries = TaggedTreeSet::GetArrayFromSet(thread_, tset);
2389     iter->SetEntries(thread_, entries);
2390     return iter;
2391 }
2392 }  // namespace panda::ecmascript
2393