Skip to content

Commit b7bff3d

Browse files
committed
fix: Various improvements. (#6)
* src,deps,test: various improvements Signed-off-by: Paolo Insogna <paolo@cowtech.it> * deps,test: fixed failures Signed-off-by: Paolo Insogna <paolo@cowtech.it> * deps,test: fixed failures Signed-off-by: Paolo Insogna <paolo@cowtech.it> * deps,test: fixed failures Signed-off-by: Paolo Insogna <paolo@cowtech.it> * deps,test: fixed failures Signed-off-by: Paolo Insogna <paolo@cowtech.it> * doc,lib: fixed failures Signed-off-by: Paolo Insogna <paolo@cowtech.it> * deps: fixed failures Signed-off-by: Paolo Insogna <paolo@cowtech.it> * test: fixed failures Signed-off-by: Paolo Insogna <paolo@cowtech.it> --------- Signed-off-by: Paolo Insogna <paolo@cowtech.it>
1 parent 2ad47ef commit b7bff3d

39 files changed

+1726
-821
lines changed

.github/workflows/test-shared.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ jobs:
196196
--arg ccache "${NIX_SCCACHE:-null}" \
197197
--arg devTools '[]' \
198198
--arg benchmarkTools '[]' \
199-
${{ endsWith(matrix.system, '-darwin') && '--arg withAmaro false --arg withLief false --arg withSQLite false --arg extraConfigFlags ''["--without-inspector" "--without-node-options"]'' \' || '\' }}
199+
${{ endsWith(matrix.system, '-darwin') && '--arg withAmaro false --arg withLief false --arg withSQLite false --arg withFFI false --arg extraConfigFlags ''["--without-inspector" "--without-node-options"]'' \' || '\' }}
200200
--run '
201201
make -C "$TAR_DIR" run-ci -j4 V=1 TEST_CI_ARGS="-p actions --measure-flakiness 9 --skip-tests=$CI_SKIP_TESTS"
202202
' "$TAR_DIR/shell.nix"

configure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2217,7 +2217,7 @@ def bundled_ffi_supported(os_name, target_arch):
22172217
'freebsd': {'arm', 'arm64', 'x64'},
22182218
'linux': {'arm', 'arm64', 'x64'},
22192219
'mac': {'arm64', 'x64'},
2220-
'win': {'arm', 'arm64', 'x64'},
2220+
'win': {'arm64', 'x64'},
22212221
}
22222222

22232223
if target_arch == 'x86':

deps/libffi/generate-headers.py

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python3
22

33
import argparse
4+
import os
5+
import platform
46
import sys
57
from pathlib import Path
68

@@ -156,7 +158,7 @@ def render_fficonfig(os_name, target_arch):
156158

157159
def generate_headers(output_dir, target_arch, os_name):
158160
base_dir = Path(__file__).resolve().parent
159-
output_dir = Path(output_dir)
161+
output_dir = Path(str(output_dir).strip().strip('"'))
160162
output_dir.mkdir(parents=True, exist_ok=True)
161163

162164
target, target_dir = get_target(os_name, target_arch)
@@ -175,15 +177,62 @@ def generate_headers(output_dir, target_arch, os_name):
175177
encoding='utf-8')
176178

177179

180+
def detect_os_name():
181+
if sys.platform.startswith('win'):
182+
return 'win'
183+
if sys.platform == 'darwin':
184+
return 'mac'
185+
if sys.platform.startswith('linux'):
186+
return 'linux'
187+
if sys.platform.startswith('freebsd'):
188+
return 'freebsd'
189+
raise ValueError(f'Unsupported host platform {sys.platform!r}')
190+
191+
192+
def detect_target_arch():
193+
candidates = [
194+
os.environ.get('TARGET_ARCH'),
195+
os.environ.get('npm_config_arch'),
196+
os.environ.get('VSCMD_ARG_TGT_ARCH'),
197+
os.environ.get('Platform'),
198+
os.environ.get('PROCESSOR_ARCHITECTURE'),
199+
platform.machine(),
200+
]
201+
202+
aliases = {
203+
'amd64': 'x64',
204+
'x86_64': 'x64',
205+
'x64': 'x64',
206+
'win32': 'x64',
207+
'i386': 'x86',
208+
'i686': 'x86',
209+
'x86': 'x86',
210+
'arm64': 'arm64',
211+
'aarch64': 'arm64',
212+
'arm': 'arm',
213+
}
214+
215+
for candidate in candidates:
216+
if not candidate:
217+
continue
218+
normalized = aliases.get(candidate.lower())
219+
if normalized is not None:
220+
return normalized
221+
222+
raise ValueError('Unable to determine target architecture for libffi headers')
223+
224+
178225
def main(argv=None):
179226
parser = argparse.ArgumentParser(description='Generate libffi headers')
180227
parser.add_argument('--output-dir', required=True)
181-
parser.add_argument('--target-arch', required=True)
182-
parser.add_argument('--os', required=True)
228+
parser.add_argument('--target-arch')
229+
parser.add_argument('--os')
183230
args = parser.parse_args(argv)
184231

185232
try:
186-
generate_headers(args.output_dir, args.target_arch, args.os)
233+
generate_headers(args.output_dir,
234+
args.target_arch or detect_target_arch(),
235+
args.os or detect_os_name())
187236
except Exception as exc: # pylint: disable=broad-except
188237
print(exc, file=sys.stderr)
189238
return 1

deps/libffi/libffi.gyp

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
'src/java_raw_api.c',
77
'src/prep_cif.c',
88
'src/raw_api.c',
9+
'src/tramp.c',
910
'src/types.c',
1011
],
1112
'libffi_defines%': [],
@@ -18,10 +19,6 @@
1819
'variables': {
1920
'libffi_arch_sources': [
2021
'src/x86/ffiw64.c',
21-
'src/x86/win64_intel.S',
22-
],
23-
'libffi_defines': [
24-
'LIBFFI_HIDE_BASIC_TYPES',
2522
],
2623
},
2724
}],
@@ -31,9 +28,6 @@
3128
'src/arm/ffi.c',
3229
'src/arm/sysv_msvc_arm32.S',
3330
],
34-
'libffi_defines': [
35-
'LIBFFI_HIDE_BASIC_TYPES',
36-
],
3731
},
3832
}],
3933
['target_arch == "arm64"', {
@@ -42,9 +36,6 @@
4236
'src/aarch64/ffi.c',
4337
'src/aarch64/win64_armasm.S',
4438
],
45-
'libffi_defines': [
46-
'LIBFFI_HIDE_BASIC_TYPES',
47-
],
4839
},
4940
}],
5041
],
@@ -54,8 +45,10 @@
5445
['target_arch == "x64"', {
5546
'variables': {
5647
'libffi_arch_sources': [
48+
'src/x86/ffiw64.c',
5749
'src/x86/ffi64.c',
5850
'src/x86/unix64.S',
51+
'src/x86/win64.S',
5952
],
6053
},
6154
}],
@@ -82,8 +75,10 @@
8275
['target_arch == "x64"', {
8376
'variables': {
8477
'libffi_arch_sources': [
78+
'src/x86/ffiw64.c',
8579
'src/x86/ffi64.c',
8680
'src/x86/unix64.S',
81+
'src/x86/win64.S',
8782
],
8883
},
8984
}],
@@ -107,7 +102,7 @@
107102
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES',
108103
},
109104
'defines': [
110-
'FFI_BUILDING',
105+
'FFI_STATIC_BUILD',
111106
'<@(libffi_defines)',
112107
],
113108
'include_dirs': [
@@ -136,19 +131,53 @@
136131
'action': [
137132
'<(python)',
138133
'generate-headers.py',
139-
'--output-dir=<(INTERMEDIATE_DIR)',
140-
'--target-arch=<(target_arch)',
141-
'--os=<(OS)',
134+
'--output-dir',
135+
'<(INTERMEDIATE_DIR)',
142136
],
143137
},
144138
],
139+
'conditions': [
140+
['OS == "win" and target_arch == "x64"', {
141+
'actions': [
142+
{
143+
'action_name': 'preprocess_win64_intel_asm',
144+
'process_outputs_as_sources': 1,
145+
'inputs': [
146+
'preprocess_asm.py',
147+
'include/ffi_cfi.h',
148+
'src/x86/asmnames.h',
149+
'src/x86/win64_intel.S',
150+
'<(INTERMEDIATE_DIR)/ffi.h',
151+
'<(INTERMEDIATE_DIR)/fficonfig.h',
152+
],
153+
'outputs': [
154+
'<(INTERMEDIATE_DIR)/win64_intel.asm',
155+
],
156+
'action': [
157+
'<(python)',
158+
'preprocess_asm.py',
159+
'--input',
160+
'src/x86/win64_intel.S',
161+
'--output',
162+
'<@(_outputs)',
163+
'--include-dir',
164+
'include',
165+
'--include-dir',
166+
'src/x86',
167+
'--define',
168+
'FFI_STATIC_BUILD',
169+
],
170+
},
171+
],
172+
}],
173+
],
145174
'direct_dependent_settings': {
146175
'include_dirs': [
147176
'include',
148177
'<(INTERMEDIATE_DIR)',
149178
],
150179
'defines': [
151-
'FFI_BUILDING',
180+
'FFI_STATIC_BUILD',
152181
],
153182
},
154183
},

deps/libffi/preprocess_asm.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import os
5+
from pathlib import Path
6+
import shlex
7+
import shutil
8+
import subprocess
9+
import sys
10+
11+
12+
def split_command(value):
13+
if not value:
14+
return None
15+
value = value.strip()
16+
if not value:
17+
return None
18+
return shlex.split(value, posix=(os.name != 'nt'))
19+
20+
21+
def find_compiler():
22+
for var in ('CC', 'CXX'):
23+
command = split_command(os.environ.get(var))
24+
if command and shutil.which(command[0]):
25+
return command
26+
27+
for name in ('cl.exe', 'cl', 'clang-cl.exe', 'clang-cl', 'cc', 'clang', 'gcc'):
28+
path = shutil.which(name)
29+
if path:
30+
return [path]
31+
32+
raise RuntimeError('Unable to locate a compiler for preprocessing assembly')
33+
34+
35+
def normalize_path(value):
36+
return str(value).strip().strip('"')
37+
38+
39+
def unique_paths(paths):
40+
seen = set()
41+
result = []
42+
for path in paths:
43+
if path in seen:
44+
continue
45+
seen.add(path)
46+
result.append(path)
47+
return result
48+
49+
50+
def preprocess(args):
51+
compiler = find_compiler()
52+
input_path = normalize_path(args.input)
53+
output = Path(normalize_path(args.output))
54+
include_dirs = [normalize_path(include_dir) for include_dir in args.include_dir]
55+
include_dirs.append(str(output.parent))
56+
include_dirs = unique_paths(include_dirs)
57+
output.parent.mkdir(parents=True, exist_ok=True)
58+
59+
if os.name == 'nt' and Path(compiler[0]).name.lower() in ('cl.exe', 'cl', 'clang-cl.exe', 'clang-cl'):
60+
command = compiler + ['/nologo', '/EP', '/TC']
61+
command += [f'/I{include_dir}' for include_dir in include_dirs]
62+
command += [f'/D{define}' for define in args.define]
63+
command += [input_path]
64+
else:
65+
command = compiler + ['-E', '-P', '-x', 'c']
66+
command += [f'-I{include_dir}' for include_dir in include_dirs]
67+
command += [f'-D{define}' for define in args.define]
68+
command += [input_path]
69+
70+
result = subprocess.run(command, capture_output=True, text=True)
71+
if result.returncode != 0:
72+
sys.stderr.write(result.stderr)
73+
raise RuntimeError(f'Preprocessing failed: {" ".join(command)}')
74+
75+
output.write_text(result.stdout, encoding='utf-8')
76+
77+
78+
def main(argv=None):
79+
parser = argparse.ArgumentParser(description='Preprocess libffi assembly source')
80+
parser.add_argument('--input', required=True)
81+
parser.add_argument('--output', required=True)
82+
parser.add_argument('--include-dir', action='append', default=[])
83+
parser.add_argument('--define', action='append', default=[])
84+
args = parser.parse_args(argv)
85+
86+
preprocess(args)
87+
return 0
88+
89+
90+
if __name__ == '__main__':
91+
raise SystemExit(main())

doc/api/cli.md

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ const lib = new DynamicLibrary('mylib.so');
213213
```
214214

215215
```console
216-
$ node --permission --experimental-ffi --allow-fs-read=* index.js
216+
$ node --permission --experimental-ffi index.js
217217
Error: Access to this API has been restricted. Use --allow-ffi to manage permissions.
218218
at node:internal/main/run_main_module:17:47 {
219219
code: 'ERR_ACCESS_DENIED',
@@ -1991,16 +1991,6 @@ changes:
19911991
19921992
Legacy alias for [`--no-require-module`][].
19931993

1994-
### `--no-experimental-ffi`
1995-
1996-
<!-- YAML
1997-
added: REPLACEME
1998-
-->
1999-
2000-
Disable the experimental [`node:ffi`][] module.
2001-
2002-
This flag is only available in builds with FFI support.
2003-
20041994
### `--no-experimental-sqlite`
20051995

20061996
<!-- YAML
@@ -2224,7 +2214,7 @@ following permissions are restricted:
22242214
* Worker Threads - manageable through [`--allow-worker`][] flag
22252215
* WASI - manageable through [`--allow-wasi`][] flag
22262216
* Addons - manageable through [`--allow-addons`][] flag
2227-
* FFI - manageable through \[`--allow-ffi`]\[] flag
2217+
* FFI - manageable through [`--allow-ffi`](#--allow-ffi) flag
22282218

22292219
### `--permission-audit`
22302220

@@ -3738,7 +3728,6 @@ one is included in the list below.
37383728
* `--no-addons`
37393729
* `--no-async-context-frame`
37403730
* `--no-deprecation`
3741-
* `--no-experimental-ffi`
37423731
* `--no-experimental-global-navigator`
37433732
* `--no-experimental-repl-await`
37443733
* `--no-experimental-sqlite`

0 commit comments

Comments
 (0)