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