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> ®exp, 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