1 /*
2  * Copyright (c) 2022-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_COMPILER_BUILTINS_STUB_H
17 #define ECMASCRIPT_COMPILER_BUILTINS_STUB_H
18 
19 #include "ecmascript/compiler/builtins/builtins_call_signature.h"
20 #include "ecmascript/compiler/circuit_builder-inl.h"
21 #include "ecmascript/compiler/stub_builder.h"
22 #include "ecmascript/ecma_runtime_call_info.h"
23 
24 namespace panda::ecmascript::kungfu {
25 class BuiltinsStubBuilder : public StubBuilder {
26 public:
BuiltinsStubBuilder(StubBuilder *parent)27     explicit BuiltinsStubBuilder(StubBuilder *parent)
28         :StubBuilder(parent) {}
BuiltinsStubBuilder(CallSignature *callSignature, Environment *env)29     BuiltinsStubBuilder(CallSignature *callSignature, Environment *env)
30         : StubBuilder(callSignature, env) {}
BuiltinsStubBuilder(Environment* env)31     BuiltinsStubBuilder(Environment* env): StubBuilder(env) {}
32     ~BuiltinsStubBuilder() override = default;
33     NO_MOVE_SEMANTIC(BuiltinsStubBuilder);
34     NO_COPY_SEMANTIC(BuiltinsStubBuilder);
35     virtual void GenerateCircuit() override = 0;
36 
GetGlue(GateRef info)37     inline GateRef GetGlue(GateRef info)
38     {
39         return Load(VariableType::NATIVE_POINTER(), info,
40             IntPtr(EcmaRuntimeCallInfo::GetThreadOffset(GetEnvironment()->IsArch32Bit())));
41     }
42 
GetNumArgs(GateRef info)43     inline GateRef GetNumArgs(GateRef info)
44     {
45         return Load(VariableType::INT64(), info,
46             IntPtr(EcmaRuntimeCallInfo::GetNumArgsOffset(GetEnvironment()->IsArch32Bit())));
47     }
48 
GetFunction(GateRef info)49     inline GateRef GetFunction(GateRef info)
50     {
51         return Load(VariableType::JS_ANY(), info,
52             IntPtr(EcmaRuntimeCallInfo::GetStackArgsOffset(GetEnvironment()->IsArch32Bit())));
53     }
54 
GetNewTarget(GateRef info)55     inline GateRef GetNewTarget(GateRef info)
56     {
57         GateRef newTargetOffset = IntPtr(EcmaRuntimeCallInfo::GetNewTargetOffset(GetEnvironment()->IsArch32Bit()));
58         return Load(VariableType::JS_ANY(), info, newTargetOffset);
59     }
60 
GetThis(GateRef info)61     inline GateRef GetThis(GateRef info)
62     {
63         GateRef thisOffset = IntPtr(EcmaRuntimeCallInfo::GetThisOffset(GetEnvironment()->IsArch32Bit()));
64         return Load(VariableType::JS_ANY(), info, thisOffset);
65     }
66 
67     GateRef GetCallArg0(GateRef numArg);
68     GateRef GetCallArg1(GateRef numArg);
69     GateRef GetCallArg2(GateRef numArg);
70 
GetArgv()71     inline GateRef GetArgv()
72     {
73         return PtrArgument(static_cast<size_t>(BuiltinsArgs::ARG0_OR_ARGV));
74     }
75 
76     GateRef GetArgFromArgv(GateRef index, GateRef numArgs = Gate::InvalidGateRef, bool needCheck = false);
77 
78     GateRef CallSlowPath(GateRef nativeCode, GateRef glue, GateRef thisValue, GateRef numArgs, GateRef func,
79                          GateRef newTarget);
80 
IsNumberYearMonthDay(GateRef year, GateRef month, GateRef day)81     inline GateRef IsNumberYearMonthDay(GateRef year, GateRef month, GateRef day)
82     {
83         GateRef condition = BitAnd(TaggedIsNumber(year), TaggedIsNumber(month));
84         return BitAnd(condition, TaggedIsNumber(day));
85     }
86 };
87 
88 #define DECLARE_BUILTINS_STUB_CLASS(name)                                                           \
89     class name##StubBuilder : public BuiltinsStubBuilder {                                          \
90     public:                                                                                         \
91         name##StubBuilder(CallSignature *callSignature, Environment *env)                           \
92             : BuiltinsStubBuilder(callSignature, env) {}                                            \
93         ~name##StubBuilder() = default;                                                             \
94         NO_MOVE_SEMANTIC(name##StubBuilder);                                                        \
95         NO_COPY_SEMANTIC(name##StubBuilder);                                                        \
96         void GenerateCircuit() override;                                                            \
97                                                                                                     \
98     private:                                                                                        \
99         void GenerateCircuitImpl(GateRef glue, GateRef nativeCode, GateRef func, GateRef newTarget, \
100                                  GateRef thisValue, GateRef numArgs);                               \
101     };
102 
103 
104 #define DECLARE_BUILTINS_STUB_CLASS_DYN(name, type, ...)                                            \
105     class type##name##StubBuilder : public BuiltinsStubBuilder {                                    \
106     public:                                                                                         \
107         type##name##StubBuilder(CallSignature *callSignature, Environment *env)                     \
108             : BuiltinsStubBuilder(callSignature, env) {}                                            \
109         ~type##name##StubBuilder() = default;                                                       \
110         NO_MOVE_SEMANTIC(type##name##StubBuilder);                                                  \
111         NO_COPY_SEMANTIC(type##name##StubBuilder);                                                  \
112         void GenerateCircuit() override;                                                            \
113                                                                                                     \
114     private:                                                                                        \
115         void GenerateCircuitImpl(GateRef glue, GateRef nativeCode, GateRef func, GateRef newTarget, \
116                                  GateRef thisValue, GateRef numArgs);                               \
117     };
118     BUILTINS_STUB_LIST(DECLARE_BUILTINS_STUB_CLASS, DECLARE_BUILTINS_STUB_CLASS_DYN, DECLARE_BUILTINS_STUB_CLASS)
119 #undef DECLARE_BUILTINS_STUB_CLASS_DYN
120 #undef DECLARE_BUILTINS_STUB_CLASS
121 }  // namespace panda::ecmascript::kungfu
122 #endif  // ECMASCRIPT_COMPILER_BUILTINS_STUB_H
123