Skip to content

Commit 55a1f20

Browse files
committed
refactor(ffi): isolate direct engine backends
1 parent 096e03a commit 55a1f20

53 files changed

Lines changed: 713 additions & 79 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ jobs:
2020
- name: Install Dependencies
2121
run: npm install
2222

23+
- name: Check FFI backend boundaries
24+
run: npm run check:ffi-boundaries
25+
2326
- name: Download V8
2427
run: ./scripts/download_v8.sh
2528

NativeScript/CMakeLists.txt

Lines changed: 122 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS}")
2020
# Arguments
2121
set(TARGET_PLATFORM "macos" CACHE STRING "Target platform for the Objective-C bridge")
2222
set(TARGET_ENGINE "v8" CACHE STRING "Target JS engine for the NativeScript runtime")
23+
set(NS_FFI_BACKEND "auto" CACHE STRING "FFI backend: auto, napi, or direct")
2324
set(NS_GSD_BACKEND "auto" CACHE STRING "Generated signature dispatch backend: auto, v8, jsc, quickjs, hermes, napi, or none")
2425
set(METADATA_SIZE 0 CACHE STRING "Size of embedded metadata in bytes")
2526
set(BUILD_CLI_BINARY OFF CACHE BOOL "Build the NativeScript CLI binary")
2627
set(BUILD_MACOS_NODE_API OFF CACHE BOOL "Build the NativeScript macOS Node API dylib")
28+
set_property(CACHE NS_FFI_BACKEND PROPERTY STRINGS auto napi direct)
2729
set_property(CACHE NS_GSD_BACKEND PROPERTY STRINGS auto v8 jsc quickjs hermes napi none)
2830

2931
if (BUILD_MACOS_NODE_API)
@@ -134,8 +136,45 @@ message(STATUS "TARGET_ENGINE = ${TARGET_ENGINE}")
134136
message(STATUS "ENABLE_JS_RUNTIME = ${ENABLE_JS_RUNTIME}")
135137
message(STATUS "GENERIC_NAPI = ${GENERIC_NAPI}")
136138

139+
if(NS_FFI_BACKEND STREQUAL "auto")
140+
if(GENERIC_NAPI OR TARGET_ENGINE_NONE)
141+
set(NS_EFFECTIVE_FFI_BACKEND "napi")
142+
elseif(TARGET_ENGINE_HERMES)
143+
set(NS_EFFECTIVE_FFI_BACKEND "direct")
144+
else()
145+
set(NS_EFFECTIVE_FFI_BACKEND "napi")
146+
endif()
147+
elseif(NS_FFI_BACKEND STREQUAL "napi" OR NS_FFI_BACKEND STREQUAL "direct")
148+
set(NS_EFFECTIVE_FFI_BACKEND "${NS_FFI_BACKEND}")
149+
else()
150+
message(FATAL_ERROR "Unknown NS_FFI_BACKEND: ${NS_FFI_BACKEND}")
151+
endif()
152+
153+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "direct" AND
154+
(GENERIC_NAPI OR TARGET_ENGINE_NONE OR BUILD_MACOS_NODE_API))
155+
message(FATAL_ERROR "NS_FFI_BACKEND=direct requires an embedded JS runtime build")
156+
endif()
157+
158+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "direct" AND NOT TARGET_ENGINE_HERMES)
159+
message(FATAL_ERROR
160+
"NS_FFI_BACKEND=direct is currently implemented for TARGET_ENGINE=hermes. "
161+
"Use NS_FFI_BACKEND=napi for the pure Node-API FFI path until the direct "
162+
"entrypoint for this engine lands.")
163+
endif()
164+
165+
message(STATUS "NS_FFI_BACKEND = ${NS_FFI_BACKEND} (${NS_EFFECTIVE_FFI_BACKEND})")
166+
167+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "direct" AND
168+
NOT (NS_GSD_BACKEND STREQUAL "auto" OR NS_GSD_BACKEND STREQUAL "none"))
169+
message(FATAL_ERROR
170+
"NS_GSD_BACKEND is only used by the Node-API FFI backend. "
171+
"Use NS_GSD_BACKEND=auto or none with NS_FFI_BACKEND=direct.")
172+
endif()
173+
137174
if(NS_GSD_BACKEND STREQUAL "auto")
138-
if(TARGET_ENGINE_V8)
175+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "direct")
176+
set(NS_EFFECTIVE_GSD_BACKEND "none")
177+
elseif(TARGET_ENGINE_V8)
139178
set(NS_EFFECTIVE_GSD_BACKEND "v8")
140179
elseif(TARGET_ENGINE_JSC)
141180
set(NS_EFFECTIVE_GSD_BACKEND "jsc")
@@ -176,15 +215,22 @@ message(STATUS "NS_GSD_BACKEND = ${NS_GSD_BACKEND} (${NS_EFFECTIVE_GSD_BACKEND})
176215
include_directories(
177216
./
178217
ffi/shared
179-
ffi/v8
180-
ffi/hermes
181-
ffi/jsc
182-
ffi/quickjs
218+
ffi/hermes/jsi
183219
../metadata-generator/include
184220
napi/common
185221
libffi/${LIBFFI_BUILD}/include
186222
)
187223

224+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "napi")
225+
include_directories(
226+
ffi/napi/engine/shared
227+
ffi/napi/engine/v8
228+
ffi/napi/engine/hermes
229+
ffi/napi/engine/jsc
230+
ffi/napi/engine/quickjs
231+
)
232+
endif()
233+
188234
set(FFI_SHARED_SOURCE_FILES
189235
ffi/shared/Tasks.cpp
190236
)
@@ -210,42 +256,51 @@ set(FFI_NAPI_SOURCE_FILES
210256
ffi/napi/Interop.mm
211257
ffi/napi/InlineFunctions.mm
212258
ffi/napi/ClassBuilder.mm
213-
ffi/napi/NativeScriptException.mm
214259
)
215260

216-
set(FFI_DIRECT_SOURCE_FILES
217-
ffi/shared/EngineDirectCall.mm
261+
set(FFI_NAPI_ENGINE_SOURCE_FILES
262+
ffi/napi/engine/shared/EngineDirectCall.mm
218263
)
219264

220-
set(FFI_V8_SOURCE_FILES
221-
ffi/v8/V8FastConversion.mm
222-
ffi/v8/V8FastNativeApi.mm
223-
ffi/v8/V8FastNativeWrapper.mm
265+
set(FFI_NAPI_V8_SOURCE_FILES
266+
ffi/napi/engine/v8/V8FastConversion.mm
267+
ffi/napi/engine/v8/V8FastNativeApi.mm
268+
ffi/napi/engine/v8/V8FastNativeWrapper.mm
224269
)
225270

226-
set(FFI_HERMES_SOURCE_FILES
271+
set(FFI_HERMES_DIRECT_SOURCE_FILES
227272
ffi/hermes/jsi/NativeApiJsi.mm
228-
ffi/hermes/HermesFastConversion.mm
229-
ffi/hermes/HermesFastNativeApi.mm
230273
)
231274

232-
set(FFI_QUICKJS_SOURCE_FILES
233-
ffi/quickjs/QuickJSFastConversion.mm
234-
ffi/quickjs/QuickJSFastNativeApi.mm
235-
ffi/quickjs/QuickJSFastReturn.mm
275+
set(FFI_NAPI_HERMES_SOURCE_FILES
276+
ffi/napi/engine/hermes/HermesFastConversion.mm
277+
ffi/napi/engine/hermes/HermesFastNativeApi.mm
236278
)
237279

238-
set(FFI_JSC_SOURCE_FILES
239-
ffi/jsc/JSCFastConversion.mm
240-
ffi/jsc/JSCFastNativeApi.mm
280+
set(FFI_NAPI_QUICKJS_SOURCE_FILES
281+
ffi/napi/engine/quickjs/QuickJSFastConversion.mm
282+
ffi/napi/engine/quickjs/QuickJSFastNativeApi.mm
283+
ffi/napi/engine/quickjs/QuickJSFastReturn.mm
284+
)
285+
286+
set(FFI_NAPI_JSC_SOURCE_FILES
287+
ffi/napi/engine/jsc/JSCFastConversion.mm
288+
ffi/napi/engine/jsc/JSCFastNativeApi.mm
241289
)
242290

243291
set(SOURCE_FILES
244292
${FFI_SHARED_SOURCE_FILES}
245-
${FFI_NAPI_SOURCE_FILES}
246-
${FFI_DIRECT_SOURCE_FILES}
293+
runtime/NativeScriptException.mm
247294
)
248295

296+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "napi")
297+
set(SOURCE_FILES
298+
${SOURCE_FILES}
299+
${FFI_NAPI_SOURCE_FILES}
300+
${FFI_NAPI_ENGINE_SOURCE_FILES}
301+
)
302+
endif()
303+
249304
if(ENABLE_JS_RUNTIME)
250305
set(SOURCE_FILES
251306
${SOURCE_FILES}
@@ -288,9 +343,15 @@ if(ENABLE_JS_RUNTIME)
288343
napi/v8/v8-module-loader.cpp
289344
napi/v8/jsr.cpp
290345
napi/v8/SimpleAllocator.cpp
291-
${FFI_V8_SOURCE_FILES}
292346
)
293347

348+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "napi")
349+
set(SOURCE_FILES
350+
${SOURCE_FILES}
351+
${FFI_NAPI_V8_SOURCE_FILES}
352+
)
353+
endif()
354+
294355
elseif(TARGET_ENGINE_HERMES)
295356
set(HERMES_HEADERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../Frameworks/hermes-headers")
296357

@@ -313,9 +374,20 @@ if(ENABLE_JS_RUNTIME)
313374
set(SOURCE_FILES
314375
${SOURCE_FILES}
315376
napi/hermes/jsr.cpp
316-
${FFI_HERMES_SOURCE_FILES}
317377
)
318378

379+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "napi")
380+
set(SOURCE_FILES
381+
${SOURCE_FILES}
382+
${FFI_NAPI_HERMES_SOURCE_FILES}
383+
)
384+
else()
385+
set(SOURCE_FILES
386+
${SOURCE_FILES}
387+
${FFI_HERMES_DIRECT_SOURCE_FILES}
388+
)
389+
endif()
390+
319391
elseif(TARGET_ENGINE_QUICKJS)
320392
set(MI_BUILD_OBJECT OFF)
321393
set(MI_OVERRIDE OFF)
@@ -346,9 +418,15 @@ if(ENABLE_JS_RUNTIME)
346418
# napi
347419
napi/quickjs/quickjs-api.c
348420
napi/quickjs/jsr.cpp
349-
${FFI_QUICKJS_SOURCE_FILES}
350421
)
351422

423+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "napi")
424+
set(SOURCE_FILES
425+
${SOURCE_FILES}
426+
${FFI_NAPI_QUICKJS_SOURCE_FILES}
427+
)
428+
endif()
429+
352430
elseif(TARGET_ENGINE_JSC)
353431
include_directories(
354432
napi/jsc
@@ -359,8 +437,14 @@ if(ENABLE_JS_RUNTIME)
359437
set(SOURCE_FILES ${SOURCE_FILES}
360438
napi/jsc/jsc-api.cpp
361439
napi/jsc/jsr.cpp
362-
${FFI_JSC_SOURCE_FILES}
363440
)
441+
442+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "napi")
443+
set(SOURCE_FILES
444+
${SOURCE_FILES}
445+
${FFI_NAPI_JSC_SOURCE_FILES}
446+
)
447+
endif()
364448
endif()
365449
else()
366450
include_directories(
@@ -453,6 +537,8 @@ set(NS_GSD_BACKEND_JSC_VALUE 0)
453537
set(NS_GSD_BACKEND_QUICKJS_VALUE 0)
454538
set(NS_GSD_BACKEND_HERMES_VALUE 0)
455539
set(NS_GSD_BACKEND_NAPI_VALUE 0)
540+
set(NS_FFI_BACKEND_DIRECT_VALUE 0)
541+
set(NS_FFI_BACKEND_NAPI_VALUE 0)
456542

457543
if(NS_EFFECTIVE_GSD_BACKEND STREQUAL "v8")
458544
set(NS_GSD_BACKEND_V8_VALUE 1)
@@ -466,12 +552,20 @@ elseif(NS_EFFECTIVE_GSD_BACKEND STREQUAL "napi")
466552
set(NS_GSD_BACKEND_NAPI_VALUE 1)
467553
endif()
468554

555+
if(NS_EFFECTIVE_FFI_BACKEND STREQUAL "direct")
556+
set(NS_FFI_BACKEND_DIRECT_VALUE 1)
557+
elseif(NS_EFFECTIVE_FFI_BACKEND STREQUAL "napi")
558+
set(NS_FFI_BACKEND_NAPI_VALUE 1)
559+
endif()
560+
469561
target_compile_definitions(${NAME} PRIVATE
470562
NS_GSD_BACKEND_V8=${NS_GSD_BACKEND_V8_VALUE}
471563
NS_GSD_BACKEND_JSC=${NS_GSD_BACKEND_JSC_VALUE}
472564
NS_GSD_BACKEND_QUICKJS=${NS_GSD_BACKEND_QUICKJS_VALUE}
473565
NS_GSD_BACKEND_HERMES=${NS_GSD_BACKEND_HERMES_VALUE}
474566
NS_GSD_BACKEND_NAPI=${NS_GSD_BACKEND_NAPI_VALUE}
567+
NS_FFI_BACKEND_DIRECT=${NS_FFI_BACKEND_DIRECT_VALUE}
568+
NS_FFI_BACKEND_NAPI=${NS_FFI_BACKEND_NAPI_VALUE}
475569
)
476570

477571
set(FRAMEWORK_VERSION_VALUE "${VERSION}")

NativeScript/cli/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <iostream>
66
#include <string>
77

8-
#include "ffi/napi/NativeScriptException.h"
8+
#include "runtime/NativeScriptException.h"
99
#include "runtime/Bundle.h"
1010
#include "runtime/Runtime.h"
1111
#include "runtime/RuntimeConfig.h"

NativeScript/ffi/hermes/jsi/NativeApiJsi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct NativeApiJsiConfig {
2121
const void* metadataPtr = nullptr;
2222
const char* globalName = "__nativeScriptNativeApi";
2323
std::shared_ptr<NativeApiJsiScheduler> scheduler = nullptr;
24+
bool installGlobalSymbols = false;
2425
};
2526

2627
facebook::jsi::Object CreateNativeApiJSI(

0 commit comments

Comments
 (0)