@ohos-ports/quickjs-wasi 3.6.0-beta.0
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 +846 -0
- package/dist/extensions.d.ts +110 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +372 -0
- package/dist/extensions.js.map +1 -0
- package/dist/index.d.ts +1263 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2787 -0
- package/dist/index.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/wasi-shim.d.ts +61 -0
- package/dist/wasi-shim.d.ts.map +1 -0
- package/dist/wasi-shim.js +103 -0
- package/dist/wasi-shim.js.map +1 -0
- package/extensions/crypto/crypto.so +0 -0
- package/extensions/encoding/encoding.so +0 -0
- package/extensions/headers/headers.so +0 -0
- package/extensions/structured-clone/structured-clone.so +0 -0
- package/extensions/url/url.so +0 -0
- package/package.json +73 -0
- package/quickjs.wasm +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM Dynamic Linking - Extension Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads WASM shared libraries (.so) compiled with wasi-sdk as extensions
|
|
5
|
+
* for the QuickJS WASM runtime. Extensions can call QuickJS C API functions
|
|
6
|
+
* directly through dynamic linking (shared memory + symbol resolution).
|
|
7
|
+
*
|
|
8
|
+
* Key concepts:
|
|
9
|
+
* - Extensions are WASM shared libraries with a `dylink.0` custom section
|
|
10
|
+
* - They share linear memory and the indirect function table with the main module
|
|
11
|
+
* - Symbol imports (env.*) are resolved against the main module's exports
|
|
12
|
+
* - Each extension gets a unique __memory_base and __table_base
|
|
13
|
+
* - Extensions export an init function (e.g., `qjs_ext_url_init`)
|
|
14
|
+
*/
|
|
15
|
+
/** Parsed content of a dylink.0 custom section */
|
|
16
|
+
export interface DylinkInfo {
|
|
17
|
+
memorySize: number;
|
|
18
|
+
memoryAlignment: number;
|
|
19
|
+
tableSize: number;
|
|
20
|
+
tableAlignment: number;
|
|
21
|
+
needed: string[];
|
|
22
|
+
}
|
|
23
|
+
/** Metadata about a loaded extension, used for snapshot/restore */
|
|
24
|
+
export interface LoadedExtension {
|
|
25
|
+
/** Name identifier for the extension */
|
|
26
|
+
name: string;
|
|
27
|
+
/** The compiled WASM module (needed for restore) */
|
|
28
|
+
module: WebAssembly.Module;
|
|
29
|
+
/** The instantiated WASM instance */
|
|
30
|
+
instance: WebAssembly.Instance;
|
|
31
|
+
/** Parsed dylink.0 info */
|
|
32
|
+
dylink: DylinkInfo;
|
|
33
|
+
/** Allocated base offset in linear memory for this extension's static data */
|
|
34
|
+
memoryBase: number;
|
|
35
|
+
/** Allocated base offset in the indirect function table */
|
|
36
|
+
tableBase: number;
|
|
37
|
+
/** Name of the init function exported by the extension */
|
|
38
|
+
initFn: string;
|
|
39
|
+
/** Version info from the extension's qjs_ext_<name>_versions() export (if any) */
|
|
40
|
+
versions?: Record<string, string>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The concrete WASI import object shared between the main module and extensions.
|
|
44
|
+
* This is the result of `createWasiShim()` (with any user overrides applied).
|
|
45
|
+
*/
|
|
46
|
+
export type WasiImports = Record<string, WebAssembly.ImportValue>;
|
|
47
|
+
/** Description of an extension to load */
|
|
48
|
+
export interface ExtensionDescriptor {
|
|
49
|
+
/** Name identifier (used in snapshot metadata) */
|
|
50
|
+
name: string;
|
|
51
|
+
/** WASM bytes or pre-compiled module */
|
|
52
|
+
wasm: BufferSource | WebAssembly.Module;
|
|
53
|
+
/** Name of the init function exported by the extension (default: `qjs_ext_${name}_init`, with `-` replaced by `_`) */
|
|
54
|
+
initFn?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Extension-provided WASI host function implementations.
|
|
57
|
+
*
|
|
58
|
+
* A factory that receives the WASM linear memory and returns an object of
|
|
59
|
+
* `wasi_snapshot_preview1` functions. These are layered between the built-in
|
|
60
|
+
* defaults and any user-provided overrides:
|
|
61
|
+
*
|
|
62
|
+
* 1. Built-in defaults (lowest priority)
|
|
63
|
+
* 2. Extension-provided (this field)
|
|
64
|
+
* 3. User-provided via `QuickJSOptions.wasi` (highest priority)
|
|
65
|
+
*
|
|
66
|
+
* This allows an extension to ship its own WASI implementations (e.g. a
|
|
67
|
+
* crypto extension providing `random_get`) while still allowing the user
|
|
68
|
+
* to override them at the top level.
|
|
69
|
+
*/
|
|
70
|
+
wasi?: (memory: WebAssembly.Memory) => Record<string, (...args: any[]) => any>;
|
|
71
|
+
}
|
|
72
|
+
/** Parse the dylink.0 custom section from a WASM module */
|
|
73
|
+
export declare function parseDylink(module: WebAssembly.Module): DylinkInfo | null;
|
|
74
|
+
/**
|
|
75
|
+
* Load a WASM shared library extension and link it against the main module.
|
|
76
|
+
*
|
|
77
|
+
* @param descriptor - Extension description (name, wasm bytes, init function)
|
|
78
|
+
* @param mainExports - The main QuickJS WASM module's exports
|
|
79
|
+
* @param wasiBuiltins - Built-in WASI implementations (lowest priority)
|
|
80
|
+
* @param wasiUserOverrides - User-provided WASI overrides (highest priority)
|
|
81
|
+
* @param memoryProxy - A memory proxy for extension WASI factories
|
|
82
|
+
* @param allocBase - Optional fixed memory/table bases (for snapshot restore)
|
|
83
|
+
*/
|
|
84
|
+
export declare function loadExtension(descriptor: ExtensionDescriptor, mainExports: Record<string, WebAssembly.ExportValue>, wasiBuiltins?: WasiImports, wasiUserOverrides?: WasiImports, memoryProxy?: WebAssembly.Memory, allocBase?: {
|
|
85
|
+
memoryBase: number;
|
|
86
|
+
tableBase: number;
|
|
87
|
+
}): Promise<LoadedExtension>;
|
|
88
|
+
/**
|
|
89
|
+
* Call the extension's init function, passing the JSContext and JSRuntime
|
|
90
|
+
* pointers from the main module.
|
|
91
|
+
*/
|
|
92
|
+
export declare function initExtension(ext: LoadedExtension, mainExports: Record<string, WebAssembly.ExportValue>): void;
|
|
93
|
+
/**
|
|
94
|
+
* Re-instantiate extensions for snapshot restore.
|
|
95
|
+
*
|
|
96
|
+
* During restore, we need to:
|
|
97
|
+
* 1. Instantiate extension modules with the same memory/table bases
|
|
98
|
+
* 2. Let them populate the function table (via elem segments and __wasm_apply_data_relocs)
|
|
99
|
+
* 3. Do NOT call the init function (the state is already in the snapshot memory)
|
|
100
|
+
*
|
|
101
|
+
* This reconstructs the function table entries that extensions need, without
|
|
102
|
+
* modifying linear memory (which will be overwritten by the snapshot).
|
|
103
|
+
*/
|
|
104
|
+
export declare function restoreExtensions(descriptors: ExtensionDescriptor[], extensionMeta: Array<{
|
|
105
|
+
name: string;
|
|
106
|
+
memoryBase: number;
|
|
107
|
+
tableBase: number;
|
|
108
|
+
initFn: string;
|
|
109
|
+
}>, mainExports: Record<string, WebAssembly.ExportValue>, wasiBuiltins?: WasiImports, wasiUserOverrides?: WasiImports, memoryProxy?: WebAssembly.Memory): Promise<LoadedExtension[]>;
|
|
110
|
+
//# sourceMappingURL=extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAyCH,kDAAkD;AAClD,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;IAC3B,qCAAqC;IACrC,QAAQ,EAAE,WAAW,CAAC,QAAQ,CAAC;IAC/B,2BAA2B;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;AAElE,0CAA0C;AAC1C,MAAM,WAAW,mBAAmB;IAClC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,IAAI,EAAE,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC;IACxC,sHAAsH;IACtH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;OAcG;IACH,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC;CAChF;AAiBD,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,GAAG,UAAU,GAAG,IAAI,CA2CzE;AAaD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,mBAAmB,EAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,EACpD,YAAY,CAAC,EAAE,WAAW,EAC1B,iBAAiB,CAAC,EAAE,WAAW,EAC/B,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAChC,SAAS,CAAC,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACpD,OAAO,CAAC,eAAe,CAAC,CA6O1B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,GACnD,IAAI,CAmBN;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,mBAAmB,EAAE,EAClC,aAAa,EAAE,KAAK,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,EACF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,CAAC,EACpD,YAAY,CAAC,EAAE,WAAW,EAC1B,iBAAiB,CAAC,EAAE,WAAW,EAC/B,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,GAC/B,OAAO,CAAC,eAAe,EAAE,CAAC,CAuB5B"}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM Dynamic Linking - Extension Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads WASM shared libraries (.so) compiled with wasi-sdk as extensions
|
|
5
|
+
* for the QuickJS WASM runtime. Extensions can call QuickJS C API functions
|
|
6
|
+
* directly through dynamic linking (shared memory + symbol resolution).
|
|
7
|
+
*
|
|
8
|
+
* Key concepts:
|
|
9
|
+
* - Extensions are WASM shared libraries with a `dylink.0` custom section
|
|
10
|
+
* - They share linear memory and the indirect function table with the main module
|
|
11
|
+
* - Symbol imports (env.*) are resolved against the main module's exports
|
|
12
|
+
* - Each extension gets a unique __memory_base and __table_base
|
|
13
|
+
* - Extensions export an init function (e.g., `qjs_ext_url_init`)
|
|
14
|
+
*/
|
|
15
|
+
const decoder = new TextDecoder();
|
|
16
|
+
/**
|
|
17
|
+
* Parse a null-terminated "key=value\nkey=value" string from WASM memory
|
|
18
|
+
* into a Record<string, string>. Used to read version info from extensions.
|
|
19
|
+
*/
|
|
20
|
+
function parseVersionString(memory, ptr) {
|
|
21
|
+
const mem = new Uint8Array(memory.buffer);
|
|
22
|
+
let end = ptr;
|
|
23
|
+
while (mem[end] !== 0)
|
|
24
|
+
end++;
|
|
25
|
+
if (end === ptr)
|
|
26
|
+
return {};
|
|
27
|
+
const str = decoder.decode(mem.slice(ptr, end));
|
|
28
|
+
const result = {};
|
|
29
|
+
for (const line of str.split('\n')) {
|
|
30
|
+
const eq = line.indexOf('=');
|
|
31
|
+
if (eq > 0) {
|
|
32
|
+
result[line.slice(0, eq)] = line.slice(eq + 1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if an extension exports a versions function and parse the result.
|
|
39
|
+
*/
|
|
40
|
+
function extractExtensionVersions(ext, memory) {
|
|
41
|
+
const versionsFnName = `qjs_ext_${ext.name.replace(/-/g, '_')}_versions`;
|
|
42
|
+
const versionsFn = ext.instance.exports[versionsFnName];
|
|
43
|
+
if (typeof versionsFn !== 'function')
|
|
44
|
+
return undefined;
|
|
45
|
+
const ptr = versionsFn();
|
|
46
|
+
if (ptr === 0)
|
|
47
|
+
return undefined;
|
|
48
|
+
return parseVersionString(memory, ptr);
|
|
49
|
+
}
|
|
50
|
+
// ---- dylink.0 parser ----
|
|
51
|
+
/** Read a ULEB128-encoded integer from a byte array */
|
|
52
|
+
function readULEB128(bytes, offset) {
|
|
53
|
+
let result = 0;
|
|
54
|
+
let shift = 0;
|
|
55
|
+
while (offset.value < bytes.length) {
|
|
56
|
+
const byte = bytes[offset.value++];
|
|
57
|
+
result |= (byte & 0x7f) << shift;
|
|
58
|
+
if ((byte & 0x80) === 0)
|
|
59
|
+
break;
|
|
60
|
+
shift += 7;
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/** Parse the dylink.0 custom section from a WASM module */
|
|
65
|
+
export function parseDylink(module) {
|
|
66
|
+
const sections = WebAssembly.Module.customSections(module, 'dylink.0');
|
|
67
|
+
if (sections.length === 0)
|
|
68
|
+
return null;
|
|
69
|
+
const bytes = new Uint8Array(sections[0]);
|
|
70
|
+
const offset = { value: 0 };
|
|
71
|
+
const info = {
|
|
72
|
+
memorySize: 0,
|
|
73
|
+
memoryAlignment: 0,
|
|
74
|
+
tableSize: 0,
|
|
75
|
+
tableAlignment: 0,
|
|
76
|
+
needed: [],
|
|
77
|
+
};
|
|
78
|
+
while (offset.value < bytes.length) {
|
|
79
|
+
const subsectionType = readULEB128(bytes, offset);
|
|
80
|
+
const subsectionSize = readULEB128(bytes, offset);
|
|
81
|
+
const subsectionEnd = offset.value + subsectionSize;
|
|
82
|
+
if (subsectionType === 1) {
|
|
83
|
+
// WASM_DYLINK_MEM_INFO
|
|
84
|
+
info.memorySize = readULEB128(bytes, offset);
|
|
85
|
+
info.memoryAlignment = readULEB128(bytes, offset);
|
|
86
|
+
info.tableSize = readULEB128(bytes, offset);
|
|
87
|
+
info.tableAlignment = readULEB128(bytes, offset);
|
|
88
|
+
}
|
|
89
|
+
else if (subsectionType === 2) {
|
|
90
|
+
// WASM_DYLINK_NEEDED
|
|
91
|
+
const count = readULEB128(bytes, offset);
|
|
92
|
+
for (let i = 0; i < count; i++) {
|
|
93
|
+
const len = readULEB128(bytes, offset);
|
|
94
|
+
const name = new TextDecoder().decode(bytes.slice(offset.value, offset.value + len));
|
|
95
|
+
offset.value += len;
|
|
96
|
+
info.needed.push(name);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
offset.value = subsectionEnd;
|
|
100
|
+
}
|
|
101
|
+
return info;
|
|
102
|
+
}
|
|
103
|
+
// ---- Alignment helper ----
|
|
104
|
+
/** Align a value up to 2^align */
|
|
105
|
+
function alignUp(value, align) {
|
|
106
|
+
if (align <= 0)
|
|
107
|
+
return value;
|
|
108
|
+
const mask = (1 << align) - 1;
|
|
109
|
+
return (value + mask) & ~mask;
|
|
110
|
+
}
|
|
111
|
+
// ---- Extension Loader ----
|
|
112
|
+
/**
|
|
113
|
+
* Load a WASM shared library extension and link it against the main module.
|
|
114
|
+
*
|
|
115
|
+
* @param descriptor - Extension description (name, wasm bytes, init function)
|
|
116
|
+
* @param mainExports - The main QuickJS WASM module's exports
|
|
117
|
+
* @param wasiBuiltins - Built-in WASI implementations (lowest priority)
|
|
118
|
+
* @param wasiUserOverrides - User-provided WASI overrides (highest priority)
|
|
119
|
+
* @param memoryProxy - A memory proxy for extension WASI factories
|
|
120
|
+
* @param allocBase - Optional fixed memory/table bases (for snapshot restore)
|
|
121
|
+
*/
|
|
122
|
+
export async function loadExtension(descriptor, mainExports, wasiBuiltins, wasiUserOverrides, memoryProxy, allocBase) {
|
|
123
|
+
// Compile the extension module
|
|
124
|
+
let module;
|
|
125
|
+
if (descriptor.wasm instanceof WebAssembly.Module) {
|
|
126
|
+
module = descriptor.wasm;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
module = await WebAssembly.compile(descriptor.wasm);
|
|
130
|
+
}
|
|
131
|
+
// Parse dylink.0 section
|
|
132
|
+
const dylink = parseDylink(module);
|
|
133
|
+
if (!dylink) {
|
|
134
|
+
throw new Error(`Extension "${descriptor.name}" is not a WASM shared library (missing dylink.0 section)`);
|
|
135
|
+
}
|
|
136
|
+
const memory = mainExports.memory;
|
|
137
|
+
const table = mainExports.__indirect_function_table;
|
|
138
|
+
const stackPointer = mainExports.__stack_pointer;
|
|
139
|
+
const mallocFn = mainExports.malloc;
|
|
140
|
+
if (!memory)
|
|
141
|
+
throw new Error('Main module does not export memory');
|
|
142
|
+
if (!table)
|
|
143
|
+
throw new Error('Main module does not export __indirect_function_table');
|
|
144
|
+
if (!mallocFn)
|
|
145
|
+
throw new Error('Main module does not export malloc');
|
|
146
|
+
// Allocate memory region for the extension's static data
|
|
147
|
+
let memoryBase;
|
|
148
|
+
let tableBase;
|
|
149
|
+
if (allocBase) {
|
|
150
|
+
// Restore mode: use the exact same bases as before
|
|
151
|
+
memoryBase = allocBase.memoryBase;
|
|
152
|
+
tableBase = allocBase.tableBase;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// Fresh allocation
|
|
156
|
+
if (dylink.memorySize > 0) {
|
|
157
|
+
// Use malloc from the main module to allocate in the shared heap
|
|
158
|
+
memoryBase = mallocFn(dylink.memorySize);
|
|
159
|
+
if (memoryBase === 0) {
|
|
160
|
+
throw new Error(`Failed to allocate ${dylink.memorySize} bytes for extension "${descriptor.name}"`);
|
|
161
|
+
}
|
|
162
|
+
// Zero-initialize the region
|
|
163
|
+
new Uint8Array(memory.buffer, memoryBase, dylink.memorySize).fill(0);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
memoryBase = 0;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Grow the function table if needed
|
|
170
|
+
if (allocBase) {
|
|
171
|
+
tableBase = allocBase.tableBase;
|
|
172
|
+
// Ensure table is large enough
|
|
173
|
+
if (tableBase + dylink.tableSize > table.length) {
|
|
174
|
+
table.grow(tableBase + dylink.tableSize - table.length);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
tableBase = table.length;
|
|
179
|
+
if (dylink.tableSize > 0) {
|
|
180
|
+
table.grow(dylink.tableSize);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Build the import object
|
|
184
|
+
const extImports = WebAssembly.Module.imports(module);
|
|
185
|
+
const importObj = {
|
|
186
|
+
env: {},
|
|
187
|
+
'GOT.mem': {},
|
|
188
|
+
'GOT.func': {},
|
|
189
|
+
};
|
|
190
|
+
// Provide wasi_snapshot_preview1 imports to extensions that need them.
|
|
191
|
+
// Layered merge: builtins → extension-provided → user overrides.
|
|
192
|
+
const needsWasi = extImports.some((imp) => imp.module === 'wasi_snapshot_preview1');
|
|
193
|
+
if (needsWasi) {
|
|
194
|
+
const extWasi = (descriptor.wasi && memoryProxy) ? descriptor.wasi(memoryProxy) : undefined;
|
|
195
|
+
importObj['wasi_snapshot_preview1'] = {
|
|
196
|
+
...wasiBuiltins, // 1. Built-in defaults (lowest priority)
|
|
197
|
+
...extWasi, // 2. Extension-provided
|
|
198
|
+
...wasiUserOverrides // 3. User overrides (highest priority)
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
// Collect names of functions the extension exports (for self-resolution)
|
|
202
|
+
const extExportNames = new Set(WebAssembly.Module.exports(module)
|
|
203
|
+
.filter((e) => e.kind === 'function')
|
|
204
|
+
.map((e) => e.name));
|
|
205
|
+
const unresolvedFuncs = new Set();
|
|
206
|
+
for (const imp of extImports) {
|
|
207
|
+
if (imp.module === 'env') {
|
|
208
|
+
if (imp.name === 'memory' && imp.kind === 'memory') {
|
|
209
|
+
importObj.env.memory = memory;
|
|
210
|
+
}
|
|
211
|
+
else if (imp.name === '__indirect_function_table' &&
|
|
212
|
+
imp.kind === 'table') {
|
|
213
|
+
importObj.env.__indirect_function_table = table;
|
|
214
|
+
}
|
|
215
|
+
else if (imp.name === '__memory_base' && imp.kind === 'global') {
|
|
216
|
+
importObj.env.__memory_base = new WebAssembly.Global({ value: 'i32', mutable: false }, memoryBase);
|
|
217
|
+
}
|
|
218
|
+
else if (imp.name === '__table_base' && imp.kind === 'global') {
|
|
219
|
+
importObj.env.__table_base = new WebAssembly.Global({ value: 'i32', mutable: false }, tableBase);
|
|
220
|
+
}
|
|
221
|
+
else if (imp.name === '__stack_pointer' && imp.kind === 'global') {
|
|
222
|
+
importObj.env.__stack_pointer = stackPointer;
|
|
223
|
+
}
|
|
224
|
+
else if (imp.kind === 'function') {
|
|
225
|
+
// Resolve function imports from the main module's exports
|
|
226
|
+
const resolved = mainExports[imp.name];
|
|
227
|
+
if (resolved && typeof resolved === 'function') {
|
|
228
|
+
importObj.env[imp.name] = resolved;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
// Provide a trap stub for unresolved symbols (e.g., C++ runtime
|
|
232
|
+
// functions like wstring methods that are imported but never called).
|
|
233
|
+
// If actually called at runtime, this will throw.
|
|
234
|
+
unresolvedFuncs.add(imp.name);
|
|
235
|
+
importObj.env[imp.name] = () => {
|
|
236
|
+
throw new Error(`Extension "${descriptor.name}" called unresolved symbol: env.${imp.name}`);
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else if (imp.kind === 'global') {
|
|
241
|
+
// Other globals - try to resolve from main exports
|
|
242
|
+
const resolved = mainExports[imp.name];
|
|
243
|
+
if (resolved instanceof WebAssembly.Global) {
|
|
244
|
+
importObj.env[imp.name] = resolved;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
// Create a zero-initialized mutable global as fallback
|
|
248
|
+
importObj.env[imp.name] = new WebAssembly.Global({ value: 'i32', mutable: true }, 0);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else if (imp.module === 'GOT.mem' && imp.kind === 'global') {
|
|
253
|
+
// GOT.mem entries are mutable globals containing memory addresses of symbols
|
|
254
|
+
// Try to resolve the symbol's address - for now, create mutable globals
|
|
255
|
+
// that can be patched by __wasm_apply_data_relocs
|
|
256
|
+
importObj['GOT.mem'][imp.name] = new WebAssembly.Global({ value: 'i32', mutable: true }, 0);
|
|
257
|
+
}
|
|
258
|
+
else if (imp.module === 'GOT.func' && imp.kind === 'global') {
|
|
259
|
+
// GOT.func entries are mutable globals containing table indices of functions.
|
|
260
|
+
// We resolve these by finding the function in the main module's exports,
|
|
261
|
+
// adding it to the indirect function table, and providing the table index.
|
|
262
|
+
const resolved = mainExports[imp.name];
|
|
263
|
+
if (resolved && typeof resolved === 'function') {
|
|
264
|
+
const idx = table.length;
|
|
265
|
+
table.grow(1);
|
|
266
|
+
table.set(idx, resolved);
|
|
267
|
+
importObj['GOT.func'][imp.name] = new WebAssembly.Global({ value: 'i32', mutable: true }, idx);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
importObj['GOT.func'][imp.name] = new WebAssembly.Global({ value: 'i32', mutable: true }, 0);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// Self-resolve: in WASM shared libraries, the linker with --allow-undefined
|
|
275
|
+
// may leave symbols as both imports and exports (e.g., C++ weak symbols from
|
|
276
|
+
// libc++ string.cpp.o that satisfy references from ada.o). We use indirection
|
|
277
|
+
// through mutable wrapper functions: first create wrappers that initially trap,
|
|
278
|
+
// then instantiate, then patch the wrappers to forward to the instance's own exports.
|
|
279
|
+
// This way all internal calls go through the wrappers which point to the final exports.
|
|
280
|
+
const selfResolvable = [...unresolvedFuncs].filter((name) => extExportNames.has(name));
|
|
281
|
+
// For self-resolvable symbols, create mutable wrappers
|
|
282
|
+
const wrappers = {};
|
|
283
|
+
for (const name of selfResolvable) {
|
|
284
|
+
const wrapper = { target: null };
|
|
285
|
+
wrappers[name] = wrapper;
|
|
286
|
+
// Replace the trap stub with a wrapper that forwards to the target
|
|
287
|
+
importObj.env[name] = (...args) => {
|
|
288
|
+
if (!wrapper.target) {
|
|
289
|
+
throw new Error(`Extension "${descriptor.name}" called unresolved symbol during init: env.${name}`);
|
|
290
|
+
}
|
|
291
|
+
return wrapper.target(...args);
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
const instance = await WebAssembly.instantiate(module, importObj);
|
|
295
|
+
const extExports = instance.exports;
|
|
296
|
+
// Patch wrappers to point to the instance's own exports
|
|
297
|
+
for (const name of selfResolvable) {
|
|
298
|
+
const selfExport = extExports[name];
|
|
299
|
+
if (typeof selfExport === 'function') {
|
|
300
|
+
wrappers[name].target = selfExport;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Apply data relocations if the extension has them
|
|
304
|
+
if (typeof extExports.__wasm_apply_data_relocs === 'function') {
|
|
305
|
+
extExports.__wasm_apply_data_relocs();
|
|
306
|
+
}
|
|
307
|
+
// Call constructors if present
|
|
308
|
+
if (typeof extExports.__wasm_call_ctors === 'function') {
|
|
309
|
+
extExports.__wasm_call_ctors();
|
|
310
|
+
}
|
|
311
|
+
const initFn = descriptor.initFn ?? `qjs_ext_${descriptor.name.replace(/-/g, '_')}_init`;
|
|
312
|
+
const ext = {
|
|
313
|
+
name: descriptor.name,
|
|
314
|
+
module,
|
|
315
|
+
instance,
|
|
316
|
+
dylink,
|
|
317
|
+
memoryBase,
|
|
318
|
+
tableBase,
|
|
319
|
+
initFn,
|
|
320
|
+
};
|
|
321
|
+
// Check for version reporting
|
|
322
|
+
ext.versions = extractExtensionVersions(ext, memory);
|
|
323
|
+
return ext;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Call the extension's init function, passing the JSContext and JSRuntime
|
|
327
|
+
* pointers from the main module.
|
|
328
|
+
*/
|
|
329
|
+
export function initExtension(ext, mainExports) {
|
|
330
|
+
const initFunc = ext.instance.exports[ext.initFn];
|
|
331
|
+
if (typeof initFunc !== 'function') {
|
|
332
|
+
throw new Error(`Extension "${ext.name}" does not export init function "${ext.initFn}"`);
|
|
333
|
+
}
|
|
334
|
+
// Get the JSContext and JSRuntime pointers from the main module
|
|
335
|
+
const ctxPtr = mainExports.qjs_get_context_ptr();
|
|
336
|
+
const rtPtr = mainExports.qjs_get_runtime_ptr();
|
|
337
|
+
// Call the extension's init function: qjs_ext_xxx_init(ctx, rt)
|
|
338
|
+
const result = initFunc(ctxPtr, rtPtr);
|
|
339
|
+
if (result !== 0) {
|
|
340
|
+
throw new Error(`Extension "${ext.name}" init function returned error code ${result}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Re-instantiate extensions for snapshot restore.
|
|
345
|
+
*
|
|
346
|
+
* During restore, we need to:
|
|
347
|
+
* 1. Instantiate extension modules with the same memory/table bases
|
|
348
|
+
* 2. Let them populate the function table (via elem segments and __wasm_apply_data_relocs)
|
|
349
|
+
* 3. Do NOT call the init function (the state is already in the snapshot memory)
|
|
350
|
+
*
|
|
351
|
+
* This reconstructs the function table entries that extensions need, without
|
|
352
|
+
* modifying linear memory (which will be overwritten by the snapshot).
|
|
353
|
+
*/
|
|
354
|
+
export async function restoreExtensions(descriptors, extensionMeta, mainExports, wasiBuiltins, wasiUserOverrides, memoryProxy) {
|
|
355
|
+
const loaded = [];
|
|
356
|
+
for (const meta of extensionMeta) {
|
|
357
|
+
// Find the descriptor for this extension
|
|
358
|
+
const descriptor = descriptors.find((d) => d.name === meta.name);
|
|
359
|
+
if (!descriptor) {
|
|
360
|
+
throw new Error(`Extension "${meta.name}" required by snapshot but not provided`);
|
|
361
|
+
}
|
|
362
|
+
// Load with fixed bases
|
|
363
|
+
const ext = await loadExtension(descriptor, mainExports, wasiBuiltins, wasiUserOverrides, memoryProxy, {
|
|
364
|
+
memoryBase: meta.memoryBase,
|
|
365
|
+
tableBase: meta.tableBase,
|
|
366
|
+
});
|
|
367
|
+
ext.initFn = meta.initFn;
|
|
368
|
+
loaded.push(ext);
|
|
369
|
+
}
|
|
370
|
+
return loaded;
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.js","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"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"}
|