Skip to content

ffi: int32/uint32 arguments reject -0 until the call is optimized #67033

Open

Description

@trivikr

Version

main

Platform

macOS

Subsystem

ffi

What steps will reproduce the bug?

import { dlopen } from 'node:ffi';

const { functions: { abs } } = dlopen(null, {
  abs: { arguments: ['i32'], return: 'i32' },
});

function call(x) {
  try { return abs(x); } catch (e) { return `${e.code}: ${e.message}`; }
}

console.log(call(-0));

function hot(x) { return call(x); }
%PrepareFunctionForOptimization(hot);
for (let i = 0; i < 1000; i++) hot(i);
%OptimizeFunctionOnNextCall(hot);
hot(1);
console.log(hot(-0));

Run it with

node --no-warnings --allow-natives-syntax repro.mjs

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

0
0

-0 is an integer (Number.isInteger(-0) === true) and is within range for both types. Every other integer width (int8, uint8, int16, uint16, int64, uint64) accepts it, and so do the optimized Fast API and SharedBuffer paths.

What do you see instead?

ERR_INVALID_ARG_VALUE: Argument 0 must be an int32
0

uint32 behaves the same way ("Argument 0 must be a uint32").

Additional information

No response

Activity

  1. self-assigned this
    on Oct 26, 2026
  2. added
    ffiIssues and PRs related to experimental Foreign Function Interface support.
    on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

ffiIssues and PRs related to experimental Foreign Function Interface support.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions