From 95c8bec912db6b68de6a26d226d6c52236cb483a Mon Sep 17 00:00:00 2001 From: Trivikram Kamat <16024985+trivikr@users.noreply.github.com> Date: Tue, 4 Aug 2026 03:54:39 +0000 Subject: [PATCH] ffi: remove dead null check in callback arguments InvokeCallback tested `args[i] == nullptr` and mapped the argument to JS `null`. `args` is libffi's avalue array, and libffi always points each slot at its own storage for the corresponding argument, so the slot pointers are never null and the branch never ran. The check also read as a guarantee the code does not provide: a NULL pointer argument surfaces as the BigInt `0n`, because ToJSArgument converts `ffi_type_pointer` values with BigInt::NewFromUnsigned. Drop the branch rather than reimplementing it in ToJSArgument, which would change behavior by making pointer parameters arrive as either a BigInt or `null`. Signed-off-by: Trivikram Kamat <16024985+trivikr@users.noreply.github.com> Assisted-by: claude:opus-5 --- src/node_ffi.cc | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/node_ffi.cc b/src/node_ffi.cc index 1e1fc5654591..28d7034286c6 100644 --- a/src/node_ffi.cc +++ b/src/node_ffi.cc @@ -32,7 +32,6 @@ using v8::Local; using v8::LocalVector; using v8::Maybe; using v8::MaybeLocal; -using v8::Null; using v8::Object; using v8::PropertyAttribute; using v8::ReadOnly; @@ -710,13 +709,11 @@ void DynamicLibrary::InvokeCallback(ffi_cif* cif, size_t expected_args = cb->args.size(); LocalVector callback_args(isolate, expected_args); + // libffi always points `args[i]` at its own storage for the value of + // argument `i`, so the slot pointers themselves are never null. A NULL + // pointer argument surfaces as the BigInt `0n` via ToJSArgument. for (size_t i = 0; i < expected_args; i++) { - if (args[i] == nullptr) { - callback_args[i] = Null(isolate); - continue; - } else { - callback_args[i] = ToJSArgument(isolate, cb->args[i], args[i]); - } + callback_args[i] = ToJSArgument(isolate, cb->args[i], args[i]); } TryCatch try_catch(isolate);