Version
main
Platform
Subsystem
ffi
What steps will reproduce the bug?
repro.c
#include <stdint.h>
#include <stdio.h>
int32_t add_i32(int32_t a, int32_t b) {
fprintf(stderr, "native add_i32 invoked: %d + %d\n", a, b);
return a + b;
}
double multiply_f64(double a, double b) {
return a * b;
}
repro.js
import { dlopen, suffix } from 'node:ffi';
const { functions } = dlopen(`./repro.${suffix}`, {
add_i32: {
arguments: ['i32', 'i32'],
return: 'i32',
},
multiply_f64: {
arguments: ['f64', 'f64'],
return: 'f64',
},
});
const { add_i32, multiply_f64 } = functions;
console.log(
'add_i32 has own prototype:',
Object.hasOwn(add_i32, 'prototype'),
);
try {
Reflect.construct(add_i32, [20, 22]);
console.log('Reflect.construct(add_i32): succeeded');
} catch (error) {
console.log(
'Reflect.construct(add_i32):',
`${error.name}: ${error.message}`,
);
}
console.log(
'multiply_f64 has own prototype:',
Object.hasOwn(multiply_f64, 'prototype'),
);
try {
Reflect.construct(multiply_f64, [6, 7]);
console.log('Reflect.construct(multiply_f64): succeeded');
} catch (error) {
console.log(
'Reflect.construct(multiply_f64):',
`${error.name}: ${error.message}`,
);
}
Commands to run:
$ cc -dynamiclib -o repro.dylib repro.c
$ node --no-warnings --experimental-ffi repro.js
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
Wrapped functions should preserve the native function’s non-constructible behavior: no own .prototype, and Reflect.construct() should throw a TypeError without invoking native code.
What do you see instead?
add_i32 has own prototype: true
native add_i32 invoked: 20 + 22
Reflect.construct(add_i32): succeeded
multiply_f64 has own prototype: false
Reflect.construct(multiply_f64): TypeError: function multiply_f64() { [native code] } is not a constructor
Wrapped native functions such as add_i32 gain an own .prototype, and Reflect.construct(add_i32, [20, 22]) succeeds and invokes native code.
Additional information
No response
Version
main
Platform
Subsystem
ffi
What steps will reproduce the bug?
repro.crepro.jsCommands to run:
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
Wrapped functions should preserve the native function’s non-constructible behavior: no own
.prototype, andReflect.construct()should throw aTypeErrorwithout invoking native code.What do you see instead?
Wrapped native functions such as
add_i32gain an own.prototype, andReflect.construct(add_i32, [20, 22])succeeds and invokes native code.Additional information
No response