Skip to content

Commit 8d87576

Browse files
committed
fixup! src,lib: initial ffi implementation
1 parent 1758ca1 commit 8d87576

8 files changed

Lines changed: 75 additions & 12 deletions

File tree

doc/api/cli.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ following permissions are restricted:
589589
\[`--allow-fs-read`]\[],\[`allow-fs-write`]\[] flags
590590
* Child Process - manageable through \[`--allow-child-process`]\[] flag
591591
* Worker Threads - manageable through \[`--allow-worker`]\[] flag
592+
* FFI - manageable through \[`--allow-ffo`]\[] flag
592593

593594
### `--experimental-policy`
594595

@@ -2088,6 +2089,7 @@ Node.js options that are allowed are:
20882089
<!-- node-options-node start -->
20892090

20902091
* `--allow-child-process`
2092+
* `--allow-ffi`
20912093
* `--allow-fs-read`
20922094
* `--allow-fs-write`
20932095
* `--allow-worker`

lib/ffi.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const {
2828
ERR_FFI_SYMBOL_NOT_FOUND,
2929
ERR_FFI_UNSUPPORTED_TYPE,
3030
ERR_INVALID_ARG_TYPE,
31-
} = require('internal/errors');
31+
} = require('internal/errors').codes;
3232

3333
// [ sigPtr | fnPtr | rvalue | avaluesPointers ]
3434
const callBuffer = new ArrayBuffer(4096);

src/node_ffi.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ void GetBufferPointer(const FunctionCallbackInfo<Value>& args) {
7878
THROW_IF_INSUFFICIENT_PERMISSIONS(
7979
env, permission::PermissionScope::kFfi, "");
8080

81-
CHECK(args[0]->IsArrayBuffer());
81+
CHECK(args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer());
8282
void* data = args[0].As<ArrayBuffer>()->Data();
8383

8484
ReturnBigInt(args.GetIsolate(), data);

test/ffi/types/test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,15 @@ for (const type of basicTypes) {
7171

7272
const ptrFnName = `test_add_ptr_${type.replace(/ /g, '_')}`;
7373
const ptrType = type + '*';
74-
const ptrFn = ffi.getNativeFunction(shared, ptrFnName, 'void', [ptrType, ptrType, ptrType]);
74+
assert.strictEqual(ffi.sizeof(ptrType), ffi.sizeof('void *'));
75+
const ptrFn = ffi.getNativeFunction(shared, ptrFnName, ptrType, [ptrType, ptrType, ptrType]);
7576
const size = ffi.sizeof(type);
7677
const buf = Buffer.alloc(size * 3);
7778
const retPtr = ffi.getBufferPointer(buf);
7879
const rwName = getRWName(type, size);
7980
buf[`write${rwName}`](three, size);
8081
buf[`write${rwName}`](four, 2 * size);
81-
ptrFn(retPtr, retPtr + BigInt(size), retPtr + BigInt(2 * size));
82+
const ret = ptrFn(retPtr, retPtr + BigInt(size), retPtr + BigInt(2 * size));
8283
assert.strictEqual(buf[`read${rwName}`](0), seven);
84+
assert.strictEqual(ret, retPtr);
8385
}

test/ffi/types/types.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include "stdint.h"
22
#define test(typ, name) typ test_add_##name(typ a, typ b) { return a + b; } \
3-
void test_add_ptr_##name(typ * ret, typ * a, typ * b) { *ret = *a + *b; }
3+
typ * test_add_ptr_##name(typ * ret, typ * a, typ * b) { \
4+
*ret = *a + *b; \
5+
return ret; \
6+
}
47
test(char, char);
58
test(signed char, signed_char);
69
test(unsigned char, unsigned_char);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const ffi = require('node:ffi');
5+
6+
function assertIsPointer(thing) {
7+
assert.strictEqual(typeof thing, 'bigint');
8+
assert.ok(thing > 0n);
9+
}
10+
11+
const buffer = Buffer.alloc(8);
12+
const arrayBufferViews = common.getArrayBufferViews(buffer);
13+
14+
assertIsPointer(ffi.getBufferPointer(buffer));
15+
for (const view of arrayBufferViews) {
16+
assertIsPointer(ffi.getBufferPointer(view));
17+
}
18+
assertIsPointer(ffi.getBufferPointer(new DataView(new ArrayBuffer(8))));
19+
assertIsPointer(ffi.getBufferPointer(new ArrayBuffer(8)));
20+
assertIsPointer(ffi.getBufferPointer(new SharedArrayBuffer(8)));
21+
22+
[
23+
7,
24+
'7',
25+
{},
26+
() => {},
27+
null,
28+
undefined,
29+
Symbol('7'),
30+
true,
31+
].forEach((value) => {
32+
assert.throws(() => {
33+
ffi.getBufferPointer(value);
34+
}, { code: 'ERR_INVALID_ARG_TYPE' });
35+
});
36+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const ffi = require('node:ffi');
5+
6+
const getpid = ffi.getNativeFunction(null, 'uv_os_getpid', 'int', []);
7+
assert.strictEqual(process.pid, getpid());
8+
9+
assert.throws(() => {
10+
ffi.getNativeFunction('strongbad', 'uv_os_getpid', 'int', []);
11+
}, { code: 'ERR_FFI_LIBRARY_LOAD_FAILED' });
12+
13+
assert.throws(() => {
14+
ffi.getNativeFunction(12345, 'uv_os_getpid', 'int', []);
15+
}, { code: 'ERR_INVALID_ARG_TYPE' });
16+
17+
assert.throws(() => {
18+
ffi.getNativeFunction(null, 'strongbad', 'int', []);
19+
}, { code: 'ERR_FFI_SYMBOL_NOT_FOUND' });
20+
21+
assert.throws(() => {
22+
ffi.getNativeFunction(null, 'uv_os_getpid', 'strongbad', []);
23+
}, { code: 'ERR_FFI_UNSUPPORTED_TYPE' });
24+
25+
assert.throws(() => {
26+
ffi.getNativeFunction(null, 'uv_os_getpid', 'int', ['strongbad']);
27+
}, { code: 'ERR_FFI_UNSUPPORTED_TYPE' });

test/parallel/test-ffi-self.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)