1 /** 2 * Copyright (c) 2021-2025 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 PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_METHOD_SIGNATURE_H_ 17 #define PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_METHOD_SIGNATURE_H_ 18 19 #include "libpandabase/utils/logger.h" 20 #include "runtime/include/method.h" 21 #include "plugins/ets/runtime/types/ets_value.h" 22 #include "plugins/ets/runtime/ani/ani_mangle.h" 23 24 namespace ark::ets { 25 26 // Arguments type separated from return type by ":". Object names bounded by 'L' and ';' 27 class EtsMethodSignature { 28 public: 29 explicit EtsMethodSignature(const std::string_view sign, bool isANIFormat = false) 30 { 31 const PandaString signature = isANIFormat ? ani::Mangle::ConvertSignature(sign) : PandaString(sign); 32 33 size_t dots = signature.find(':'); 34 // Return if ':' wasn't founded or was founded at the end 35 if (dots == PandaString::npos || dots == signature.size() - 1) { 36 return; 37 } 38 // Process return type after ':' 39 if (ProcessParameter(signature, dots + 1) != signature.size() - 1) { 40 return; 41 } 42 // Process arguments 43 size_t i; 44 for (i = 0; i < dots; i++) { 45 i = ProcessParameter(signature, i); 46 if (i == PandaString::npos) { 47 return; 48 } 49 } 50 isValid_ = true; 51 for (auto ¶mType : paramTypes_) { 52 pandaProto_.GetRefTypes().push_back(paramType); 53 } 54 } 55 IsValid()56 bool IsValid() 57 { 58 return isValid_; 59 } 60 GetProto()61 Method::Proto &GetProto() 62 { 63 return pandaProto_; 64 } 65 66 private: ProcessParameter(const PandaString & signature,size_t i)67 size_t ProcessParameter(const PandaString &signature, size_t i) 68 { 69 EtsType paramType = GetTypeByFirstChar(signature[i]); 70 // Check that type is valid and return type is not void 71 if (paramType == EtsType::UNKNOWN || (paramType == EtsType::VOID && (i != signature.size() - 1))) { 72 return PandaString::npos; 73 } 74 pandaProto_.GetShorty().push_back(ets::ConvertEtsTypeToPandaType(paramType)); 75 76 if (paramType != EtsType::OBJECT) { 77 return i; 78 } 79 size_t nameStart = i; 80 i = ProcessObjectParameter(signature, i); 81 if (i == PandaString::npos) { 82 return i; 83 } 84 paramTypes_.push_back(signature.substr(nameStart, i + 1 - nameStart)); 85 return i; 86 } 87 88 PandaSmallVector<PandaString> paramTypes_; 89 Method::Proto pandaProto_; 90 bool isValid_ {false}; 91 ProcessObjectParameter(const PandaString & signature,size_t i)92 size_t ProcessObjectParameter(const PandaString &signature, size_t i) 93 { 94 while (signature[i] == '[') { 95 ++i; 96 if (i >= signature.size()) { 97 return PandaString::npos; 98 } 99 } 100 if (GetTypeByFirstChar(signature[i]) == EtsType::UNKNOWN) { 101 return PandaString::npos; 102 } 103 104 if (signature[i] == 'L') { 105 // Get object name bounded by 'L' and ';' 106 size_t prevI = i; 107 i = signature.find(';', i); 108 if (i == PandaString::npos || i == (prevI + 1)) { 109 return PandaString::npos; 110 } 111 } 112 return i; 113 } GetTypeByFirstChar(char c)114 EtsType GetTypeByFirstChar(char c) 115 { 116 switch (c) { 117 case 'L': 118 case '[': 119 return EtsType::OBJECT; 120 case 'Z': 121 return EtsType::BOOLEAN; 122 case 'B': 123 return EtsType::BYTE; 124 case 'C': 125 return EtsType::CHAR; 126 case 'S': 127 return EtsType::SHORT; 128 case 'I': 129 return EtsType::INT; 130 case 'J': 131 return EtsType::LONG; 132 case 'F': 133 return EtsType::FLOAT; 134 case 'D': 135 return EtsType::DOUBLE; 136 case 'V': 137 return EtsType::VOID; 138 default: 139 return EtsType::UNKNOWN; 140 } 141 } 142 }; 143 144 } // namespace ark::ets 145 146 #endif // PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_METHOD_SIGNATURE_H_ 147