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