1 /*
2 * Copyright (c) 2023-2024 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/builtins/builtins.h"
17
18 #include "ecmascript/builtins/builtins_function.h"
19 #include "ecmascript/builtins/builtins_object.h"
20 #include "ecmascript/builtins/builtins_symbol.h"
21 #include "ecmascript/builtins/builtins_sendable_arraybuffer.h"
22 #include "ecmascript/builtins/builtins_shared_async_function.h"
23 #include "ecmascript/builtins/builtins_shared_function.h"
24 #include "ecmascript/builtins/builtins_shared_object.h"
25 #include "ecmascript/builtins/builtins_shared_map.h"
26 #include "ecmascript/builtins/builtins_shared_set.h"
27 #include "ecmascript/builtins/builtins_shared_typedarray.h"
28 #include "ecmascript/containers/containers_bitvector.h"
29 #include "ecmascript/js_api/js_api_bitvector.h"
30 #include "ecmascript/shared_objects/js_shared_array.h"
31 #include "ecmascript/shared_objects/js_sendable_arraybuffer.h"
32 #include "ecmascript/shared_objects/js_shared_map.h"
33 #include "ecmascript/shared_objects/js_shared_set.h"
34 #include "ecmascript/shared_objects/js_shared_typed_array.h"
35 #include "ecmascript/js_async_function.h"
36 #include "ecmascript/js_object-inl.h"
37 #include "ecmascript/symbol_table.h"
38 #include "ecmascript/builtins/builtins_shared_array.h"
39
40 namespace panda::ecmascript {
41 using BuiltinsSharedObject = builtins::BuiltinsSharedObject;
42 using BuiltinsSharedFunction = builtins::BuiltinsSharedFunction;
43 using BuiltinsSharedAsyncFunction = builtins::BuiltinsSharedAsyncFunction;
44 using Function = builtins::BuiltinsFunction;
45 using Object = builtins::BuiltinsObject;
46 using BuiltinsSharedSet = builtins::BuiltinsSharedSet;
47 using BuiltinsSharedMap = builtins::BuiltinsSharedMap;
48 using BuiltinsSharedArray = builtins::BuiltinsSharedArray;
49 using BuiltinsSharedTypedArray = builtins::BuiltinsSharedTypedArray;
50 using BuiltinsSendableArrayBuffer = builtins::BuiltinsSendableArrayBuffer;
51 using ContainersBitVector = containers::ContainersBitVector;
52
InitializeSObjectAndSFunction(const JSHandle<GlobalEnv> & env) const53 void Builtins::InitializeSObjectAndSFunction(const JSHandle<GlobalEnv> &env) const
54 {
55 [[maybe_unused]] EcmaHandleScope scope(thread_);
56 // SharedObject.prototype[hclass]
57 JSHandle<JSHClass> sobjPrototypeHClass = CreateSObjectPrototypeHClass();
58 // SharedObject.prototype
59 JSHandle<JSObject> sObjPrototype =
60 factory_->NewSharedOldSpaceJSObject(sobjPrototypeHClass);
61 JSHandle<JSTaggedValue> sObjPrototypeVal(sObjPrototype);
62 // SharedObject.prototype_or_hclass
63 auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
64 JSHandle<JSHClass> sObjIHClass =
65 factory_->NewSEcmaHClass(JSSharedObject::SIZE, 0, JSType::JS_SHARED_OBJECT, sObjPrototypeVal,
66 emptySLayout);
67 // SharedFunction.prototype_or_hclass
68 JSHandle<JSHClass> sFuncPrototypeHClass = CreateSFunctionPrototypeHClass(sObjPrototypeVal);
69 // SharedFunction.prototype
70 JSHandle<JSFunction> sFuncPrototype = factory_->NewSFunctionByHClass(
71 reinterpret_cast<void *>(Function::FunctionPrototypeInvokeSelf), sFuncPrototypeHClass,
72 FunctionKind::NORMAL_FUNCTION);
73 InitializeSFunction(env, sFuncPrototype);
74 InitializeSAsyncFunction(env, sObjIHClass);
75 InitializeSObject(env, sObjIHClass, sObjPrototype, sFuncPrototype);
76 InitializeSSet(env, sObjPrototype, sFuncPrototype);
77 InitializeSMap(env, sObjPrototype, sFuncPrototype);
78 InitializeSharedArray(env, sObjPrototype, sFuncPrototype);
79 InitializeSTypedArray(env, sObjPrototype, sFuncPrototype);
80 InitializeSArrayBuffer(env, sObjPrototype, sFuncPrototype);
81 InitializeSModuleNamespace(env, sObjIHClass);
82 env->SetSObjectFunctionPrototype(thread_, sObjPrototype);
83 }
84
CopySObjectAndSFunction(const JSHandle<GlobalEnv> & env,const JSTaggedValue & srcEnv) const85 void Builtins::CopySObjectAndSFunction(const JSHandle<GlobalEnv> &env, const JSTaggedValue &srcEnv) const
86 {
87 // Copy shareds.
88 ASSERT(srcEnv.IsJSGlobalEnv());
89 auto sGlobalEnv = reinterpret_cast<GlobalEnv*>(srcEnv.GetTaggedObject());
90 #define COPY_ENV_SHARED_FIELDS(Type, Name, INDEX) \
91 env->Set##Name(thread_, sGlobalEnv->Get##Name());
92 GLOBAL_ENV_SHARED_FIELDS(COPY_ENV_SHARED_FIELDS)
93 #undef COPY_ENV_SHARED_FIELDS
94 }
95
InitializeSObject(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & sObjIHClass,const JSHandle<JSObject> & sObjPrototype,const JSHandle<JSFunction> & sFuncPrototype) const96 void Builtins::InitializeSObject(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &sObjIHClass,
97 const JSHandle<JSObject> &sObjPrototype,
98 const JSHandle<JSFunction> &sFuncPrototype) const
99 {
100 [[maybe_unused]] EcmaHandleScope scope(thread_);
101 // SharedObject constructor (forbidden use NewBuiltinConstructor)
102 JSHandle<JSHClass> sObjectFunctionHClass = CreateSObjectFunctionHClass(sFuncPrototype);
103 JSHandle<JSFunction> sObjectFunction =
104 factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedObject::SharedObjectConstructor),
105 sObjectFunctionHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
106
107 InitializeSCtor(sObjIHClass, sObjectFunction, "SharedObject", FunctionLength::ONE);
108 env->SetSObjectFunction(thread_, sObjectFunction);
109 // sObject method.
110 uint32_t fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
111 for (const base::BuiltinFunctionEntry &entry : Object::GetObjectFunctions()) {
112 SetSFunction(env, JSHandle<JSObject>(sObjectFunction), entry.GetName(), entry.GetEntrypoint(),
113 fieldIndex++, entry.GetLength(), entry.GetBuiltinStubId());
114 }
115 // sObject.prototype method
116 fieldIndex = 0; // constructor
117 sObjPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, sObjectFunction.GetTaggedValue());
118 for (const base::BuiltinFunctionEntry &entry : Object::GetObjectPrototypeFunctions()) {
119 SetSFunction(env, sObjPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++, entry.GetLength(),
120 entry.GetBuiltinStubId());
121 }
122 // B.2.2.1 sObject.prototype.__proto__
123 JSHandle<JSTaggedValue> protoGetter =
124 CreateSGetterSetter(env, Object::ProtoGetter, "__proto__", FunctionLength::ZERO);
125 JSHandle<JSTaggedValue> protoSetter =
126 CreateSGetterSetter(env, Object::ProtoSetter, "__proto__", FunctionLength::ONE);
127 SetSAccessor(sObjPrototype, fieldIndex, protoGetter, protoSetter);
128 }
129
InitializeSArrayBuffer(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & sObjPrototype,const JSHandle<JSFunction> & sFuncPrototype) const130 void Builtins::InitializeSArrayBuffer(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
131 const JSHandle<JSFunction> &sFuncPrototype) const
132 {
133 [[maybe_unused]] EcmaHandleScope scope(thread_);
134 const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
135 // SendableArrayBuffer.prototype
136 JSHandle<JSHClass> arrayBufferPrototypeHClass = CreateSArrayBufferPrototypeHClass(sObjPrototype);
137 JSHandle<JSObject> arrayBufferPrototype =
138 factory_->NewSharedOldSpaceJSObjectWithInit(arrayBufferPrototypeHClass);
139
140 JSHandle<JSTaggedValue> arrayBufferPrototypeValue(arrayBufferPrototype);
141
142 // SendableArrayBuffer.prototype_or_hclass
143 auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo();
144 JSHandle<JSHClass> arrayBufferIHClass = factory_->NewSEcmaHClass(
145 JSSendableArrayBuffer::SIZE, 0, JSType::JS_SENDABLE_ARRAY_BUFFER, arrayBufferPrototypeValue, emptySLayout);
146
147 // SendableArrayBuffer = new Function()
148 JSHandle<JSHClass> arrayBufferFuncHClass = CreateSArrayBufferFunctionHClass(sFuncPrototype);
149
150 JSHandle<JSFunction> arrayBufferFunction =
151 factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSendableArrayBuffer::ArrayBufferConstructor),
152 arrayBufferFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
153
154 InitializeSCtor(arrayBufferIHClass, arrayBufferFunction, "SendableArrayBuffer", FunctionLength::ONE);
155 JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
156 JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableArrayBuffer"));
157 PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(arrayBufferFunction), true, false, true);
158 JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
159 RETURN_IF_ABRUPT_COMPLETION(thread_);
160
161 // SendableArrayBuffer prototype method
162 uint32_t fieldIndex = 0;
163 SetSFunction(env, arrayBufferPrototype, "slice",
164 BuiltinsSendableArrayBuffer::Slice, fieldIndex++, FunctionLength::TWO);
165
166 // 24.1.4.1 get SendableArrayBuffer.prototype.byteLength
167 JSHandle<JSTaggedValue> lengthGetter =
168 CreateSGetterSetter(env, BuiltinsSendableArrayBuffer::GetByteLength, "byteLength", FunctionLength::ZERO);
169 SetSAccessor(
170 JSHandle<JSObject>(arrayBufferPrototype), fieldIndex++, lengthGetter, globalConst->GetHandledUndefined());
171
172 // 24.1.4.4 SendableArrayBuffer.prototype[@@toStringTag]
173 JSHandle<JSTaggedValue> strTag(factory_->NewFromUtf8ReadOnly("SendableArrayBuffer"));
174 arrayBufferPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, strTag.GetTaggedValue());
175
176 // 24.1.3.3 get SendableArrayBuffer[@@species]
177 fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
178 JSHandle<JSTaggedValue> speciesGetter =
179 CreateSGetterSetter(env, BuiltinsSendableArrayBuffer::Species, "[Symbol.species]", FunctionLength::ZERO);
180 SetSAccessor(
181 JSHandle<JSObject>(arrayBufferFunction), fieldIndex++, speciesGetter, globalConst->GetHandledUndefined());
182
183 // SendableArrayBuffer method
184 for (const base::BuiltinFunctionEntry& entry: BuiltinsSendableArrayBuffer::GetArrayBufferFunctions()) {
185 SetSFunction(env, JSHandle<JSObject>(arrayBufferFunction), entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
186 entry.GetLength(), entry.GetBuiltinStubId());
187 }
188
189 env->SetSendableArrayBufferPrototype(thread_, arrayBufferPrototype);
190 env->SetSBuiltininArrayBufferFunction(thread_, arrayBufferFunction);
191 }
192
InitializeSSet(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & sObjPrototype,const JSHandle<JSFunction> & sFuncPrototype) const193 void Builtins::InitializeSSet(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
194 const JSHandle<JSFunction> &sFuncPrototype) const
195 {
196 [[maybe_unused]] EcmaHandleScope scope(thread_);
197 const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
198 // SharedSet.prototype
199 JSHandle<JSHClass> setPrototypeHClass = CreateSSetPrototypeHClass(sObjPrototype);
200 JSHandle<JSObject> setPrototype =
201 factory_->NewSharedOldSpaceJSObjectWithInit(setPrototypeHClass);
202
203 JSHandle<JSTaggedValue> setPrototypeValue(setPrototype);
204 // SharedSet.prototype_or_hclass
205 auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo();
206 JSHandle<JSHClass> setIHClass =
207 factory_->NewSEcmaHClass(JSSharedSet::SIZE, 0, JSType::JS_SHARED_SET, setPrototypeValue, emptySLayout);
208 // SharedSet.hclass
209 JSHandle<JSHClass> setFuncHClass = CreateSSetFunctionHClass(sFuncPrototype);
210 // SharedSet() = new Function()
211 JSHandle<JSFunction> setFunction =
212 factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedSet::Constructor),
213 setFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
214
215 InitializeSCtor(setIHClass, setFunction, "SendableSet", FunctionLength::ZERO);
216 JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
217 JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableSet"));
218 PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(setFunction), true, false, true);
219 JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
220 RETURN_IF_ABRUPT_COMPLETION(thread_);
221
222 // "constructor" property on the prototype
223 uint32_t fieldIndex = 0; // constructor
224 setPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, setFunction.GetTaggedValue());
225
226 // SharedSet.prototype functions, excluding keys()
227 for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedSet::GetSetPrototypeFunctions()) {
228 SetSFunction(env, setPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
229 entry.GetLength(), entry.GetBuiltinStubId());
230 }
231 // SharedSet.prototype.keys, which is strictly equal to Set.prototype.values
232 JSHandle<JSTaggedValue> keys(factory_->NewFromASCIIReadOnly("keys"));
233 JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
234 JSHandle<JSTaggedValue> valuesFunc =
235 JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(setPrototype), values);
236 RETURN_IF_ABRUPT_COMPLETION(thread_);
237 setPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, valuesFunc.GetTaggedValue());
238
239 // @@ToStringTag
240 JSHandle<JSTaggedValue> strTag(factory_->NewFromUtf8ReadOnly("SendableSet"));
241 setPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, strTag.GetTaggedValue());
242
243 // 23.1.3.10get SharedSet.prototype.size
244 JSHandle<JSTaggedValue> sizeGetter = CreateSGetterSetter(env, BuiltinsSharedSet::GetSize, "size",
245 FunctionLength::ZERO);
246 SetSAccessor(setPrototype, fieldIndex++, sizeGetter, globalConst->GetHandledUndefined());
247
248 // %SetPrototype% [ @@iterator ]
249 setPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, valuesFunc.GetTaggedValue());
250
251 fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
252 // 23.1.2.2get SharedSet [ @@species ]
253 JSHandle<JSTaggedValue> speciesGetter =
254 CreateSGetterSetter(env, BuiltinsSharedSet::Species, "[Symbol.species]", FunctionLength::ZERO);
255 SetSAccessor(JSHandle<JSObject>(setFunction), fieldIndex, speciesGetter, globalConst->GetHandledUndefined());
256
257 env->SetSharedSetPrototype(thread_, setPrototype);
258 env->SetSBuiltininSetFunction(thread_, setFunction);
259 }
260
InitializeSMap(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & sObjPrototype,const JSHandle<JSFunction> & sFuncPrototype) const261 void Builtins::InitializeSMap(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
262 const JSHandle<JSFunction> &sFuncPrototype) const
263 {
264 [[maybe_unused]] EcmaHandleScope scope(thread_);
265 const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
266 // SharedMap.prototype
267 JSHandle<JSHClass> mapPrototypeHClass = CreateSMapPrototypeHClass(sObjPrototype);
268 JSHandle<JSObject> mapPrototype =
269 factory_->NewSharedOldSpaceJSObjectWithInit(mapPrototypeHClass);
270 JSHandle<JSTaggedValue> mapPrototypeValue(mapPrototype);
271 // SharedMap.prototype_or_hclass
272 auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo();
273 JSHandle<JSHClass> mapIHClass =
274 factory_->NewSEcmaHClass(JSSharedMap::SIZE, 0, JSType::JS_SHARED_MAP, mapPrototypeValue, emptySLayout);
275 // SharedMap.hclass
276 JSHandle<JSHClass> mapFuncHClass = CreateSMapFunctionHClass(sFuncPrototype);
277 // SharedMap() = new Function()
278 JSHandle<JSFunction> mapFunction =
279 factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedMap::Constructor),
280 mapFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
281 InitializeSCtor(mapIHClass, mapFunction, "SendableMap", FunctionLength::ZERO);
282 JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
283 JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableMap"));
284 PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(mapFunction), true, false, true);
285 JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
286 RETURN_IF_ABRUPT_COMPLETION(thread_);
287
288 // "constructor" property on the prototype
289 uint32_t fieldIndex = 0; // constructor
290 mapPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, mapFunction.GetTaggedValue());
291 // SharedMap.prototype functions
292 for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedMap::GetMapPrototypeFunctions()) {
293 SetSFunction(env, mapPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
294 entry.GetLength(), entry.GetBuiltinStubId());
295 }
296 // @@ToStringTag
297 JSHandle<JSTaggedValue> strTag(factory_->NewFromUtf8ReadOnly("SendableMap"));
298 mapPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, strTag.GetTaggedValue());
299
300 // 23.1.3.10get SharedMap.prototype.size
301 JSHandle<JSTaggedValue> sizeGetter = CreateSGetterSetter(env, BuiltinsSharedMap::GetSize, "size",
302 FunctionLength::ZERO);
303 SetSAccessor(mapPrototype, fieldIndex++, sizeGetter, globalConst->GetHandledUndefined());
304
305 // %MapPrototype% [ @@iterator ]
306 JSHandle<JSTaggedValue> entries(factory_->NewFromASCIIReadOnly("entries"));
307 JSHandle<JSTaggedValue> entriesFunc =
308 JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(mapPrototype), entries);
309 RETURN_IF_ABRUPT_COMPLETION(thread_);
310 mapPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, entriesFunc.GetTaggedValue());
311
312 fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
313 // 23.1.2.2get SharedMap [ @@species ]
314 JSHandle<JSTaggedValue> speciesGetter =
315 CreateSGetterSetter(env, BuiltinsSharedMap::Species, "[Symbol.species]", FunctionLength::ZERO);
316 SetSAccessor(JSHandle<JSObject>(mapFunction), fieldIndex, speciesGetter, globalConst->GetHandledUndefined());
317
318 env->SetSharedMapPrototype(thread_, mapPrototype);
319 env->SetSBuiltininMapFunction(thread_, mapFunction);
320 }
321
InitializeSModuleNamespace(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & sObjIHClass) const322 void Builtins::InitializeSModuleNamespace(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &sObjIHClass) const
323 {
324 [[maybe_unused]] EcmaHandleScope scope(thread_);
325 // SharedModuleNamespace.prototype
326 JSHandle<JSObject> moduleNamespacePrototype = factory_->NewSharedOldSpaceJSObjectWithInit(sObjIHClass);
327 JSHandle<JSTaggedValue> moduleNamespacePrototypeValue(moduleNamespacePrototype);
328
329 // SharedModuleNamespace.prototype_or_hclass
330 auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
331
332 JSHandle<JSHClass> moduleNamespaceHClass = factory_->NewSEcmaHClass(ModuleNamespace::SIZE, 0,
333 JSType::JS_MODULE_NAMESPACE, moduleNamespacePrototypeValue, emptySLayout);
334 moduleNamespaceHClass->SetPrototype(thread_, JSTaggedValue::Null());
335 env->SetSharedModuleNamespaceClass(thread_, moduleNamespaceHClass.GetTaggedValue());
336
337 // SharedmoduleNamespace.prototype [ @@toStringTag ]
338 SetStringTagSymbol(env, moduleNamespacePrototype, "Module");
339 }
340
InitializeSAsyncFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSHClass> & sObjIHClass) const341 void Builtins::InitializeSAsyncFunction(const JSHandle<GlobalEnv> &env,
342 const JSHandle<JSHClass> &sObjIHClass) const
343 {
344 // SharedAsyncFunction.prototype
345 JSHandle<JSObject> sAsyncFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(sObjIHClass);
346 JSObject::SetPrototype(thread_, sAsyncFuncPrototype, env->GetSFunctionPrototype());
347 // SharedAsyncFunction.prototype_or_hclass
348 auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
349 JSHandle<JSHClass> sAsyncFuncIHClass = factory_->NewSEcmaHClass(JSAsyncFunction::SIZE, 0,
350 JSType::JS_SHARED_ASYNC_FUNCTION, JSHandle<JSTaggedValue>(sAsyncFuncPrototype), emptySLayout);
351 // SharedAsyncFunction = new SharedFunction()
352 JSHandle<JSFunction> sAsyncFuncFunction = factory_->NewSFunctionByHClass(
353 reinterpret_cast<void *>(BuiltinsSharedAsyncFunction::SharedAsyncFunctionConstructor),
354 sAsyncFuncIHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
355 JSObject::SetPrototype(thread_, JSHandle<JSObject>(sAsyncFuncFunction), env->GetSFunctionFunction());
356 sAsyncFuncFunction->SetProtoOrHClass(thread_, sAsyncFuncIHClass);
357 env->SetSAsyncFunctionFunction(thread_, sAsyncFuncFunction);
358 env->SetSAsyncFunctionPrototype(thread_, sAsyncFuncPrototype);
359 JSHandle<JSTaggedValue> sAsyncFuncPrototypeVal(thread_, sAsyncFuncPrototype.GetTaggedValue());
360 JSHandle<JSHClass> sAsyncFuncClass = factory_->CreateSFunctionClass(
361 JSAsyncFunction::SIZE, JSType::JS_SHARED_ASYNC_FUNCTION, sAsyncFuncPrototypeVal);
362 env->SetSAsyncFunctionClass(thread_, sAsyncFuncClass);
363 }
364
InitializeSFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSFunction> & sFuncPrototype) const365 void Builtins::InitializeSFunction(const JSHandle<GlobalEnv> &env,
366 const JSHandle<JSFunction> &sFuncPrototype) const
367 {
368 [[maybe_unused]] EcmaHandleScope scope(thread_);
369 SetSFunctionLength(sFuncPrototype, FunctionLength::ZERO);
370 SetSFunctionName(sFuncPrototype, thread_->GlobalConstants()->GetHandledEmptyString());
371 // SharedFunction.prototype_or_hclass
372 auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
373 JSHandle<JSHClass> sFuncIHClass = factory_->NewSEcmaHClass(JSSharedFunction::SIZE, 0, JSType::JS_SHARED_FUNCTION,
374 JSHandle<JSTaggedValue>(sFuncPrototype), emptySLayout);
375 sFuncIHClass->SetCallable(true);
376 sFuncIHClass->SetConstructor(true);
377 // SharedFunction.hclass
378 JSHandle<JSHClass> sFuncHClass = CreateSFunctionHClass(sFuncPrototype);
379 // new SharedFunction() (forbidden use NewBuiltinConstructor)
380 JSHandle<JSFunction> sFuncFunction = factory_->NewSFunctionByHClass(
381 reinterpret_cast<void *>(BuiltinsSharedFunction::SharedFunctionConstructor),
382 sFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
383 InitializeSCtor(sFuncIHClass, sFuncFunction, "SharedFunction", FunctionLength::ONE);
384 env->SetSFunctionFunction(thread_, sFuncFunction);
385 env->SetSFunctionPrototype(thread_, sFuncPrototype);
386
387 JSHandle<JSTaggedValue> sFuncPrototypeVal(sFuncPrototype);
388 JSHandle<JSHClass> functionClass =
389 factory_->CreateSFunctionClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
390 sFuncPrototypeVal);
391 env->SetSFunctionClassWithoutProto(thread_, functionClass);
392 JSHandle<JSHClass> functionClassWithProto =
393 factory_->CreateSFunctionClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
394 sFuncPrototypeVal, true, true);
395 env->SetSFunctionClassWithProto(thread_, functionClassWithProto);
396
397 JSHandle<JSHClass> functionClassWithoutAccessor =
398 factory_->CreateSFunctionClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
399 sFuncPrototypeVal, false);
400 env->SetSFunctionClassWithoutAccessor(thread_, functionClassWithoutAccessor);
401 uint32_t fieldIndex = 2; // 2: length and name
402 JSHandle<JSObject> sFuncPrototypeObj(sFuncPrototype);
403 sFuncPrototypeObj->SetPropertyInlinedProps(thread_, fieldIndex++, sFuncFunction.GetTaggedValue()); // constructor
404 SharedStrictModeForbiddenAccessCallerArguments(env, fieldIndex, sFuncPrototypeObj);
405 // Function.prototype method
406 // 19.2.3.1 Function.prototype.apply ( thisArg, argArray )
407 SetSFunction(env, sFuncPrototypeObj, "apply", Function::FunctionPrototypeApply, fieldIndex++, FunctionLength::TWO,
408 BUILTINS_STUB_ID(FunctionPrototypeApply));
409 // 19.2.3.2 Function.prototype.bind ( thisArg , ...args)
410 SetSFunction(env, sFuncPrototypeObj, "bind", Function::FunctionPrototypeBind, fieldIndex++, FunctionLength::ONE);
411 // 19.2.3.3 Function.prototype.call (thisArg , ...args)
412 SetSFunction(env, sFuncPrototypeObj, "call", Function::FunctionPrototypeCall, fieldIndex++, FunctionLength::ONE);
413 // 19.2.3.5 Function.prototype.toString ( )
414 SetSFunction(env, sFuncPrototypeObj, thread_->GlobalConstants()->GetHandledToStringString(),
415 Function::FunctionPrototypeToString, fieldIndex++, FunctionLength::ZERO);
416 SetSFunction(env, sFuncPrototypeObj, "[Symbol.hasInstance]",
417 Function::FunctionPrototypeHasInstance, fieldIndex++, FunctionLength::ONE);
418 }
419
CreateSObjectFunctionHClass(const JSHandle<JSFunction> & sFuncPrototype) const420 JSHandle<JSHClass> Builtins::CreateSObjectFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
421 {
422 uint32_t index = 0;
423 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
424 attributes.SetIsInlinedProps(true);
425 attributes.SetRepresentation(Representation::TAGGED);
426 auto properties = Object::GetFunctionProperties();
427 uint32_t length = properties.size();
428 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
429 for (const std::pair<std::string_view, bool> &each : properties) {
430 attributes.SetOffset(index);
431 attributes.SetIsAccessor(each.second);
432 JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(each.first));
433 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
434 }
435 JSHandle<JSHClass> sobjPrototypeHClass =
436 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
437 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
438 sobjPrototypeHClass->SetConstructor(true);
439 sobjPrototypeHClass->SetCallable(true);
440 return sobjPrototypeHClass;
441 }
442
CreateSObjectPrototypeHClass() const443 JSHandle<JSHClass> Builtins::CreateSObjectPrototypeHClass() const
444 {
445 const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
446 JSHandle<JSTaggedValue> nullHandle = globalConst->GetHandledNull();
447
448 uint32_t index = 0;
449 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
450 attributes.SetIsInlinedProps(true);
451 attributes.SetRepresentation(Representation::TAGGED);
452 auto properties = Object::GetFunctionPrototypeProperties();
453 uint32_t length = properties.size();
454 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
455 for (const std::pair<std::string_view, bool> &each : properties) {
456 attributes.SetOffset(index);
457 attributes.SetIsAccessor(each.second);
458 JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(each.first));
459 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
460 }
461
462 JSHandle<JSHClass> sobjPrototypeHClass =
463 factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT, nullHandle,
464 JSHandle<JSTaggedValue>(layout));
465 return sobjPrototypeHClass;
466 }
467
CreateSFunctionHClass(const JSHandle<JSFunction> & sFuncPrototype) const468 JSHandle<JSHClass> Builtins::CreateSFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
469 {
470 uint32_t index = 0;
471 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
472 attributes.SetIsInlinedProps(true);
473 attributes.SetRepresentation(Representation::TAGGED);
474 auto properties = Function::GetFunctionProperties();
475 uint32_t length = properties.size();
476 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
477 for (const base::BuiltinsPropertyConfig &each : properties) {
478 attributes.SetOffset(index);
479 attributes.SetIsAccessor(each.GetIsAccessor());
480 JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(each.GetName()));
481 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
482 }
483 JSHandle<JSHClass> sobjPrototypeHClass =
484 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
485 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
486 sobjPrototypeHClass->SetConstructor(true);
487 sobjPrototypeHClass->SetCallable(true);
488 return sobjPrototypeHClass;
489 }
490
CreateSArrayBufferFunctionHClass(const JSHandle<JSFunction> & sFuncPrototype) const491 JSHandle<JSHClass> Builtins::CreateSArrayBufferFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
492 {
493 uint32_t index = 0;
494 auto env = vm_->GetGlobalEnv();
495 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
496 attributes.SetIsInlinedProps(true);
497 attributes.SetRepresentation(Representation::TAGGED);
498 auto properties = BuiltinsSendableArrayBuffer::GetFunctionProperties();
499 uint32_t length = properties.size();
500 JSHandle<JSTaggedValue> keyString;
501 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
502 for (const auto &[key, isAccessor] : properties) {
503 attributes.SetOffset(index);
504 attributes.SetIsAccessor(isAccessor);
505 if (key == "[Symbol.species]") {
506 keyString = env->GetSpeciesSymbol();
507 } else {
508 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
509 }
510 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
511 }
512 JSHandle<JSHClass> sobjPrototypeHClass =
513 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
514 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
515 sobjPrototypeHClass->SetConstructor(true);
516 sobjPrototypeHClass->SetCallable(true);
517 return sobjPrototypeHClass;
518 }
519
CreateSSetFunctionHClass(const JSHandle<JSFunction> & sFuncPrototype) const520 JSHandle<JSHClass> Builtins::CreateSSetFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
521 {
522 uint32_t index = 0;
523 auto env = vm_->GetGlobalEnv();
524 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
525 attributes.SetIsInlinedProps(true);
526 attributes.SetRepresentation(Representation::TAGGED);
527 auto properties = BuiltinsSharedSet::GetFunctionProperties();
528 uint32_t length = properties.size();
529 JSHandle<JSTaggedValue> keyString;
530 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
531 for (const auto &[key, isAccessor] : properties) {
532 attributes.SetOffset(index);
533 attributes.SetIsAccessor(isAccessor);
534 if (key == "[Symbol.species]") {
535 keyString = env->GetSpeciesSymbol();
536 } else {
537 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
538 }
539 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
540 }
541 JSHandle<JSHClass> sobjPrototypeHClass =
542 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
543 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
544 sobjPrototypeHClass->SetConstructor(true);
545 sobjPrototypeHClass->SetCallable(true);
546 return sobjPrototypeHClass;
547 }
548
CreateSMapFunctionHClass(const JSHandle<JSFunction> & sFuncPrototype) const549 JSHandle<JSHClass> Builtins::CreateSMapFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
550 {
551 uint32_t index = 0;
552 auto env = vm_->GetGlobalEnv();
553 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
554 attributes.SetIsInlinedProps(true);
555 attributes.SetRepresentation(Representation::TAGGED);
556 auto properties = BuiltinsSharedMap::GetFunctionProperties();
557 uint32_t length = properties.size();
558 JSHandle<JSTaggedValue> keyString;
559 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
560 for (const auto &[key, isAccessor] : properties) {
561 attributes.SetOffset(index);
562 attributes.SetIsAccessor(isAccessor);
563 if (key == "[Symbol.species]") {
564 keyString = env->GetSpeciesSymbol();
565 } else {
566 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
567 }
568 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
569 }
570 JSHandle<JSHClass> sobjPrototypeHClass =
571 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
572 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
573 sobjPrototypeHClass->SetConstructor(true);
574 sobjPrototypeHClass->SetCallable(true);
575 return sobjPrototypeHClass;
576 }
577
CreateBitVectorFunctionHClass(const JSHandle<JSFunction> & sFuncPrototype) const578 JSHandle<JSHClass> Builtins::CreateBitVectorFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
579 {
580 uint32_t index = 0;
581 auto env = vm_->GetGlobalEnv();
582 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
583 attributes.SetIsInlinedProps(true);
584 attributes.SetRepresentation(Representation::TAGGED);
585 auto properties = ContainersBitVector::GetFunctionProperties();
586 uint32_t length = properties.size();
587 JSHandle<JSTaggedValue> keyString;
588 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
589 for (const auto &[key, isAccessor] : properties) {
590 attributes.SetOffset(index);
591 attributes.SetIsAccessor(isAccessor);
592 if (key == "[Symbol.species]") {
593 keyString = env->GetSpeciesSymbol();
594 } else {
595 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
596 }
597 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
598 }
599 JSHandle<JSHClass> sobjPrototypeHClass =
600 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
601 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
602 sobjPrototypeHClass->SetConstructor(true);
603 sobjPrototypeHClass->SetCallable(true);
604 return sobjPrototypeHClass;
605 }
606
CreateSFunctionPrototypeHClass(const JSHandle<JSTaggedValue> & sObjPrototypeVal) const607 JSHandle<JSHClass> Builtins::CreateSFunctionPrototypeHClass(const JSHandle<JSTaggedValue> &sObjPrototypeVal) const
608 {
609 uint32_t index = 0;
610 auto env = vm_->GetGlobalEnv();
611 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
612 attributes.SetIsInlinedProps(true);
613 attributes.SetRepresentation(Representation::TAGGED);
614 auto properties = Function::GetFunctionPrototypeProperties();
615 uint32_t length = properties.size();
616 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
617 JSHandle<JSTaggedValue> keyString;
618 for (const base::BuiltinsPropertyConfig &each : properties) {
619 attributes.SetOffset(index);
620 attributes.SetIsAccessor(each.GetIsAccessor());
621 if (each.GetName() == "[Symbol.hasInstance]") {
622 keyString = env->GetHasInstanceSymbol();
623 } else {
624 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(each.GetName()));
625 }
626 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
627 }
628 JSHandle<JSHClass> sobjPrototypeHClass =
629 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION, sObjPrototypeVal,
630 JSHandle<JSTaggedValue>(layout));
631 sobjPrototypeHClass->SetCallable(true);
632 return sobjPrototypeHClass;
633 }
634
CreateSArrayBufferPrototypeHClass(const JSHandle<JSObject> & sObjPrototype) const635 JSHandle<JSHClass> Builtins::CreateSArrayBufferPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
636 {
637 uint32_t index = 0;
638 auto env = vm_->GetGlobalEnv();
639 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
640 attributes.SetIsInlinedProps(true);
641 attributes.SetRepresentation(Representation::TAGGED);
642 auto properties = BuiltinsSendableArrayBuffer::GetPrototypeProperties();
643 uint32_t length = properties.size();
644 ASSERT(length == BuiltinsSendableArrayBuffer::GetNumPrototypeInlinedProperties());
645 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
646 JSHandle<JSTaggedValue> keyString;
647 for (const auto &[key, isAccessor] : properties) {
648 attributes.SetOffset(index);
649 attributes.SetIsAccessor(isAccessor);
650 if (key == "[Symbol.toStringTag]") {
651 keyString = env->GetToStringTagSymbol();
652 } else {
653 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
654 }
655 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
656 }
657 JSHandle<JSHClass> sArrayBufferPrototypeHClass =
658 factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
659 JSHandle<JSTaggedValue>(sObjPrototype),
660 JSHandle<JSTaggedValue>(layout));
661 return sArrayBufferPrototypeHClass;
662 }
663
CreateSSetPrototypeHClass(const JSHandle<JSObject> & sObjPrototype) const664 JSHandle<JSHClass> Builtins::CreateSSetPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
665 {
666 uint32_t index = 0;
667 auto env = vm_->GetGlobalEnv();
668 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
669 attributes.SetIsInlinedProps(true);
670 attributes.SetRepresentation(Representation::TAGGED);
671 auto properties = BuiltinsSharedSet::GetPrototypeProperties();
672 uint32_t length = properties.size();
673 ASSERT(length == BuiltinsSharedSet::GetNumPrototypeInlinedProperties());
674 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
675 JSHandle<JSTaggedValue> keyString;
676 for (const auto &[key, isAccessor] : properties) {
677 attributes.SetOffset(index);
678 attributes.SetIsAccessor(isAccessor);
679 if (key == "[Symbol.iterator]") {
680 keyString = env->GetIteratorSymbol();
681 } else if (key == "[Symbol.toStringTag]") {
682 keyString = env->GetToStringTagSymbol();
683 } else {
684 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
685 }
686 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
687 }
688 JSHandle<JSHClass> sSetPrototypeHClass =
689 factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
690 JSHandle<JSTaggedValue>(sObjPrototype),
691 JSHandle<JSTaggedValue>(layout));
692 return sSetPrototypeHClass;
693 }
694
CreateSMapPrototypeHClass(const JSHandle<JSObject> & sObjPrototype) const695 JSHandle<JSHClass> Builtins::CreateSMapPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
696 {
697 uint32_t index = 0;
698 auto env = vm_->GetGlobalEnv();
699 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
700 attributes.SetIsInlinedProps(true);
701 attributes.SetRepresentation(Representation::TAGGED);
702 auto properties = BuiltinsSharedMap::GetPrototypeProperties();
703 uint32_t length = properties.size();
704 ASSERT(length == BuiltinsSharedMap::GetNumPrototypeInlinedProperties());
705 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
706 JSHandle<JSTaggedValue> keyString;
707 for (const auto &[key, isAccessor] : properties) {
708 attributes.SetOffset(index);
709 attributes.SetIsAccessor(isAccessor);
710 if (key == "[Symbol.iterator]") {
711 keyString = env->GetIteratorSymbol();
712 } else if (key == "[Symbol.toStringTag]") {
713 keyString = env->GetToStringTagSymbol();
714 } else {
715 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
716 }
717 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
718 }
719 JSHandle<JSHClass> sMapPrototypeHClass =
720 factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
721 JSHandle<JSTaggedValue>(sObjPrototype),
722 JSHandle<JSTaggedValue>(layout));
723 return sMapPrototypeHClass;
724 }
725
CreateBitVectorPrototypeHClass(const JSHandle<JSObject> & sObjPrototype) const726 JSHandle<JSHClass> Builtins::CreateBitVectorPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
727 {
728 uint32_t index = 0;
729 auto env = vm_->GetGlobalEnv();
730 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
731 attributes.SetIsInlinedProps(true);
732 attributes.SetRepresentation(Representation::TAGGED);
733 auto properties = ContainersBitVector::GetPrototypeProperties();
734 uint32_t length = properties.size();
735 ASSERT(length == ContainersBitVector::GetNumPrototypeInlinedProperties());
736 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
737 JSHandle<JSTaggedValue> keyString;
738 for (const auto &[key, isAccessor] : properties) {
739 attributes.SetOffset(index);
740 attributes.SetIsAccessor(isAccessor);
741 if (key == "[Symbol.iterator]") {
742 keyString = env->GetIteratorSymbol();
743 } else if (key == "[Symbol.toStringTag]") {
744 keyString = env->GetToStringTagSymbol();
745 } else {
746 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
747 }
748 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
749 }
750 JSHandle<JSHClass> sBitVectorPrototypeHClass =
751 factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
752 JSHandle<JSTaggedValue>(sObjPrototype),
753 JSHandle<JSTaggedValue>(layout));
754 return sBitVectorPrototypeHClass;
755 }
756
CreateSArrayPrototypeHClass(const JSHandle<JSObject> & sObjPrototype) const757 JSHandle<JSHClass> Builtins::CreateSArrayPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
758 {
759 uint32_t index = 0;
760 auto env = vm_->GetGlobalEnv();
761 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
762 attributes.SetIsInlinedProps(true);
763 attributes.SetRepresentation(Representation::TAGGED);
764 auto properties = BuiltinsSharedArray::GetPrototypeProperties();
765 uint32_t length = properties.size();
766 ASSERT(length == BuiltinsSharedArray::GetNumPrototypeInlinedProperties());
767 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
768 JSHandle<JSTaggedValue> keyString;
769 for (const auto &[key, isAccessor] : properties) {
770 attributes.SetOffset(index);
771 attributes.SetIsAccessor(isAccessor);
772 if (key == "[Symbol.iterator]") {
773 keyString = env->GetIteratorSymbol();
774 } else if (key == "[Symbol.toStringTag]") {
775 keyString = env->GetToStringTagSymbol();
776 } else {
777 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
778 }
779 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
780 }
781 JSHandle<JSHClass> sArrayPrototypeHClass =
782 factory_->NewSEcmaHClass(JSSharedArray::SIZE, length, JSType::JS_SHARED_ARRAY,
783 JSHandle<JSTaggedValue>(sObjPrototype),
784 JSHandle<JSTaggedValue>(layout));
785 return sArrayPrototypeHClass;
786 }
787
CreateSArrayFunctionHClass(const JSHandle<JSFunction> & sFuncPrototype) const788 JSHandle<JSHClass> Builtins::CreateSArrayFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
789 {
790 uint32_t index = 0;
791 auto env = vm_->GetGlobalEnv();
792 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
793 attributes.SetIsInlinedProps(true);
794 attributes.SetRepresentation(Representation::TAGGED);
795 auto properties = BuiltinsSharedArray::GetFunctionProperties();
796 uint32_t length = properties.size();
797 JSHandle<JSTaggedValue> keyString;
798 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
799 for (const auto &[key, isAccessor] : properties) {
800 LOG_ECMA(DEBUG) << "CreateSArrayFunctionHClass " << key;
801 attributes.SetOffset(index);
802 attributes.SetIsAccessor(isAccessor);
803 if (key == "[Symbol.species]") {
804 keyString = env->GetSpeciesSymbol();
805 } else {
806 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
807 }
808 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
809 }
810 JSHandle<JSHClass> sobjPrototypeHClass =
811 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
812 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
813 sobjPrototypeHClass->SetConstructor(true);
814 sobjPrototypeHClass->SetCallable(true);
815 return sobjPrototypeHClass;
816 }
817
SetSFunctionName(const JSHandle<JSFunction> & ctor,std::string_view name) const818 void Builtins::SetSFunctionName(const JSHandle<JSFunction> &ctor, std::string_view name) const
819 {
820 JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(name));
821 SetSFunctionName(ctor, nameString);
822 }
823
SetSFunctionName(const JSHandle<JSFunction> & ctor,const JSHandle<JSTaggedValue> & name) const824 void Builtins::SetSFunctionName(const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &name) const
825 {
826 auto nameIndex = JSFunction::NAME_INLINE_PROPERTY_INDEX;
827 ctor->SetPropertyInlinedProps(thread_, nameIndex, name.GetTaggedValue());
828 }
829
SetSFunctionLength(const JSHandle<JSFunction> & ctor,int length) const830 void Builtins::SetSFunctionLength(const JSHandle<JSFunction> &ctor, int length) const
831 {
832 JSTaggedValue taggedLength(length);
833 auto lengthIndex = JSFunction::LENGTH_INLINE_PROPERTY_INDEX;
834 ctor->SetPropertyInlinedProps(thread_, lengthIndex, taggedLength);
835 }
836
SetSFunctionPrototype(const JSHandle<JSFunction> & ctor,const JSTaggedValue & prototype) const837 void Builtins::SetSFunctionPrototype(const JSHandle<JSFunction> &ctor, const JSTaggedValue &prototype) const
838 {
839 auto prototypeIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX;
840 ctor->SetPropertyInlinedProps(thread_, prototypeIndex, prototype);
841 }
842
InitializeSCtor(const JSHandle<JSHClass> & protoHClass,const JSHandle<JSFunction> & ctor,std::string_view name,int length) const843 void Builtins::InitializeSCtor(const JSHandle<JSHClass> &protoHClass, const JSHandle<JSFunction> &ctor,
844 std::string_view name, int length) const
845 {
846 SetSFunctionLength(ctor, length);
847 SetSFunctionName(ctor, name);
848 SetSFunctionPrototype(ctor, protoHClass->GetProto());
849 ctor->SetProtoOrHClass(thread_, protoHClass);
850 }
851
NewSFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSTaggedValue> & key,EcmaEntrypoint func,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const852 JSHandle<JSFunction> Builtins::NewSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &key,
853 EcmaEntrypoint func, int length,
854 kungfu::BuiltinsStubCSigns::ID builtinId) const
855 {
856 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutAccessor());
857 JSHandle<JSFunction> function = factory_->NewSFunctionByHClass(reinterpret_cast<void *>(func),
858 hclass, FunctionKind::NORMAL_FUNCTION, builtinId, MemSpaceType::SHARED_NON_MOVABLE);
859 SetSFunctionLength(function, length);
860 SetSFunctionName(function, key);
861 function->GetJSHClass()->SetExtensible(false);
862 return function;
863 }
864
SetSFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,std::string_view key,EcmaEntrypoint func,uint32_t index,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const865 void Builtins::SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, std::string_view key,
866 EcmaEntrypoint func, uint32_t index, int length,
867 kungfu::BuiltinsStubCSigns::ID builtinId) const
868 {
869 JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8ReadOnly(key));
870 SetSFunction(env, obj, keyString, func, index, length, builtinId);
871 }
872
SetSFunction(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & obj,const JSHandle<JSTaggedValue> & key,EcmaEntrypoint func,uint32_t index,int length,kungfu::BuiltinsStubCSigns::ID builtinId) const873 void Builtins::SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
874 const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, uint32_t index, int length,
875 kungfu::BuiltinsStubCSigns::ID builtinId) const
876 {
877 JSHandle<JSFunction> function(NewSFunction(env, key, func, length, builtinId));
878 obj->SetPropertyInlinedProps(thread_, index, function.GetTaggedValue());
879 }
880
SetSAccessor(const JSHandle<JSObject> & obj,uint32_t index,const JSHandle<JSTaggedValue> & getter,const JSHandle<JSTaggedValue> & setter) const881 void Builtins::SetSAccessor(const JSHandle<JSObject> &obj, uint32_t index,
882 const JSHandle<JSTaggedValue> &getter, const JSHandle<JSTaggedValue> &setter) const
883 {
884 JSHandle<AccessorData> accessor = factory_->NewSAccessorData();
885 accessor->SetGetter(thread_, getter);
886 accessor->SetSetter(thread_, setter);
887 obj->SetPropertyInlinedProps(thread_, index, accessor.GetTaggedValue());
888 }
889
CreateSGetterSetter(const JSHandle<GlobalEnv> & env,EcmaEntrypoint func,std::string_view name,int length) const890 JSHandle<JSTaggedValue> Builtins::CreateSGetterSetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
891 std::string_view name, int length) const
892 {
893 JSHandle<JSTaggedValue> funcName(factory_->NewFromUtf8ReadOnly(name));
894 JSHandle<JSFunction> function = NewSFunction(env, funcName, func, length);
895 return JSHandle<JSTaggedValue>(function);
896 }
897
SharedStrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> & env,uint32_t & index,const JSHandle<JSObject> & prototype) const898 void Builtins::SharedStrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> &env, uint32_t &index,
899 const JSHandle<JSObject> &prototype) const
900 {
901 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutProto());
902 JSHandle<JSFunction> func =
903 factory_->NewSFunctionWithAccessor(
904 reinterpret_cast<void *>(JSFunction::AccessCallerArgumentsThrowTypeError), hclass,
905 FunctionKind::NORMAL_FUNCTION);
906 // "caller"
907 SetSAccessor(prototype, index++, JSHandle<JSTaggedValue>(func), JSHandle<JSTaggedValue>(func));
908 // "arguments"
909 SetSAccessor(prototype, index++, JSHandle<JSTaggedValue>(func), JSHandle<JSTaggedValue>(func));
910 }
911
InitializeSSymbolAttributes(const JSHandle<GlobalEnv> & env)912 void Builtins::InitializeSSymbolAttributes(const JSHandle<GlobalEnv> &env)
913 {
914 JSHandle<JSTaggedValue> hasInstanceSymbol(
915 factory_->NewSWellKnownSymbolWithChar("Symbol.hasInstance"));
916 JSHandle<JSTaggedValue> isConcatSpreadableSymbol(
917 factory_->NewSWellKnownSymbolWithChar("Symbol.isConcatSpreadable"));
918 JSHandle<JSTaggedValue> toStringTagSymbol(
919 factory_->NewSWellKnownSymbolWithChar("Symbol.toStringTag"));
920 JSHandle<JSTaggedValue> asyncIteratorSymbol(
921 factory_->NewSPublicSymbolWithChar("Symbol.asyncIterator"));
922 JSHandle<JSTaggedValue> matchSymbol(
923 factory_->NewSPublicSymbolWithChar("Symbol.match"));
924 JSHandle<JSTaggedValue> searchSymbol(
925 factory_->NewSPublicSymbolWithChar("Symbol.search"));
926 JSHandle<JSTaggedValue> toPrimitiveSymbol(
927 factory_->NewSPublicSymbolWithChar("Symbol.toPrimitive"));
928 JSHandle<JSTaggedValue> unscopablesSymbol(
929 factory_->NewSPublicSymbolWithChar("Symbol.unscopables"));
930 JSHandle<JSTaggedValue> nativeBindingSymbol(
931 factory_->NewSPublicSymbolWithChar("Symbol.nativeBinding"));
932
933 // Symbol attributes with detectors
934 // Create symbol string before create symbol to allocate symbol continuously
935 // Attention: Symbol serialization & deserialization are not supported now and
936 // the order of symbols and symbol-strings must be maintained too when
937 // Symbol serialization & deserialization are ready.
938 #define INIT_SYMBOL_STRING(name, description, key) \
939 { \
940 [[maybe_unused]] JSHandle<EcmaString> string = factory_->NewFromUtf8ReadOnly(description); \
941 }
942 DETECTOR_SYMBOL_LIST(INIT_SYMBOL_STRING)
943 #undef INIT_SYMBOL_STRING
944
945 #define INIT_PUBLIC_SYMBOL(name, description, key) \
946 JSHandle<JSSymbol> key##Symbol = factory_->NewSEmptySymbol(); \
947 JSHandle<EcmaString> key##String = factory_->NewFromUtf8ReadOnly(description); \
948 key##Symbol->SetDescription(thread_, key##String.GetTaggedValue()); \
949 key##Symbol->SetHashField(SymbolTable::Hash(key##String.GetTaggedValue()));
950 DETECTOR_SYMBOL_LIST(INIT_PUBLIC_SYMBOL)
951 #undef INIT_PUBLIC_SYMBOL
952
953 #define REGISTER_SYMBOL(name, Name) \
954 env->Set##Name##Symbol(thread_, name##Symbol);
955 BUILTIN_ALL_SYMBOLS(REGISTER_SYMBOL)
956 #undef REGISTER_SYMBOL
957 }
958
InitializeArrayPrototype(JSHandle<JSHClass> & arrBaseFuncInstanceHClass) const959 JSHandle<JSObject> Builtins::InitializeArrayPrototype(JSHandle<JSHClass> &arrBaseFuncInstanceHClass) const
960 {
961 JSHandle<JSObject> arrFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(arrBaseFuncInstanceHClass);
962 auto accessor = thread_->GlobalConstants()->GetSharedArrayLengthAccessor();
963 int32_t protoFieldIndex = JSSharedArray::LENGTH_INLINE_PROPERTY_INDEX;
964 static_assert(JSSharedArray::LENGTH_INLINE_PROPERTY_INDEX == 0);
965 arrFuncPrototype->SetPropertyInlinedProps(thread_, protoFieldIndex++, accessor);
966 return arrFuncPrototype;
967 }
968
InitializeArrayPrototypeHClass(const JSHandle<JSObject> & arrFuncPrototype) const969 JSHandle<JSHClass> Builtins::InitializeArrayPrototypeHClass(const JSHandle<JSObject> &arrFuncPrototype) const
970 {
971 JSHandle<JSTaggedValue> arrFuncPrototypeValue(arrFuncPrototype);
972 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(1);
973 PropertyAttributes attributes = PropertyAttributes::DefaultAccessor(true, false, false);
974 attributes.SetIsInlinedProps(true);
975 attributes.SetRepresentation(Representation::TAGGED);
976 layout->AddKey(thread_, 0, thread_->GlobalConstants()->GetHandledLengthString().GetTaggedValue(), attributes);
977
978 JSHandle<JSHClass> arrFuncInstanceHClass = factory_->NewSEcmaHClass(
979 JSSharedArray::SIZE, 1, JSType::JS_SHARED_ARRAY, arrFuncPrototypeValue, JSHandle<JSTaggedValue>::Cast(layout));
980 arrFuncInstanceHClass->SetExtensible(false);
981 return arrFuncInstanceHClass;
982 }
983
InitializeSharedArray(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & sObjIHClass,JSHandle<JSFunction> & sFuncPrototype) const984 void Builtins::InitializeSharedArray(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjIHClass,
985 JSHandle<JSFunction> &sFuncPrototype) const
986 {
987 [[maybe_unused]] EcmaHandleScope scope(thread_);
988 const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
989 // Arraybase.prototype
990 JSHandle<JSHClass> arrBaseFuncInstanceHClass = CreateSArrayPrototypeHClass(sObjIHClass);
991
992 // Array.prototype
993 JSHandle<JSObject> arrFuncPrototype = InitializeArrayPrototype(arrBaseFuncInstanceHClass);
994 // Array.prototype_or_hclass
995 JSHandle<JSHClass> arrFuncInstanceHClass = InitializeArrayPrototypeHClass(arrFuncPrototype);
996 int32_t protoFieldIndex = JSSharedArray::LENGTH_INLINE_PROPERTY_INDEX + 1;
997
998 // SharedArray.hclass
999 JSHandle<JSHClass> arrayFuncHClass = CreateSArrayFunctionHClass(sFuncPrototype);
1000 arrayFuncHClass->SetExtensible(false);
1001 // SharedArray() = new Function()
1002 JSHandle<JSFunction> arrayFunction =
1003 factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedArray::ArrayConstructor), arrayFuncHClass,
1004 FunctionKind::BUILTIN_CONSTRUCTOR);
1005
1006 InitializeSCtor(arrFuncInstanceHClass, arrayFunction, "SendableArray", FunctionLength::ZERO);
1007
1008 arrFuncPrototype->SetPropertyInlinedProps(thread_, protoFieldIndex++, arrayFunction.GetTaggedValue());
1009 JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject());
1010 JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly("SendableArray"));
1011 PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(arrayFunction), false, false, false);
1012 JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc);
1013 RETURN_IF_ABRUPT_COMPLETION(thread_);
1014 for (const base::BuiltinFunctionEntry &entry : BuiltinsSharedArray::GetSharedArrayPrototypeFunctions()) {
1015 SetSFunction(env, arrFuncPrototype, entry.GetName(), entry.GetEntrypoint(), protoFieldIndex++,
1016 entry.GetLength(), entry.GetBuiltinStubId());
1017 }
1018
1019 // %ArrayPrototype% [ @@iterator ]
1020 JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
1021 JSHandle<JSTaggedValue> valuesFunc =
1022 JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(arrFuncPrototype), values);
1023 RETURN_IF_ABRUPT_COMPLETION(thread_);
1024 int32_t funcFieldIndex = 3; // 3: length, name, prototype
1025 for (const base::BuiltinFunctionEntry &entry : BuiltinsSharedArray::GetSharedArrayFunctions()) {
1026 SetSFunction(env, JSHandle<JSObject>(arrayFunction), entry.GetName(), entry.GetEntrypoint(), funcFieldIndex++,
1027 entry.GetLength(), entry.GetBuiltinStubId());
1028 }
1029
1030 // %SetPrototype% [ @@iterator ]
1031 arrFuncPrototype->SetPropertyInlinedProps(thread_, protoFieldIndex++, valuesFunc.GetTaggedValue());
1032
1033 // 22.1.2.5 get %Array% [ @@species ]
1034 JSHandle<JSTaggedValue> speciesGetter =
1035 CreateSGetterSetter(env, BuiltinsSharedArray::Species, "[Symbol.species]", FunctionLength::ZERO);
1036 SetSAccessor(JSHandle<JSObject>(arrayFunction), funcFieldIndex++, speciesGetter,
1037 globalConst->GetHandledUndefined());
1038
1039 // Array.prototype [ @@unscopables ]
1040 JSHandle<JSTaggedValue> unscopablesGetter =
1041 CreateSGetterSetter(env, BuiltinsSharedArray::Unscopables, "[Symbol.unscopables]", FunctionLength::ZERO);
1042 SetSAccessor(JSHandle<JSObject>(arrFuncPrototype), protoFieldIndex++, unscopablesGetter,
1043 globalConst->GetHandledUndefined());
1044 arrBaseFuncInstanceHClass->SetExtensible(false);
1045 env->SetSharedArrayFunction(thread_, arrayFunction);
1046 env->SetSharedArrayPrototype(thread_, arrFuncPrototype);
1047 }
1048
InitializeSharedBitVector(const JSHandle<GlobalEnv> & env,const JSHandle<JSObject> & sObjPrototype,const JSHandle<JSFunction> & sFuncPrototype) const1049 void Builtins::InitializeSharedBitVector(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
1050 const JSHandle<JSFunction> &sFuncPrototype) const
1051 {
1052 [[maybe_unused]] EcmaHandleScope scope(thread_);
1053 auto globalConst = const_cast<GlobalEnvConstants*>(thread_->GlobalConstants());
1054 // BitVector.prototype
1055 JSHandle<JSHClass> prototypeHClass = CreateBitVectorPrototypeHClass(sObjPrototype);
1056 JSHandle<JSObject> bitVectorFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(prototypeHClass);
1057 JSHandle<JSTaggedValue> bitVectorFuncPrototypeValue(bitVectorFuncPrototype);
1058
1059 // BitVector.prototype_or_hclass
1060 auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo();
1061 JSHandle<JSHClass> bitVectorInstanceClass =
1062 factory_->NewSEcmaHClass(JSAPIBitVector::SIZE, 0,
1063 JSType::JS_API_BITVECTOR, bitVectorFuncPrototypeValue, emptySLayout);
1064
1065 // BitVector.hclass
1066 JSHandle<JSHClass> bitVectorFuncHClass = CreateBitVectorFunctionHClass(sFuncPrototype);
1067 bitVectorFuncHClass->SetExtensible(false);
1068
1069 // BitVector() = new Function()
1070 JSHandle<JSFunction> bitVectorFunction =
1071 factory_->NewSFunctionByHClass(reinterpret_cast<void *>(ContainersBitVector::BitVectorConstructor),
1072 bitVectorFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
1073 InitializeSCtor(bitVectorInstanceClass, bitVectorFunction, "BitVector", FunctionLength::ONE);
1074 // BitVector.prototype
1075 int32_t protoFieldIndex = 0;
1076 bitVectorFuncPrototype->SetPropertyInlinedProps(thread_, protoFieldIndex++, bitVectorFunction.GetTaggedValue());
1077 for (const base::BuiltinFunctionEntry &entry: ContainersBitVector::GetBitVectorPrototypeFunctions()) {
1078 SetSFunction(env, bitVectorFuncPrototype, entry.GetName(), entry.GetEntrypoint(), protoFieldIndex++,
1079 entry.GetLength(), entry.GetBuiltinStubId());
1080 }
1081 // @@StringTag
1082 JSHandle<JSTaggedValue> strTag(factory_->NewFromUtf8ReadOnly("BitVector"));
1083 bitVectorFuncPrototype->SetPropertyInlinedProps(thread_, protoFieldIndex++, strTag.GetTaggedValue());
1084
1085 JSHandle<JSTaggedValue> sizeGetter = CreateSGetterSetter(env, ContainersBitVector::GetSize, "size",
1086 FunctionLength::ZERO);
1087 JSHandle<JSTaggedValue> lengthGetter = CreateSGetterSetter(env, ContainersBitVector::GetSize, "length",
1088 FunctionLength::ZERO);
1089 SetSAccessor(bitVectorFuncPrototype, protoFieldIndex++, sizeGetter, globalConst->GetHandledUndefined());
1090 SetSAccessor(bitVectorFuncPrototype, protoFieldIndex++, lengthGetter, globalConst->GetHandledUndefined());
1091
1092 SetSFunction(env, bitVectorFuncPrototype, "[Symbol.iterator]",
1093 ContainersBitVector::GetIteratorObj, protoFieldIndex++, FunctionLength::ONE);
1094 env->SetBitVectorPrototype(thread_, bitVectorFuncPrototype);
1095 env->SetBitVectorFunction(thread_, bitVectorFunction);
1096 }
1097
1098
1099 // todo: remove sendableName when refactor
1100 #define BUILTIN_SHARED_TYPED_ARRAY_DEFINE_INITIALIZE(Type, ctorName, TYPE, bytesPerElement, sendableName) \
1101 void Builtins::InitializeS##Type(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &arrFuncClass) const \
1102 { \
1103 [[maybe_unused]] EcmaHandleScope scope(thread_); \
1104 const GlobalEnvConstants *globalConst = thread_->GlobalConstants(); \
1105 auto emptySLayout = globalConst->GetHandledEmptySLayoutInfo(); \
1106 /* %SharedTypedArray%.prototype (where %SharedTypedArray% is one of Int8Array, Uint8Array, etc.) */ \
1107 JSHandle<JSObject> arrFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(arrFuncClass); \
1108 JSHandle<JSTaggedValue> arrFuncPrototypeValue(arrFuncPrototype); \
1109 /* %SharedTypedArray%.prototype_or_hclass */ \
1110 JSHandle<JSHClass> arrFuncInstanceHClass = factory_->NewSEcmaHClass( \
1111 JSSharedTypedArray::SIZE, 0, JSType::JS_SHARED_##TYPE, arrFuncPrototypeValue, emptySLayout); \
1112 JSHandle<JSHClass> arrFuncInstanceHClassOnHeap = factory_->NewSEcmaHClass( \
1113 JSSharedTypedArray::SIZE, 0, JSType::JS_SHARED_##TYPE, arrFuncPrototypeValue, emptySLayout); \
1114 arrFuncInstanceHClassOnHeap->SetIsOnHeap(true); \
1115 arrFuncInstanceHClass->SetHasConstructor(false); \
1116 /* %SharedTypedArray% = new Function() */ \
1117 JSHandle<JSHClass> specificTypedArrayFuncClass = JSHandle<JSHClass>::Cast( \
1118 env->GetSharedSpecificTypedArrayFunctionClass()); \
1119 JSHandle<JSFunction> arrayFunction = factory_->NewSFunctionByHClass( \
1120 reinterpret_cast<void *>(BuiltinsSharedTypedArray::Type##Constructor), specificTypedArrayFuncClass, \
1121 FunctionKind::BUILTIN_CONSTRUCTOR); \
1122 InitializeSCtor(arrFuncInstanceHClass, arrayFunction, #sendableName, FunctionLength::THREE); \
1123 JSHandle<JSObject> globalObject(thread_, env->GetGlobalObject()); \
1124 JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8ReadOnly(#sendableName)); \
1125 PropertyDescriptor desc(thread_, JSHandle<JSTaggedValue>::Cast(arrayFunction), false, false, false); \
1126 JSObject::DefineOwnProperty(thread_, globalObject, nameString, desc); \
1127 RETURN_IF_ABRUPT_COMPLETION(thread_); \
1128 /* 0: constructor index */ \
1129 uint32_t fieldIndex = 0; \
1130 arrFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, arrayFunction.GetTaggedValue()); \
1131 arrFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex, JSTaggedValue(bytesPerElement)); \
1132 fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1; \
1133 JSHandle<JSObject>(arrayFunction)->SetPropertyInlinedProps(thread_, fieldIndex, \
1134 JSTaggedValue(bytesPerElement)); \
1135 env->Set##ctorName##Function(thread_, arrayFunction); \
1136 env->Set##ctorName##FunctionPrototype(thread_, arrFuncPrototypeValue); \
1137 env->Set##ctorName##RootHclass(thread_, arrFuncInstanceHClass); \
1138 env->Set##ctorName##RootHclassOnHeap(thread_, arrFuncInstanceHClassOnHeap); \
1139 }
1140
BUILTIN_SHARED_TYPED_ARRAY_TYPES(BUILTIN_SHARED_TYPED_ARRAY_DEFINE_INITIALIZE)1141 BUILTIN_SHARED_TYPED_ARRAY_TYPES(BUILTIN_SHARED_TYPED_ARRAY_DEFINE_INITIALIZE)
1142 #undef BUILTIN_SHARED_TYPED_ARRAY_DEFINE_INITIALIZE
1143
1144 void Builtins::InitializeSTypedArray(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &sObjPrototype,
1145 const JSHandle<JSFunction> &sFuncPrototype) const
1146 {
1147 [[maybe_unused]] EcmaHandleScope scope(thread_);
1148 const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
1149 // SharedTypedArray.prototype
1150 JSHandle<JSHClass> typedArrFuncPrototypeHClass = CreateSTypedArrayPrototypeHClass(sObjPrototype);
1151 JSHandle<JSObject> typedArrFuncPrototype = factory_->NewSharedOldSpaceJSObjectWithInit(typedArrFuncPrototypeHClass);
1152 JSHandle<JSTaggedValue> typedArrFuncPrototypeValue(typedArrFuncPrototype);
1153
1154 // SharedTypedArray.prototype_or_hclass
1155 JSHandle<JSHClass> typedArrFuncInstanceHClass = CreateSSpecificTypedArrayInstanceHClass(
1156 typedArrFuncPrototype);
1157 // SharedTypedArray.hclass
1158 JSHandle<JSHClass> typedArrFuncHClass = CreateSTypedArrayFunctionHClass(sFuncPrototype);
1159 // SharedTypedArray = new Function()
1160 JSHandle<JSFunction> typedArrayFunction =
1161 factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedTypedArray::TypedArrayBaseConstructor),
1162 typedArrFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
1163 InitializeSCtor(typedArrFuncInstanceHClass, typedArrayFunction, "SharedTypedArray", FunctionLength::ZERO);
1164
1165 // "constructor" property on the prototype
1166 uint32_t fieldIndex = 0; // constructor
1167 typedArrFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, typedArrayFunction.GetTaggedValue());
1168
1169 // SharedTypedArray.prototype method
1170 for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedTypedArray::GetTypedArrayPrototypeFunctions()) {
1171 SetSFunction(env, typedArrFuncPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++,
1172 entry.GetLength(), entry.GetBuiltinStubId());
1173 }
1174 // SharedTypedArray.prototype get accessor
1175 for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedTypedArray::GetTypedArrayPrototypeAccessors()) {
1176 JSHandle<JSTaggedValue> getter = CreateSGetterSetter(env, entry.GetEntrypoint(),
1177 entry.GetName(), entry.GetLength());
1178 SetSAccessor(typedArrFuncPrototype, fieldIndex++, getter, globalConst->GetHandledUndefined());
1179 }
1180
1181 // %SharedTypedArray%.prototype [ @@iterator ] ( )
1182 JSHandle<JSTaggedValue> values(factory_->NewFromASCIIReadOnly("values"));
1183 JSHandle<JSTaggedValue> valuesFunc =
1184 JSObject::GetMethod(thread_, JSHandle<JSTaggedValue>::Cast(typedArrFuncPrototype), values);
1185 RETURN_IF_ABRUPT_COMPLETION(thread_);
1186 typedArrFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, valuesFunc.GetTaggedValue());
1187
1188 // 22.2.3.31 get %SharedTypedArray%.prototype [ @@toStringTag ]
1189 JSHandle<JSTaggedValue> toStringTagGetter =
1190 CreateSGetterSetter(env, BuiltinsSharedTypedArray::ToStringTag, "[Symbol.toStringTag]", FunctionLength::ZERO);
1191 SetSAccessor(typedArrFuncPrototype, fieldIndex++, toStringTagGetter, globalConst->GetHandledUndefined());
1192
1193 uint32_t funcFieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1; // length, name, prototype, ...
1194 // SharedTypedArray method
1195 for (const base::BuiltinFunctionEntry &entry: BuiltinsSharedTypedArray::GetTypedArrayFunctions()) {
1196 SetSFunction(env, JSHandle<JSObject>(typedArrayFunction), entry.GetName(), entry.GetEntrypoint(),
1197 funcFieldIndex++, entry.GetLength(), entry.GetBuiltinStubId());
1198 }
1199
1200 // 22.2.2.4 get %SharedTypedArray% [ @@species ]
1201 JSHandle<JSTaggedValue> speciesGetter =
1202 CreateSGetterSetter(env, BuiltinsSharedTypedArray::Species, "[Symbol.species]", FunctionLength::ZERO);
1203 SetSAccessor(JSHandle<JSObject>(typedArrayFunction), funcFieldIndex++, speciesGetter,
1204 globalConst->GetHandledUndefined());
1205
1206 env->SetSharedTypedArrayFunction(thread_, typedArrayFunction.GetTaggedValue());
1207 env->SetSharedTypedArrayPrototype(thread_, typedArrFuncPrototype);
1208
1209 JSHandle<JSHClass> specificTypedArrayFuncClass = CreateSSpecificTypedArrayFuncHClass(typedArrayFunction);
1210 env->SetSharedSpecificTypedArrayFunctionClass(thread_, specificTypedArrayFuncClass);
1211
1212 #define BUILTIN_SHARED_TYPED_ARRAY_CALL_INITIALIZE(Type, ctorName, TYPE, bytesPerElement, sendableName) \
1213 InitializeS##Type(env, typedArrFuncInstanceHClass);
1214 BUILTIN_SHARED_TYPED_ARRAY_TYPES(BUILTIN_SHARED_TYPED_ARRAY_CALL_INITIALIZE)
1215 #undef BUILTIN_SHARED_TYPED_ARRAY_CALL_INITIALIZE
1216 }
1217
CreateSTypedArrayPrototypeHClass(const JSHandle<JSObject> & sObjPrototype) const1218 JSHandle<JSHClass> Builtins::CreateSTypedArrayPrototypeHClass(const JSHandle<JSObject> &sObjPrototype) const
1219 {
1220 uint32_t index = 0;
1221 auto env = vm_->GetGlobalEnv();
1222 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
1223 attributes.SetIsInlinedProps(true);
1224 attributes.SetRepresentation(Representation::TAGGED);
1225 auto properties = BuiltinsSharedTypedArray::GetPrototypeProperties();
1226 uint32_t length = properties.size();
1227 ASSERT(length == BuiltinsSharedTypedArray::GetNumPrototypeInlinedProperties());
1228 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
1229 JSHandle<JSTaggedValue> keyString;
1230 for (const auto &[key, isAccessor] : properties) {
1231 attributes.SetOffset(index);
1232 attributes.SetIsAccessor(isAccessor);
1233 if (key == "[Symbol.iterator]") {
1234 keyString = env->GetIteratorSymbol();
1235 } else if (key == "[Symbol.toStringTag]") {
1236 keyString = env->GetToStringTagSymbol();
1237 } else {
1238 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
1239 }
1240 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
1241 }
1242 JSHandle<JSHClass> sTypedArrayPrototypeHClass =
1243 factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
1244 JSHandle<JSTaggedValue>(sObjPrototype),
1245 JSHandle<JSTaggedValue>(layout));
1246 return sTypedArrayPrototypeHClass;
1247 }
1248
CreateSTypedArrayFunctionHClass(const JSHandle<JSFunction> & sFuncPrototype) const1249 JSHandle<JSHClass> Builtins::CreateSTypedArrayFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
1250 {
1251 uint32_t index = 0;
1252 auto env = vm_->GetGlobalEnv();
1253 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
1254 attributes.SetIsInlinedProps(true);
1255 attributes.SetRepresentation(Representation::TAGGED);
1256 auto properties = BuiltinsSharedTypedArray::GetFunctionProperties();
1257 uint32_t length = properties.size();
1258 JSHandle<JSTaggedValue> keyString;
1259 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
1260 for (const auto &[key, isAccessor] : properties) {
1261 attributes.SetOffset(index);
1262 attributes.SetIsAccessor(isAccessor);
1263 if (key == "[Symbol.species]") {
1264 keyString = env->GetSpeciesSymbol();
1265 } else {
1266 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
1267 }
1268 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
1269 }
1270 JSHandle<JSHClass> sobjPrototypeHClass =
1271 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
1272 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
1273 sobjPrototypeHClass->SetConstructor(true);
1274 sobjPrototypeHClass->SetCallable(true);
1275 return sobjPrototypeHClass;
1276 }
1277
CreateSSpecificTypedArrayFuncHClass(const JSHandle<JSFunction> & sFuncPrototype) const1278 JSHandle<JSHClass> Builtins::CreateSSpecificTypedArrayFuncHClass(const JSHandle<JSFunction> &sFuncPrototype) const
1279 {
1280 uint32_t index = 0;
1281 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
1282 attributes.SetIsInlinedProps(true);
1283 attributes.SetRepresentation(Representation::TAGGED);
1284 auto properties = BuiltinsSharedTypedArray::GetSpecificFunctionProperties();
1285 uint32_t length = properties.size();
1286 JSHandle<JSTaggedValue> keyString;
1287 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
1288 for (const auto &[key, isAccessor] : properties) {
1289 attributes.SetOffset(index);
1290 attributes.SetIsAccessor(isAccessor);
1291 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
1292 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
1293 }
1294 JSHandle<JSHClass> sobjPrototypeHClass =
1295 factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
1296 JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
1297 sobjPrototypeHClass->SetConstructor(true);
1298 sobjPrototypeHClass->SetCallable(true);
1299 return sobjPrototypeHClass;
1300 }
1301
CreateSSpecificTypedArrayInstanceHClass(const JSHandle<JSObject> & sObjPrototype) const1302 JSHandle<JSHClass> Builtins::CreateSSpecificTypedArrayInstanceHClass(const JSHandle<JSObject> &sObjPrototype) const
1303 {
1304 uint32_t index = 0;
1305 PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
1306 attributes.SetIsInlinedProps(true);
1307 attributes.SetRepresentation(Representation::TAGGED);
1308 auto properties = BuiltinsSharedTypedArray::GetSpecificArrayPrototypeProperties();
1309 uint32_t length = properties.size();
1310 JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
1311 JSHandle<JSTaggedValue> keyString;
1312 for (const auto &[key, isAccessor] : properties) {
1313 attributes.SetOffset(index);
1314 attributes.SetIsAccessor(isAccessor);
1315 keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8ReadOnly(key));
1316 layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
1317 }
1318 JSHandle<JSHClass> sSpecificTypedArrayPrototypeHClass =
1319 factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT,
1320 JSHandle<JSTaggedValue>(sObjPrototype),
1321 JSHandle<JSTaggedValue>(layout));
1322 return sSpecificTypedArrayPrototypeHClass;
1323 }
1324 } // namespace panda::ecmascript
1325