Skip to content

Commit 91ea884

Browse files
committed
Enhance NativeScript FFI with Generated Dispatch Control and Fast Conversion
- Introduced environment variable control for generated dispatch (GSD) functionality in SignatureDispatch.h, allowing users to enable or disable GSD at runtime. - Implemented fast-path conversion for known metadata kinds in TypeConv.h and TypeConv.mm, optimizing argument conversion for NAPI. - Updated benchmark tests to alternate between GSD and non-GSD runs, providing a more comprehensive performance analysis. - Added a glass effect view to the view controller app, enhancing the UI experience. - Improved error handling in the metadata generation script to provide clearer feedback on failures.
1 parent 0cd51d8 commit 91ea884

File tree

9 files changed

+670
-106
lines changed

9 files changed

+670
-106
lines changed

NativeScript/ffi/CFunction.mm

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "ffi/NativeScriptException.h"
66
#include "ffi/Tasks.h"
77
#include <cstring>
8+
#include <vector>
89
#ifdef ENABLE_JS_RUNTIME
910
#include "jsr.h"
1011
#endif
@@ -99,8 +100,36 @@ inline void ensureCFunctionDispatchLookup(CFunction* function, Cif* cif) {
99100
MDFunctionFlag functionFlags = bridgeState->metadata->getFunctionFlag(
100101
offset + sizeof(MDSectionOffset) * 2);
101102

102-
size_t argc = cif->argc;
103-
napi_get_cb_info(env, cbinfo, &argc, cif->argv, nullptr, nullptr);
103+
const napi_value* invocationArgs = nullptr;
104+
std::vector<napi_value> dynamicArgs;
105+
std::vector<napi_value> paddedArgs;
106+
napi_value stackArgs[16];
107+
if (cif->argc > 0) {
108+
size_t actualArgc = 16;
109+
napi_get_cb_info(env, cbinfo, &actualArgc, stackArgs, nullptr, nullptr);
110+
111+
const napi_value* callArgs = stackArgs;
112+
if (actualArgc > 16) {
113+
dynamicArgs.resize(actualArgc);
114+
size_t retryArgc = actualArgc;
115+
napi_get_cb_info(env, cbinfo, &retryArgc, dynamicArgs.data(), nullptr, nullptr);
116+
dynamicArgs.resize(retryArgc);
117+
actualArgc = retryArgc;
118+
callArgs = dynamicArgs.data();
119+
}
120+
121+
invocationArgs = callArgs;
122+
if (actualArgc != cif->argc) {
123+
napi_value jsUndefined = nullptr;
124+
napi_get_undefined(env, &jsUndefined);
125+
paddedArgs.assign(cif->argc, jsUndefined);
126+
size_t copyArgc = actualArgc < cif->argc ? actualArgc : cif->argc;
127+
if (copyArgc > 0) {
128+
memcpy(paddedArgs.data(), callArgs, copyArgc * sizeof(napi_value));
129+
}
130+
invocationArgs = paddedArgs.data();
131+
}
132+
}
104133

105134
uint32_t toJSFlags = kCStringAsReference;
106135
if ((functionFlags & mdFunctionReturnOwned) != 0) {
@@ -112,7 +141,7 @@ inline void ensureCFunctionDispatchLookup(CFunction* function, Cif* cif) {
112141

113142
if (napiInvoker != nullptr && !isMainEntrypoint) {
114143
@try {
115-
if (!napiInvoker(env, cif, func->fnptr, cif->argv, cif->rvalue)) {
144+
if (!napiInvoker(env, cif, func->fnptr, invocationArgs, cif->rvalue)) {
116145
return nullptr;
117146
}
118147
} @catch (NSException* exception) {
@@ -136,7 +165,8 @@ inline void ensureCFunctionDispatchLookup(CFunction* function, Cif* cif) {
136165
for (unsigned int i = 0; i < cif->argc; i++) {
137166
shouldFree[i] = false;
138167
avalues[i] = cif->avalues[i];
139-
cif->argTypes[i]->toNative(env, cif->argv[i], avalues[i], &shouldFree[i], &shouldFreeAny);
168+
cif->argTypes[i]->toNative(env, invocationArgs[i], avalues[i], &shouldFree[i],
169+
&shouldFreeAny);
140170
}
141171
}
142172

0 commit comments

Comments
 (0)