• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #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/ic/profile_type_info_cell.h"
22 #include "ecmascript/js_object.h"
23 #include "ecmascript/js_proxy.h"
24 
25 namespace panda::ecmascript {
26 class JSThread;
27 struct EcmaRuntimeCallInfo;
28 struct CJSInfo;
29 
30 class JSFunctionBase : public JSObject {
31 public:
32     CAST_CHECK(JSFunctionBase, IsJSFunctionBase);
33 
SetConstructor(bool flag)34     inline void SetConstructor(bool flag)
35     {
36         JSHClass *hclass = GetJSHClass();
37         hclass->SetConstructor(flag);
38     }
39 
40     static bool SetFunctionName(JSThread *thread, const JSHandle<JSFunctionBase> &func,
41                                 const JSHandle<JSTaggedValue> &name, const JSHandle<JSTaggedValue> &prefix);
42     static JSHandle<JSTaggedValue> GetFunctionName(JSThread *thread, const JSHandle<JSFunctionBase> &func);
43 
SetCallNapi(bool isCallNapi)44     void SetCallNapi(bool isCallNapi)
45     {
46         JSTaggedValue method = GetMethod();
47         Method::Cast(method.GetTaggedObject())->SetCallNapi(isCallNapi);
48     }
49 
IsCallNapi()50     bool IsCallNapi() const
51     {
52         JSTaggedValue method = GetMethod();
53         return Method::ConstCast(method.GetTaggedObject())->IsCallNapi();
54     }
55 
GetFunctionKind()56     FunctionKind GetFunctionKind() const
57     {
58         JSTaggedValue method = GetMethod();
59         return Method::ConstCast(method.GetTaggedObject())->GetFunctionKind();
60     }
61 
62     void SetCompiledFuncEntry(uintptr_t codeEntry, bool isFastCall);
63 
SetIsCompiledFastCall(bool isFastCall)64     void SetIsCompiledFastCall(bool isFastCall)
65     {
66         uint32_t bitField = GetBitField();
67         uint32_t newValue = IsFastCallBit::Update(bitField, isFastCall);
68         SetBitField(newValue);
69     }
70 
IsCompiledFastCall()71     bool IsCompiledFastCall() const
72     {
73         uint32_t bitField = GetBitField();
74         return IsFastCallBit::Decode(bitField);
75     }
76 
IsCompiledCodeFromCallTarget(JSTaggedValue callTarget)77     static bool IsCompiledCodeFromCallTarget(JSTaggedValue callTarget)
78     {
79         if (callTarget.IsJSFunction()) {
80             return Cast(callTarget.GetTaggedObject())->IsCompiledCode();
81         } else {
82             ECMAObject *target = reinterpret_cast<ECMAObject*>(callTarget.GetTaggedObject());
83             ASSERT(target != nullptr);
84             Method *method = target->GetCallTarget();
85             return method->IsAotWithCallField();
86         }
87     }
88 
IsFastCallFromCallTarget(JSTaggedValue callTarget)89     static bool IsFastCallFromCallTarget(JSTaggedValue callTarget)
90     {
91         if (callTarget.IsJSFunction()) {
92             return Cast(callTarget.GetTaggedObject())->IsCompiledFastCall();
93         } else {
94             ECMAObject *target = reinterpret_cast<ECMAObject*>(callTarget.GetTaggedObject());
95             ASSERT(target != nullptr);
96             Method *method = target->GetCallTarget();
97             return method->IsFastCall();
98         }
99     }
100 
SetCompiledCodeBit(bool isCompiled)101     void SetCompiledCodeBit(bool isCompiled)
102     {
103         uint32_t bitField = GetBitField();
104         uint32_t newValue = IsCompiledCodeBit::Update(bitField, isCompiled);
105         SetBitField(newValue);
106     }
107 
IsCompiledCode()108     bool IsCompiledCode() const
109     {
110         uint32_t bitField = GetBitField();
111         return IsCompiledCodeBit::Decode(bitField);
112     }
113 
114     void ClearCompiledCodeFlags();
115 
SetTaskConcurrentFuncFlag(bool value)116     void SetTaskConcurrentFuncFlag(bool value)
117     {
118         uint32_t bitField = GetBitField();
119         uint32_t newValue = TaskConcurrentFuncFlagBit::Update(bitField, value);
120         SetBitField(newValue);
121     }
122 
GetTaskConcurrentFuncFlag()123     bool GetTaskConcurrentFuncFlag() const
124     {
125         uint32_t bitField = GetBitField();
126         return TaskConcurrentFuncFlagBit::Decode(bitField);
127     }
128 
129     /* compiled code flag field */
130     using IsCompiledCodeBit = BitField<bool, 0, 1>;        // offset 0
131     using IsFastCallBit = IsCompiledCodeBit::NextFlag;     // offset 1
132     static constexpr uint32_t COMPILED_CODE_FASTCALL_BITS = 0x3; // 0x3U: compiled code and fastcall bit field
133 
134     using TaskConcurrentFuncFlagBit = IsFastCallBit::NextFlag;     // offset 2
135 
136     static constexpr size_t METHOD_OFFSET = JSObject::SIZE;
137     ACCESSORS(Method, METHOD_OFFSET, CODE_ENTRY_OFFSET)
138     ACCESSORS_PRIMITIVE_FIELD(CodeEntry, uintptr_t, CODE_ENTRY_OFFSET, LENGTH_OFFSET)
139     ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, BIT_FIELD_OFFSET)
140     ACCESSORS_PRIMITIVE_FIELD(BitField, uint32_t, BIT_FIELD_OFFSET, LAST_OFFSET)
141     DEFINE_ALIGN_SIZE(LAST_OFFSET);
142 
143     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, METHOD_OFFSET, CODE_ENTRY_OFFSET)
144     DECL_DUMP()
145 };
146 
147 static_assert((JSFunctionBase::SIZE % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT)) == 0);
148 static_assert(JSFunctionBase::METHOD_OFFSET == JSProxy::METHOD_OFFSET);
149 
150 class JSFunction : public JSFunctionBase {
151 public:
152     static constexpr int LENGTH_OF_INLINE_PROPERTIES = 3;
153     static constexpr int LENGTH_INLINE_PROPERTY_INDEX = 0;
154     static constexpr int NAME_INLINE_PROPERTY_INDEX = 1;
155     static constexpr int PROTOTYPE_INLINE_PROPERTY_INDEX = 2;
156     static constexpr int CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX = 1;
157 
158     CAST_CHECK(JSFunction, IsJSFunction);
159 
160     static void InitializeJSFunction(JSThread *thread, const JSHandle<GlobalEnv> &env, const JSHandle<JSFunction> &func,
161                                      FunctionKind kind = FunctionKind::NORMAL_FUNCTION);
162     // ecma6 7.3
163     static bool OrdinaryHasInstance(JSThread *thread, const JSHandle<JSTaggedValue> &constructor,
164                                     const JSHandle<JSTaggedValue> &obj);
165 
166     static JSTaggedValue SpeciesConstructor(const JSHandle<JSFunction> &func,
167                                             const JSHandle<JSFunction> &defaultConstructor);
168 
169     // ecma6 9.2
170     // 7.3.12 Call(F, V, argumentsList)
171 
172     static JSTaggedValue Call(EcmaRuntimeCallInfo *info);
173 
174     static JSTaggedValue Construct(EcmaRuntimeCallInfo *info);
175     static JSTaggedValue Invoke(EcmaRuntimeCallInfo *info, const JSHandle<JSTaggedValue> &key);
176     static JSTaggedValue InvokeOptimizedEntrypoint(JSThread *thread, JSHandle<JSFunction> mainFunc,
177         JSHandle<JSTaggedValue> &thisArg, CJSInfo* cjsInfo);
178     static JSTaggedValue InvokeOptimizedEntrypoint(JSThread *thread, JSHandle<JSFunction> func,
179         EcmaRuntimeCallInfo *info);
180     // 9.2.2[[Construct]](argumentsList, newTarget)
181     // 9.3.2[[Construct]](argumentsList, newTarget)
182     static JSTaggedValue ConstructInternal(EcmaRuntimeCallInfo *info);
183 
184     static bool AddRestrictedFunctionProperties(const JSHandle<JSFunction> &func, const JSHandle<JSTaggedValue> &realm);
185     static bool MakeConstructor(JSThread *thread, const JSHandle<JSFunction> &func,
186                                 const JSHandle<JSTaggedValue> &proto, bool writable = true);
187     static bool SetFunctionLength(JSThread *thread, const JSHandle<JSFunction> &func, JSTaggedValue length,
188                                   bool cfg = true);
189     static JSHandle<JSObject> NewJSFunctionPrototype(JSThread *thread, const JSHandle<JSFunction> &func);
190     static JSTaggedValue AccessCallerArgumentsThrowTypeError(EcmaRuntimeCallInfo *argv);
191     static JSTaggedValue PrototypeGetter(JSThread *thread, const JSHandle<JSObject> &self);
192     static bool PrototypeSetter(JSThread *thread, const JSHandle<JSObject> &self, const JSHandle<JSTaggedValue> &value,
193                                 bool mayThrow);
194     static JSTaggedValue NameGetter(JSThread *thread, const JSHandle<JSObject> &self);
195     static JSTaggedValue LengthGetter(JSThread *thread, const JSHandle<JSObject> &self);
196     static bool NameSetter(JSThread *thread, const JSHandle<JSObject> &self, const JSHandle<JSTaggedValue> &value,
197                            bool mayThrow);
198     static void SetFunctionNameNoPrefix(JSThread *thread, JSFunction *func, JSTaggedValue name);
GetFunctionPrototype()199     inline JSTaggedValue GetFunctionPrototype() const
200     {
201         ASSERT(HasFunctionPrototype());
202         JSTaggedValue protoOrHClass = GetProtoOrHClass();
203         if (protoOrHClass.IsJSHClass()) {
204             return JSHClass::Cast(protoOrHClass.GetTaggedObject())->GetPrototype();
205         }
206 
207         return protoOrHClass;
208     }
209 
210     static void SetFunctionPrototypeOrInstanceHClass(const JSThread *thread, const JSHandle<JSFunction> &fun,
211                                                      JSTaggedValue protoOrHClass);
212 
213     static EcmaString* GetFunctionNameString(JSThread *thread, JSHandle<EcmaString> concatString,
214                                              ObjectFactory *factory, JSHandle<JSTaggedValue> target);
215 
HasInitialClass()216     inline bool HasInitialClass() const
217     {
218         JSTaggedValue protoOrHClass = GetProtoOrHClass();
219         return protoOrHClass.IsJSHClass();
220     }
221 
HasFunctionPrototype()222     inline bool HasFunctionPrototype() const
223     {
224         JSTaggedValue protoOrHClass = GetProtoOrHClass();
225         return !protoOrHClass.IsHole();
226     }
227 
228     void SetFunctionLength(const JSThread *thread, JSTaggedValue length);
229 
IsGetterOrSetter()230     inline bool IsGetterOrSetter() const
231     {
232         FunctionKind kind = GetFunctionKind();
233         return kind == FunctionKind::GETTER_FUNCTION || kind == FunctionKind::SETTER_FUNCTION;
234     }
235 
IsGetter()236     inline bool IsGetter() const
237     {
238         FunctionKind kind = GetFunctionKind();
239         return kind == FunctionKind::GETTER_FUNCTION;
240     }
241 
IsBase()242     inline bool IsBase() const
243     {
244         FunctionKind kind = GetFunctionKind();
245         return kind <= FunctionKind::CLASS_CONSTRUCTOR;
246     }
247 
IsDerivedConstructor()248     inline bool IsDerivedConstructor() const
249     {
250         FunctionKind kind = GetFunctionKind();
251         return kind == FunctionKind::DERIVED_CONSTRUCTOR;
252     }
253 
IsArrowFunction(FunctionKind kind)254     inline static bool IsArrowFunction(FunctionKind kind)
255     {
256         return (kind >= FunctionKind::ARROW_FUNCTION) && (kind <= FunctionKind::ASYNC_ARROW_FUNCTION);
257     }
258 
IsClassConstructor(FunctionKind kind)259     inline static bool IsClassConstructor(FunctionKind kind)
260     {
261         return (kind == FunctionKind::CLASS_CONSTRUCTOR) || (kind == FunctionKind::DERIVED_CONSTRUCTOR);
262     }
263 
IsConstructorKind(FunctionKind kind)264     inline static bool IsConstructorKind(FunctionKind kind)
265     {
266         return (kind >= FunctionKind::BASE_CONSTRUCTOR) && (kind <= FunctionKind::DERIVED_CONSTRUCTOR);
267     }
268 
IsBuiltinConstructor()269     inline bool IsBuiltinConstructor()
270     {
271         FunctionKind kind = GetFunctionKind();
272         return kind >= FunctionKind::BUILTIN_PROXY_CONSTRUCTOR && kind <= FunctionKind::BUILTIN_CONSTRUCTOR;
273     }
274 
HasPrototype(FunctionKind kind)275     inline static bool HasPrototype(FunctionKind kind)
276     {
277         return (kind >= FunctionKind::BASE_CONSTRUCTOR) && (kind <= FunctionKind::ASYNC_GENERATOR_FUNCTION) &&
278             (kind != FunctionKind::BUILTIN_PROXY_CONSTRUCTOR);
279     }
280 
IsNormalFunctionAndCanSkipWbWhenInitialization(FunctionKind kind)281     inline static bool IsNormalFunctionAndCanSkipWbWhenInitialization(FunctionKind kind)
282     {
283         return kind != FunctionKind::LAST_FUNCTION_KIND;
284     }
285 
HasAccessor(FunctionKind kind)286     inline static bool HasAccessor(FunctionKind kind)
287     {
288         return kind >= FunctionKind::NORMAL_FUNCTION && kind <= FunctionKind::ASYNC_FUNCTION;
289     }
290 
IsBaseConstructorKind(FunctionKind kind)291     inline static bool IsBaseConstructorKind(FunctionKind kind)
292     {
293         return kind == FunctionKind::BASE_CONSTRUCTOR;
294     }
295 
IsClassConstructor()296     inline bool IsClassConstructor() const
297     {
298         return GetClass()->IsClassConstructor();
299     }
300 
SetClassConstructor(bool flag)301     inline void SetClassConstructor(bool flag)
302     {
303         GetClass()->SetClassConstructor(flag);
304     }
305 
HasProfileTypeInfo(JSThread * thread)306     inline bool HasProfileTypeInfo(JSThread *thread) const
307     {
308         return GetRawProfileTypeInfo().IsProfileTypeInfoCell() &&
309                !ProfileTypeInfoCell::Cast(GetRawProfileTypeInfo())->IsEmptyProfileTypeInfoCell(thread);
310     }
311 
312     void SetFunctionExtraInfo(JSThread *thread, void *nativeFunc, const NativePointerCallback &deleter,
313                               void *data, size_t nativeBindingsize = 0, Concurrent isConcurrent = Concurrent::NO);
314     void SetSFunctionExtraInfo(JSThread *thread, void *nativeFunc, const NativePointerCallback &deleter,
315                                void *data, size_t nativeBindingsize = 0);
316     static void SetProfileTypeInfo(const JSThread *thread, const JSHandle<JSFunction> &func,
317                                    const JSHandle<JSTaggedValue> &value, BarrierMode mode = WRITE_BARRIER);
318     static void UpdateProfileTypeInfoCell(JSThread *thread, JSHandle<FunctionTemplate> literalFunc,
319                                           JSHandle<JSFunction> targetFunc);
320     void SetJitMachineCodeCache(const JSThread *thread, const JSHandle<MachineCode> &machineCode);
321 
322     JSTaggedValue GetFunctionExtraInfo() const;
323     JSTaggedValue GetNativeFunctionExtraInfo() const;
324     CString GetRecordName() const;
GetProfileTypeInfo()325     JSTaggedValue GetProfileTypeInfo() const
326     {
327         JSTaggedValue raw = GetRawProfileTypeInfo();
328         return ProfileTypeInfoCell::Cast(raw.GetTaggedObject())->GetValue();
329     }
330 
331     void SetJitCompiledFuncEntry(JSThread *thread, JSHandle<MachineCode> &machineCode, bool isFastCall);
332 
333     static void InitializeForConcurrentFunction(JSThread *thread, JSHandle<JSFunction> &func);
334 
335     bool IsSendableOrConcurrentFunction() const;
336     bool IsSharedFunction() const;
337 
338     static void InitializeJSFunction(JSThread *thread, const JSHandle<JSFunction> &func,
339                                      FunctionKind kind = FunctionKind::NORMAL_FUNCTION);
340     static void InitializeSFunction(JSThread *thread, const JSHandle<JSFunction> &func,
341                                     FunctionKind kind = FunctionKind::NORMAL_FUNCTION);
342     static void InitializeWithDefaultValue(JSThread *thread, const JSHandle<JSFunction> &func);
343     static JSHClass *PUBLIC_API GetOrCreateInitialJSHClass(JSThread *thread, const JSHandle<JSFunction> &fun);
344     static JSHandle<JSHClass> GetInstanceJSHClass(JSThread *thread, JSHandle<JSFunction> constructor,
345                                                   JSHandle<JSTaggedValue> newTarget);
346 
347     static constexpr size_t PROTO_OR_DYNCLASS_OFFSET = JSFunctionBase::SIZE;
348     ACCESSORS(ProtoOrHClass, PROTO_OR_DYNCLASS_OFFSET, LEXICAL_ENV_OFFSET)
349     // For runtime native function, the LexicalEnv field is used to store GlobalEnv, such as RegExp's native function
350     ACCESSORS(LexicalEnv, LEXICAL_ENV_OFFSET, MACHINECODE_OFFSET)
351     ACCESSORS(MachineCode, MACHINECODE_OFFSET, BASELINECODE_OFFSET)
352     ACCESSORS(BaselineCode, BASELINECODE_OFFSET, RAW_PROFILE_TYPE_INFO_OFFSET)
353     ACCESSORS(RawProfileTypeInfo, RAW_PROFILE_TYPE_INFO_OFFSET, HOME_OBJECT_OFFSET)
354     ACCESSORS(HomeObject, HOME_OBJECT_OFFSET, ECMA_MODULE_OFFSET)
355     ACCESSORS(Module, ECMA_MODULE_OFFSET, PROTO_TRANS_ROOT_HCLASS_OFFSET)
356     ACCESSORS(ProtoTransRootHClass, PROTO_TRANS_ROOT_HCLASS_OFFSET, WORK_NODE_POINTER_OFFSET)
357     ACCESSORS_PRIMITIVE_FIELD(WorkNodePointer, uintptr_t, WORK_NODE_POINTER_OFFSET, LAST_OFFSET)
358     DEFINE_ALIGN_SIZE(LAST_OFFSET);
359 
360     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunctionBase, PROTO_OR_DYNCLASS_OFFSET, WORK_NODE_POINTER_OFFSET)
361     DECL_DUMP()
362 
363 private:
364     static JSHandle<JSHClass> GetOrCreateDerivedJSHClass(JSThread *thread, JSHandle<JSFunction> derived,
365                                                          JSHandle<JSHClass> ctorInitialClass);
366     static std::vector<JSTaggedType> GetArgsData(bool isFastCall, JSHandle<JSTaggedValue> &thisArg,
367                                                  JSHandle<JSFunction> mainFunc,  CJSInfo* cjsInfo);
368 };
369 
370 class JSGeneratorFunction : public JSFunction {
371 public:
372     CAST_CHECK(JSGeneratorFunction, IsGeneratorFunction);
373 
374     static constexpr size_t SIZE = JSFunction::SIZE;
375 
376     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, SIZE, SIZE)
377 
378     DECL_DUMP()
379 };
380 
381 class JSBoundFunction : public JSFunctionBase {
382 public:
383     CAST_CHECK(JSBoundFunction, IsBoundFunction);
384 
385     // 9.4.1.2[[Construct]](argumentsList, newTarget)
386     static JSTaggedValue ConstructInternal(EcmaRuntimeCallInfo *info);
387 
388     static constexpr size_t BOUND_TARGET_OFFSET = JSFunctionBase::SIZE;
389     ACCESSORS(BoundTarget, BOUND_TARGET_OFFSET, BOUND_THIS_OFFSET);
390     ACCESSORS(BoundThis, BOUND_THIS_OFFSET, BOUND_ARGUMENTS_OFFSET);
391     ACCESSORS(BoundArguments, BOUND_ARGUMENTS_OFFSET, SIZE);
392 
393     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunctionBase, BOUND_TARGET_OFFSET, SIZE)
394 
395     DECL_DUMP()
396 };
397 
398 class JSProxyRevocFunction : public JSFunction {
399 public:
400     CAST_CHECK(JSProxyRevocFunction, IsProxyRevocFunction);
401 
402     static void ProxyRevocFunctions(const JSThread *thread, const JSHandle<JSProxyRevocFunction> &revoker);
403 
404     static constexpr size_t REVOCABLE_PROXY_OFFSET = JSFunction::SIZE;
405     ACCESSORS(RevocableProxy, REVOCABLE_PROXY_OFFSET, SIZE);
406 
407     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, REVOCABLE_PROXY_OFFSET, SIZE)
408 
409     DECL_DUMP()
410 };
411 
412 // ResolveFunction/RejectFunction
413 class JSPromiseReactionsFunction : public JSFunction {
414 public:
415     CAST_CHECK(JSPromiseReactionsFunction, IsJSPromiseReactionFunction);
416 
417     static constexpr size_t PROMISE_OFFSET = JSFunction::SIZE;
418     ACCESSORS(Promise, PROMISE_OFFSET, ALREADY_RESOLVED_OFFSET);
419     ACCESSORS(AlreadyResolved, ALREADY_RESOLVED_OFFSET, SIZE);
420 
421     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, PROMISE_OFFSET, SIZE)
422 
423     DECL_DUMP()
424 };
425 
426 // ExecutorFunction
427 class JSPromiseExecutorFunction : public JSFunction {
428 public:
429     CAST_CHECK(JSPromiseExecutorFunction, IsJSPromiseExecutorFunction);
430 
431     static constexpr size_t CAPABILITY_OFFSET = JSFunction::SIZE;
432     ACCESSORS(Capability, CAPABILITY_OFFSET, SIZE);
433 
434     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, CAPABILITY_OFFSET, SIZE)
435 
436     DECL_DUMP()
437 };
438 
439 class JSAsyncModuleFulfilledFunction : public JSFunction {
440 public:
441     CAST_CHECK(JSAsyncModuleFulfilledFunction, IsJSAsyncModuleFulfilledFunction);
442 
443     static constexpr size_t SIZE = JSFunction::SIZE;
444 
445     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, SIZE, SIZE)
446 
447     DECL_DUMP()
448 };
449 
450 class JSAsyncModuleRejectedFunction : public JSFunction {
451 public:
452     CAST_CHECK(JSAsyncModuleRejectedFunction, IsJSAsyncModuleRejectedFunction);
453 
454     static constexpr size_t SIZE = JSFunction::SIZE;
455 
456     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, SIZE, SIZE)
457 
458     DECL_DUMP()
459 };
460 
461 class JSPromiseAllResolveElementFunction : public JSFunction {
462 public:
463     CAST_CHECK(JSPromiseAllResolveElementFunction, IsJSPromiseAllResolveElementFunction);
464 
465     static constexpr size_t INDEX_OFFSET = JSFunction::SIZE;
466     ACCESSORS(Index, INDEX_OFFSET, VALUES_OFFSET);
467     ACCESSORS(Values, VALUES_OFFSET, CAPABILITIES_OFFSET);
468     ACCESSORS(Capabilities, CAPABILITIES_OFFSET, REMAINING_ELEMENTS_OFFSET);
469     ACCESSORS(RemainingElements, REMAINING_ELEMENTS_OFFSET, ALREADY_CALLED_OFFSET);
470     ACCESSORS(AlreadyCalled, ALREADY_CALLED_OFFSET, SIZE);
471 
472     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, INDEX_OFFSET, SIZE)
473 
474     DECL_DUMP()
475 };
476 
477 // PromiseAnyRejectElementFunction
478 class JSPromiseAnyRejectElementFunction : public JSFunction {
479 public:
480     CAST_CHECK(JSPromiseAnyRejectElementFunction, IsJSPromiseAnyRejectElementFunction);
481 
482     static constexpr size_t ERRORS_OFFSET = JSFunction::SIZE;
483 
484     ACCESSORS(Errors, ERRORS_OFFSET, CAPABILITY_OFFSET);
485     ACCESSORS(Capability, CAPABILITY_OFFSET, REMAINING_ELEMENTS_OFFSET);
486     ACCESSORS(RemainingElements, REMAINING_ELEMENTS_OFFSET, ALREADY_CALLED_OFFSET);
487     ACCESSORS(AlreadyCalled, ALREADY_CALLED_OFFSET, INDEX_OFFSET);
488     ACCESSORS_PRIMITIVE_FIELD(Index, uint32_t, INDEX_OFFSET, LAST_OFFSET);
489     DEFINE_ALIGN_SIZE(LAST_OFFSET);
490 
491     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, ERRORS_OFFSET, INDEX_OFFSET)
492 
493     DECL_DUMP()
494 };
495 
496 // PromiseAllSettledElementFunction
497 class JSPromiseAllSettledElementFunction : public JSFunction {
498 public:
499     CAST_CHECK(JSPromiseAllSettledElementFunction, IsJSPromiseAllSettledElementFunction);
500 
501     static constexpr size_t ALREADY_CALLED_OFFSET = JSFunction::SIZE;
502     ACCESSORS(AlreadyCalled, ALREADY_CALLED_OFFSET, VALUES_OFFSET);
503     ACCESSORS(Values, VALUES_OFFSET, CAPABILITY_OFFSET);
504     ACCESSORS(Capability, CAPABILITY_OFFSET, REMAINING_ELEMENTS_OFFSET);
505     ACCESSORS(RemainingElements, REMAINING_ELEMENTS_OFFSET, INDEX_OFFSET);
506     ACCESSORS_PRIMITIVE_FIELD(Index, uint32_t, INDEX_OFFSET, LAST_OFFSET);
507     DEFINE_ALIGN_SIZE(LAST_OFFSET);
508 
509     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, ALREADY_CALLED_OFFSET, INDEX_OFFSET)
510 
511     DECL_DUMP()
512 };
513 
514 // PromiseFinallyFunction
515 class JSPromiseFinallyFunction : public JSFunction {
516 public:
517     CAST_CHECK(JSPromiseFinallyFunction, IsJSPromiseFinallyFunction);
518 
519     static constexpr size_t CONSTRUCTOR_OFFSET = JSFunction::SIZE;
520     ACCESSORS(Constructor, CONSTRUCTOR_OFFSET, ONFINALLY_OFFSET);
521     ACCESSORS(OnFinally, ONFINALLY_OFFSET, SIZE);
522 
523     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, CONSTRUCTOR_OFFSET, SIZE)
524 
525     DECL_DUMP()
526 };
527 
528 // ValueThunkOrThrowReason
529 class JSPromiseValueThunkOrThrowerFunction : public JSFunction {
530 public:
531     CAST_CHECK(JSPromiseValueThunkOrThrowerFunction, IsJSPromiseValueThunkOrThrowerFunction);
532 
533     static constexpr size_t RESULT_OFFSET = JSFunction::SIZE;
534     ACCESSORS(Result, RESULT_OFFSET, SIZE);
535 
536     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, RESULT_OFFSET, SIZE)
537 
538     DECL_DUMP()
539 };
540 
541 class JSIntlBoundFunction : public JSFunction {
542 public:
543     CAST_CHECK(JSIntlBoundFunction, IsJSIntlBoundFunction);
544 
545     static JSTaggedValue IntlNameGetter(JSThread *thread, const JSHandle<JSObject> &self);
546 
547     static constexpr size_t NUMBER_FORMAT_OFFSET = JSFunction::SIZE;
548 
549     ACCESSORS(NumberFormat, NUMBER_FORMAT_OFFSET, DATETIME_FORMAT_OFFSET);
550     ACCESSORS(DateTimeFormat, DATETIME_FORMAT_OFFSET, COLLATOR_OFFSET);
551     ACCESSORS(Collator, COLLATOR_OFFSET, SIZE);
552 
553     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, NUMBER_FORMAT_OFFSET, SIZE)
554     DECL_DUMP()
555 };
556 
557 class JSAsyncGeneratorFunction : public JSFunction {
558 public:
559     CAST_CHECK(JSAsyncGeneratorFunction, IsAsyncGeneratorFunction);
560     static constexpr size_t  SIZE = JSFunction::SIZE;
561     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, SIZE, SIZE)
562     DECL_DUMP()
563 };
564 
565 class JSAsyncFromSyncIterUnwarpFunction : public JSFunction {
566 public:
567     CAST_CHECK(JSAsyncFromSyncIterUnwarpFunction, IsJSAsyncFromSyncIterUnwarpFunction);
568     static constexpr size_t DONE_OFFSET = JSFunction::SIZE;
569     ACCESSORS(Done, DONE_OFFSET, SIZE);
570 
571     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, DONE_OFFSET, SIZE);
572     DECL_DUMP()
573 };
574 
575 class JSSharedFunction : public JSFunction {
576 public:
577     CAST_CHECK(JSSharedFunction, IsJSSharedFunction);
578     static constexpr size_t SIZE = JSFunction::SIZE;
579     static constexpr uint32_t MAX_INLINE = PropertyAttributes::MAX_FAST_PROPS_CAPACITY -
580         SIZE / JSTaggedValue::TaggedTypeSize() + 1;
581     DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, SIZE, SIZE)
582 };
583 
584 class FunctionTemplate : public TaggedObject {
585 public:
GetFunctionKind()586     FunctionKind GetFunctionKind() const
587     {
588         JSTaggedValue method = GetMethod();
589         return Method::ConstCast(method.GetTaggedObject())->GetFunctionKind();
590     }
591 
IsGetterOrSetter()592     inline bool IsGetterOrSetter() const
593     {
594         FunctionKind kind = GetFunctionKind();
595         return kind == FunctionKind::GETTER_FUNCTION || kind == FunctionKind::SETTER_FUNCTION;
596     }
597 
IsGetter()598     inline bool IsGetter() const
599     {
600         FunctionKind kind = GetFunctionKind();
601         return kind == FunctionKind::GETTER_FUNCTION;
602     }
603 
604     CAST_CHECK(FunctionTemplate, IsFunctionTemplate);
605     static constexpr size_t METHOD_OFFSET = TaggedObject::SIZE;
606     ACCESSORS(Method, METHOD_OFFSET, MODULE_OFFSET);
607     ACCESSORS(Module, MODULE_OFFSET, RAW_PROFILE_TYPE_INFO_OFFSET);
608     ACCESSORS(RawProfileTypeInfo, RAW_PROFILE_TYPE_INFO_OFFSET, LENGTH_OFFSET);
609     ACCESSORS_PRIMITIVE_FIELD(Length, uint32_t, LENGTH_OFFSET, LAST_OFFSET)
610     DEFINE_ALIGN_SIZE(LAST_OFFSET);
611 
612     DECL_VISIT_OBJECT(METHOD_OFFSET, LENGTH_OFFSET);
613     DECL_DUMP()
614 };
615 
616 }  // namespace panda::ecmascript
617 #endif  // ECMASCRIPT_JSFUNCTION_H
618