napi backend: JSMethodCallback runs napi calls on the invoking thread — JS IMPs crash when ObjC calls them on foreign threads
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 18/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- c, cpp, macos, nodejs, objective-c
- 领域
- backend
调研方向
Start in NativeScript/ffi/napi/Closure.mm and compare JSMethodCallback with JSBlockCallback, which already checks closure->jsThreadId and marshals foreign-thread calls onto the JS run loop or threadsafe function. The repro needs a macOS arm64 build with -DNS_FFI_BACKEND=napi, so the first check is whether the spawned-thread ping call crashes in ObjCBridgeState::getObject. Done means that call either blocks until the JS thread returns 42 or fails with a clear error, without a SIGSEGV.
由索引模型根据 Issue 内容生成。
描述
Summary
JSMethodCallback (NativeScript/ffi/napi/Closure.mm) performs napi calls — ObjCBridgeState::getObject, napi_get_named_property, napi_call_function — directly on whatever thread invoked the ffi closure, with no thread check. When a JS-backed ObjC method IMP is invoked on a non-JS thread, the bridge calls into the JS engine off-thread and crashes.
JSBlockCallback in the same file does check the calling thread (currentThreadId == closure->jsThreadId) and marshals foreign-thread invocations onto the JS side (napi_call_threadsafe_function for generic-napi builds; CFRunLoopPerformBlock(jsRunLoop, kCFRunLoopCommonModes) for embedded-runtime builds). Method IMPs get no equivalent handling. JSFunctionCallback (C-function-pointer callbacks) has the same unguarded shape.
Concrete hit in the wild: NSPrintOperation with canSpawnSeparateThread=YES invokes the operation's didRunSelector on the spawned print thread — a JS didRun IMP there crashes inside ObjCBridgeState::getObject → tryResolveBridgedClassConstructor (SIGSEGV).
Reproduction
macOS arm64, NativeScript.framework built at 5b697b39 with -DTARGET_ENGINE=none -DNS_FFI_BACKEND=napi (code identical on main), env owned by the main thread:
var Delegate = NSObject.extend(
{ ping: function () { return 42; } },
{ exposedMethods: { ping: { returns: interop.types.int32 } } }
);
var obj = Delegate.new();
obj.respondsToSelector(NSSelectorFromString("ping")); // true
NSThread.detachNewThreadSelectorToTargetWithObject(NSSelectorFromString("ping"), obj, null);
→ EXC_BAD_ACCESS (SIGSEGV) on the spawned thread:
nativescript::ObjCBridgeState::tryResolveBridgedClassConstructor(napi_env*, napi_value*, objc_class**)
nativescript::ObjCBridgeState::getObject(napi_env*, objc_object*, napi_value*, ObjectOwnership)
nativescript::JSMethodCallback(ffi_cif*, void*, void**, void*)
ffi_closure_SYSV_inner
__NSThread__start__
_pthread_start
Expected
Foreign-thread IMP/closure invocations should be marshalled to the JS thread the way JSBlockCallback already does — the caller blocks until the return value is produced, which suits synchronous IMPs — or fail deterministically with a clear error rather than corrupting engine state. As it stands, delegate methods that Apple legitimately invokes off the main thread (spawned NSPrintOperation threads, some AVFoundation/UN delegate calls on background queues) cannot be implemented in JS at all, and a missed-thread dispatch takes down the whole process.
Environment
NativeScript/runtimesmain(verified identical at5b697b39)- Generic napi backend,
TARGET_PLATFORM=macos, arm64; the sameffi/napicode path ships in the iOS napi runtime.
- 主要语言
- C++
- 星标
- 27
- 派生
- 4
- 平均合并
- 5 天 11 小时
- 30 天内合并 PR
- 12
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
NativeScript/runtimes 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 30/100
NativeScript/runtimes#111 ·
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 22/100
NativeScript/runtimes#110 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 32/100
NativeScript/runtimes#109 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 40/100
NativeScript/runtimes#107 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 42/100
NativeScript/runtimes#106 ·
维护者通常 1 天内回复
查看 NativeScript/runtimes 的全部 Issue
相似的 Issue
-
Code: Performance
难度 1/5 1 小时以内 新手友好度 88/100
CrimsonCrossBunker/Cataclysm-Cleanwater-Bomb#1167 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
meshcore-dev/MeshCore#3760 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 88/100
deepseek-ai/DeepGEMM-Ascend#29 ·
维护者通常 1 天内回复
-
area:lattice bug
难度 1/5 1-3 小时 新手友好度 78/100
维护者通常 3 天内回复