@tybys/wasm-util 0.1.0 → 0.3.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 +46 -43
- package/dist/wasm-util.d.ts +24 -1
- package/dist/wasm-util.esm-bundler.js +80 -21
- package/dist/wasm-util.esm.js +80 -21
- package/dist/wasm-util.esm.min.js +1 -1
- package/dist/wasm-util.js +83 -20
- package/dist/wasm-util.min.js +1 -1
- package/lib/cjs/asyncify.js +5 -11
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/jspi.js +46 -0
- package/lib/cjs/load.js +10 -6
- package/lib/cjs/memory.js +6 -3
- package/lib/cjs/wasi/preview1.js +6 -1
- package/lib/cjs/wasi/util.js +13 -1
- package/lib/cjs/webassembly.js +13 -0
- package/lib/mjs/asyncify.mjs +6 -12
- package/lib/mjs/index.mjs +1 -0
- package/lib/mjs/jspi.mjs +39 -0
- package/lib/mjs/load.mjs +10 -6
- package/lib/mjs/memory.mjs +5 -2
- package/lib/mjs/wasi/preview1.mjs +5 -1
- package/lib/mjs/wasi/util.mjs +11 -0
- package/lib/mjs/webassembly.mjs +9 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,51 @@ WebAssembly related utils for browser environment
|
|
|
8
8
|
|
|
9
9
|
All example code below need to be bundled by ES module bundlers like `webpack` / `rollup`, or specify import map in browser native ES module runtime.
|
|
10
10
|
|
|
11
|
+
### WASI polyfill for browser
|
|
12
|
+
|
|
13
|
+
The API is similar to the `require('wasi').WASI` in Node.js.
|
|
14
|
+
|
|
15
|
+
You can use `memfs-browser` to provide filesystem capability.
|
|
16
|
+
|
|
17
|
+
- Example: [https://github.com/toyobayashi/wasi-wabt](https://github.com/toyobayashi/wasi-wabt)
|
|
18
|
+
- Demo: [https://toyobayashi.github.io/wasi-wabt/](https://toyobayashi.github.io/wasi-wabt/)
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { load, WASI } from '@tybys/wasm-util'
|
|
22
|
+
import { Volumn, createFsFromVolume } from 'memfs-browser'
|
|
23
|
+
|
|
24
|
+
const fs = createFsFromVolume(Volume.from({
|
|
25
|
+
'/home/wasi': null
|
|
26
|
+
}))
|
|
27
|
+
|
|
28
|
+
const wasi = new WASI({
|
|
29
|
+
args: ['chrome', 'file.wasm'],
|
|
30
|
+
env: {
|
|
31
|
+
NODE_ENV: 'development',
|
|
32
|
+
WASI_SDK_PATH: '/opt/wasi-sdk'
|
|
33
|
+
},
|
|
34
|
+
preopens: {
|
|
35
|
+
'/': '/'
|
|
36
|
+
},
|
|
37
|
+
filesystem: { type: 'memfs', fs },
|
|
38
|
+
|
|
39
|
+
// redirect stdout / stderr
|
|
40
|
+
|
|
41
|
+
// print (text) { console.log(text) },
|
|
42
|
+
// printErr (text) { console.error(text) }
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const imports = {
|
|
46
|
+
wasi_snapshot_preview1: wasi.wasiImport
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const { module, instance } = await load('/path/to/file.wasm', imports)
|
|
50
|
+
wasi.start(instance)
|
|
51
|
+
// wasi.initialize(instance)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Implemented syscalls: [wasi_snapshot_preview1](#wasi_snapshot_preview1)
|
|
55
|
+
|
|
11
56
|
### `load` / `loadSync`
|
|
12
57
|
|
|
13
58
|
`loadSync` has 4KB wasm size limit in browser.
|
|
@@ -99,49 +144,7 @@ await p
|
|
|
99
144
|
console.log(Date.now() - now >= 200)
|
|
100
145
|
```
|
|
101
146
|
|
|
102
|
-
###
|
|
103
|
-
|
|
104
|
-
The API is similar to the `require('wasi').WASI` in Node.js.
|
|
105
|
-
|
|
106
|
-
You can use `memfs-browser` to provide filesystem capability.
|
|
107
|
-
|
|
108
|
-
```js
|
|
109
|
-
import { load, WASI } from '@tybys/wasm-util'
|
|
110
|
-
import { Volumn, createFsFromVolume } from 'memfs-browser'
|
|
111
|
-
|
|
112
|
-
const fs = createFsFromVolume(Volume.from({
|
|
113
|
-
'/home/wasi': null
|
|
114
|
-
}))
|
|
115
|
-
|
|
116
|
-
const wasi = new WASI({
|
|
117
|
-
args: ['chrome', 'file.wasm'],
|
|
118
|
-
env: {
|
|
119
|
-
NODE_ENV: 'development',
|
|
120
|
-
WASI_SDK_PATH: '/opt/wasi-sdk'
|
|
121
|
-
},
|
|
122
|
-
preopens: {
|
|
123
|
-
'/': '/'
|
|
124
|
-
},
|
|
125
|
-
filesystem: { type: 'memfs', fs },
|
|
126
|
-
|
|
127
|
-
// redirect stdout / stderr
|
|
128
|
-
|
|
129
|
-
// print (text) { console.log(text) },
|
|
130
|
-
// printErr (text) { console.error(text) }
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
const imports = {
|
|
134
|
-
wasi_snapshot_preview1: wasi.wasiImport
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const { module, instance } = await load('/path/to/file.wasm', imports)
|
|
138
|
-
wasi.start(instance)
|
|
139
|
-
// wasi.initialize(instance)
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
Implemented syscalls:
|
|
143
|
-
|
|
144
|
-
#### wasi_snapshot_preview1
|
|
147
|
+
### wasi_snapshot_preview1
|
|
145
148
|
|
|
146
149
|
- [x] args_get
|
|
147
150
|
- [x] args_sizes_get
|
package/dist/wasm-util.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export declare function load(urlOrBuffer: string | URL | BufferSource, imports?:
|
|
|
64
64
|
export declare function loadSync(buffer: BufferSource, imports?: WebAssembly.Imports, asyncify?: AsyncifyOptions): WebAssembly.WebAssemblyInstantiatedSource;
|
|
65
65
|
|
|
66
66
|
/** @public */
|
|
67
|
-
export declare class Memory extends
|
|
67
|
+
export declare class Memory extends WebAssemblyMemory {
|
|
68
68
|
constructor(descriptor: WebAssembly.MemoryDescriptor);
|
|
69
69
|
get HEAP8(): Int8Array;
|
|
70
70
|
get HEAPU8(): Uint8Array;
|
|
@@ -79,6 +79,11 @@ export declare class Memory extends WebAssembly.Memory {
|
|
|
79
79
|
get view(): DataView;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/** @public */
|
|
83
|
+
export declare type PromisifyExports<T, U> = T extends Record<string, any> ? {
|
|
84
|
+
[P in keyof T]: T[P] extends Callable ? U extends Array<keyof T> ? P extends U[number] ? AsyncifyExportFunction<T[P]> : T[P] : AsyncifyExportFunction<T[P]> : T[P];
|
|
85
|
+
} : T;
|
|
86
|
+
|
|
82
87
|
/** @public */
|
|
83
88
|
export declare class WASI {
|
|
84
89
|
private [kSetMemory];
|
|
@@ -108,6 +113,24 @@ export declare interface WASIOptions {
|
|
|
108
113
|
};
|
|
109
114
|
}
|
|
110
115
|
|
|
116
|
+
/** @public */
|
|
117
|
+
export declare const WebAssemblyMemory: {
|
|
118
|
+
new (descriptor: WebAssembly.MemoryDescriptor): WebAssembly.Memory;
|
|
119
|
+
prototype: WebAssembly.Memory;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/** @public */
|
|
123
|
+
export declare function wrapAsyncExport<T extends Function = any>(f: Function): T;
|
|
124
|
+
|
|
125
|
+
/** @public */
|
|
126
|
+
export declare function wrapAsyncImport(f: Function, parameterType: WebAssembly.ValueType[], returnType: WebAssembly.ValueType[]): Function;
|
|
127
|
+
|
|
128
|
+
/** @public */
|
|
129
|
+
export declare function wrapExports<T extends WebAssembly.Exports>(exports: T): PromisifyExports<T, void>;
|
|
130
|
+
|
|
131
|
+
/** @public */
|
|
132
|
+
export declare function wrapExports<T extends WebAssembly.Exports, U extends Array<keyof T>>(exports: T, needWrap: U): PromisifyExports<T, U>;
|
|
133
|
+
|
|
111
134
|
export { }
|
|
112
135
|
|
|
113
136
|
export as namespace wasmUtil;
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
const _WebAssembly = typeof WebAssembly !== 'undefined'
|
|
2
|
+
? WebAssembly
|
|
3
|
+
: typeof WXWebAssembly !== 'undefined'
|
|
4
|
+
? WXWebAssembly
|
|
5
|
+
: undefined;
|
|
6
|
+
if (!_WebAssembly) {
|
|
7
|
+
throw new Error('WebAssembly is not supported in this environment');
|
|
8
|
+
}
|
|
9
|
+
|
|
1
10
|
function validateObject(value, name) {
|
|
2
11
|
if (value === null || typeof value !== 'object') {
|
|
3
12
|
throw new TypeError(`${name} must be an object. Received ${value === null ? 'null' : typeof value}`);
|
|
@@ -30,6 +39,17 @@ function validateUndefined(value, name) {
|
|
|
30
39
|
}
|
|
31
40
|
function isPromiseLike(obj) {
|
|
32
41
|
return !!(obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function');
|
|
42
|
+
}
|
|
43
|
+
function wrapInstanceExports(exports, mapFn) {
|
|
44
|
+
const newExports = Object.create(null);
|
|
45
|
+
Object.keys(exports).forEach(name => {
|
|
46
|
+
const exportValue = exports[name];
|
|
47
|
+
Object.defineProperty(newExports, name, {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
value: mapFn(exportValue, name)
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
return newExports;
|
|
33
53
|
}
|
|
34
54
|
|
|
35
55
|
const ignoreNames = [
|
|
@@ -69,7 +89,7 @@ class Asyncify {
|
|
|
69
89
|
if (this.exports) {
|
|
70
90
|
throw new Error('Asyncify has been initialized');
|
|
71
91
|
}
|
|
72
|
-
if (!(memory instanceof
|
|
92
|
+
if (!(memory instanceof _WebAssembly.Memory)) {
|
|
73
93
|
throw new TypeError('Require WebAssembly.Memory object');
|
|
74
94
|
}
|
|
75
95
|
const exports = instance.exports;
|
|
@@ -104,7 +124,7 @@ class Asyncify {
|
|
|
104
124
|
new Int32Array(memory.buffer, this.dataPtr).set([address.start, address.end]);
|
|
105
125
|
}
|
|
106
126
|
this.exports = this.wrapExports(exports, options.wrapExports);
|
|
107
|
-
const asyncifiedInstance = Object.create(
|
|
127
|
+
const asyncifiedInstance = Object.create(_WebAssembly.Instance.prototype);
|
|
108
128
|
Object.defineProperty(asyncifiedInstance, 'exports', { value: this.exports });
|
|
109
129
|
// Object.setPrototypeOf(instance, Instance.prototype)
|
|
110
130
|
return asyncifiedInstance;
|
|
@@ -163,20 +183,13 @@ class Asyncify {
|
|
|
163
183
|
});
|
|
164
184
|
}
|
|
165
185
|
wrapExports(exports, needWrap) {
|
|
166
|
-
|
|
167
|
-
Object.keys(exports).forEach(name => {
|
|
168
|
-
const exportValue = exports[name];
|
|
186
|
+
return wrapInstanceExports(exports, (exportValue, name) => {
|
|
169
187
|
let ignore = ignoreNames.indexOf(name) !== -1 || typeof exportValue !== 'function';
|
|
170
188
|
if (Array.isArray(needWrap)) {
|
|
171
189
|
ignore = ignore || (needWrap.indexOf(name) === -1);
|
|
172
190
|
}
|
|
173
|
-
|
|
174
|
-
enumerable: true,
|
|
175
|
-
value: ignore ? exportValue : this.wrapExportFunction(exportValue)
|
|
176
|
-
});
|
|
191
|
+
return ignore ? exportValue : this.wrapExportFunction(exportValue);
|
|
177
192
|
});
|
|
178
|
-
// wrappedExports.set(exports, newExports)
|
|
179
|
-
return newExports;
|
|
180
193
|
}
|
|
181
194
|
}
|
|
182
195
|
// /** @public */
|
|
@@ -194,9 +207,12 @@ class Asyncify {
|
|
|
194
207
|
// Object.defineProperty(Instance.prototype, 'exports', { enumerable: true })
|
|
195
208
|
|
|
196
209
|
async function fetchWasm(urlOrBuffer, imports) {
|
|
210
|
+
if (typeof wx !== 'undefined' && typeof __wxConfig !== 'undefined') {
|
|
211
|
+
return await _WebAssembly.instantiate(urlOrBuffer, imports);
|
|
212
|
+
}
|
|
197
213
|
const response = await fetch(urlOrBuffer);
|
|
198
214
|
const buffer = await response.arrayBuffer();
|
|
199
|
-
const source = await
|
|
215
|
+
const source = await _WebAssembly.instantiate(buffer, imports);
|
|
200
216
|
return source;
|
|
201
217
|
}
|
|
202
218
|
/** @public */
|
|
@@ -213,7 +229,7 @@ async function load(urlOrBuffer, imports, asyncify) {
|
|
|
213
229
|
imports = asyncifyHelper.wrapImports(imports);
|
|
214
230
|
}
|
|
215
231
|
if (urlOrBuffer instanceof ArrayBuffer || ArrayBuffer.isView(urlOrBuffer)) {
|
|
216
|
-
source = await
|
|
232
|
+
source = await _WebAssembly.instantiate(urlOrBuffer, imports);
|
|
217
233
|
if (asyncify) {
|
|
218
234
|
const memory = source.instance.exports.memory || ((_a = imports.env) === null || _a === void 0 ? void 0 : _a.memory);
|
|
219
235
|
return { module: source.module, instance: asyncifyHelper.init(memory, source.instance, asyncify) };
|
|
@@ -223,9 +239,9 @@ async function load(urlOrBuffer, imports, asyncify) {
|
|
|
223
239
|
if (typeof urlOrBuffer !== 'string' && !(urlOrBuffer instanceof URL)) {
|
|
224
240
|
throw new TypeError('Invalid source');
|
|
225
241
|
}
|
|
226
|
-
if (typeof
|
|
242
|
+
if (typeof _WebAssembly.instantiateStreaming === 'function') {
|
|
227
243
|
try {
|
|
228
|
-
source = await
|
|
244
|
+
source = await _WebAssembly.instantiateStreaming(fetch(urlOrBuffer), imports);
|
|
229
245
|
}
|
|
230
246
|
catch (_) {
|
|
231
247
|
source = await fetchWasm(urlOrBuffer, imports);
|
|
@@ -255,8 +271,8 @@ function loadSync(buffer, imports, asyncify) {
|
|
|
255
271
|
asyncifyHelper = new Asyncify();
|
|
256
272
|
imports = asyncifyHelper.wrapImports(imports);
|
|
257
273
|
}
|
|
258
|
-
const module = new
|
|
259
|
-
const instance = new
|
|
274
|
+
const module = new _WebAssembly.Module(buffer);
|
|
275
|
+
const instance = new _WebAssembly.Instance(module, imports);
|
|
260
276
|
const source = { instance, module };
|
|
261
277
|
if (asyncify) {
|
|
262
278
|
const memory = source.instance.exports.memory || ((_a = imports.env) === null || _a === void 0 ? void 0 : _a.memory);
|
|
@@ -842,7 +858,9 @@ class FileDescriptorTable {
|
|
|
842
858
|
}
|
|
843
859
|
|
|
844
860
|
/** @public */
|
|
845
|
-
|
|
861
|
+
const WebAssemblyMemory = _WebAssembly.Memory;
|
|
862
|
+
/** @public */
|
|
863
|
+
class Memory extends WebAssemblyMemory {
|
|
846
864
|
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
|
847
865
|
constructor(descriptor) {
|
|
848
866
|
super(descriptor);
|
|
@@ -861,7 +879,7 @@ class Memory extends WebAssembly.Memory {
|
|
|
861
879
|
}
|
|
862
880
|
/** @public */
|
|
863
881
|
function extendMemory(memory) {
|
|
864
|
-
if (Object.getPrototypeOf(memory) ===
|
|
882
|
+
if (Object.getPrototypeOf(memory) === _WebAssembly.Memory.prototype) {
|
|
865
883
|
Object.setPrototypeOf(memory, Memory.prototype);
|
|
866
884
|
}
|
|
867
885
|
return memory;
|
|
@@ -972,7 +990,7 @@ function readStdin() {
|
|
|
972
990
|
class WASI$1 {
|
|
973
991
|
constructor(args, env, preopens, stdio, filesystem, print, printErr) {
|
|
974
992
|
this._setMemory = function _setMemory(m) {
|
|
975
|
-
if (!(m instanceof
|
|
993
|
+
if (!(m instanceof _WebAssembly.Memory)) {
|
|
976
994
|
throw new TypeError('"instance.exports.memory" property must be a WebAssembly.Memory');
|
|
977
995
|
}
|
|
978
996
|
_memory.set(this, extendMemory(m));
|
|
@@ -1279,6 +1297,9 @@ class WASI$1 {
|
|
|
1279
1297
|
let buffer;
|
|
1280
1298
|
let nread = 0;
|
|
1281
1299
|
if (fd === 0) {
|
|
1300
|
+
if (typeof window === 'undefined' || typeof window.prompt !== 'function') {
|
|
1301
|
+
return 58 /* WasiErrno.ENOTSUP */;
|
|
1302
|
+
}
|
|
1282
1303
|
buffer = readStdin();
|
|
1283
1304
|
nread = buffer ? copyMemory(ioVecs, buffer) : 0;
|
|
1284
1305
|
}
|
|
@@ -1876,4 +1897,42 @@ function wasiReturnOnProcExit(rval) {
|
|
|
1876
1897
|
throw kExitCode;
|
|
1877
1898
|
}
|
|
1878
1899
|
|
|
1879
|
-
|
|
1900
|
+
function checkWebAssemblyFunction() {
|
|
1901
|
+
const WebAssemblyFunction = _WebAssembly.Function;
|
|
1902
|
+
if (typeof WebAssemblyFunction !== 'function') {
|
|
1903
|
+
throw new Error('WebAssembly.Function is not supported in this environment.' +
|
|
1904
|
+
' If you are using V8 based browser like Chrome, try to specify' +
|
|
1905
|
+
' --js-flag="--wasm-staging --experimental-wasm-stack-switching"');
|
|
1906
|
+
}
|
|
1907
|
+
return WebAssemblyFunction;
|
|
1908
|
+
}
|
|
1909
|
+
/** @public */
|
|
1910
|
+
function wrapAsyncImport(f, parameterType, returnType) {
|
|
1911
|
+
const WebAssemblyFunction = checkWebAssemblyFunction();
|
|
1912
|
+
if (typeof f !== 'function') {
|
|
1913
|
+
throw new TypeError('Function required');
|
|
1914
|
+
}
|
|
1915
|
+
const parameters = parameterType.slice(0);
|
|
1916
|
+
parameters.unshift('externref');
|
|
1917
|
+
return new WebAssemblyFunction({ parameters, results: returnType }, f, { suspending: 'first' });
|
|
1918
|
+
}
|
|
1919
|
+
/** @public */
|
|
1920
|
+
function wrapAsyncExport(f) {
|
|
1921
|
+
const WebAssemblyFunction = checkWebAssemblyFunction();
|
|
1922
|
+
if (typeof f !== 'function') {
|
|
1923
|
+
throw new TypeError('Function required');
|
|
1924
|
+
}
|
|
1925
|
+
return new WebAssemblyFunction({ parameters: [...WebAssemblyFunction.type(f).parameters.slice(1)], results: ['externref'] }, f, { promising: 'first' });
|
|
1926
|
+
}
|
|
1927
|
+
/** @public */
|
|
1928
|
+
function wrapExports(exports, needWrap) {
|
|
1929
|
+
return wrapInstanceExports(exports, (exportValue, name) => {
|
|
1930
|
+
let ignore = typeof exportValue !== 'function';
|
|
1931
|
+
if (Array.isArray(needWrap)) {
|
|
1932
|
+
ignore = ignore || (needWrap.indexOf(name) === -1);
|
|
1933
|
+
}
|
|
1934
|
+
return ignore ? exportValue : wrapAsyncExport(exportValue);
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
export { Asyncify, Memory, WASI, WebAssemblyMemory, extendMemory, load, loadSync, wrapAsyncExport, wrapAsyncImport, wrapExports };
|
package/dist/wasm-util.esm.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
const _WebAssembly = typeof WebAssembly !== 'undefined'
|
|
2
|
+
? WebAssembly
|
|
3
|
+
: typeof WXWebAssembly !== 'undefined'
|
|
4
|
+
? WXWebAssembly
|
|
5
|
+
: undefined;
|
|
6
|
+
if (!_WebAssembly) {
|
|
7
|
+
throw new Error('WebAssembly is not supported in this environment');
|
|
8
|
+
}
|
|
9
|
+
|
|
1
10
|
function validateObject(value, name) {
|
|
2
11
|
if (value === null || typeof value !== 'object') {
|
|
3
12
|
throw new TypeError(`${name} must be an object. Received ${value === null ? 'null' : typeof value}`);
|
|
@@ -30,6 +39,17 @@ function validateUndefined(value, name) {
|
|
|
30
39
|
}
|
|
31
40
|
function isPromiseLike(obj) {
|
|
32
41
|
return !!(obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function');
|
|
42
|
+
}
|
|
43
|
+
function wrapInstanceExports(exports, mapFn) {
|
|
44
|
+
const newExports = Object.create(null);
|
|
45
|
+
Object.keys(exports).forEach(name => {
|
|
46
|
+
const exportValue = exports[name];
|
|
47
|
+
Object.defineProperty(newExports, name, {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
value: mapFn(exportValue, name)
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
return newExports;
|
|
33
53
|
}
|
|
34
54
|
|
|
35
55
|
const ignoreNames = [
|
|
@@ -69,7 +89,7 @@ class Asyncify {
|
|
|
69
89
|
if (this.exports) {
|
|
70
90
|
throw new Error('Asyncify has been initialized');
|
|
71
91
|
}
|
|
72
|
-
if (!(memory instanceof
|
|
92
|
+
if (!(memory instanceof _WebAssembly.Memory)) {
|
|
73
93
|
throw new TypeError('Require WebAssembly.Memory object');
|
|
74
94
|
}
|
|
75
95
|
const exports = instance.exports;
|
|
@@ -104,7 +124,7 @@ class Asyncify {
|
|
|
104
124
|
new Int32Array(memory.buffer, this.dataPtr).set([address.start, address.end]);
|
|
105
125
|
}
|
|
106
126
|
this.exports = this.wrapExports(exports, options.wrapExports);
|
|
107
|
-
const asyncifiedInstance = Object.create(
|
|
127
|
+
const asyncifiedInstance = Object.create(_WebAssembly.Instance.prototype);
|
|
108
128
|
Object.defineProperty(asyncifiedInstance, 'exports', { value: this.exports });
|
|
109
129
|
// Object.setPrototypeOf(instance, Instance.prototype)
|
|
110
130
|
return asyncifiedInstance;
|
|
@@ -163,20 +183,13 @@ class Asyncify {
|
|
|
163
183
|
});
|
|
164
184
|
}
|
|
165
185
|
wrapExports(exports, needWrap) {
|
|
166
|
-
|
|
167
|
-
Object.keys(exports).forEach(name => {
|
|
168
|
-
const exportValue = exports[name];
|
|
186
|
+
return wrapInstanceExports(exports, (exportValue, name) => {
|
|
169
187
|
let ignore = ignoreNames.indexOf(name) !== -1 || typeof exportValue !== 'function';
|
|
170
188
|
if (Array.isArray(needWrap)) {
|
|
171
189
|
ignore = ignore || (needWrap.indexOf(name) === -1);
|
|
172
190
|
}
|
|
173
|
-
|
|
174
|
-
enumerable: true,
|
|
175
|
-
value: ignore ? exportValue : this.wrapExportFunction(exportValue)
|
|
176
|
-
});
|
|
191
|
+
return ignore ? exportValue : this.wrapExportFunction(exportValue);
|
|
177
192
|
});
|
|
178
|
-
// wrappedExports.set(exports, newExports)
|
|
179
|
-
return newExports;
|
|
180
193
|
}
|
|
181
194
|
}
|
|
182
195
|
// /** @public */
|
|
@@ -194,9 +207,12 @@ class Asyncify {
|
|
|
194
207
|
// Object.defineProperty(Instance.prototype, 'exports', { enumerable: true })
|
|
195
208
|
|
|
196
209
|
async function fetchWasm(urlOrBuffer, imports) {
|
|
210
|
+
if (typeof wx !== 'undefined' && typeof __wxConfig !== 'undefined') {
|
|
211
|
+
return await _WebAssembly.instantiate(urlOrBuffer, imports);
|
|
212
|
+
}
|
|
197
213
|
const response = await fetch(urlOrBuffer);
|
|
198
214
|
const buffer = await response.arrayBuffer();
|
|
199
|
-
const source = await
|
|
215
|
+
const source = await _WebAssembly.instantiate(buffer, imports);
|
|
200
216
|
return source;
|
|
201
217
|
}
|
|
202
218
|
/** @public */
|
|
@@ -213,7 +229,7 @@ async function load(urlOrBuffer, imports, asyncify) {
|
|
|
213
229
|
imports = asyncifyHelper.wrapImports(imports);
|
|
214
230
|
}
|
|
215
231
|
if (urlOrBuffer instanceof ArrayBuffer || ArrayBuffer.isView(urlOrBuffer)) {
|
|
216
|
-
source = await
|
|
232
|
+
source = await _WebAssembly.instantiate(urlOrBuffer, imports);
|
|
217
233
|
if (asyncify) {
|
|
218
234
|
const memory = source.instance.exports.memory || ((_a = imports.env) === null || _a === void 0 ? void 0 : _a.memory);
|
|
219
235
|
return { module: source.module, instance: asyncifyHelper.init(memory, source.instance, asyncify) };
|
|
@@ -223,9 +239,9 @@ async function load(urlOrBuffer, imports, asyncify) {
|
|
|
223
239
|
if (typeof urlOrBuffer !== 'string' && !(urlOrBuffer instanceof URL)) {
|
|
224
240
|
throw new TypeError('Invalid source');
|
|
225
241
|
}
|
|
226
|
-
if (typeof
|
|
242
|
+
if (typeof _WebAssembly.instantiateStreaming === 'function') {
|
|
227
243
|
try {
|
|
228
|
-
source = await
|
|
244
|
+
source = await _WebAssembly.instantiateStreaming(fetch(urlOrBuffer), imports);
|
|
229
245
|
}
|
|
230
246
|
catch (_) {
|
|
231
247
|
source = await fetchWasm(urlOrBuffer, imports);
|
|
@@ -255,8 +271,8 @@ function loadSync(buffer, imports, asyncify) {
|
|
|
255
271
|
asyncifyHelper = new Asyncify();
|
|
256
272
|
imports = asyncifyHelper.wrapImports(imports);
|
|
257
273
|
}
|
|
258
|
-
const module = new
|
|
259
|
-
const instance = new
|
|
274
|
+
const module = new _WebAssembly.Module(buffer);
|
|
275
|
+
const instance = new _WebAssembly.Instance(module, imports);
|
|
260
276
|
const source = { instance, module };
|
|
261
277
|
if (asyncify) {
|
|
262
278
|
const memory = source.instance.exports.memory || ((_a = imports.env) === null || _a === void 0 ? void 0 : _a.memory);
|
|
@@ -842,7 +858,9 @@ class FileDescriptorTable {
|
|
|
842
858
|
}
|
|
843
859
|
|
|
844
860
|
/** @public */
|
|
845
|
-
|
|
861
|
+
const WebAssemblyMemory = _WebAssembly.Memory;
|
|
862
|
+
/** @public */
|
|
863
|
+
class Memory extends WebAssemblyMemory {
|
|
846
864
|
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
|
847
865
|
constructor(descriptor) {
|
|
848
866
|
super(descriptor);
|
|
@@ -861,7 +879,7 @@ class Memory extends WebAssembly.Memory {
|
|
|
861
879
|
}
|
|
862
880
|
/** @public */
|
|
863
881
|
function extendMemory(memory) {
|
|
864
|
-
if (Object.getPrototypeOf(memory) ===
|
|
882
|
+
if (Object.getPrototypeOf(memory) === _WebAssembly.Memory.prototype) {
|
|
865
883
|
Object.setPrototypeOf(memory, Memory.prototype);
|
|
866
884
|
}
|
|
867
885
|
return memory;
|
|
@@ -972,7 +990,7 @@ function readStdin() {
|
|
|
972
990
|
class WASI$1 {
|
|
973
991
|
constructor(args, env, preopens, stdio, filesystem, print, printErr) {
|
|
974
992
|
this._setMemory = function _setMemory(m) {
|
|
975
|
-
if (!(m instanceof
|
|
993
|
+
if (!(m instanceof _WebAssembly.Memory)) {
|
|
976
994
|
throw new TypeError('"instance.exports.memory" property must be a WebAssembly.Memory');
|
|
977
995
|
}
|
|
978
996
|
_memory.set(this, extendMemory(m));
|
|
@@ -1279,6 +1297,9 @@ class WASI$1 {
|
|
|
1279
1297
|
let buffer;
|
|
1280
1298
|
let nread = 0;
|
|
1281
1299
|
if (fd === 0) {
|
|
1300
|
+
if (typeof window === 'undefined' || typeof window.prompt !== 'function') {
|
|
1301
|
+
return 58 /* WasiErrno.ENOTSUP */;
|
|
1302
|
+
}
|
|
1282
1303
|
buffer = readStdin();
|
|
1283
1304
|
nread = buffer ? copyMemory(ioVecs, buffer) : 0;
|
|
1284
1305
|
}
|
|
@@ -1876,4 +1897,42 @@ function wasiReturnOnProcExit(rval) {
|
|
|
1876
1897
|
throw kExitCode;
|
|
1877
1898
|
}
|
|
1878
1899
|
|
|
1879
|
-
|
|
1900
|
+
function checkWebAssemblyFunction() {
|
|
1901
|
+
const WebAssemblyFunction = _WebAssembly.Function;
|
|
1902
|
+
if (typeof WebAssemblyFunction !== 'function') {
|
|
1903
|
+
throw new Error('WebAssembly.Function is not supported in this environment.' +
|
|
1904
|
+
' If you are using V8 based browser like Chrome, try to specify' +
|
|
1905
|
+
' --js-flag="--wasm-staging --experimental-wasm-stack-switching"');
|
|
1906
|
+
}
|
|
1907
|
+
return WebAssemblyFunction;
|
|
1908
|
+
}
|
|
1909
|
+
/** @public */
|
|
1910
|
+
function wrapAsyncImport(f, parameterType, returnType) {
|
|
1911
|
+
const WebAssemblyFunction = checkWebAssemblyFunction();
|
|
1912
|
+
if (typeof f !== 'function') {
|
|
1913
|
+
throw new TypeError('Function required');
|
|
1914
|
+
}
|
|
1915
|
+
const parameters = parameterType.slice(0);
|
|
1916
|
+
parameters.unshift('externref');
|
|
1917
|
+
return new WebAssemblyFunction({ parameters, results: returnType }, f, { suspending: 'first' });
|
|
1918
|
+
}
|
|
1919
|
+
/** @public */
|
|
1920
|
+
function wrapAsyncExport(f) {
|
|
1921
|
+
const WebAssemblyFunction = checkWebAssemblyFunction();
|
|
1922
|
+
if (typeof f !== 'function') {
|
|
1923
|
+
throw new TypeError('Function required');
|
|
1924
|
+
}
|
|
1925
|
+
return new WebAssemblyFunction({ parameters: [...WebAssemblyFunction.type(f).parameters.slice(1)], results: ['externref'] }, f, { promising: 'first' });
|
|
1926
|
+
}
|
|
1927
|
+
/** @public */
|
|
1928
|
+
function wrapExports(exports, needWrap) {
|
|
1929
|
+
return wrapInstanceExports(exports, (exportValue, name) => {
|
|
1930
|
+
let ignore = typeof exportValue !== 'function';
|
|
1931
|
+
if (Array.isArray(needWrap)) {
|
|
1932
|
+
ignore = ignore || (needWrap.indexOf(name) === -1);
|
|
1933
|
+
}
|
|
1934
|
+
return ignore ? exportValue : wrapAsyncExport(exportValue);
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
export { Asyncify, Memory, WASI, WebAssemblyMemory, extendMemory, load, loadSync, wrapAsyncExport, wrapAsyncImport, wrapExports };
|