1 /*
2 * Copyright (c) 2022-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 #include <string>
16 #include <vector>
17 #include <map>
18
19 #ifdef KOALA_INTEROP_MODULE
20 #undef KOALA_INTEROP_MODULE
21 #endif
22
23 #define KOALA_INTEROP_MODULE InteropNativeModule
24 #include "common-interop.h"
25 #include "interop-logging.h"
26 #include "dynamic-loader.h"
27
28
29 #if KOALA_INTEROP_PROFILER
30 #include "profiler.h"
31
32 InteropProfiler* InteropProfiler::_instance = nullptr;
33
34 #endif
35
36 using std::string;
37
38 #ifdef KOALA_NAPI
39 // Callback dispatcher MOVED to convertors-napi.cc.
40 // Let's keep platform-specific parts of the code together
41
42 typedef void (*hold_t)(KInt);
43
impl_MaterializeBuffer(KNativePointer data,KLong length,KInt resourceId,KNativePointer holdPtr,KNativePointer releasePtr)44 KInteropBuffer impl_MaterializeBuffer(KNativePointer data, KLong length, KInt resourceId, KNativePointer holdPtr, KNativePointer releasePtr) {
45 auto hold = reinterpret_cast<void(*)(KInt)>(holdPtr);
46 auto release = reinterpret_cast<void(*)(KInt)>(releasePtr);
47 hold(resourceId);
48 return KInteropBuffer { length, data, resourceId, release };
49 }
KOALA_INTEROP_5(MaterializeBuffer,KInteropBuffer,KNativePointer,KLong,KInt,KNativePointer,KNativePointer)50 KOALA_INTEROP_5(MaterializeBuffer, KInteropBuffer, KNativePointer, KLong, KInt, KNativePointer, KNativePointer)
51
52 KNativePointer impl_GetNativeBufferPointer(KInteropBuffer buffer) {
53 return buffer.data;
54 }
55 KOALA_INTEROP_1(GetNativeBufferPointer, KNativePointer, KInteropBuffer)
56
57 #endif
58
59 #ifdef KOALA_ETS_NAPI
60 #include "etsapi.h"
61
62 static struct {
63 ets_class clazz = nullptr;
64 ets_method method = nullptr;
65 } g_koalaEtsNapiCallbackDispatcher;
66
setKoalaEtsNapiCallbackDispatcher(EtsEnv * etsEnv,ets_class clazz,const char * dispatcherMethodName,const char * dispactherMethodSig)67 bool setKoalaEtsNapiCallbackDispatcher(
68 EtsEnv* etsEnv,
69 ets_class clazz,
70 const char* dispatcherMethodName,
71 const char* dispactherMethodSig
72 ) {
73 g_koalaEtsNapiCallbackDispatcher.clazz = clazz;
74 etsEnv->NewGlobalRef(clazz);
75 ets_method method = etsEnv->GetStaticp_method(
76 clazz, dispatcherMethodName, dispactherMethodSig
77 );
78 if (method == nullptr) {
79 return false;
80 }
81 g_koalaEtsNapiCallbackDispatcher.method = method;
82 return true;
83 }
84
getKoalaEtsNapiCallbackDispatcher(ets_class * clazz,ets_method * method)85 void getKoalaEtsNapiCallbackDispatcher(ets_class* clazz, ets_method* method) {
86 *clazz = g_koalaEtsNapiCallbackDispatcher.clazz;
87 *method = g_koalaEtsNapiCallbackDispatcher.method;
88 }
89 #endif
90
91 #ifdef KOALA_JNI
92 #include "jni.h"
93 static struct {
94 jclass clazz = nullptr;
95 jmethodID method = nullptr;
96 } g_koalaJniCallbackDispatcher;
97
setKoalaJniCallbackDispatcher(JNIEnv * jniEnv,jclass clazz,const char * dispatcherMethodName,const char * dispactherMethodSig)98 bool setKoalaJniCallbackDispatcher(
99 JNIEnv* jniEnv,
100 jclass clazz,
101 const char* dispatcherMethodName,
102 const char* dispactherMethodSig
103 ) {
104 g_koalaJniCallbackDispatcher.clazz = clazz;
105 jniEnv->NewGlobalRef(clazz);
106 jmethodID method = jniEnv->GetStaticMethodID(
107 clazz, dispatcherMethodName, dispactherMethodSig
108 );
109 if (method == nullptr) {
110 return false;
111 }
112 g_koalaJniCallbackDispatcher.method = method;
113 return true;
114 }
115
getKoalaJniCallbackDispatcher(jclass * clazz,jmethodID * method)116 void getKoalaJniCallbackDispatcher(jclass* clazz, jmethodID* method) {
117 *clazz = g_koalaJniCallbackDispatcher.clazz;
118 *method = g_koalaJniCallbackDispatcher.method;
119 }
120 #endif
121
impl_StringLength(KNativePointer ptr)122 KInt impl_StringLength(KNativePointer ptr) {
123 string* s = reinterpret_cast<string*>(ptr);
124 return s->length();
125 }
KOALA_INTEROP_1(StringLength,KInt,KNativePointer)126 KOALA_INTEROP_1(StringLength, KInt, KNativePointer)
127
128 void impl_StringData(KNativePointer ptr, KByte* bytes, KUInt size) {
129 string* s = reinterpret_cast<string*>(ptr);
130 if (s) {
131 #ifdef __STDC_LIB_EXT1__
132 errno_t res = memcpy_s(bytes, size, s->c_str(), size);
133 if (res != EOK) {
134 return;
135 }
136 #else
137 memcpy(bytes, s->c_str(), size);
138 #endif
139 }
140 }
KOALA_INTEROP_V3(StringData,KNativePointer,KByte *,KUInt)141 KOALA_INTEROP_V3(StringData, KNativePointer, KByte*, KUInt)
142
143
144 #ifdef KOALA_JNI
145 // For Java only yet.
146 KInteropBuffer impl_StringDataBytes(KVMContext vmContext, KNativePointer ptr) {
147 string* s = reinterpret_cast<std::string*>(ptr);
148 KInteropBuffer result = { (int32_t)s->length(), (void*)s->c_str()};
149 return result;
150 }
KOALA_INTEROP_CTX_1(StringDataBytes,KInteropBuffer,KNativePointer)151 KOALA_INTEROP_CTX_1(StringDataBytes, KInteropBuffer, KNativePointer)
152 #endif
153
154 KNativePointer impl_StringMake(const KStringPtr& str) {
155 return new string(str.c_str());
156 }
KOALA_INTEROP_1(StringMake,KNativePointer,KStringPtr)157 KOALA_INTEROP_1(StringMake, KNativePointer, KStringPtr)
158
159 // For slow runtimes w/o fast encoders.
160 KInt impl_ManagedStringWrite(const KStringPtr& string, KByte* buffer, KInt offset) {
161 #ifdef __STDC_LIB_EXT1__
162 errno_t res = memcpy_s(buffer + offset, string.length() + 1, string.c_str(), string.length() + 1);
163 if (res != EOK) {
164 return 0;
165 }
166 #else
167 memcpy(buffer + offset, string.c_str(), string.length() + 1);
168 #endif
169 return string.length() + 1;
170 }
KOALA_INTEROP_3(ManagedStringWrite,KInt,KStringPtr,KByte *,KInt)171 KOALA_INTEROP_3(ManagedStringWrite, KInt, KStringPtr, KByte*, KInt)
172
173 void stringFinalizer(string* ptr) {
174 delete ptr;
175 }
impl_GetStringFinalizer()176 KNativePointer impl_GetStringFinalizer() {
177 return fnPtr<string>(stringFinalizer);
178 }
KOALA_INTEROP_0(GetStringFinalizer,KNativePointer)179 KOALA_INTEROP_0(GetStringFinalizer, KNativePointer)
180
181 void impl_InvokeFinalizer(KNativePointer obj, KNativePointer finalizer) {
182 auto finalizer_f = reinterpret_cast<void (*)(KNativePointer)>(finalizer);
183 finalizer_f(obj);
184 }
KOALA_INTEROP_V2(InvokeFinalizer,KNativePointer,KNativePointer)185 KOALA_INTEROP_V2(InvokeFinalizer, KNativePointer, KNativePointer)
186
187 KInt impl_GetPtrVectorSize(KNativePointer ptr) {
188 return reinterpret_cast<std::vector<void*>*>(ptr)->size();
189 }
KOALA_INTEROP_1(GetPtrVectorSize,KInt,KNativePointer)190 KOALA_INTEROP_1(GetPtrVectorSize, KInt, KNativePointer)
191
192 KNativePointer impl_GetPtrVectorElement(KNativePointer ptr, KInt index) {
193 auto vector = reinterpret_cast<std::vector<void*>*>(ptr);
194 auto element = vector->at(index);
195 return nativePtr(element);
196 }
KOALA_INTEROP_2(GetPtrVectorElement,KNativePointer,KNativePointer,KInt)197 KOALA_INTEROP_2(GetPtrVectorElement, KNativePointer, KNativePointer, KInt)
198
199 inline KUInt unpackUInt(const KByte* bytes) {
200 return (bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24));
201 }
202
makeStringVector(KStringArray strArray)203 std::vector<KStringPtr> makeStringVector(KStringArray strArray) {
204 if (strArray == nullptr) {
205 return std::vector<KStringPtr>(0);
206 }
207 KUInt arraySize = unpackUInt(strArray);
208 std::vector<KStringPtr> res(arraySize);
209 size_t offset = sizeof(KUInt);
210 for (KUInt i = 0; i < arraySize; ++i) {
211 int len = unpackUInt(strArray + offset);
212 res[i].assign((const char*)(strArray + offset + sizeof(KUInt)), len);
213 offset += len + sizeof(KUInt);
214 }
215 return res;
216 }
217
makeStringVector(KNativePointerArray arr,KInt length)218 std::vector<KStringPtr> makeStringVector(KNativePointerArray arr, KInt length) {
219 if (arr == nullptr) {
220 return std::vector<KStringPtr>(0);
221 } else {
222 std::vector<KStringPtr> res(length);
223 char** strings = reinterpret_cast<char**>(arr);
224 for (KInt i = 0; i < length; ++i) {
225 const char* str = reinterpret_cast<const char*>(strings[i]);
226 res[i].assign(str);
227 }
228 return res;
229 }
230 }
231
impl_GetGroupedLog(KInt index)232 KNativePointer impl_GetGroupedLog(KInt index) {
233 return new std::string(GetDefaultLogger()->getGroupedLog(index));
234 }
KOALA_INTEROP_1(GetGroupedLog,KNativePointer,KInt)235 KOALA_INTEROP_1(GetGroupedLog, KNativePointer, KInt)
236
237 void impl_StartGroupedLog(KInt index) {
238 GetDefaultLogger()->startGroupedLog(index);
239 }
KOALA_INTEROP_V1(StartGroupedLog,KInt)240 KOALA_INTEROP_V1(StartGroupedLog, KInt)
241
242 void impl_StopGroupedLog(KInt index) {
243 GetDefaultLogger()->stopGroupedLog(index);
244 }
KOALA_INTEROP_V1(StopGroupedLog,KInt)245 KOALA_INTEROP_V1(StopGroupedLog, KInt)
246
247 void impl_AppendGroupedLog(KInt index, const KStringPtr& message) {
248 if (GetDefaultLogger()->needGroupedLog(index))
249 GetDefaultLogger()->appendGroupedLog(index, message.c_str());
250 }
KOALA_INTEROP_V2(AppendGroupedLog,KInt,KStringPtr)251 KOALA_INTEROP_V2(AppendGroupedLog, KInt, KStringPtr)
252
253 void impl_PrintGroupedLog(KInt index) {
254 #ifdef KOALA_OHOS
255 LOGI("%" LOG_PUBLIC "s", GetDefaultLogger()->getGroupedLog(index));
256 #else
257 fprintf(stdout, "%s\n", GetDefaultLogger()->getGroupedLog(index));
258 fflush(stdout);
259 #endif
260 }
KOALA_INTEROP_V1(PrintGroupedLog,KInt)261 KOALA_INTEROP_V1(PrintGroupedLog, KInt)
262
263 int32_t callCallback(KVMContext context, int32_t methodId, uint8_t* argsData, int32_t argsLength) {
264 #if KOALA_USE_NODE_VM || KOALA_USE_HZ_VM || KOALA_USE_PANDA_VM || KOALA_USE_JAVA_VM || KOALA_CJ
265 KOALA_INTEROP_CALL_INT(context, methodId, argsLength, argsData);
266 #else
267 return 0;
268 #endif
269 }
270
271 struct ForeignVMContext {
272 KVMContext vmContext;
273 int32_t (*callSync)(KVMContext vmContext, int32_t callback, uint8_t* data, int32_t length);
274 };
275 typedef KInt (*LoadVirtualMachine_t)(KInt vmKind, const char* classPath, const char* libraryPath, const struct ForeignVMContext* foreignVM);
276 typedef KNativePointer (*StartApplication_t)(const char* appUrl, const char* appParams);
277 typedef KBoolean (*RunApplication_t)(const KInt arg0, const KInt arg1);
278 typedef const char* (*EmitEvent_t)(const KInt type, const KInt target, const KInt arg0, const KInt arg1);
279 typedef void (*RestartWith_t)(const char* page);
280
getImpl(const char * path,const char * name)281 void* getImpl(const char* path, const char* name) {
282 static void* lib = nullptr;
283 if (!lib && name) {
284 auto name =
285 #ifndef KOALA_OHOS // dlopen on OHOS doesn't like paths
286 std::string(path) + "/" +
287 #endif
288 libName("vmloader");
289 lib = loadLibrary(name);
290 if (!lib) {
291 fprintf(stderr, "Ensure vmloader library %s was built\n", name.c_str());
292 }
293 }
294 return findSymbol(lib, name);
295 }
296
impl_LoadVirtualMachine(KVMContext vmContext,KInt vmKind,const KStringPtr & classPath,const KStringPtr & libraryPath)297 KInt impl_LoadVirtualMachine(KVMContext vmContext, KInt vmKind, const KStringPtr& classPath, const KStringPtr& libraryPath) {
298 const char* envClassPath = std::getenv("PANDA_CLASS_PATH");
299 if (envClassPath) {
300 LOGI("CLASS PATH updated from env var PANDA_CLASS_PATH, %" LOG_PUBLIC "s", envClassPath);
301 }
302 const char* appClassPath = envClassPath ? envClassPath : classPath.c_str();
303 const char* nativeLibPath = envClassPath ? envClassPath : libraryPath.c_str();
304
305 static LoadVirtualMachine_t impl = nullptr;
306 if (!impl) impl = reinterpret_cast<LoadVirtualMachine_t>(getImpl(nativeLibPath, "LoadVirtualMachine"));
307 if (!impl) KOALA_INTEROP_THROW_STRING(vmContext, "Cannot load VM", -1);
308 const ForeignVMContext foreignVM = {
309 vmContext, &callCallback
310 };
311 return impl(vmKind, appClassPath, nativeLibPath, &foreignVM);
312 }
KOALA_INTEROP_CTX_3(LoadVirtualMachine,KInt,KInt,KStringPtr,KStringPtr)313 KOALA_INTEROP_CTX_3(LoadVirtualMachine, KInt, KInt, KStringPtr, KStringPtr)
314
315 KNativePointer impl_StartApplication(const KStringPtr& appUrl, const KStringPtr& appParams) {
316 static StartApplication_t impl = nullptr;
317 if (!impl) impl = reinterpret_cast<StartApplication_t>(getImpl(nullptr, "StartApplication"));
318 return impl(appUrl.c_str(), appParams.c_str());
319 }
KOALA_INTEROP_2(StartApplication,KNativePointer,KStringPtr,KStringPtr)320 KOALA_INTEROP_2(StartApplication, KNativePointer, KStringPtr, KStringPtr)
321
322 KBoolean impl_RunApplication(const KInt arg0, const KInt arg1) {
323 static RunApplication_t impl = nullptr;
324 if (!impl) impl = reinterpret_cast<RunApplication_t>(getImpl(nullptr, "RunApplication"));
325 return impl(arg0, arg1);
326 }
KOALA_INTEROP_2(RunApplication,KBoolean,KInt,KInt)327 KOALA_INTEROP_2(RunApplication, KBoolean, KInt, KInt)
328
329 KStringPtr impl_EmitEvent(KVMContext vmContext, KInt type, KInt target, KInt arg0, KInt arg1) {
330 static EmitEvent_t impl = nullptr;
331 if (!impl) impl = reinterpret_cast<EmitEvent_t>(getImpl(nullptr, "EmitEvent"));
332 const char* out = impl(type, target, arg0, arg1);
333 auto size = std::string(out).size();
334 KStringPtr result(out, size, true);
335 return result;
336 }
KOALA_INTEROP_CTX_4(EmitEvent,KStringPtr,KInt,KInt,KInt,KInt)337 KOALA_INTEROP_CTX_4(EmitEvent, KStringPtr, KInt, KInt, KInt, KInt)
338
339 void impl_RestartWith(const KStringPtr& page) {
340 static RestartWith_t impl = nullptr;
341 if (!impl) impl = reinterpret_cast<RestartWith_t>(getImpl(nullptr, "RestartWith"));
342 impl(page.c_str());
343 }
344 KOALA_INTEROP_V1(RestartWith, KStringPtr)
345
346 static Callback_Caller_t g_callbackCaller = nullptr;
setCallbackCaller(Callback_Caller_t callbackCaller)347 void setCallbackCaller(Callback_Caller_t callbackCaller) {
348 g_callbackCaller = callbackCaller;
349 }
350
impl_CallCallback(KInt callbackKind,KByte * args,KInt argsSize)351 void impl_CallCallback(KInt callbackKind, KByte* args, KInt argsSize) {
352 if (g_callbackCaller) {
353 g_callbackCaller(callbackKind, args, argsSize);
354 }
355 }
356 KOALA_INTEROP_V3(CallCallback, KInt, KByte*, KInt)
357
358 static Callback_Caller_Sync_t g_callbackCallerSync = nullptr;
setCallbackCallerSync(Callback_Caller_Sync_t callbackCallerSync)359 void setCallbackCallerSync(Callback_Caller_Sync_t callbackCallerSync) {
360 g_callbackCallerSync = callbackCallerSync;
361 }
362
impl_CallCallbackSync(KVMContext vmContext,KInt callbackKind,KByte * args,KInt argsSize)363 void impl_CallCallbackSync(KVMContext vmContext, KInt callbackKind, KByte* args, KInt argsSize) {
364 if (g_callbackCallerSync) {
365 g_callbackCallerSync(vmContext, callbackKind, args, argsSize);
366 }
367 }
KOALA_INTEROP_CTX_V3(CallCallbackSync,KInt,KByte *,KInt)368 KOALA_INTEROP_CTX_V3(CallCallbackSync, KInt, KByte*, KInt)
369
370 void impl_CallCallbackResourceHolder(KNativePointer holder, KInt resourceId) {
371 reinterpret_cast<void(*)(KInt)>(holder)(resourceId);
372 }
KOALA_INTEROP_V2(CallCallbackResourceHolder,KNativePointer,KInt)373 KOALA_INTEROP_V2(CallCallbackResourceHolder, KNativePointer, KInt)
374
375 void impl_CallCallbackResourceReleaser(KNativePointer releaser, KInt resourceId) {
376 reinterpret_cast<void(*)(KInt)>(releaser)(resourceId);
377 }
KOALA_INTEROP_V2(CallCallbackResourceReleaser,KNativePointer,KInt)378 KOALA_INTEROP_V2(CallCallbackResourceReleaser, KNativePointer, KInt)
379
380 KInt impl_CallForeignVM(KNativePointer foreignContextRaw, KInt function, KByte* data, KInt length) {
381 const ForeignVMContext* foreignContext = (const ForeignVMContext*)foreignContextRaw;
382 // TODO: set actuall callbacks caller/holder/releaser.
383 /*
384 *(int64_t*)(data + 8) = impl_CallCallbackSync;
385 *(int64_t*)(data + 16) = 0;
386 *(int64_t*)(data + 24) = 0; */
387 return foreignContext->callSync(foreignContext->vmContext, function, data, length);
388 }
KOALA_INTEROP_4(CallForeignVM,KInt,KNativePointer,KInt,KByte *,KInt)389 KOALA_INTEROP_4(CallForeignVM, KInt, KNativePointer, KInt, KByte*, KInt)
390
391
392 #define QUOTE(x) #x
393
394 void impl_NativeLog(const KStringPtr& str) {
395 #ifdef KOALA_OHOS
396 LOGI("%{public}s: %{public}s", QUOTE(INTEROP_LIBRARY_NAME), str.c_str());
397 #else
398 fprintf(stdout, "%s: %s\n", QUOTE(INTEROP_LIBRARY_NAME), str.c_str());
399 fflush(stdout);
400 #endif
401 }
KOALA_INTEROP_V1(NativeLog,KStringPtr)402 KOALA_INTEROP_V1(NativeLog, KStringPtr)
403
404
405
406 void resolveDeferred(KVMDeferred* deferred, uint8_t* argsData, int32_t argsLength) {
407 #ifdef KOALA_NAPI
408 auto status = napi_call_threadsafe_function((napi_threadsafe_function)deferred->handler, deferred, napi_tsfn_nonblocking);
409 if (status != napi_ok) LOGE("cannot call thread-safe function; status=%d", status);
410 napi_release_threadsafe_function((napi_threadsafe_function)deferred->handler, napi_tsfn_release);
411 #endif
412 }
413
rejectDeferred(KVMDeferred * deferred,const char * message)414 void rejectDeferred(KVMDeferred* deferred, const char* message) {
415 #ifdef KOALA_NAPI
416 napi_release_threadsafe_function((napi_threadsafe_function)deferred->handler, napi_tsfn_release);
417 delete deferred;
418 #endif
419 }
420
421 #ifdef KOALA_NAPI
resolveDeferredImpl(napi_env env,napi_value js_callback,KVMDeferred * deferred,void * data)422 void resolveDeferredImpl(napi_env env, napi_value js_callback, KVMDeferred* deferred, void* data) {
423 napi_value undefined = nullptr;
424 napi_get_undefined(env, &undefined);
425 auto status = napi_resolve_deferred(env, (napi_deferred)deferred->context, undefined);
426 if (status != napi_ok) LOGE("cannot resolve deferred; status=%d", status);
427 delete deferred;
428 }
429 #endif
430
CreateDeferred(KVMContext vmContext,KVMObjectHandle * promiseHandle)431 KVMDeferred* CreateDeferred(KVMContext vmContext, KVMObjectHandle* promiseHandle) {
432 KVMDeferred* deferred = new KVMDeferred();
433 deferred->resolve = resolveDeferred;
434 deferred->reject = rejectDeferred;
435 #ifdef KOALA_NAPI
436 // TODO: move to interop!
437 napi_env env = (napi_env)vmContext;
438 napi_value promise;
439 napi_value resourceName;
440 napi_create_string_utf8(env, "Async", 5, &resourceName);
441 auto status = napi_create_promise(env, (napi_deferred*)&deferred->context, &promise);
442 if (status != napi_ok) LOGE("cannot make a promise; status=%d", status);
443 status = napi_create_threadsafe_function(env,
444 nullptr,
445 nullptr,
446 resourceName,
447 0,
448 1,
449 nullptr,
450 nullptr,
451 deferred,
452 (napi_threadsafe_function_call_js)resolveDeferredImpl,
453 (napi_threadsafe_function*)&deferred->handler);
454 if (status != napi_ok) LOGE("cannot make threadsafe function; status=%d", status);
455 *promiseHandle = (KVMObjectHandle)promise;
456 #endif
457 return deferred;
458 }
459
460 #if defined(KOALA_ETS_NAPI) || defined(KOALA_NAPI) || defined(KOALA_JNI) || defined(KOALA_CJ)
461 // Allocate, so CTX versions.
impl_Utf8ToString(KVMContext vmContext,KByte * data,KInt offset,KInt length)462 KStringPtr impl_Utf8ToString(KVMContext vmContext, KByte* data, KInt offset, KInt length) {
463 KStringPtr result((const char*)(data + offset), length, false);
464 return result;
465 }
KOALA_INTEROP_CTX_3(Utf8ToString,KStringPtr,KByte *,KInt,KInt)466 KOALA_INTEROP_CTX_3(Utf8ToString, KStringPtr, KByte*, KInt, KInt)
467
468 KStringPtr impl_StdStringToString(KVMContext vmContext, KNativePointer stringPtr) {
469 std::string* string = reinterpret_cast<std::string*>(stringPtr);
470 KStringPtr result(string->c_str(), string->size(), false);
471 return result;
472 }
KOALA_INTEROP_CTX_1(StdStringToString,KStringPtr,KNativePointer)473 KOALA_INTEROP_CTX_1(StdStringToString, KStringPtr, KNativePointer)
474 #endif
475
476 #if defined(KOALA_JNI) || defined(KOALA_NAPI) || defined(KOALA_CJ)
477 KInteropReturnBuffer impl_RawReturnData(KVMContext vmContext, KInt v1, KInt v2) {
478 void* data = new int8_t[v1];
479 #ifdef __STDC_LIB_EXT1__
480 errno_t res = memset_s(data, v1, v2, v1);
481 if (res != EOK) {
482 LOGE("RawReturnData failed");
483 }
484 #else
485 memset(data, v2, v1);
486 #endif
487 KInteropReturnBuffer buffer = { v1, data, [](KNativePointer ptr, KInt) { delete[] (int8_t*)ptr; }};
488 return buffer;
489 }
490 KOALA_INTEROP_CTX_2(RawReturnData, KInteropReturnBuffer, KInt, KInt)
491 #endif
492