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