napi backend: JSMethodCallback runs napi calls on the invoking thread — JS IMPs crash when ObjC calls them on foreign threads

Đang mở
#108 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
18/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
c, cpp, macos, nodejs, objective-c
Lĩnh vực
backend

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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/runtimes main (verified identical at 5b697b39)
  • Generic napi backend, TARGET_PLATFORM=macos, arm64; the same ffi/napi code path ships in the iOS napi runtime.
Ngôn ngữ chính
C++
Star
27
Fork
4
Merge trung bình
5 ngày 11 giờ
Pull request đã merge (30 ngày)
12

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của NativeScript/runtimes

Tất cả issue của NativeScript/runtimes

Issue tương tự

Thêm issue về C++

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.