Skip to content

Commit 079591f

Browse files
committed
ffi: combine fast integer validation and conversion
Validate and convert integer arguments in a single helper to avoid repeated type metadata lookups and conversion checks. Handle safe integer Number inputs for 64-bit arguments separately, while preserving the existing type and range checks for BigInt inputs. Return other argument types unchanged for subsequent pointer conversion. Signed-off-by: HoonDongKang <d159123@naver.com> Assisted-by: Codex:Astra-medium
1 parent 3799107 commit 079591f

1 file changed

Lines changed: 14 additions & 26 deletions

File tree

‎lib/internal/ffi/fast-api.js‎

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -85,34 +85,24 @@ function throwFFIArgCountError(expected, actual) {
8585
`Invalid argument count: expected ${expected}, got ${actual}`);
8686
}
8787

88-
function validateFastIntegerArg(type, value, index) {
88+
function validateAndConvertFastIntegerArg(type, value, index) {
8989
const info = fastIntegerTypeInfo[type];
90-
if (info === undefined) return;
90+
if (info === undefined) return value;
9191

92-
let valid;
93-
94-
if (info.kind === 'number') {
95-
valid = typeof value === 'number' && NumberIsInteger(value) &&
96-
value >= info.min && value <= info.max;
97-
} else if (typeof value === 'bigint') {
98-
valid = value >= info.min && value <= info.max;
99-
} else {
100-
valid = typeof value === 'number' && NumberIsSafeInteger(value) &&
101-
(info.min < 0n || value >= 0);
92+
// The native Fast API expects BigInt for 64-bit integer arguments.
93+
if (info.kind === 'bigint' && typeof value === 'number') {
94+
if (!NumberIsSafeInteger(value) || (info.min === 0n && value < 0)) {
95+
throwFFIArgError(`Argument ${index} must be ${info.label}`);
96+
}
97+
return BigInt(value);
10298
}
10399

104-
if (!valid) {
100+
const validType = info.kind === 'number' ?
101+
typeof value === 'number' && NumberIsInteger(value) :
102+
typeof value === 'bigint';
103+
if (!validType || value < info.min || value > info.max) {
105104
throwFFIArgError(`Argument ${index} must be ${info.label}`);
106105
}
107-
}
108-
109-
function convertFastIntegerArg(type, value) {
110-
const info = fastIntegerTypeInfo[type];
111-
if (info !== undefined &&
112-
info.kind === 'bigint' &&
113-
typeof value === 'number') {
114-
return BigInt(value);
115-
}
116106

117107
return value;
118108
}
@@ -246,8 +236,7 @@ function getFastArgumentIndexes(argumentsTypes) {
246236
}
247237

248238
function convertFastArg(type, value, stringState, index) {
249-
validateFastIntegerArg(type, value, index);
250-
value = convertFastIntegerArg(type, value);
239+
value = validateAndConvertFastIntegerArg(type, value, index);
251240

252241
return needsPointerConversion(type) ?
253242
convertPointerArg(type, value, stringState, index) : value;
@@ -320,9 +309,8 @@ function wrapWithRawPointerConversions(rawFn, argumentTypes, owner) {
320309
if (arguments.length !== 1) {
321310
throwFFIArgCountError(1, arguments.length);
322311
}
323-
validateFastIntegerArg(t0, a0, 0);
312+
let arg = validateAndConvertFastIntegerArg(t0, a0, 0);
324313
validateFastPointerArg(t0, a0, 0);
325-
let arg = convertFastIntegerArg(t0, a0);
326314
if (needsNullPointerConversion(t0) &&
327315
(arg === null || arg === undefined)) {
328316
arg = 0n;

0 commit comments

Comments
 (0)