1 /*
2 * Copyright (c) 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 #include "stdio.h"
17 #include <cstring>
18 #include <vector>
19
20 #include "signatures.h"
21 #include "interop-types.h"
22
23 // For types with the same name on ets and jni
24 #define KOALA_INTEROP_TYPEDEF(func, lang, CPP_TYPE, SIG_TYPE, CODE_TYPE) \
25 if (std::strcmp(func, "sigType") == 0) if (type == CPP_TYPE) return SIG_TYPE; \
26 if (std::strcmp(func, "codeType") == 0) if (type == CPP_TYPE) return CODE_TYPE;
27
28 // For types with distinct names on ets and jni
29 #define KOALA_INTEROP_TYPEDEF_LS(func, lang, CPP_TYPE, ETS_SIG_TYPE, ETS_CODE_TYPE, JNI_SIG_TYPE, JNI_CODE_TYPE) \
30 if (std::strcmp(func, "sigType") == 0 && std::strcmp(lang, "ets") == 0) if (type == CPP_TYPE) return ETS_SIG_TYPE; \
31 if (std::strcmp(func, "codeType") == 0 && std::strcmp(lang, "ets") == 0) if (type == CPP_TYPE) return ETS_CODE_TYPE; \
32 if (std::strcmp(func, "sigType") == 0 && std::strcmp(lang, "jni") == 0) if (type == CPP_TYPE) return JNI_SIG_TYPE; \
33 if (std::strcmp(func, "codeType") == 0 && std::strcmp(lang, "jni") == 0) if (type == CPP_TYPE) return JNI_CODE_TYPE;
34
35 #define KOALA_INTEROP_TYPEDEFS(func, lang) \
36 KOALA_INTEROP_TYPEDEF(func, lang, "void", "V", "void") \
37 KOALA_INTEROP_TYPEDEF(func, lang, "KBoolean", "Z", "boolean") \
38 KOALA_INTEROP_TYPEDEF(func, lang, "OH_Boolean", "Z", "boolean") \
39 KOALA_INTEROP_TYPEDEF(func, lang, "Ark_Boolean", "Z", "boolean") \
40 KOALA_INTEROP_TYPEDEF(func, lang, "int32_t", "I", "int") \
41 KOALA_INTEROP_TYPEDEF(func, lang, "uint32_t", "I", "int") \
42 KOALA_INTEROP_TYPEDEF(func, lang, "int", "I", "int") \
43 KOALA_INTEROP_TYPEDEF(func, lang, "KInt", "I", "int") \
44 KOALA_INTEROP_TYPEDEF(func, lang, "KUInt", "I", "int") \
45 KOALA_INTEROP_TYPEDEF(func, lang, "KLong", "J", "long") \
46 KOALA_INTEROP_TYPEDEF(func, lang, "OH_Int32", "I", "int") \
47 KOALA_INTEROP_TYPEDEF(func, lang, "OH_Int64", "J", "long") \
48 KOALA_INTEROP_TYPEDEF(func, lang, "Ark_Int32", "I", "int") \
49 KOALA_INTEROP_TYPEDEF(func, lang, "Ark_Int64", "J", "long") \
50 KOALA_INTEROP_TYPEDEF(func, lang, "KNativePointer", "J", "long") \
51 KOALA_INTEROP_TYPEDEF(func, lang, "KSerializerBuffer", "J", "long") \
52 KOALA_INTEROP_TYPEDEF(func, lang, "Ark_NativePointer", "J", "long") \
53 KOALA_INTEROP_TYPEDEF(func, lang, "OH_NativePointer", "J", "long") \
54 KOALA_INTEROP_TYPEDEF(func, lang, "float", "F", "float") \
55 KOALA_INTEROP_TYPEDEF(func, lang, "KFloat", "F", "float") \
56 KOALA_INTEROP_TYPEDEF(func, lang, "Ark_Float32", "F", "float") \
57 KOALA_INTEROP_TYPEDEF(func, lang, "double", "D", "double") \
58 KOALA_INTEROP_TYPEDEF(func, lang, "KDouble", "D", "double") \
59 KOALA_INTEROP_TYPEDEF(func, lang, "KInteropNumber", "D", "double") \
60 KOALA_INTEROP_TYPEDEF(func, lang, "KVMObjectHandle", "Ljava/lang/Object;", "Object") \
61 KOALA_INTEROP_TYPEDEF(func, lang, "uint8_t*", "[B", "byte[]") \
62 KOALA_INTEROP_TYPEDEF(func, lang, "KByte*", "[B", "byte[]") \
63 KOALA_INTEROP_TYPEDEF(func, lang, "KInteropBuffer", "[B", "byte[]") \
64 KOALA_INTEROP_TYPEDEF(func, lang, "KShort*", "[S", "short[]") \
65 KOALA_INTEROP_TYPEDEF(func, lang, "KUShort*", "[S", "short[]") \
66 KOALA_INTEROP_TYPEDEF(func, lang, "int32_t*", "[I", "int[]") \
67 KOALA_INTEROP_TYPEDEF(func, lang, "KInt*", "[I", "int[]") \
68 KOALA_INTEROP_TYPEDEF(func, lang, "KNativePointerArray", "[J", "long[]") \
69 KOALA_INTEROP_TYPEDEF(func, lang, "KInteropReturnBuffer", "[B", "byte[]") \
70 KOALA_INTEROP_TYPEDEF(func, lang, "float*", "[F", "float[]") \
71 KOALA_INTEROP_TYPEDEF(func, lang, "KFloatArray", "[F", "float[]") \
72 KOALA_INTEROP_TYPEDEF(func, lang, "KFloat*", "[F", "float[]") \
73 KOALA_INTEROP_TYPEDEF_LS(func, lang, "KStringPtr", "Lstd/core/String;", "String", "Ljava/lang/String;", "String") \
74 KOALA_INTEROP_TYPEDEF_LS(func, lang, "KStringArray", "[Lstd/core/String;", "String[]", "[Ljava/lang/String;", "String[]") \
75 KOALA_INTEROP_TYPEDEF_LS(func, lang, "KLength", "Lstd/core/String;", "String", "Ljava/lang/String;", "String")
76
sigType(const std::string & type)77 std::string sigType(const std::string &type) {
78 #if KOALA_USE_PANDA_VM
79 KOALA_INTEROP_TYPEDEFS("sigType", "ets")
80 #elif KOALA_USE_JAVA_VM
81 KOALA_INTEROP_TYPEDEFS("sigType", "jni")
82 #endif
83 INTEROP_FATAL("Unhandled type: %s\n", type.c_str());
84 return type;
85 }
86
codeType(const std::string & type)87 std::string codeType(const std::string &type) {
88 #if KOALA_USE_PANDA_VM
89 KOALA_INTEROP_TYPEDEFS("codeType", "ets")
90 #elif KOALA_USE_JAVA_VM
91 KOALA_INTEROP_TYPEDEFS("codeType", "jni")
92 #endif
93 INTEROP_FATAL("Unhandled type: %s\n", type.c_str());
94 return "";
95 }
96
convertType(const char * name,const char * koalaType)97 std::string convertType(const char* name, const char* koalaType) {
98 std::string result;
99 size_t current = 0, last = 0;
100 std::string input(koalaType);
101 std::vector<std::string> tokens;
102 while ((current = input.find('|', last)) != std::string::npos)
103 {
104 auto token = input.substr(last, current - last);
105 tokens.push_back(token);
106 last = current + 1;
107 }
108 tokens.push_back(input.substr(last, input.length() - last));
109
110 #if KOALA_USE_PANDA_VM
111
112 for (int i = 1; i < (int)tokens.size(); i++)
113 {
114 result.append(sigType(tokens[i]));
115 }
116 result.append(":");
117 result.append(sigType(tokens[0]));
118
119 #elif KOALA_USE_JAVA_VM
120
121 result.append("(");
122 for (int i = 1; i < (int)tokens.size(); i++)
123 {
124 result.append(sigType(tokens[i]));
125 }
126 result.append(")");
127 result.append(sigType(tokens[0]));
128
129 #endif
130
131 #ifdef KOALA_BUILD_FOR_SIGNATURES
132 #ifdef KOALA_USE_PANDA_VM
133 std::string params;
134 for (int i = 1; i < (int)tokens.size(); i++)
135 {
136 params.append("arg");
137 params.append(std::to_string(i));
138 params.append(": ");
139 params.append(codeType(tokens[i]));
140 if (i < (int)(tokens.size() - 1))
141 params.append(", ");
142 }
143 fprintf(stderr, " static native %s(%s): %s;\n", name, params.c_str(), codeType(tokens[0]).c_str());
144 #elif KOALA_USE_JAVA_VM
145 std::string params;
146 for (int i = 1; i < (int)tokens.size(); i++)
147 {
148 params.append(codeType(tokens[i]));
149 params.append(" arg");
150 params.append(std::to_string(i));
151 if (i < (int)(tokens.size() - 1))
152 params.append(", ");
153 }
154 fprintf(stderr, " public static native %s %s(%s);\n", codeType(tokens[0]).c_str(), name, params.c_str());
155 #endif
156 #endif
157
158 return result;
159 }
160