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 #ifndef ECMASCRIPT_COMPILER_STUB_DESCRIPTOR_H 16 #define ECMASCRIPT_COMPILER_STUB_DESCRIPTOR_H 17 18 #include <array> 19 #include <memory> 20 21 #include "ecmascript/compiler/fast_stub_define.h" 22 #include "ecmascript/compiler/machine_type.h" 23 #include "libpandabase/macros.h" 24 #include "libpandabase/utils/bit_field.h" 25 #include "llvm-c/Types.h" 26 27 namespace panda::ecmascript::kungfu { 28 enum class ArgumentsOrder { 29 DEFAULT_ORDER, // Push Arguments in stack from right -> left 30 }; 31 32 class StubDescriptor { 33 public: 34 using VariableArgsBits = panda::BitField<bool, 0, 1>; // 1 variable argument 35 enum class CallStubKind { 36 CODE_STUB, 37 RUNTIME_STUB, 38 BYTECODE_HANDLER, 39 RUNTIME_STUB_NO_GC, 40 TEST_FUNC, 41 }; StubDescriptor(std::string name,int flags,int paramCounter,ArgumentsOrder order,StubMachineType returnType)42 explicit StubDescriptor(std::string name, int flags, int paramCounter, ArgumentsOrder order, 43 StubMachineType returnType) 44 : name_(name), flags_(flags), paramCounter_(paramCounter), order_(order), returnType_(returnType) 45 { 46 } 47 StubDescriptor() = default; 48 ~StubDescriptor() = default; StubDescriptor(StubDescriptor const & other)49 StubDescriptor(StubDescriptor const &other) 50 { 51 name_ = other.name_; 52 flags_ = other.flags_; 53 paramCounter_ = other.paramCounter_; 54 order_ = other.order_; 55 kind_ = other.kind_; 56 returnType_ = other.returnType_; 57 if (paramCounter_ > 0 && other.paramsType_ != nullptr) { 58 paramsType_ = std::make_unique<std::vector<StubMachineType>>(paramCounter_); 59 for (int i = 0; i < paramCounter_; i++) { 60 (*paramsType_)[i] = other.GetParametersType()[i]; 61 } 62 } 63 } 64 65 StubDescriptor &operator=(StubDescriptor const &other) 66 { 67 name_ = other.name_; 68 flags_ = other.flags_; 69 paramCounter_ = other.paramCounter_; 70 order_ = other.order_; 71 kind_ = other.kind_; 72 returnType_ = other.returnType_; 73 if (paramCounter_ > 0 && other.paramsType_ != nullptr) { 74 paramsType_ = std::make_unique<std::vector<StubMachineType>>(paramCounter_); 75 for (int i = 0; i < paramCounter_; i++) { 76 (*paramsType_)[i] = other.GetParametersType()[i]; 77 } 78 } 79 return *this; 80 } 81 SetParameters(StubMachineType * paramsType)82 void SetParameters(StubMachineType *paramsType) 83 { 84 if (paramCounter_ > 0 && paramsType_ == nullptr) { 85 paramsType_ = std::make_unique<std::vector<StubMachineType>>(paramCounter_); 86 for (int i = 0; i < paramCounter_; i++) { 87 (*paramsType_)[i] = paramsType[i]; 88 } 89 } 90 } 91 GetParametersType()92 StubMachineType *GetParametersType() const 93 { 94 if (paramsType_ != nullptr) { 95 return paramsType_->data(); 96 } else { 97 return nullptr; 98 } 99 } 100 GetParametersCount()101 int GetParametersCount() const 102 { 103 return paramCounter_; 104 } 105 GetReturnType()106 StubMachineType GetReturnType() const 107 { 108 return returnType_; 109 } 110 GetArgumentsOrder()111 ArgumentsOrder GetArgumentsOrder() const 112 { 113 return order_; 114 } 115 GetFlags()116 int GetFlags() const 117 { 118 return flags_; 119 } 120 SetFlags(int flag)121 void SetFlags(int flag) 122 { 123 flags_ = flag; 124 } 125 GetVariableArgs()126 bool GetVariableArgs() const 127 { 128 return VariableArgsBits::Decode(flags_); 129 } 130 SetVariableArgs(bool variable)131 void SetVariableArgs(bool variable) 132 { 133 uint64_t newVal = VariableArgsBits::Update(flags_, variable); 134 SetFlags(newVal); 135 } 136 GetStubKind()137 CallStubKind GetStubKind() const 138 { 139 return kind_; 140 } 141 SetStubKind(CallStubKind kind)142 void SetStubKind(CallStubKind kind) 143 { 144 kind_ = kind; 145 } 146 GetName()147 const std::string &GetName() 148 { 149 return name_; 150 } 151 152 private: 153 std::string name_; 154 CallStubKind kind_ {CallStubKind::CODE_STUB}; 155 int flags_ {0}; 156 int paramCounter_ {0}; 157 ArgumentsOrder order_ {ArgumentsOrder::DEFAULT_ORDER}; 158 159 StubMachineType returnType_ {StubMachineType::NONE}; 160 std::unique_ptr<std::vector<StubMachineType>> paramsType_ {nullptr}; 161 }; 162 163 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 164 #define GET_STUBDESCRIPTOR(name) FastStubDescriptors::GetInstance().GetStubDescriptor(FAST_STUB_ID(name)) 165 166 class FastStubDescriptors { 167 public: GetInstance()168 static FastStubDescriptors &GetInstance() 169 { 170 static FastStubDescriptors instance; 171 return instance; 172 } 173 174 void InitializeStubDescriptors(); 175 GetStubDescriptor(int index)176 StubDescriptor *GetStubDescriptor(int index) 177 { 178 return &callStubsDescriptor_[index]; 179 } 180 181 private: FastStubDescriptors()182 FastStubDescriptors() 183 { 184 InitializeStubDescriptors(); 185 } ~FastStubDescriptors()186 ~FastStubDescriptors() {} 187 NO_MOVE_SEMANTIC(FastStubDescriptors); 188 NO_COPY_SEMANTIC(FastStubDescriptors); 189 std::array<StubDescriptor, CALL_STUB_MAXCOUNT> callStubsDescriptor_ {}; 190 }; 191 } // namespace panda::ecmascript::kungfu 192 #endif // ECMASCRIPT_COMPILER_STUB_DESCRIPTOR_H 193