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