• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_COMPILER_BUILTINS_STUB_H
17 #define ECMASCRIPT_COMPILER_BUILTINS_STUB_H
18 
19 #include "ecmascript/base/config.h"
20 #include "ecmascript/compiler/builtins/builtins_call_signature.h"
21 #include "ecmascript/compiler/interpreter_stub.h"
22 #include "ecmascript/ecma_runtime_call_info.h"
23 #include "ecmascript/ecma_string.h"
24 
25 namespace panda::ecmascript::kungfu {
26 class BuiltinsStubBuilder : public StubBuilder {
27 public:
BuiltinsStubBuilder(StubBuilder * parent)28     explicit BuiltinsStubBuilder(StubBuilder *parent)
29         :StubBuilder(parent) {}
BuiltinsStubBuilder(CallSignature * callSignature,Environment * env)30     BuiltinsStubBuilder(CallSignature *callSignature, Environment *env)
31         : StubBuilder(callSignature, 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 
GetCallArg0(GateRef numArg)67     inline GateRef GetCallArg0(GateRef numArg)
68     {
69         auto env = GetEnvironment();
70         Label subentry(env);
71         env->SubCfgEntry(&subentry);
72         DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
73         Label isValid(env);
74         Label exit(env);
75         Branch(Int32GreaterThan(TruncPtrToInt32(numArg), Int32(0)), &isValid, &exit);
76         Bind(&isValid);
77         {
78             result = TaggedArgument(static_cast<size_t>(BuiltinsArgs::ARG0_OR_ARGV));
79             Jump(&exit);
80         }
81         Bind(&exit);
82         auto res = *result;
83         env->SubCfgExit();
84         return res;
85     }
86 
GetCallArg1(GateRef numArg)87     inline GateRef GetCallArg1(GateRef numArg)
88     {
89         auto env = GetEnvironment();
90         Label subentry(env);
91         env->SubCfgEntry(&subentry);
92         DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
93         Label isValid(env);
94         Label exit(env);
95         Branch(Int32GreaterThan(TruncPtrToInt32(numArg), Int32(1)), &isValid, &exit);
96         Bind(&isValid);
97         {
98             result = TaggedArgument(static_cast<size_t>(BuiltinsArgs::ARG1));
99             Jump(&exit);
100         }
101         Bind(&exit);
102         auto res = *result;
103         env->SubCfgExit();
104         return res;
105     }
106 
GetCallArg2(GateRef numArg)107     inline GateRef GetCallArg2(GateRef numArg)
108     {
109         auto env = GetEnvironment();
110         Label subentry(env);
111         env->SubCfgEntry(&subentry);
112         DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
113         Label isValid(env);
114         Label exit(env);
115         // 2: 2 args
116         Branch(Int32GreaterThan(TruncPtrToInt32(numArg), Int32(2)), &isValid, &exit);
117         Bind(&isValid);
118         {
119             result = TaggedArgument(static_cast<size_t>(BuiltinsArgs::ARG2));
120             Jump(&exit);
121         }
122         Bind(&exit);
123         auto res = *result;
124         env->SubCfgExit();
125         return res;
126     }
127 
GetArgv()128     inline GateRef GetArgv()
129     {
130         return PtrArgument(static_cast<size_t>(BuiltinsArgs::ARG0_OR_ARGV));
131     }
132 
133     // not check whether index is valid, if not sure, invoke GetArg
GetArgNCheck(GateRef index)134     inline GateRef GetArgNCheck(GateRef index)
135     {
136         GateRef argv = GetArgv();
137         return Load(VariableType::JS_ANY(), argv, PtrMul(index, IntPtr(JSTaggedValue::TaggedTypeSize())));
138     }
139 
140     GateRef GetArg(GateRef numArgs, GateRef index);
141 
142     GateRef CallSlowPath(GateRef nativeCode, GateRef glue, GateRef thisValue, GateRef numArgs, GateRef func,
143                          GateRef newTarget, const char* comment = nullptr);
144 
IsNumberYearMonthDay(GateRef year,GateRef month,GateRef day)145     inline GateRef IsNumberYearMonthDay(GateRef year, GateRef month, GateRef day)
146     {
147         GateRef condition = BoolAnd(TaggedIsNumber(year), TaggedIsNumber(month));
148         return BoolAnd(condition, TaggedIsNumber(day));
149     }
150 };
151 
152 #define DECLARE_BUILTINS_STUB_CLASS(name)                                                           \
153     class name##StubBuilder : public BuiltinsStubBuilder {                                          \
154     public:                                                                                         \
155         name##StubBuilder(CallSignature *callSignature, Environment *env)                           \
156             : BuiltinsStubBuilder(callSignature, env) {}                                            \
157         ~name##StubBuilder() = default;                                                             \
158         NO_MOVE_SEMANTIC(name##StubBuilder);                                                        \
159         NO_COPY_SEMANTIC(name##StubBuilder);                                                        \
160         void GenerateCircuit() override;                                                            \
161                                                                                                     \
162     private:                                                                                        \
163         void GenerateCircuitImpl(GateRef glue, GateRef nativeCode, GateRef func, GateRef newTarget, \
164                                  GateRef thisValue, GateRef numArgs);                               \
165     };
166     BUILTINS_STUB_LIST(DECLARE_BUILTINS_STUB_CLASS)
167 #undef DECLARE_BUILTINS_STUB_CLASS
168 }  // namespace panda::ecmascript::kungfu
169 #endif  // ECMASCRIPT_COMPILER_BUILTINS_STUB_H
170