crossbind 2.0.0-beta.62 → 2.0.0-beta.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +6 -1
- package/src/actions/buildDependencies.js +15 -2
- package/src/actions/buildExternal.js +9 -1
- package/src/actions/buildLib.js +25 -8
- package/src/actions/buildNativeCommand.js +84 -0
- package/src/actions/buildNode.js +48 -7
- package/src/actions/buildTypes.js +8 -2
- package/src/actions/buildWasiCommand.js +0 -4
- package/src/actions/buildWasm.js +49 -29
- package/src/actions/cloudCommands.js +133 -0
- package/src/actions/createImportedBridges.js +64 -0
- package/src/actions/createInterface.js +247 -68
- package/src/actions/createLib.js +57 -41
- package/src/actions/getData.js +4 -1
- package/src/actions/getLinkInputs.js +12 -5
- package/src/actions/isSourceNewer.js +2 -0
- package/src/actions/licenses.js +143 -19
- package/src/actions/prepareConanDependencies.js +51 -0
- package/src/actions/publishBinary.js +32 -0
- package/src/actions/run.js +63 -66
- package/src/actions/runnerCommands.js +421 -0
- package/src/actions/writeRuntimeEntry.js +69 -0
- package/src/assets/cmake/command/CMakeLists.txt +21 -0
- package/src/assets/cmake/command/command.cpp +1 -0
- package/src/assets/cmake/dist.cmake +2 -1
- package/src/assets/configure/install.sh +22 -0
- package/src/assets/js-runtime/adapters/path-url.js +6 -3
- package/src/assets/js-runtime/adapters/unboundMessage.js +2 -0
- package/src/assets/js-runtime/adapters/worker-comlink.js +87 -60
- package/src/assets/js-runtime/core.js +11 -0
- package/src/assets/node-import-hooks.mjs +61 -0
- package/src/assets/toolchain-digests.json +19 -19
- package/src/assets/wasi-runtime/stubs.c +29 -0
- package/src/bin.js +257 -50
- package/src/index.js +3 -0
- package/src/integration/bindHeaderImports.js +18 -0
- package/src/integration/getCrossbindScript.js +46 -10
- package/src/integration/getDependFilePath.js +9 -0
- package/src/integration/resolveNativeImport.js +14 -0
- package/src/node/dev.mjs +19 -0
- package/src/runner/blobs.js +135 -0
- package/src/runner/files.js +193 -0
- package/src/runner/server.js +320 -0
- package/src/state/attachConanDependencies.js +56 -0
- package/src/state/index.js +17 -9
- package/src/state/loadConfig.js +33 -24
- package/src/state/refreshBuiltDependencies.js +20 -0
- package/src/state/refreshConanDependencies.js +17 -0
- package/src/utils/androidToolchain.js +4 -0
- package/src/utils/appRustCrates.js +15 -1
- package/src/utils/appSources.js +97 -6
- package/src/utils/archiveFlags.js +12 -0
- package/src/utils/boundHeaders.js +79 -0
- package/src/utils/bridgeExtras.js +486 -0
- package/src/utils/bridgeRuntimeFixes.js +48 -0
- package/src/utils/bundledLicenses.js +26 -0
- package/src/utils/cargoTarget.js +21 -3
- package/src/utils/cloudAccount.js +55 -0
- package/src/utils/conanDependencies.js +66 -0
- package/src/utils/conanImport.js +58 -0
- package/src/utils/conanInstall.js +154 -0
- package/src/utils/conanProfile.js +203 -0
- package/src/utils/conanStage.js +292 -0
- package/src/utils/copyToDistSource.js +13 -0
- package/src/utils/cppDts.js +58 -15
- package/src/utils/darwinToolchain.js +11 -0
- package/src/utils/dirLock.js +137 -28
- package/src/utils/downloadAndExtractFile.js +34 -7
- package/src/utils/embindArgumentGuards.js +41 -2
- package/src/utils/embindCallArguments.js +19 -0
- package/src/utils/embindJspiQueue.js +25 -0
- package/src/utils/execContainer.js +49 -0
- package/src/utils/headerImports.js +16 -5
- package/src/utils/hostPlatform.js +21 -0
- package/src/utils/iosToolchain.js +6 -0
- package/src/utils/isSourceCmakePackage.js +10 -0
- package/src/utils/licenseReport.js +11 -2
- package/src/utils/linuxToolchain.js +24 -0
- package/src/utils/makeTreeWritable.js +12 -0
- package/src/utils/nativeImports.js +23 -0
- package/src/utils/nativeSourceStamp.js +36 -0
- package/src/utils/nodeDevBuild.js +92 -0
- package/src/utils/packageLicense.js +101 -0
- package/src/utils/pthreadMainScript.js +14 -0
- package/src/utils/pullDockerImage.js +3 -1
- package/src/utils/relocatePrebuilt.js +119 -0
- package/src/utils/remoteClient.js +127 -0
- package/src/utils/remoteOutputs.js +39 -0
- package/src/utils/remoteRunner.js +97 -0
- package/src/utils/remoteUpload.js +134 -0
- package/src/utils/replaceFile.js +8 -0
- package/src/utils/runCargo.js +48 -51
- package/src/utils/runConan.js +257 -0
- package/src/utils/runtimeEntries.js +56 -0
- package/src/utils/rustBridgeGen.js +9 -4
- package/src/utils/rustMt.js +4 -0
- package/src/utils/scopedEmbind.js +22 -0
- package/src/utils/selectRunner.js +81 -0
- package/src/utils/sourceFingerprint.js +4 -3
- package/src/utils/swigInterface.js +69 -4
- package/src/utils/systemKeys.js +35 -3
- package/src/utils/targets.js +49 -4
- package/src/utils/toolchainNotices.js +5 -0
- package/src/utils/wasiToolchain.js +14 -1
- package/src/utils/windowsToolchain.js +18 -0
- package/vitest.config.js +11 -0
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
callWithVectorCoercion, wrapWithVectorCoercion, setCoercionModule, unwrapCoercionProxy,
|
|
6
6
|
} from './vector-coercion.js';
|
|
7
7
|
import { patchModuleForExceptionDecode } from './exception-decode.js';
|
|
8
|
+
import urlPath from './path-url.js';
|
|
9
|
+
import { UNBOUND_MESSAGE } from './unboundMessage.js';
|
|
8
10
|
|
|
9
11
|
const isWorkerScope = typeof WorkerGlobalScope !== 'undefined'
|
|
10
12
|
&& typeof self !== 'undefined'
|
|
@@ -12,17 +14,39 @@ const isWorkerScope = typeof WorkerGlobalScope !== 'undefined'
|
|
|
12
14
|
|
|
13
15
|
// === Embind <-> Comlink Bridge ===
|
|
14
16
|
// Worker-side registry: id -> original embind object
|
|
15
|
-
// Main-thread registry:
|
|
17
|
+
// Main-thread registry: handle -> id
|
|
16
18
|
const embindRegistry = new Map();
|
|
17
19
|
const embindProxyIds = new WeakMap();
|
|
18
20
|
let nextEmbindId = 1;
|
|
19
21
|
|
|
22
|
+
// The objects the worker hands out are reached through the module's channel, so writes to them keep their order
|
|
23
|
+
// with the calls after them; messages on different channels keep none.
|
|
24
|
+
const HANDLES = '__crossbindHandles';
|
|
25
|
+
let remoteModule = null;
|
|
26
|
+
|
|
20
27
|
function registerEmbindObject(obj) {
|
|
21
28
|
const id = nextEmbindId++;
|
|
22
29
|
embindRegistry.set(id, obj);
|
|
23
30
|
return id;
|
|
24
31
|
}
|
|
25
32
|
|
|
33
|
+
// Comlink answers every member with a remote one: JSON.stringify and String() called toJSON and Symbol.toPrimitive
|
|
34
|
+
// on the worker's object, which has neither, and a member below the module is thenable. A handle answers them as a
|
|
35
|
+
// direct-mode object does.
|
|
36
|
+
const LOCAL_MEMBERS = {
|
|
37
|
+
then: undefined,
|
|
38
|
+
toJSON: () => ({}),
|
|
39
|
+
[Symbol.toPrimitive]: (hint) => (hint === 'number' ? NaN : '[object Object]'),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function handleFor(id) {
|
|
43
|
+
const handle = new Proxy(remoteModule[HANDLES][id], {
|
|
44
|
+
get: (target, prop) => (Object.hasOwn(LOCAL_MEMBERS, prop) ? LOCAL_MEMBERS[prop] : target[prop]),
|
|
45
|
+
});
|
|
46
|
+
embindProxyIds.set(handle, id);
|
|
47
|
+
return handle;
|
|
48
|
+
}
|
|
49
|
+
|
|
26
50
|
// Reorder transfer handlers for correct priority
|
|
27
51
|
const _proxyHandler = Comlink.transferHandlers.get('proxy');
|
|
28
52
|
const _throwHandler = Comlink.transferHandlers.get('throw');
|
|
@@ -47,22 +71,16 @@ Comlink.transferHandlers.set('proxy', {
|
|
|
47
71
|
canHandle: _proxyHandler.canHandle,
|
|
48
72
|
serialize(obj) {
|
|
49
73
|
if (typeof obj.delete === 'function' && typeof obj.isDeleted === 'function') {
|
|
50
|
-
// CONSTRUCT results (Comlink marks them with proxy()) are
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
const raw = unwrapCoercionProxy(obj);
|
|
55
|
-
const [port, transferables] = _proxyHandler.serialize(wrapWithVectorCoercion(raw));
|
|
56
|
-
const id = registerEmbindObject(raw);
|
|
57
|
-
return [{ __embindId: id, __port: port }, transferables];
|
|
74
|
+
// CONSTRUCT results (Comlink marks them with proxy()) are handed out as
|
|
75
|
+
// method-returned objects are (embindObject handler), and the registry keeps
|
|
76
|
+
// the RAW object so arguments resolve back to real embind identities.
|
|
77
|
+
return [{ __embindId: registerEmbindObject(unwrapCoercionProxy(obj)) }, []];
|
|
58
78
|
}
|
|
59
79
|
return _proxyHandler.serialize(obj);
|
|
60
80
|
},
|
|
61
81
|
deserialize(data) {
|
|
62
82
|
if (data != null && typeof data === 'object' && '__embindId' in data) {
|
|
63
|
-
|
|
64
|
-
embindProxyIds.set(proxy, data.__embindId);
|
|
65
|
-
return proxy;
|
|
83
|
+
return handleFor(data.__embindId);
|
|
66
84
|
}
|
|
67
85
|
return _proxyHandler.deserialize(data);
|
|
68
86
|
},
|
|
@@ -102,40 +120,18 @@ Comlink.transferHandlers.set('embindVector', {
|
|
|
102
120
|
serialize(obj) {
|
|
103
121
|
const len = obj.size();
|
|
104
122
|
const elements = new Array(len);
|
|
105
|
-
let hasObjects = false;
|
|
106
123
|
for (let i = 0; i < len; i++) {
|
|
107
124
|
const elem = obj.get(i);
|
|
108
|
-
elements[i] = elem
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (!hasObjects) {
|
|
114
|
-
return [elements, []];
|
|
115
|
-
}
|
|
116
|
-
const transferables = [];
|
|
117
|
-
for (let i = 0; i < len; i++) {
|
|
118
|
-
const elem = elements[i];
|
|
119
|
-
if (elem !== null && typeof elem === 'object') {
|
|
120
|
-
const id = registerEmbindObject(elem);
|
|
121
|
-
const { port1, port2 } = new MessageChannel();
|
|
122
|
-
Comlink.expose(wrapWithVectorCoercion(elem), port1);
|
|
123
|
-
transferables.push(port2);
|
|
124
|
-
elements[i] = { __comlinkProxy: true, __embindId: id, port: port2 };
|
|
125
|
-
}
|
|
125
|
+
elements[i] = elem !== null && typeof elem === 'object'
|
|
126
|
+
? { __comlinkProxy: true, __embindId: registerEmbindObject(elem) }
|
|
127
|
+
: elem;
|
|
126
128
|
}
|
|
127
|
-
return [elements,
|
|
129
|
+
return [elements, []];
|
|
128
130
|
},
|
|
129
131
|
deserialize(elements) {
|
|
130
|
-
return elements.map((elem) =>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const proxy = Comlink.wrap(elem.port);
|
|
134
|
-
embindProxyIds.set(proxy, elem.__embindId);
|
|
135
|
-
return proxy;
|
|
136
|
-
}
|
|
137
|
-
return elem;
|
|
138
|
-
});
|
|
132
|
+
return elements.map((elem) => (elem && typeof elem === 'object' && elem.__comlinkProxy
|
|
133
|
+
? handleFor(elem.__embindId)
|
|
134
|
+
: elem));
|
|
139
135
|
},
|
|
140
136
|
});
|
|
141
137
|
|
|
@@ -210,20 +206,13 @@ Comlink.transferHandlers.set('embindObject', {
|
|
|
210
206
|
&& typeof obj.isDeleted === 'function';
|
|
211
207
|
},
|
|
212
208
|
serialize(obj) {
|
|
213
|
-
// An object a property returns comes wrapped by its owner's coercion proxy. Registering
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
const id = registerEmbindObject(raw);
|
|
218
|
-
const { port1, port2 } = new MessageChannel();
|
|
219
|
-
Comlink.expose(wrapWithVectorCoercion(raw), port1);
|
|
220
|
-
return [{ __embindId: id, port: port2 }, [port2]];
|
|
209
|
+
// An object a property returns comes wrapped by its owner's coercion proxy. Registering the raw object,
|
|
210
|
+
// as the proxy handler does, keeps objects read from it one wrapper deep, which an argument's unwrapping
|
|
211
|
+
// undoes.
|
|
212
|
+
return [{ __embindId: registerEmbindObject(unwrapCoercionProxy(obj)) }, []];
|
|
221
213
|
},
|
|
222
214
|
deserialize(data) {
|
|
223
|
-
data.
|
|
224
|
-
const proxy = Comlink.wrap(data.port);
|
|
225
|
-
embindProxyIds.set(proxy, data.__embindId);
|
|
226
|
-
return proxy;
|
|
215
|
+
return handleFor(data.__embindId);
|
|
227
216
|
},
|
|
228
217
|
});
|
|
229
218
|
|
|
@@ -251,16 +240,28 @@ Comlink.transferHandlers.set('embindProxyArray', {
|
|
|
251
240
|
|
|
252
241
|
let _worker = null;
|
|
253
242
|
|
|
243
|
+
// Configurable, so the coercion wrapper wraps the objects read through it as it does every other member.
|
|
244
|
+
export function moduleRoot(m) {
|
|
245
|
+
Object.defineProperty(m, HANDLES, {
|
|
246
|
+
value: new Proxy({}, { get: (_, id) => embindRegistry.get(Number(id)) }),
|
|
247
|
+
configurable: true,
|
|
248
|
+
});
|
|
249
|
+
return wrapWithVectorCoercion(m);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function adoptModule(remote) {
|
|
253
|
+
remoteModule = remote;
|
|
254
|
+
return remote;
|
|
255
|
+
}
|
|
256
|
+
|
|
254
257
|
function resolveScriptUrl(config) {
|
|
255
258
|
const fileName = config.paths.js || config.paths.worker;
|
|
256
|
-
let prefix =
|
|
259
|
+
let prefix = urlPath.getDefaultPathPrefix();
|
|
257
260
|
if (config.path) {
|
|
258
261
|
prefix = config.path;
|
|
259
262
|
if (prefix.slice(-1) !== '/') prefix += '/';
|
|
260
263
|
}
|
|
261
|
-
|
|
262
|
-
if (output.substring(0, 4) !== 'http' && output[0] !== '/') output = `/${output}`;
|
|
263
|
-
return output;
|
|
264
|
+
return urlPath.finalizePath(prefix + fileName);
|
|
264
265
|
}
|
|
265
266
|
|
|
266
267
|
function exposeWorker(systemConfig, createModule) {
|
|
@@ -273,7 +274,7 @@ function exposeWorker(systemConfig, createModule) {
|
|
|
273
274
|
// comlink throw handler, a raw WebAssembly.Exception does not.
|
|
274
275
|
patchModuleForExceptionDecode(m);
|
|
275
276
|
registerModuleEnums(m);
|
|
276
|
-
return Comlink.proxy(
|
|
277
|
+
return Comlink.proxy(moduleRoot(m));
|
|
277
278
|
},
|
|
278
279
|
};
|
|
279
280
|
Comlink.expose(workerApi);
|
|
@@ -288,10 +289,35 @@ async function initWithWorker(config, userConfig) {
|
|
|
288
289
|
logHandler, errorHandler, onRuntimeInitialized, getWasmFunction, useWorker, workerUrl,
|
|
289
290
|
...serializableConfig
|
|
290
291
|
} = userConfig;
|
|
291
|
-
|
|
292
|
+
// The worker resolves a relative URL against its own script, so it gets the path resolved against the page.
|
|
293
|
+
const workerConfig = config.path ? { ...serializableConfig, path: urlPath.finalizePath(config.path) } : serializableConfig;
|
|
294
|
+
return moduleOnMainThread(adoptModule(await workerApi.init(workerConfig)));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// A call the worker cannot make, because the module lacks the function, fails there with a TypeError from inside comlink
|
|
298
|
+
// that names nothing: the failed call asks for the member, and names it when the module has none.
|
|
299
|
+
function namedCall(member, name, module) {
|
|
300
|
+
return new Proxy(member, {
|
|
301
|
+
// A member still needs Comlink's then to read its value (including an absent export).
|
|
302
|
+
get(target, prop) {
|
|
303
|
+
// Console formatters inspect function names and constructors synchronously.
|
|
304
|
+
if (prop === 'name') return name;
|
|
305
|
+
if (prop === 'constructor') return Function;
|
|
306
|
+
return prop !== 'then' && Object.hasOwn(LOCAL_MEMBERS, prop) ? LOCAL_MEMBERS[prop] : target[prop];
|
|
307
|
+
},
|
|
308
|
+
apply: (call, thisArg, args) => Reflect.apply(call, thisArg, args).catch(async (error) => {
|
|
309
|
+
const isBound = await Promise.resolve(module[name]).then((value) => value !== undefined, () => true);
|
|
310
|
+
if (isBound) throw error;
|
|
311
|
+
throw new Error(`crossbind: ${name} ${UNBOUND_MESSAGE}`);
|
|
312
|
+
}),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
292
315
|
|
|
316
|
+
export function moduleOnMainThread(module) {
|
|
293
317
|
return new Proxy(module, {
|
|
294
318
|
get(target, prop) {
|
|
319
|
+
if (Object.hasOwn(LOCAL_MEMBERS, prop)) return LOCAL_MEMBERS[prop];
|
|
320
|
+
if (prop === 'constructor') return Object;
|
|
295
321
|
if (prop === 'toArray') {
|
|
296
322
|
return function toArray(vector) {
|
|
297
323
|
if (Array.isArray(vector)) return vector;
|
|
@@ -306,7 +332,8 @@ async function initWithWorker(config, userConfig) {
|
|
|
306
332
|
return target.toVector(classOrName, array);
|
|
307
333
|
};
|
|
308
334
|
}
|
|
309
|
-
|
|
335
|
+
const member = target[prop];
|
|
336
|
+
return typeof prop === 'string' && typeof member === 'function' ? namedCall(member, prop, target) : member;
|
|
310
337
|
},
|
|
311
338
|
});
|
|
312
339
|
}
|
|
@@ -73,6 +73,16 @@ function buildLocateFile(config, adapter) {
|
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
// WASMFS's FS.writeFile writes at the end of a file that exists (emsdk 6.0.9 js_api.cpp), where the classic FS
|
|
77
|
+
// replaces it; opening the file for writing empties it first.
|
|
78
|
+
function replaceOnWriteFile(FS) {
|
|
79
|
+
const { writeFile } = FS;
|
|
80
|
+
FS.writeFile = (path, data) => {
|
|
81
|
+
FS.close(FS.open(path, 'w'));
|
|
82
|
+
return writeFile(path, data);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
76
86
|
export function createBaseModule(Module, config, adapter) {
|
|
77
87
|
return new Promise((resolve, reject) => {
|
|
78
88
|
const locateFile = buildLocateFile(config, adapter);
|
|
@@ -137,6 +147,7 @@ export function createBaseModule(Module, config, adapter) {
|
|
|
137
147
|
// fs-browser), which emscripten's onRuntimeInitialized callback cannot, so
|
|
138
148
|
// both hooks run after the factory settles - adapter first, then the user's.
|
|
139
149
|
Module(m).then(async (mod) => {
|
|
150
|
+
if (mod.FS) replaceOnWriteFile(mod.FS);
|
|
140
151
|
if (adapter.onModuleReady) await adapter.onModuleReady(mod, config);
|
|
141
152
|
if (config.onRuntimeInitialized) config.onRuntimeInitialized(mod);
|
|
142
153
|
return mod;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Node's module hooks for the native imports one crossbind build bound, so a Node app imports a header, a
|
|
2
|
+
// conan: header or a package's header the way a bundler plugin lets it. Each resolves to a module that
|
|
3
|
+
// re-exports its names from the runtime entry, which initNative() fills. Copied into dist by the build.
|
|
4
|
+
import { registerHooks } from 'node:module';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const SCHEME = /^(cargo|conan):/;
|
|
9
|
+
const isBare = (specifier) => !/^(\.{1,2}\/|\/|[A-Za-z]:[\\/]|file:)/.test(specifier);
|
|
10
|
+
|
|
11
|
+
function notBound(what, parentURL, cause) {
|
|
12
|
+
const from = parentURL ? `, imported from ${parentURL},` : '';
|
|
13
|
+
return new Error(`crossbind: ${what}${from} is not bound by the last crossbind build. Build again after adding a native import, or start Node with --import crossbind/node/dev to build whenever one is added; an import specifier computed at run time is not found by the build.`, { cause });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const exportOf = (name) => (typeof name === 'string' ? name : `${name.wire} as ${name.local}`);
|
|
17
|
+
const proxyOf = (entry, names) => `export { ${['initNative', 'AllSymbols', ...names.map(exportOf)].join(', ')} } from ${JSON.stringify(entry)};\n`;
|
|
18
|
+
|
|
19
|
+
// Another hook may still serve it; Node's own resolver hands an unknown scheme on unresolved.
|
|
20
|
+
function resolveUnbound(specifier, context, nextResolve) {
|
|
21
|
+
let resolved;
|
|
22
|
+
try {
|
|
23
|
+
resolved = nextResolve(specifier, context);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
throw notBound(specifier, context.parentURL, error);
|
|
26
|
+
}
|
|
27
|
+
if (SCHEME.test(resolved.url)) throw notBound(specifier, context.parentURL);
|
|
28
|
+
return resolved;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// `natives` lists each bound file, relative to the entry, with the bare specifiers that name it and the names it
|
|
32
|
+
// exports, a name the entry exports under another as { local, wire }.
|
|
33
|
+
export default function registerNativeImports(entry, { extensions, natives }) {
|
|
34
|
+
const entryUrl = new URL(entry).href;
|
|
35
|
+
const dir = path.dirname(fileURLToPath(entryUrl));
|
|
36
|
+
const isNative = new RegExp(`\\.(${extensions.join('|')})$`);
|
|
37
|
+
const byFile = new Map();
|
|
38
|
+
const bySpecifier = new Map();
|
|
39
|
+
natives.forEach(({ file, specifiers, names }) => {
|
|
40
|
+
const absolute = path.resolve(dir, file);
|
|
41
|
+
byFile.set(absolute, names);
|
|
42
|
+
specifiers.forEach((specifier) => bySpecifier.set(specifier, pathToFileURL(absolute).href));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
registerHooks({
|
|
46
|
+
resolve(specifier, context, nextResolve) {
|
|
47
|
+
const url = bySpecifier.get(specifier);
|
|
48
|
+
if (url) return { url, format: 'module', shortCircuit: true };
|
|
49
|
+
if (isBare(specifier) && (SCHEME.test(specifier) || isNative.test(specifier))) return resolveUnbound(specifier, context, nextResolve);
|
|
50
|
+
return nextResolve(specifier, context);
|
|
51
|
+
},
|
|
52
|
+
load(url, context, nextLoad) {
|
|
53
|
+
if (!url.startsWith('file:')) return nextLoad(url, context);
|
|
54
|
+
const file = fileURLToPath(url);
|
|
55
|
+
const names = byFile.get(file);
|
|
56
|
+
if (names) return { format: 'module', source: proxyOf(entryUrl, names), shortCircuit: true };
|
|
57
|
+
if (isNative.test(file)) throw notBound(file);
|
|
58
|
+
return nextLoad(url, context);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.
|
|
2
|
+
"version": "1.0.12",
|
|
3
3
|
"registry": "ghcr.io/crossbind",
|
|
4
4
|
"toolchains": {
|
|
5
|
-
"rust": "1.
|
|
5
|
+
"rust": "1.99.0"
|
|
6
6
|
},
|
|
7
7
|
"images": {
|
|
8
8
|
"rust-sysroot": {
|
|
9
|
-
"index": "sha256:
|
|
9
|
+
"index": "sha256:fcaddb9514956c80c28152679d11817599b3c544e2bb56568d79dbd7699af805",
|
|
10
10
|
"platforms": {
|
|
11
|
-
"linux/arm64": "sha256:
|
|
12
|
-
"linux/amd64": "sha256:
|
|
11
|
+
"linux/arm64": "sha256:70dca2248666ee712ad5cb11fd013274ca4bb1efdafee732a0ec15492889f622",
|
|
12
|
+
"linux/amd64": "sha256:a3377c70598ef4e1918a73feeebb0ec1b80b3cde956daac9b2b62f9d742b88dc"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"base": {
|
|
16
|
-
"index": "sha256:
|
|
16
|
+
"index": "sha256:86c6559bd51c10f8fc1ff6cbc0cf5386115fd7f0491a59f30f0d26a0203c200d",
|
|
17
17
|
"platforms": {
|
|
18
|
-
"linux/
|
|
19
|
-
"linux/
|
|
18
|
+
"linux/amd64": "sha256:16056b4bd85ba1792791401003db0325c31d4aa4821ff40f6f2eb1e0fff1d3ce",
|
|
19
|
+
"linux/arm64": "sha256:8d213f83ddd1ad9101b74b2b071f304ac8924ffbe68d79ece50668076e0172c0"
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"web": {
|
|
23
|
-
"index": "sha256:
|
|
23
|
+
"index": "sha256:ffa089b83160e380e0b4447f483bf66cb87324f89b8e80b5776ed9346275a5ca",
|
|
24
24
|
"platforms": {
|
|
25
|
-
"linux/
|
|
26
|
-
"linux/
|
|
25
|
+
"linux/arm64": "sha256:1baf14ee0f1a821c1562d12902fe362d3639f57acb31f969402f2a2d8486647f",
|
|
26
|
+
"linux/amd64": "sha256:d3bd3aa785447f1679fdcb898921f614579d9eaad2aa9e828675ba7f82dc11ec"
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
29
|
"android": {
|
|
30
|
-
"index": "sha256:
|
|
30
|
+
"index": "sha256:830286886d8bb259e94e112e4f1bab5f153106365b17859d20c9ef714349e520",
|
|
31
31
|
"platforms": {
|
|
32
|
-
"linux/amd64": "sha256:
|
|
32
|
+
"linux/amd64": "sha256:1004144243fea89a8915417954073e8ffabb20d8a9aed31045ce2a95c1abe1da"
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"linux": {
|
|
36
|
-
"index": "sha256:
|
|
36
|
+
"index": "sha256:8d4cc55d2ef8ea40845fd13708575e06f6aecdc035e7200deddf8c662d5c910f",
|
|
37
37
|
"platforms": {
|
|
38
|
-
"linux/
|
|
39
|
-
"linux/
|
|
38
|
+
"linux/arm64": "sha256:0de59cc6ce7b381f213af0d26ccc83e0c41545a91eb0b36c51832c7fb660566c",
|
|
39
|
+
"linux/amd64": "sha256:3b3bc24d8f5dffe3a2408193265a807764fcf2744243c0a5e07f312f608fc6c0"
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"windows": {
|
|
43
|
-
"index": "sha256:
|
|
43
|
+
"index": "sha256:a31110874a9b6b9e3fec177edc8a8093905902bcc6abc6a85e45eb0927d4f070",
|
|
44
44
|
"platforms": {
|
|
45
|
-
"linux/
|
|
46
|
-
"linux/
|
|
45
|
+
"linux/arm64": "sha256:bd9ec6ba60952f929e09777374a3bb05512bbe796325c0e8a0b84e1a12d1b86c",
|
|
46
|
+
"linux/amd64": "sha256:01f4bd8c4d1044bde68fe758d2632c510f8efb76aa4bad28696f9e9b199c8f4e"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -7,12 +7,32 @@
|
|
|
7
7
|
|
|
8
8
|
#include <netinet/in.h>
|
|
9
9
|
#include <sys/socket.h>
|
|
10
|
+
#include <sys/stat.h>
|
|
11
|
+
#include <unistd.h>
|
|
10
12
|
|
|
11
13
|
/* Compiled by the C++ driver at the command link; keep C linkage. */
|
|
12
14
|
#ifdef __cplusplus
|
|
13
15
|
extern "C" {
|
|
14
16
|
#endif
|
|
15
17
|
|
|
18
|
+
/* wasi-libc p2/p3 leaves its output stream at the old offset after SEEK_END. SEEK_SET resets
|
|
19
|
+
that stream, so resolve the end offset through fstat and perform an absolute seek instead. */
|
|
20
|
+
off_t __real_lseek(int fd, off_t offset, int whence);
|
|
21
|
+
off_t __wrap_lseek(int fd, off_t offset, int whence)
|
|
22
|
+
{
|
|
23
|
+
if (whence == SEEK_END) {
|
|
24
|
+
struct stat status;
|
|
25
|
+
if (fstat(fd, &status) != 0) return (off_t)-1;
|
|
26
|
+
off_t absolute;
|
|
27
|
+
if (__builtin_add_overflow(status.st_size, offset, &absolute)) {
|
|
28
|
+
errno = EOVERFLOW;
|
|
29
|
+
return (off_t)-1;
|
|
30
|
+
}
|
|
31
|
+
return __real_lseek(fd, absolute, SEEK_SET);
|
|
32
|
+
}
|
|
33
|
+
return __real_lseek(fd, offset, whence);
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
/* No dynamic loading on WASI; loaders treat NULL as "plugin unavailable". */
|
|
17
37
|
void *dlopen(const char *file, int mode)
|
|
18
38
|
{
|
|
@@ -79,6 +99,15 @@ int getpeername(int fd, struct sockaddr *addr, socklen_t *len)
|
|
|
79
99
|
return crossbind_zeroed_inet(addr, len);
|
|
80
100
|
}
|
|
81
101
|
|
|
102
|
+
/* The WASI SQLite leaves extension loading out, yet SpatiaLite's stored procedures switch it off; this answers
|
|
103
|
+
SQLITE_ERROR as such a build does. Weak, so a SQLite that has the function keeps its own. */
|
|
104
|
+
__attribute__((weak)) int sqlite3_enable_load_extension(void *db, int onoff)
|
|
105
|
+
{
|
|
106
|
+
(void)db;
|
|
107
|
+
(void)onoff;
|
|
108
|
+
return 1;
|
|
109
|
+
}
|
|
110
|
+
|
|
82
111
|
#ifdef __cplusplus
|
|
83
112
|
}
|
|
84
113
|
#endif
|