• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_CALL_SIGNATURE_H
17 #define ECMASCRIPT_COMPILER_CALL_SIGNATURE_H
18 
19 #include <array>
20 #include <functional>
21 #include <memory>
22 
23 #include "ecmascript/compiler/variable_type.h"
24 #include "ecmascript/compiler/test_stubs_signature.h"
25 
26 #include "libpandabase/macros.h"
27 #include "libpandabase/utils/bit_field.h"
28 
29 namespace panda::ecmascript::kungfu {
30 class Circuit;
31 
32 enum class ArgumentsOrder {
33     DEFAULT_ORDER,  // Push Arguments in stack from right -> left
34 };
35 
36 class CallSignature {
37 public:
38     using TargetConstructor = std::function<void *(void *)>;
39     enum class TargetKind : uint8_t {
40         COMMON_STUB = 0,
41         RUNTIME_STUB,
42         RUNTIME_STUB_VARARGS,
43         RUNTIME_STUB_NO_GC,
44         DEOPT_STUB,
45         BYTECODE_HANDLER,
46         BYTECODE_DEBUGGER_HANDLER,
47         BYTECODE_HELPER_HANDLER,
48         JSFUNCTION,
49         BUILTINS_STUB,
50         BUILTINS_WITH_ARGV_STUB,
51 
52         STUB_BEGIN = COMMON_STUB,
53         STUB_END = BYTECODE_HANDLER,
54         BCHANDLER_BEGIN = BYTECODE_HANDLER,
55         BCHANDLER_END = JSFUNCTION
56     };
57     enum class CallConv: uint8_t {
58         CCallConv = 0,
59         GHCCallConv = 1,
60         WebKitJSCallConv = 2,
61     };
62     static constexpr size_t TARGET_KIND_BIT_LENGTH = 4;
63     static constexpr size_t CALL_CONV_BIT_LENGTH = 2;
64     using TargetKindBit = panda::BitField<TargetKind, 0, TARGET_KIND_BIT_LENGTH>;
65     using CallConvBit = TargetKindBit::NextField<CallConv, CALL_CONV_BIT_LENGTH>;
66     using VariadicArgsBit = CallConvBit::NextField<bool, 1>;
67     using TailCallBit = VariadicArgsBit::NextField<bool, 1>;
68     using GCLeafFunctionBit = TailCallBit::NextField<bool, 1>;
69 
CallSignature(std::string name,int flags,size_t paramCounter,ArgumentsOrder order,VariableType returnType)70     explicit CallSignature(std::string name, int flags, size_t paramCounter, ArgumentsOrder order,
71                            VariableType returnType)
72         : name_(name), paramCounter_(paramCounter), order_(order), returnType_(returnType)
73     {
74         SetTargetKind(TargetKind::COMMON_STUB);
75         SetCallConv(CallSignature::CallConv::CCallConv);
76         SetTailCall(false);
77         SetGCLeafFunction(false);
78         SetVariadicArgs(flags);
79     }
80 
81     CallSignature() = default;
82 
83     ~CallSignature() = default;
84 
CallSignature(CallSignature const & other)85     CallSignature(CallSignature const &other)
86     {
87         name_ = other.name_;
88         paramCounter_ = other.paramCounter_;
89         order_ = other.order_;
90         id_ = other.id_;
91         returnType_ = other.returnType_;
92         constructor_ = other.constructor_;
93         if (paramCounter_ > 0 && other.paramsType_ != nullptr) {
94             paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_);
95             for (size_t i = 0; i < paramCounter_; i++) {
96                 (*paramsType_)[i] = other.GetParametersType()[i];
97             }
98         }
99         kind_ = other.kind_;
100     }
101 
102     CallSignature &operator=(CallSignature const &other)
103     {
104         name_ = other.name_;
105         paramCounter_ = other.paramCounter_;
106         order_ = other.order_;
107         id_ = other.id_;
108         returnType_ = other.returnType_;
109         constructor_ = other.constructor_;
110         if (paramCounter_ > 0 && other.paramsType_ != nullptr) {
111             paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_);
112             for (size_t i = 0; i < paramCounter_; i++) {
113                 (*paramsType_)[i] = other.GetParametersType()[i];
114             }
115         }
116         kind_ = other.kind_;
117         return *this;
118     }
119 
IsCommonStub()120     bool IsCommonStub() const
121     {
122         return (GetTargetKind() == TargetKind::COMMON_STUB);
123     }
124 
IsRuntimeVAStub()125     bool IsRuntimeVAStub() const
126     {
127         return (GetTargetKind() == TargetKind::RUNTIME_STUB_VARARGS);
128     }
129 
IsRuntimeStub()130     bool IsRuntimeStub() const
131     {
132         return (GetTargetKind() == TargetKind::RUNTIME_STUB);
133     }
134 
IsRuntimeNGCStub()135     bool IsRuntimeNGCStub() const
136     {
137         return (GetTargetKind() == TargetKind::RUNTIME_STUB_NO_GC);
138     }
139 
IsBCDebuggerStub()140     bool IsBCDebuggerStub() const
141     {
142         return (GetTargetKind() == TargetKind::BYTECODE_DEBUGGER_HANDLER);
143     }
144 
IsStub()145     bool IsStub() const
146     {
147         TargetKind targetKind = GetTargetKind();
148         return TargetKind::STUB_BEGIN <= targetKind && targetKind < TargetKind::STUB_END;
149     }
150 
IsBCStub()151     bool IsBCStub() const
152     {
153         TargetKind targetKind = GetTargetKind();
154         return TargetKind::BCHANDLER_BEGIN <= targetKind && targetKind < TargetKind::BCHANDLER_END;
155     }
156 
IsBuiltinsStub()157     bool IsBuiltinsStub() const
158     {
159         return (GetTargetKind() == TargetKind::BUILTINS_STUB);
160     }
161 
IsBuiltinsWithArgvStub()162     bool IsBuiltinsWithArgvStub() const
163     {
164         return (GetTargetKind() == TargetKind::BUILTINS_WITH_ARGV_STUB);
165     }
166 
IsBCHandlerStub()167     bool IsBCHandlerStub() const
168     {
169         return (GetTargetKind() == TargetKind::BYTECODE_HANDLER);
170     }
171 
IsDeoptStub()172     bool IsDeoptStub() const
173     {
174         return (GetTargetKind() == TargetKind::DEOPT_STUB);
175     }
176 
SetParameters(VariableType * paramsType)177     void SetParameters(VariableType *paramsType)
178     {
179         if (paramCounter_ > 0 && paramsType_ == nullptr) {
180             paramsType_ = std::make_unique<std::vector<VariableType>>(paramCounter_);
181             for (size_t i = 0; i < paramCounter_; i++) {
182                 (*paramsType_)[i] = paramsType[i];
183             }
184         }
185     }
186 
GetParametersType()187     VariableType *GetParametersType() const
188     {
189         if (paramsType_ != nullptr) {
190             return paramsType_->data();
191         } else {
192             return nullptr;
193         }
194     }
195 
GetParametersCount()196     size_t GetParametersCount() const
197     {
198         return paramCounter_;
199     }
200 
GetReturnType()201     VariableType GetReturnType() const
202     {
203         return returnType_;
204     }
205 
GetArgumentsOrder()206     ArgumentsOrder GetArgumentsOrder() const
207     {
208         return order_;
209     }
210 
IsVariadicArgs()211     bool IsVariadicArgs() const
212     {
213         return VariadicArgsBit::Decode(kind_);
214     }
215 
SetVariadicArgs(bool variable)216     void SetVariadicArgs(bool variable)
217     {
218         VariadicArgsBit::Set<uint64_t>(variable, &kind_);
219     }
220 
SetTailCall(bool tailCall)221     void SetTailCall(bool tailCall)
222     {
223         TailCallBit::Set<uint64_t>(tailCall, &kind_);
224     }
225 
GetTailCall()226     bool GetTailCall() const
227     {
228         return TailCallBit::Decode(kind_);
229     }
230 
SetGCLeafFunction(bool value)231     void SetGCLeafFunction(bool value)
232     {
233         GCLeafFunctionBit::Set<uint64_t>(value, &kind_);
234     }
235 
GetGCLeafFunction()236     bool GetGCLeafFunction() const
237     {
238         return GCLeafFunctionBit::Decode(kind_);
239     }
240 
GetTargetKind()241     TargetKind GetTargetKind() const
242     {
243         return TargetKindBit::Decode(kind_);
244     }
245 
SetTargetKind(TargetKind kind)246     void SetTargetKind(TargetKind kind)
247     {
248         TargetKindBit::Set<uint64_t>(kind, &kind_);
249     }
250 
GetCallConv()251     CallConv GetCallConv() const
252     {
253         return CallConvBit::Decode(kind_);
254     }
255 
SetCallConv(CallConv cc)256     void SetCallConv(CallConv cc)
257     {
258         CallConvBit::Set<uint64_t>(cc, &kind_);
259     }
260 
GetName()261     const std::string &GetName() const
262     {
263         return name_;
264     }
265 
SetName(const std::string & str)266     void SetName(const std::string &str)
267     {
268         name_ = str;
269     }
270 
SetConstructor(TargetConstructor ctor)271     void SetConstructor(TargetConstructor ctor)
272     {
273         constructor_ = ctor;
274     }
275 
GetConstructor()276     TargetConstructor GetConstructor() const
277     {
278         return constructor_;
279     }
280 
HasConstructor()281     bool HasConstructor() const
282     {
283         return constructor_ != nullptr;
284     }
285 
GetID()286     int GetID() const
287     {
288         return id_;
289     }
290 
SetID(int id)291     void SetID(int id)
292     {
293         id_ = id;
294     }
295 
296 private:
297     std::string name_;
298     size_t paramCounter_ {0};
299     int id_ {-1};
300     ArgumentsOrder order_ {ArgumentsOrder::DEFAULT_ORDER};
301     VariableType returnType_ {VariableType::VOID()};
302     std::unique_ptr<std::vector<VariableType>> paramsType_ {nullptr};
303     TargetConstructor constructor_ {nullptr};
304     uint64_t kind_ {0};
305 };
306 
307 #define EXPLICIT_CALL_SIGNATURE_LIST(V)     \
308     V(Add)                                  \
309     V(Sub)                                  \
310     V(Mul)                                  \
311     V(MulGCTest)                            \
312     V(Div)                                  \
313     V(Mod)                                  \
314     V(TypeOf)                               \
315     V(Equal)                                \
316     V(NotEqual)                             \
317     V(Less)                                 \
318     V(LessEq)                               \
319     V(Greater)                              \
320     V(GreaterEq)                            \
321     V(Shl)                                  \
322     V(Shr)                                  \
323     V(Ashr)                                 \
324     V(And)                                  \
325     V(Or)                                   \
326     V(Xor)                                  \
327     V(Instanceof)                           \
328     V(Inc)                                  \
329     V(Dec)                                  \
330     V(Neg)                                  \
331     V(Not)                                  \
332     V(ToBoolean)                            \
333     V(SetPropertyByName)                    \
334     V(DeprecatedSetPropertyByName)          \
335     V(SetPropertyByNameWithOwn)             \
336     V(SetPropertyByValue)                   \
337     V(DeprecatedSetPropertyByValue)         \
338     V(TryLdGlobalByName)                    \
339     V(TryStGlobalByName)                    \
340     V(LdGlobalVar)                          \
341     V(StGlobalVar)                          \
342     V(SetPropertyByValueWithOwn)            \
343     V(GetPropertyByName)                    \
344     V(DeprecatedGetPropertyByName)          \
345     V(GetPropertyByIndex)                   \
346     V(SetPropertyByIndex)                   \
347     V(SetPropertyByIndexWithOwn)            \
348     V(GetPropertyByValue)                   \
349     V(DeprecatedGetPropertyByValue)         \
350     V(TryLoadICByName)                      \
351     V(TryLoadICByValue)                     \
352     V(TryStoreICByName)                     \
353     V(TryStoreICByValue)                    \
354     V(SetValueWithBarrier)                  \
355     V(NewLexicalEnv)                        \
356     V(GetUnmapedArgs)                       \
357     V(NewThisObjectChecked)                 \
358     V(ConstructorCheck)                     \
359     V(GetTaggedArrayPtrTest)                \
360     V(BytecodeHandler)                      \
361     V(Builtins)                             \
362     V(BuiltinsWithArgv)                     \
363     V(BytecodeDebuggerHandler)              \
364     V(CallRuntime)                          \
365     V(AsmInterpreterEntry)                  \
366     V(GeneratorReEnterAsmInterp)            \
367     V(CallRuntimeWithArgv)                  \
368     V(OptimizedCallOptimized)               \
369     V(PushCallArg0AndDispatch)              \
370     V(PushCallArgsAndDispatchNative)        \
371     V(PushCallArg1AndDispatch)              \
372     V(PushCallArgs2AndDispatch)             \
373     V(PushCallArgs3AndDispatch)             \
374     V(PushCallRangeAndDispatch)             \
375     V(PushCallRangeAndDispatchNative)       \
376     V(PushCallThisRangeAndDispatch)         \
377     V(PushCallThisArg0AndDispatch)          \
378     V(PushCallThisArg1AndDispatch)          \
379     V(PushCallThisArgs2AndDispatch)         \
380     V(PushCallThisArgs3AndDispatch)         \
381     V(PushCallNewAndDispatchNative)         \
382     V(PushCallNewAndDispatch)               \
383     V(CallGetter)                           \
384     V(CallSetter)                           \
385     V(CallContainersArgs3)                  \
386     V(JSCallWithArgV)                       \
387     V(ConstructorJSCallWithArgV)            \
388     V(ResumeRspAndDispatch)                 \
389     V(ResumeRspAndReturn)                   \
390     V(ResumeCaughtFrameAndDispatch)         \
391     V(ResumeUncaughtFrameAndReturn)         \
392     V(StringsAreEquals)                     \
393     V(BigIntEquals)                         \
394     V(DebugPrint)                           \
395     V(DebugPrintInstruction)                \
396     V(PGOProfiler)                          \
397     V(FatalPrint)                           \
398     V(GetActualArgvNoGC)                    \
399     V(InsertOldToNewRSet)                   \
400     V(DoubleToInt)                          \
401     V(FloatMod)                             \
402     V(FloatSqrt)                            \
403     V(FloatCos)                             \
404     V(FloatSin)                             \
405     V(FloatACos)                            \
406     V(FloatATan)                            \
407     V(FloatFloor)                           \
408     V(FindElementWithCache)                 \
409     V(MarkingBarrier)                       \
410     V(StoreBarrier)                         \
411     V(CallArg0)                             \
412     V(CallArg1)                             \
413     V(CallArgs2)                            \
414     V(CallArgs3)                            \
415     V(CallThisRange)                        \
416     V(CallRange)                            \
417     V(JSCall)                               \
418     V(ConstructorJSCall)                    \
419     V(JSFunctionEntry)                      \
420     V(JSProxyCallInternalWithArgV)          \
421     V(CreateArrayFromList)                  \
422     V(JSObjectGetMethod)                    \
423     V(JsProxyCallInternal)                  \
424     V(DeoptHandlerAsm)                      \
425     V(JSCallNew)                            \
426     V(JSCallNewWithArgV)                    \
427     V(TimeClip)                             \
428     V(SetDateValues)                        \
429     TEST_STUB_SIGNATRUE_LIST(V)
430 
431 #define DECL_CALL_SIGNATURE(name)                                  \
432 class name##CallSignature final {                                  \
433     public:                                                        \
434         static void Initialize(CallSignature *descriptor);         \
435     };
436 EXPLICIT_CALL_SIGNATURE_LIST(DECL_CALL_SIGNATURE)
437 
438 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
439 #define DEF_CALL_SIGNATURE(name)                                  \
440     void name##CallSignature::Initialize([[maybe_unused]] CallSignature *callSign)
441 }  // namespace panda::ecmascript::kungfu
442 #endif  // ECMASCRIPT_COMPILER_CALL_SIGNATURE_H
443