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