• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &paramType : 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_