• 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 
25 #include "libpandabase/macros.h"
26 #include "libpandabase/utils/bit_field.h"
27 
28 namespace panda::ecmascript::kungfu {
29 class Circuit;
30 
31 enum class ArgumentsOrder {
32     DEFAULT_ORDER,  // Push Arguments in stack from right -> left
33 };
34 
35 class CallSignature {
36 public:
37     using TargetConstructor = std::function<void *(void *)>;
38     enum class TargetKind : uint8_t {
39         COMMON_STUB = 0,
40         RUNTIME_STUB,
41         RUNTIME_STUB_VARARGS,
42         RUNTIME_STUB_NO_GC,
43         OPTIMIZED_STUB,
44         OPTIMIZED_FAST_CALL_STUB,
45         DEOPT_STUB,
46         BYTECODE_HANDLER,
47         BYTECODE_DEBUGGER_HANDLER,
48         BYTECODE_HELPER_HANDLER,
49         BYTECODE_PROFILE_HANDLER,
50         BYTECODE_JIT_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(ToBooleanTrue)                            \
348     V(ToBooleanFalse)                           \
349     V(SetPropertyByName)                        \
350     V(DeprecatedSetPropertyByName)              \
351     V(SetPropertyByNameWithOwn)                 \
352     V(SetPropertyByValue)                       \
353     V(DeprecatedSetPropertyByValue)             \
354     V(TryLdGlobalByName)                        \
355     V(TryStGlobalByName)                        \
356     V(LdGlobalVar)                              \
357     V(StGlobalVar)                              \
358     V(StOwnByIndex)                             \
359     V(StOwnByValue)                             \
360     V(StOwnByName)                              \
361     V(StOwnByValueWithNameSet)                  \
362     V(StOwnByNameWithNameSet)                   \
363     V(StObjByIndex)                             \
364     V(LdObjByIndex)                             \
365     V(SetPropertyByValueWithOwn)                \
366     V(GetPropertyByName)                        \
367     V(DeprecatedGetPropertyByName)              \
368     V(GetPropertyByIndex)                       \
369     V(SetPropertyByIndex)                       \
370     V(SetPropertyByIndexWithOwn)                \
371     V(GetPropertyByValue)                       \
372     V(DeprecatedGetPropertyByValue)             \
373     V(TryLoadICByName)                          \
374     V(TryLoadICByValue)                         \
375     V(TryStoreICByName)                         \
376     V(TryStoreICByValue)                        \
377     V(SetValueWithBarrier)                      \
378     V(NewLexicalEnv)                            \
379     V(GetUnmapedArgs)                           \
380     V(NewThisObjectChecked)                     \
381     V(ConstructorCheck)                         \
382     V(CreateEmptyArray)                         \
383     V(CreateArrayWithBuffer)                    \
384     V(NewJSObject)                              \
385     V(GetTaggedArrayPtrTest)                    \
386     V(BytecodeHandler)                          \
387     V(Builtins)                                 \
388     V(BuiltinsWithArgv)                         \
389     V(BytecodeDebuggerHandler)                  \
390     V(CallRuntime)                              \
391     V(AsmInterpreterEntry)                      \
392     V(GeneratorReEnterAsmInterp)                \
393     V(CallRuntimeWithArgv)                      \
394     V(OptimizedCallAndPushUndefined)            \
395     V(OptimizedFastCallAndPushUndefined)        \
396     V(PushCallArg0AndDispatch)                  \
397     V(PushCallArgsAndDispatchNative)            \
398     V(PushCallArg1AndDispatch)                  \
399     V(PushCallArgs2AndDispatch)                 \
400     V(PushCallArgs3AndDispatch)                 \
401     V(PushCallRangeAndDispatch)                 \
402     V(PushCallRangeAndDispatchNative)           \
403     V(PushCallThisRangeAndDispatch)             \
404     V(PushCallThisArg0AndDispatch)              \
405     V(PushCallThisArg1AndDispatch)              \
406     V(PushCallThisArgs2AndDispatch)             \
407     V(PushCallThisArgs3AndDispatch)             \
408     V(PushCallNewAndDispatchNative)             \
409     V(PushNewTargetAndDispatchNative)           \
410     V(PushCallNewAndDispatch)                   \
411     V(PushSuperCallAndDispatch)                 \
412     V(CallGetter)                               \
413     V(CallSetter)                               \
414     V(CallContainersArgs3)                      \
415     V(JSCallWithArgV)                           \
416     V(JSFastCallWithArgV)                       \
417     V(JSFastCallWithArgVAndPushUndefined)       \
418     V(JSCallWithArgVAndPushUndefined)           \
419     V(ResumeRspAndDispatch)                     \
420     V(ResumeRspAndReturn)                       \
421     V(ResumeCaughtFrameAndDispatch)             \
422     V(ResumeUncaughtFrameAndReturn)             \
423     V(ResumeRspAndRollback)                     \
424     V(StringsAreEquals)                         \
425     V(BigIntEquals)                             \
426     V(BigIntSameValueZero)                      \
427     V(Dump)                                     \
428     V(DebugDump)                                \
429     V(DumpWithHint)                             \
430     V(DebugDumpWithHint)                        \
431     V(DebugPrint)                               \
432     V(DebugPrintCustom)                         \
433     V(DebugPrintInstruction)                    \
434     V(Comment)                                  \
435     V(FatalPrint)                               \
436     V(FatalPrintCustom)                         \
437     V(GetActualArgvNoGC)                        \
438     V(InsertOldToNewRSet)                       \
439     V(DoubleToInt)                              \
440     V(DoubleToLength)                           \
441     V(FloatMod)                                 \
442     V(FloatSqrt)                                \
443     V(FloatCos)                                 \
444     V(FloatSin)                                 \
445     V(FloatACos)                                \
446     V(FloatATan)                                \
447     V(FloatFloor)                               \
448     V(FindElementWithCache)                     \
449     V(MarkingBarrier)                           \
450     V(StoreBarrier)                             \
451     V(CallArg0)                                 \
452     V(CallArg1)                                 \
453     V(CallArgs2)                                \
454     V(CallArgs3)                                \
455     V(CallThisRange)                            \
456     V(CallRange)                                \
457     V(JSCall)                                   \
458     V(JSOptimizedCall)                          \
459     V(JSOptimizedFastCall)                      \
460     V(JSFunctionEntry)                          \
461     V(OptimizedFastCallEntry)                   \
462     V(JSProxyCallInternalWithArgV)              \
463     V(TryToElementsIndexOrFindInStringTable)    \
464     V(TryGetInternString)                       \
465     V(CreateArrayFromList)                      \
466     V(JSObjectGetMethod)                        \
467     V(JsProxyCallInternal)                      \
468     V(JsBoundCallInternal)                      \
469     V(DeoptHandlerAsm)                          \
470     V(JSCallNew)                                \
471     V(CallOptimized)                            \
472     V(TimeClip)                                 \
473     V(SetDateValues)                            \
474     V(CallReturnWithArgv)                       \
475     V(StartCallTimer)                           \
476     V(EndCallTimer)                             \
477     V(GetSingleCharCodeByIndex)                 \
478     V(CreateStringBySingleCharCode)             \
479     V(FastStringEqual)                          \
480     V(FastStringAdd)                            \
481     V(DeleteObjectProperty)                     \
482     V(Getpropiterator)                          \
483     V(Getnextpropname)                          \
484     V(CreateJSSetIterator)                      \
485     V(CreateJSMapIterator)                      \
486     V(JSHClassFindProtoTransitions)             \
487     V(NumberHelperStringToDouble)               \
488     V(GetStringToListCacheArray)                \
489     V(FastArraySort)                            \
490     V(LocaleCompareNoGc)                        \
491     V(StringGetStart)                           \
492     V(StringGetEnd)                             \
493     V(ArrayTrim)
494 
495 #define DECL_CALL_SIGNATURE(name)                                  \
496 class name##CallSignature final {                                  \
497     public:                                                        \
498         static void Initialize(CallSignature *descriptor);         \
499     };
500 EXPLICIT_CALL_SIGNATURE_LIST(DECL_CALL_SIGNATURE)
501 
502 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
503 #define DEF_CALL_SIGNATURE(name)                                  \
504     void name##CallSignature::Initialize([[maybe_unused]] CallSignature *callSign)
505 }  // namespace panda::ecmascript::kungfu
506 #endif  // ECMASCRIPT_COMPILER_CALL_SIGNATURE_H
507