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