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