From 2ba116a447ae19193f70d06e6d8705c1d8a37513 Mon Sep 17 00:00:00 2001 From: "evgeniy.generalov" Date: Sat, 30 Aug 2025 18:52:13 +0300 Subject: [PATCH 1/3] Add array decoder via napi's external buffer --- interop/src/cpp/common-interop.cc | 8 +++++- interop/src/cpp/napi/convertors-napi.h | 26 ++++++++++++++----- interop/src/cpp/types/koala-types.h | 8 ++++++ ui2abc/libarkts/src/InteropNativeModule.ts | 3 +++ .../arkts-api/utilities/nativePtrDecoder.ts | 19 +++++++++++++- .../src/arkts-api/utilities/private.ts | 1 + 6 files changed, 56 insertions(+), 9 deletions(-) diff --git a/interop/src/cpp/common-interop.cc b/interop/src/cpp/common-interop.cc index 7003f568e8..d0cd2f5d08 100644 --- a/interop/src/cpp/common-interop.cc +++ b/interop/src/cpp/common-interop.cc @@ -189,6 +189,12 @@ void impl_InvokeFinalizer(KNativePointer obj, KNativePointer finalizer) { } KOALA_INTEROP_V2(InvokeFinalizer, KNativePointer, KNativePointer) +KInteropReturnBuffer impl_GetPtrVector(KNativePointer ptr) { + auto vector = reinterpret_cast*>(ptr); + return KInteropReturnBuffer::from(*vector); +} +KOALA_INTEROP_1(GetPtrVector, KInteropReturnBuffer, KNativePointer) + KInt impl_GetPtrVectorSize(KNativePointer ptr) { return reinterpret_cast*>(ptr)->size(); } @@ -778,4 +784,4 @@ void impl_ReportMemLeaks() { } KOALA_INTEROP_V0(ReportMemLeaks) -#endif \ No newline at end of file +#endif diff --git a/interop/src/cpp/napi/convertors-napi.h b/interop/src/cpp/napi/convertors-napi.h index d1551ad4ad..af62a2c9bf 100644 --- a/interop/src/cpp/napi/convertors-napi.h +++ b/interop/src/cpp/napi/convertors-napi.h @@ -184,22 +184,35 @@ struct InteropTypeConverter { } }; +inline napi_typedarray_type getNapiType(KInt size) +{ + switch (size) { + case 1: return napi_uint8_array; + case 2: return napi_uint16_array; + case 4: return napi_uint32_array; + case 8: return napi_biguint64_array; + default: break; + } + return napi_uint8_array; +} + template<> struct InteropTypeConverter { using InteropType = napi_value; static inline KInteropReturnBuffer convertFrom(napi_env env, InteropType value) = delete; static void disposer(napi_env env, void* data, void* hint) { KInteropReturnBuffer* bufferCopy = (KInteropReturnBuffer*)hint; - bufferCopy->dispose(bufferCopy->data, bufferCopy->length); + // todo: Should the dispose signature contain length? It is not common for libc + // and removing it can avoid an extra allocation. + bufferCopy->dispose ? bufferCopy->dispose(bufferCopy->data, bufferCopy->length) : (void)0; delete bufferCopy; } static InteropType convertTo(napi_env env, KInteropReturnBuffer value) { napi_value result = nullptr; napi_value arrayBuffer = nullptr; - auto clone = new KInteropReturnBuffer(); - *clone = value; - napi_create_external_arraybuffer(env, value.data, value.length, disposer, clone, &arrayBuffer); - napi_create_typedarray(env, napi_uint8_array, value.length, arrayBuffer, 0, &result); + auto clone = new KInteropReturnBuffer(value); + napi_create_external_arraybuffer(env, value.data, value.length * value.elementSize, disposer, clone, &arrayBuffer); + napi_create_typedarray(env, getNapiType(value.elementSize), value.length, arrayBuffer, 0, &result); return result; } static inline void release(napi_env env, InteropType value, const KInteropReturnBuffer& converted) = delete; @@ -333,7 +346,6 @@ template <> inline napi_typedarray_type getNapiType() { return napi_biguint64_array; } - napi_valuetype getValueTypeChecked(napi_env env, napi_value value); bool isTypedArray(napi_env env, napi_value value); @@ -1437,4 +1449,4 @@ napi_value getKoalaNapiCallbackDispatcher(napi_env env); #endif // KOALA_NAPI -#endif // _CONVERTORS_NAPI_H_ \ No newline at end of file +#endif // _CONVERTORS_NAPI_H_ diff --git a/interop/src/cpp/types/koala-types.h b/interop/src/cpp/types/koala-types.h index 0c5bd658fc..5a006f2871 100644 --- a/interop/src/cpp/types/koala-types.h +++ b/interop/src/cpp/types/koala-types.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "interop-types.h" #include "interop-utils.h" @@ -230,6 +231,13 @@ struct KInteropReturnBuffer { KInt length; KNativePointer data; void (*dispose)(KNativePointer data, KInt length); + KInt elementSize = 1; + + template + static KInteropReturnBuffer from(std::vector const& v, decltype(dispose) dispose = nullptr) + { + return { (KInt)v.size(), (KNativePointer)v.data(), dispose, (KInt)sizeof(T) }; + } }; typedef _InteropVMContext *KVMContext; diff --git a/ui2abc/libarkts/src/InteropNativeModule.ts b/ui2abc/libarkts/src/InteropNativeModule.ts index 5b4d480484..9bded8fb32 100644 --- a/ui2abc/libarkts/src/InteropNativeModule.ts +++ b/ui2abc/libarkts/src/InteropNativeModule.ts @@ -37,6 +37,9 @@ export class InteropNativeModule { _InvokeFinalizer(ptr: KPtr, finalizer: KPtr): void { throw new Error("Not implemented") } + _GetPtrVector(ptr: KPtr): BigUint64Array { + throw new Error("Not implemented") + } _GetPtrVectorSize(ptr: KPtr): KInt { throw new Error("Not implemented") } diff --git a/ui2abc/libarkts/src/arkts-api/utilities/nativePtrDecoder.ts b/ui2abc/libarkts/src/arkts-api/utilities/nativePtrDecoder.ts index 08bf50a728..174693c103 100644 --- a/ui2abc/libarkts/src/arkts-api/utilities/nativePtrDecoder.ts +++ b/ui2abc/libarkts/src/arkts-api/utilities/nativePtrDecoder.ts @@ -66,4 +66,21 @@ export class NativePtrDecoder extends ArrayDecoder { getArrayElement(blob: pointer, index: int32): pointer { return global.interop._GetPtrVectorElement(blob, index) } -} \ No newline at end of file +} + +// This decoder uses a napi's external buffer and +// it is not efficient for small arraya(guessing, less than 10) +export class OptimizedNativePtrDecoder { + disposeArray(blob: pointer): void { + // Improve: + } + decode(blob: pointer): Array { + const data = global.interop._GetPtrVector(blob) + const result = Array.from(data) + this.disposeArray(blob) + return result + } + decodeNoCopy(blob: pointer): BigUint64Array { + return global.interop._GetPtrVector(blob) + } +} diff --git a/ui2abc/libarkts/src/arkts-api/utilities/private.ts b/ui2abc/libarkts/src/arkts-api/utilities/private.ts index 4153060b86..f3ac81fe39 100644 --- a/ui2abc/libarkts/src/arkts-api/utilities/private.ts +++ b/ui2abc/libarkts/src/arkts-api/utilities/private.ts @@ -24,6 +24,7 @@ import { withStringArray } from "@koalaui/interop" import { NativePtrDecoder } from "./nativePtrDecoder" +//import { OptimizedNativePtrDecoder as NativePtrDecoder } from "./nativePtrDecoder" import { Es2pandaAstNodeType, Es2pandaModifierFlags, Es2pandaScriptFunctionFlags } from "../../../generated/Es2pandaEnums" import { nodeFrom } from "../class-by-peer" import { AstNode } from "../peers/AstNode" -- Gitee From d2be2f9a2d57056be09a1c87796b15ef3de69f4d Mon Sep 17 00:00:00 2001 From: "evgeniy.generalov" Date: Wed, 3 Sep 2025 14:37:06 +0300 Subject: [PATCH 2/3] Change return type and add code snippets --- .../src/arkts-api/utilities/nativePtrDecoder.ts | 8 ++++---- ui2abc/libarkts/src/arkts-api/utilities/private.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ui2abc/libarkts/src/arkts-api/utilities/nativePtrDecoder.ts b/ui2abc/libarkts/src/arkts-api/utilities/nativePtrDecoder.ts index 174693c103..9e12bb1324 100644 --- a/ui2abc/libarkts/src/arkts-api/utilities/nativePtrDecoder.ts +++ b/ui2abc/libarkts/src/arkts-api/utilities/nativePtrDecoder.ts @@ -74,13 +74,13 @@ export class OptimizedNativePtrDecoder { disposeArray(blob: pointer): void { // Improve: } - decode(blob: pointer): Array { + decode(blob: pointer): BigUint64Array { + return global.interop._GetPtrVector(blob) + } + decodeAndCopy(blob: pointer): Array { const data = global.interop._GetPtrVector(blob) const result = Array.from(data) this.disposeArray(blob) return result } - decodeNoCopy(blob: pointer): BigUint64Array { - return global.interop._GetPtrVector(blob) - } } diff --git a/ui2abc/libarkts/src/arkts-api/utilities/private.ts b/ui2abc/libarkts/src/arkts-api/utilities/private.ts index f3ac81fe39..3f98662571 100644 --- a/ui2abc/libarkts/src/arkts-api/utilities/private.ts +++ b/ui2abc/libarkts/src/arkts-api/utilities/private.ts @@ -66,6 +66,12 @@ export function assertValidPeer(peer: KPtr, expectedKind: Es2pandaAstNodeType): } export function acceptNativeObjectArrayResult(arrayObject: KNativePointer, factory: (instance: KNativePointer) => T): T[] { + // For OptimizedNativePtrDecoder + //const decoded = new NativePtrDecoder().decode(arrayObject) + //return decoded.reduce((prev, curr) => { + // prev.push(factory(curr)) + // return prev + //}, [] as T[]) return new NativePtrDecoder().decode(arrayObject).map(factory); } @@ -91,6 +97,12 @@ export function unpackNodeArray(nodesPtr: KNativePointer, typ if (nodesPtr === nullptr) { return [] } + // For OptimizedNativePtrDecoder + //const decoded = new NativePtrDecoder().decode(nodesPtr) + //return decoded.reduce((prev, curr) => { + // prev.push(unpackNonNullableNode(curr, typeHint)) + // return prev + //}, [] as T[]) return new NativePtrDecoder() .decode(nodesPtr) .map((peer: KNativePointer) => unpackNonNullableNode(peer, typeHint)) -- Gitee From 9e8b8d8244e0216cb2725cf389f6c2ae715fc717 Mon Sep 17 00:00:00 2001 From: "evgeniy.generalov" Date: Wed, 3 Sep 2025 14:45:50 +0300 Subject: [PATCH 3/3] Fix default value --- interop/src/cpp/common-interop.cc | 2 +- interop/src/cpp/types/koala-types.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interop/src/cpp/common-interop.cc b/interop/src/cpp/common-interop.cc index d0cd2f5d08..082b8d0225 100644 --- a/interop/src/cpp/common-interop.cc +++ b/interop/src/cpp/common-interop.cc @@ -191,7 +191,7 @@ KOALA_INTEROP_V2(InvokeFinalizer, KNativePointer, KNativePointer) KInteropReturnBuffer impl_GetPtrVector(KNativePointer ptr) { auto vector = reinterpret_cast*>(ptr); - return KInteropReturnBuffer::from(*vector); + return KInteropReturnBuffer::from(*vector, nullptr); } KOALA_INTEROP_1(GetPtrVector, KInteropReturnBuffer, KNativePointer) diff --git a/interop/src/cpp/types/koala-types.h b/interop/src/cpp/types/koala-types.h index 5a006f2871..36d00bbc3b 100644 --- a/interop/src/cpp/types/koala-types.h +++ b/interop/src/cpp/types/koala-types.h @@ -234,7 +234,7 @@ struct KInteropReturnBuffer { KInt elementSize = 1; template - static KInteropReturnBuffer from(std::vector const& v, decltype(dispose) dispose = nullptr) + static KInteropReturnBuffer from(std::vector const& v, decltype(dispose) dispose) { return { (KInt)v.size(), (KNativePointer)v.data(), dispose, (KInt)sizeof(T) }; } -- Gitee