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