1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_JSFUNCTION_H 17 #define ECMASCRIPT_JSFUNCTION_H 18 19 #include "ecmascript/accessor_data.h" 20 #include "ecmascript/ecma_macros.h" 21 #include "ecmascript/js_object-inl.h" 22 #include "ecmascript/lexical_env.h" 23 #include "ecmascript/js_proxy.h" 24 25 namespace panda::ecmascript { 26 class JSThread; 27 struct EcmaRuntimeCallInfo; 28 29 class JSFunctionBase : public JSObject { 30 public: 31 CAST_CHECK(JSFunctionBase, IsJSFunctionBase); 32 SetConstructor(bool flag)33 inline void SetConstructor(bool flag) 34 { 35 JSHClass *hclass = GetJSHClass(); 36 hclass->SetConstructor(flag); 37 } 38 39 static bool SetFunctionName(JSThread *thread, const JSHandle<JSFunctionBase> &func, 40 const JSHandle<JSTaggedValue> &name, const JSHandle<JSTaggedValue> &prefix); 41 static JSHandle<JSTaggedValue> GetFunctionName(JSThread *thread, const JSHandle<JSFunctionBase> &func); 42 SetCallNapi(bool isCallNapi)43 void SetCallNapi(bool isCallNapi) 44 { 45 JSTaggedValue method = GetMethod(); 46 Method::Cast(method.GetTaggedObject())->SetCallNapi(isCallNapi); 47 } 48 IsCallNapi()49 bool IsCallNapi() const 50 { 51 JSTaggedValue method = GetMethod(); 52 return Method::ConstCast(method.GetTaggedObject())->IsCallNapi(); 53 } 54 GetFunctionKind()55 FunctionKind GetFunctionKind() const 56 { 57 JSTaggedValue method = GetMethod(); 58 return Method::ConstCast(method.GetTaggedObject())->GetFunctionKind(); 59 } 60 GetModule()61 JSTaggedValue GetModule() const 62 { 63 JSTaggedValue method = GetMethod(); 64 return Method::ConstCast(method.GetTaggedObject())->GetModule(); 65 } 66 67 static constexpr size_t METHOD_OFFSET = JSObject::SIZE; 68 ACCESSORS(Method, METHOD_OFFSET, LENGTH_OFFSET) 69 ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, LAST_OFFSET) 70 DEFINE_ALIGN_SIZE(LAST_OFFSET); 71 72 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, METHOD_OFFSET, LENGTH_OFFSET) 73 DECL_DUMP() 74 }; 75 76 static_assert((JSFunctionBase::SIZE % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT)) == 0); 77 static_assert(JSFunctionBase::METHOD_OFFSET == JSProxy::METHOD_OFFSET); 78 79 class JSFunction : public JSFunctionBase { 80 public: 81 static constexpr int LENGTH_OF_INLINE_PROPERTIES = 3; 82 static constexpr int LENGTH_INLINE_PROPERTY_INDEX = 0; 83 static constexpr int NAME_INLINE_PROPERTY_INDEX = 1; 84 static constexpr int PROTOTYPE_INLINE_PROPERTY_INDEX = 2; 85 static constexpr int CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX = 1; 86 87 CAST_CHECK(JSFunction, IsJSFunction); 88 89 static void InitializeJSFunction(JSThread *thread, const JSHandle<GlobalEnv> &env, const JSHandle<JSFunction> &func, 90 FunctionKind kind = FunctionKind::NORMAL_FUNCTION); 91 // ecma6 7.3 92 static bool OrdinaryHasInstance(JSThread *thread, const JSHandle<JSTaggedValue> &constructor, 93 const JSHandle<JSTaggedValue> &obj); 94 95 static JSTaggedValue SpeciesConstructor(const JSHandle<JSFunction> &func, 96 const JSHandle<JSFunction> &defaultConstructor); 97 98 // ecma6 9.2 99 // 7.3.12 Call(F, V, argumentsList) 100 101 static JSTaggedValue Call(EcmaRuntimeCallInfo *info); 102 103 static JSTaggedValue Construct(EcmaRuntimeCallInfo *info); 104 static JSTaggedValue Invoke(EcmaRuntimeCallInfo *info, const JSHandle<JSTaggedValue> &key); 105 static JSTaggedValue InvokeOptimizedEntrypoint(JSThread *thread, JSHandle<JSFunction> mainFunc, 106 JSHandle<JSTaggedValue> &thisArg, std::string_view entryPoint, CJSInfo* cjsInfo); 107 static JSTaggedValue InvokeOptimizedEntrypoint(JSThread *thread, JSHandle<JSFunction> func, 108 EcmaRuntimeCallInfo *info); 109 // 9.2.2[[Construct]](argumentsList, newTarget) 110 // 9.3.2[[Construct]](argumentsList, newTarget) 111 static JSTaggedValue ConstructInternal(EcmaRuntimeCallInfo *info); 112 113 static bool AddRestrictedFunctionProperties(const JSHandle<JSFunction> &func, const JSHandle<JSTaggedValue> &realm); 114 static bool MakeConstructor(JSThread *thread, const JSHandle<JSFunction> &func, 115 const JSHandle<JSTaggedValue> &proto, bool writable = true); 116 static bool SetFunctionLength(JSThread *thread, const JSHandle<JSFunction> &func, JSTaggedValue length, 117 bool cfg = true); 118 static JSHandle<JSObject> NewJSFunctionPrototype(JSThread *thread, const JSHandle<JSFunction> &func); 119 static JSTaggedValue AccessCallerArgumentsThrowTypeError(EcmaRuntimeCallInfo *argv); 120 static JSTaggedValue PrototypeGetter(JSThread *thread, const JSHandle<JSObject> &self); 121 static bool PrototypeSetter(JSThread *thread, const JSHandle<JSObject> &self, const JSHandle<JSTaggedValue> &value, 122 bool mayThrow); 123 static JSTaggedValue NameGetter(JSThread *thread, const JSHandle<JSObject> &self); 124 static JSTaggedValue LengthGetter(JSThread *thread, const JSHandle<JSObject> &self); 125 static bool NameSetter(JSThread *thread, const JSHandle<JSObject> &self, const JSHandle<JSTaggedValue> &value, 126 bool mayThrow); 127 static void SetFunctionNameNoPrefix(JSThread *thread, JSFunction *func, JSTaggedValue name); GetFunctionPrototype()128 inline JSTaggedValue GetFunctionPrototype() const 129 { 130 ASSERT(HasFunctionPrototype()); 131 JSTaggedValue protoOrHClass = GetProtoOrHClass(); 132 if (protoOrHClass.IsJSHClass()) { 133 return JSHClass::Cast(protoOrHClass.GetTaggedObject())->GetPrototype(); 134 } 135 136 return protoOrHClass; 137 } 138 139 static void SetFunctionPrototypeOrInstanceHClass(const JSThread *thread, const JSHandle<JSFunction> &fun, 140 JSTaggedValue protoOrHClass); 141 HasInitialClass()142 inline bool HasInitialClass() const 143 { 144 JSTaggedValue protoOrHClass = GetProtoOrHClass(); 145 return protoOrHClass.IsJSHClass(); 146 } 147 HasFunctionPrototype()148 inline bool HasFunctionPrototype() const 149 { 150 JSTaggedValue protoOrHClass = GetProtoOrHClass(); 151 return !protoOrHClass.IsHole(); 152 } 153 SetFunctionLength(const JSThread * thread,JSTaggedValue length)154 inline void SetFunctionLength(const JSThread *thread, JSTaggedValue length) 155 { 156 ASSERT(!IsPropertiesDict()); 157 SetPropertyInlinedProps(thread, LENGTH_INLINE_PROPERTY_INDEX, length); 158 } 159 IsGetterOrSetter()160 inline bool IsGetterOrSetter() const 161 { 162 FunctionKind kind = GetFunctionKind(); 163 return kind == FunctionKind::GETTER_FUNCTION || kind == FunctionKind::SETTER_FUNCTION; 164 } 165 IsGetter()166 inline bool IsGetter() const 167 { 168 FunctionKind kind = GetFunctionKind(); 169 return kind == FunctionKind::GETTER_FUNCTION; 170 } 171 IsBase()172 inline bool IsBase() const 173 { 174 FunctionKind kind = GetFunctionKind(); 175 return kind <= FunctionKind::CLASS_CONSTRUCTOR; 176 } 177 IsDerivedConstructor()178 inline bool IsDerivedConstructor() const 179 { 180 FunctionKind kind = GetFunctionKind(); 181 return kind == FunctionKind::DERIVED_CONSTRUCTOR; 182 } 183 IsArrowFunction(FunctionKind kind)184 inline static bool IsArrowFunction(FunctionKind kind) 185 { 186 return (kind >= FunctionKind::ARROW_FUNCTION) && (kind <= FunctionKind::ASYNC_ARROW_FUNCTION); 187 } 188 IsClassConstructor(FunctionKind kind)189 inline static bool IsClassConstructor(FunctionKind kind) 190 { 191 return (kind == FunctionKind::CLASS_CONSTRUCTOR) || (kind == FunctionKind::DERIVED_CONSTRUCTOR); 192 } 193 IsConstructorKind(FunctionKind kind)194 inline static bool IsConstructorKind(FunctionKind kind) 195 { 196 return (kind >= FunctionKind::BASE_CONSTRUCTOR) && (kind <= FunctionKind::DERIVED_CONSTRUCTOR); 197 } 198 IsBuiltinConstructor()199 inline bool IsBuiltinConstructor() 200 { 201 FunctionKind kind = GetFunctionKind(); 202 return kind >= FunctionKind::BUILTIN_PROXY_CONSTRUCTOR && kind <= FunctionKind::BUILTIN_CONSTRUCTOR; 203 } 204 HasPrototype(FunctionKind kind)205 inline static bool HasPrototype(FunctionKind kind) 206 { 207 return (kind >= FunctionKind::BASE_CONSTRUCTOR) && (kind <= FunctionKind::ASYNC_GENERATOR_FUNCTION) && 208 (kind != FunctionKind::BUILTIN_PROXY_CONSTRUCTOR); 209 } 210 HasAccessor(FunctionKind kind)211 inline static bool HasAccessor(FunctionKind kind) 212 { 213 return kind >= FunctionKind::NORMAL_FUNCTION && kind <= FunctionKind::ASYNC_FUNCTION; 214 } 215 IsClassConstructor()216 inline bool IsClassConstructor() const 217 { 218 return GetClass()->IsClassConstructor(); 219 } 220 SetClassConstructor(bool flag)221 inline void SetClassConstructor(bool flag) 222 { 223 GetClass()->SetClassConstructor(flag); 224 } 225 226 void SetFunctionExtraInfo(JSThread *thread, void *nativeFunc, const DeleteEntryPoint &deleter, 227 void *data, size_t nativeBindingsize = 0); 228 229 JSTaggedValue GetFunctionExtraInfo() const; 230 JSTaggedValue GetNativeFunctionExtraInfo() const; 231 JSTaggedValue GetRecordName() const; 232 233 void InitializeForConcurrentFunction(JSThread *thread); 234 235 static void InitializeJSFunction(JSThread *thread, const JSHandle<JSFunction> &func, 236 FunctionKind kind = FunctionKind::NORMAL_FUNCTION); 237 static JSHClass *GetOrCreateInitialJSHClass(JSThread *thread, const JSHandle<JSFunction> &fun); 238 static JSHandle<JSHClass> GetInstanceJSHClass(JSThread *thread, JSHandle<JSFunction> constructor, 239 JSHandle<JSTaggedValue> newTarget); 240 241 static constexpr size_t PROTO_OR_DYNCLASS_OFFSET = JSFunctionBase::SIZE; 242 ACCESSORS(ProtoOrHClass, PROTO_OR_DYNCLASS_OFFSET, LEXICAL_ENV_OFFSET) 243 // For runtime native function, the LexicalEnv field is used to store GlobalEnv, such as RegExp's native function 244 ACCESSORS(LexicalEnv, LEXICAL_ENV_OFFSET, HOME_OBJECT_OFFSET) 245 ACCESSORS(HomeObject, HOME_OBJECT_OFFSET, WORK_NODE_POINTER_OFFSET) 246 ACCESSORS_PRIMITIVE_FIELD(WorkNodePointer, uintptr_t, WORK_NODE_POINTER_OFFSET, LAST_OFFSET) 247 DEFINE_ALIGN_SIZE(LAST_OFFSET); 248 249 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunctionBase, PROTO_OR_DYNCLASS_OFFSET, WORK_NODE_POINTER_OFFSET) 250 DECL_DUMP() 251 252 private: 253 static JSHandle<JSHClass> GetOrCreateDerivedJSHClass(JSThread *thread, JSHandle<JSFunction> derived, 254 JSHandle<JSHClass> ctorInitialClass); 255 static std::vector<JSTaggedType> GetArgsData(bool isFastCall, JSHandle<JSTaggedValue> &thisArg, 256 JSHandle<JSFunction> mainFunc, CJSInfo* cjsInfo); 257 }; 258 259 class JSGeneratorFunction : public JSFunction { 260 public: 261 CAST_CHECK(JSGeneratorFunction, IsGeneratorFunction); 262 263 static constexpr size_t SIZE = JSFunction::SIZE; 264 265 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, SIZE, SIZE) 266 267 DECL_DUMP() 268 }; 269 270 class JSBoundFunction : public JSFunctionBase { 271 public: 272 CAST_CHECK(JSBoundFunction, IsBoundFunction); 273 274 // 9.4.1.2[[Construct]](argumentsList, newTarget) 275 static JSTaggedValue ConstructInternal(EcmaRuntimeCallInfo *info); 276 277 static constexpr size_t BOUND_TARGET_OFFSET = JSFunctionBase::SIZE; 278 ACCESSORS(BoundTarget, BOUND_TARGET_OFFSET, BOUND_THIS_OFFSET); 279 ACCESSORS(BoundThis, BOUND_THIS_OFFSET, BOUND_ARGUMENTS_OFFSET); 280 ACCESSORS(BoundArguments, BOUND_ARGUMENTS_OFFSET, SIZE); 281 282 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunctionBase, BOUND_TARGET_OFFSET, SIZE) 283 284 DECL_DUMP() 285 }; 286 287 class JSProxyRevocFunction : public JSFunction { 288 public: 289 CAST_CHECK(JSProxyRevocFunction, IsProxyRevocFunction); 290 291 static void ProxyRevocFunctions(const JSThread *thread, const JSHandle<JSProxyRevocFunction> &revoker); 292 293 static constexpr size_t REVOCABLE_PROXY_OFFSET = JSFunction::SIZE; 294 ACCESSORS(RevocableProxy, REVOCABLE_PROXY_OFFSET, SIZE); 295 296 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, REVOCABLE_PROXY_OFFSET, SIZE) 297 298 DECL_DUMP() 299 }; 300 301 // ResolveFunction/RejectFunction 302 class JSPromiseReactionsFunction : public JSFunction { 303 public: 304 CAST_CHECK(JSPromiseReactionsFunction, IsJSPromiseReactionFunction); 305 306 static constexpr size_t PROMISE_OFFSET = JSFunction::SIZE; 307 ACCESSORS(Promise, PROMISE_OFFSET, ALREADY_RESOLVED_OFFSET); 308 ACCESSORS(AlreadyResolved, ALREADY_RESOLVED_OFFSET, SIZE); 309 310 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, PROMISE_OFFSET, SIZE) 311 312 DECL_DUMP() 313 }; 314 315 // ExecutorFunction 316 class JSPromiseExecutorFunction : public JSFunction { 317 public: 318 CAST_CHECK(JSPromiseExecutorFunction, IsJSPromiseExecutorFunction); 319 320 static constexpr size_t CAPABILITY_OFFSET = JSFunction::SIZE; 321 ACCESSORS(Capability, CAPABILITY_OFFSET, SIZE); 322 323 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, CAPABILITY_OFFSET, SIZE) 324 325 DECL_DUMP() 326 }; 327 328 class JSAsyncModuleFulfilledFunction : public JSFunction { 329 public: 330 CAST_CHECK(JSAsyncModuleFulfilledFunction, IsJSAsyncModuleFulfilledFunction); 331 332 static constexpr size_t MODULE_OFFSET = JSFunction::SIZE; 333 ACCESSORS(Module, MODULE_OFFSET, SIZE); 334 335 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, MODULE_OFFSET, SIZE) 336 337 DECL_DUMP() 338 }; 339 340 class JSAsyncModuleRejectedFunction : public JSFunction { 341 public: 342 CAST_CHECK(JSAsyncModuleRejectedFunction, IsJSAsyncModuleRejectedFunction); 343 344 static constexpr size_t MODULE_OFFSET = JSFunction::SIZE; 345 ACCESSORS(Module, MODULE_OFFSET, SIZE); 346 347 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, MODULE_OFFSET, SIZE) 348 349 DECL_DUMP() 350 }; 351 352 class JSPromiseAllResolveElementFunction : public JSFunction { 353 public: 354 CAST_CHECK(JSPromiseAllResolveElementFunction, IsJSPromiseAllResolveElementFunction); 355 356 static constexpr size_t INDEX_OFFSET = JSFunction::SIZE; 357 ACCESSORS(Index, INDEX_OFFSET, VALUES_OFFSET); 358 ACCESSORS(Values, VALUES_OFFSET, CAPABILITIES_OFFSET); 359 ACCESSORS(Capabilities, CAPABILITIES_OFFSET, REMAINING_ELEMENTS_OFFSET); 360 ACCESSORS(RemainingElements, REMAINING_ELEMENTS_OFFSET, ALREADY_CALLED_OFFSET); 361 ACCESSORS(AlreadyCalled, ALREADY_CALLED_OFFSET, SIZE); 362 363 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, INDEX_OFFSET, SIZE) 364 365 DECL_DUMP() 366 }; 367 368 // PromiseAnyRejectElementFunction 369 class JSPromiseAnyRejectElementFunction : public JSFunction { 370 public: 371 CAST_CHECK(JSPromiseAnyRejectElementFunction, IsJSPromiseAnyRejectElementFunction); 372 373 static constexpr size_t ERRORS_OFFSET = JSFunction::SIZE; 374 375 ACCESSORS(Errors, ERRORS_OFFSET, CAPABILITY_OFFSET); 376 ACCESSORS(Capability, CAPABILITY_OFFSET, REMAINING_ELEMENTS_OFFSET); 377 ACCESSORS(RemainingElements, REMAINING_ELEMENTS_OFFSET, ALREADY_CALLED_OFFSET); 378 ACCESSORS(AlreadyCalled, ALREADY_CALLED_OFFSET, INDEX_OFFSET); 379 ACCESSORS_PRIMITIVE_FIELD(Index, uint32_t, INDEX_OFFSET, LAST_OFFSET); 380 DEFINE_ALIGN_SIZE(LAST_OFFSET); 381 382 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, ERRORS_OFFSET, INDEX_OFFSET) 383 384 DECL_DUMP() 385 }; 386 387 // PromiseAllSettledElementFunction 388 class JSPromiseAllSettledElementFunction : public JSFunction { 389 public: 390 CAST_CHECK(JSPromiseAllSettledElementFunction, IsJSPromiseAllSettledElementFunction); 391 392 static constexpr size_t ALREADY_CALLED_OFFSET = JSFunction::SIZE; 393 ACCESSORS(AlreadyCalled, ALREADY_CALLED_OFFSET, VALUES_OFFSET); 394 ACCESSORS(Values, VALUES_OFFSET, CAPABILITY_OFFSET); 395 ACCESSORS(Capability, CAPABILITY_OFFSET, REMAINING_ELEMENTS_OFFSET); 396 ACCESSORS(RemainingElements, REMAINING_ELEMENTS_OFFSET, INDEX_OFFSET); 397 ACCESSORS_PRIMITIVE_FIELD(Index, uint32_t, INDEX_OFFSET, LAST_OFFSET); 398 DEFINE_ALIGN_SIZE(LAST_OFFSET); 399 400 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, ALREADY_CALLED_OFFSET, INDEX_OFFSET) 401 402 DECL_DUMP() 403 }; 404 405 // PromiseFinallyFunction 406 class JSPromiseFinallyFunction : public JSFunction { 407 public: 408 CAST_CHECK(JSPromiseFinallyFunction, IsJSPromiseFinallyFunction); 409 410 static constexpr size_t CONSTRUCTOR_OFFSET = JSFunction::SIZE; 411 ACCESSORS(Constructor, CONSTRUCTOR_OFFSET, ONFINALLY_OFFSET); 412 ACCESSORS(OnFinally, ONFINALLY_OFFSET, SIZE); 413 414 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, CONSTRUCTOR_OFFSET, SIZE) 415 416 DECL_DUMP() 417 }; 418 419 // ValueThunkOrThrowReason 420 class JSPromiseValueThunkOrThrowerFunction : public JSFunction { 421 public: 422 CAST_CHECK(JSPromiseValueThunkOrThrowerFunction, IsJSPromiseValueThunkOrThrowerFunction); 423 424 static constexpr size_t RESULT_OFFSET = JSFunction::SIZE; 425 ACCESSORS(Result, RESULT_OFFSET, SIZE); 426 427 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, RESULT_OFFSET, SIZE) 428 429 DECL_DUMP() 430 }; 431 432 class JSIntlBoundFunction : public JSFunction { 433 public: 434 CAST_CHECK(JSIntlBoundFunction, IsJSIntlBoundFunction); 435 436 static JSTaggedValue IntlNameGetter(JSThread *thread, const JSHandle<JSObject> &self); 437 438 static constexpr size_t NUMBER_FORMAT_OFFSET = JSFunction::SIZE; 439 440 ACCESSORS(NumberFormat, NUMBER_FORMAT_OFFSET, DATETIME_FORMAT_OFFSET); 441 ACCESSORS(DateTimeFormat, DATETIME_FORMAT_OFFSET, COLLATOR_OFFSET); 442 ACCESSORS(Collator, COLLATOR_OFFSET, SIZE); 443 444 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, NUMBER_FORMAT_OFFSET, SIZE) 445 DECL_DUMP() 446 }; 447 448 class JSAsyncGeneratorFunction : public JSFunction { 449 public: 450 CAST_CHECK(JSAsyncGeneratorFunction, IsAsyncGeneratorFunction); 451 static constexpr size_t SIZE = JSFunction::SIZE; 452 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, SIZE, SIZE) 453 DECL_DUMP() 454 }; 455 456 class JSAsyncFromSyncIterUnwarpFunction : public JSFunction { 457 public: 458 CAST_CHECK(JSAsyncFromSyncIterUnwarpFunction, IsJSAsyncFromSyncIterUnwarpFunction); 459 static constexpr size_t DONE_OFFSET = JSFunction::SIZE; 460 ACCESSORS(Done, DONE_OFFSET, SIZE); 461 462 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, DONE_OFFSET, SIZE); 463 DECL_DUMP() 464 }; 465 466 class JSSharedFunction : public JSFunction { 467 public: 468 CAST_CHECK(JSSharedFunction, IsJSSharedFunction); 469 static constexpr size_t SIZE = JSFunction::SIZE; 470 static constexpr uint32_t MAX_INLINE = PropertyAttributes::MAX_FAST_PROPS_CAPACITY - 471 SIZE / JSTaggedValue::TaggedTypeSize() + 1; 472 DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, SIZE, SIZE) 473 }; 474 475 } // namespace panda::ecmascript 476 477 #endif // ECMASCRIPT_JSFUNCTION_H 478