wasm-bindgen-lite 0.3.0 → 0.3.2
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 +78 -0
- package/bin/wasm-bindgen-lite.js +12 -1
- package/package.json +4 -1
- package/src/cli/bench.js +887 -0
- package/src/cli/build.js +61 -9
- package/src/cli/config.js +9 -1
- package/src/cli/emit.js +121 -64
- package/src/cli/index.js +30 -1
- package/src/js/browser-inline.js +23 -10
- package/src/js/browser.js +22 -17
- package/src/js/node-inline.js +23 -10
- package/src/js/node.js +21 -12
- package/src/js/util.js +30 -0
package/src/cli/build.js
CHANGED
|
@@ -11,16 +11,47 @@ function exec(cmd, options = {}) {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function
|
|
14
|
+
function resolveTargetDir(crateDir) {
|
|
15
|
+
try {
|
|
16
|
+
const raw = execSync('cargo metadata --format-version 1 --no-deps', {
|
|
17
|
+
cwd: crateDir,
|
|
18
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
19
|
+
}).toString()
|
|
20
|
+
const meta = JSON.parse(raw)
|
|
21
|
+
if (meta?.target_directory) return meta.target_directory
|
|
22
|
+
} catch {
|
|
23
|
+
console.warn(
|
|
24
|
+
'Warning: failed to read cargo metadata, defaulting to local target dir'
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
return join(crateDir, 'target')
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function runCargoBuild({ crateDir, release, simd, targetDir, features }) {
|
|
15
31
|
const args = ['build', '--target', 'wasm32-unknown-unknown']
|
|
16
32
|
if (release) args.push('--release')
|
|
33
|
+
if (features) {
|
|
34
|
+
args.push('--features', features)
|
|
35
|
+
}
|
|
17
36
|
|
|
18
37
|
const env = { ...process.env }
|
|
38
|
+
|
|
39
|
+
if (release) {
|
|
40
|
+
// Explicitly force opt-level 3 for fastest execution
|
|
41
|
+
env.CARGO_PROFILE_RELEASE_OPT_LEVEL = '3'
|
|
42
|
+
env.CARGO_PROFILE_RELEASE_PANIC = 'abort'
|
|
43
|
+
env.CARGO_PROFILE_RELEASE_CODEGEN_UNITS = '1'
|
|
44
|
+
env.CARGO_PROFILE_RELEASE_LTO = 'fat'
|
|
45
|
+
}
|
|
46
|
+
|
|
19
47
|
if (simd) {
|
|
20
|
-
const base =
|
|
48
|
+
const base = env.RUSTFLAGS || ''
|
|
21
49
|
const extra = '-C target-feature=+simd128'
|
|
22
50
|
env.RUSTFLAGS = [base, extra].filter(Boolean).join(' ').trim()
|
|
23
51
|
}
|
|
52
|
+
if (targetDir) {
|
|
53
|
+
env.CARGO_TARGET_DIR = targetDir
|
|
54
|
+
}
|
|
24
55
|
|
|
25
56
|
exec(`cargo ${args.join(' ')}`, {
|
|
26
57
|
cwd: crateDir,
|
|
@@ -28,18 +59,17 @@ function runCargoBuild({ crateDir, release, simd }) {
|
|
|
28
59
|
})
|
|
29
60
|
}
|
|
30
61
|
|
|
31
|
-
function wasmPath({
|
|
62
|
+
function wasmPath({ targetDir, release, wasmFileStem }) {
|
|
32
63
|
const profile = release ? 'release' : 'debug'
|
|
33
64
|
return join(
|
|
34
|
-
|
|
35
|
-
'target',
|
|
65
|
+
targetDir,
|
|
36
66
|
'wasm32-unknown-unknown',
|
|
37
67
|
profile,
|
|
38
68
|
`${wasmFileStem}.wasm`
|
|
39
69
|
)
|
|
40
70
|
}
|
|
41
71
|
|
|
42
|
-
function maybeRunWasmOpt(wasmFile, wasmOpt) {
|
|
72
|
+
function maybeRunWasmOpt(wasmFile, wasmOpt, release) {
|
|
43
73
|
if (wasmOpt.mode === 'off') return
|
|
44
74
|
if (wasmOpt.mode === 'auto') {
|
|
45
75
|
try {
|
|
@@ -49,7 +79,24 @@ function maybeRunWasmOpt(wasmFile, wasmOpt) {
|
|
|
49
79
|
}
|
|
50
80
|
}
|
|
51
81
|
|
|
52
|
-
const args = ['wasm-opt'
|
|
82
|
+
const args = ['wasm-opt']
|
|
83
|
+
|
|
84
|
+
if (release) {
|
|
85
|
+
// Only strip metadata and debug info for fastest performance
|
|
86
|
+
args.push('--strip-debug')
|
|
87
|
+
args.push('--strip-producers')
|
|
88
|
+
args.push('--strip-target-features')
|
|
89
|
+
|
|
90
|
+
// We EXPLICITLY avoid -O passes here to maintain absolute fastest speed
|
|
91
|
+
// unless the user provided specific args
|
|
92
|
+
if (wasmOpt.args.length > 0) {
|
|
93
|
+
args.push(...wasmOpt.args)
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
args.push(...wasmOpt.args)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
args.push(wasmFile, '-o', wasmFile)
|
|
53
100
|
exec(args.join(' '))
|
|
54
101
|
}
|
|
55
102
|
|
|
@@ -62,6 +109,7 @@ export function buildArtifacts({
|
|
|
62
109
|
release,
|
|
63
110
|
wasmOpt,
|
|
64
111
|
}) {
|
|
112
|
+
const targetDir = resolveTargetDir(crateDir)
|
|
65
113
|
mkdirSync(outDir, { recursive: true })
|
|
66
114
|
const wasmOutDir = join(outDir, 'wasm')
|
|
67
115
|
mkdirSync(wasmOutDir, { recursive: true })
|
|
@@ -72,9 +120,13 @@ export function buildArtifacts({
|
|
|
72
120
|
const label = isSimd ? 'SIMD' : 'baseline'
|
|
73
121
|
console.log(`Building ${label} wasm...`)
|
|
74
122
|
|
|
75
|
-
|
|
123
|
+
const simdFeatures = isSimd ? targets.simdFeatures : null
|
|
124
|
+
const baselineFeatures = !isSimd ? targets.baselineFeatures : null
|
|
125
|
+
const features = simdFeatures || baselineFeatures
|
|
126
|
+
|
|
127
|
+
runCargoBuild({ crateDir, release, simd: isSimd, targetDir, features })
|
|
76
128
|
|
|
77
|
-
const built = wasmPath({
|
|
129
|
+
const built = wasmPath({ targetDir, release, wasmFileStem })
|
|
78
130
|
const dest = join(wasmOutDir, `${artifactBaseName}.${suffix}.wasm`)
|
|
79
131
|
|
|
80
132
|
copyFileSync(built, dest)
|
package/src/cli/config.js
CHANGED
|
@@ -21,7 +21,7 @@ const DEFAULT_CONFIG = {
|
|
|
21
21
|
inline: true,
|
|
22
22
|
types: true,
|
|
23
23
|
},
|
|
24
|
-
custom: null, // path to custom JS file to include and re-export
|
|
24
|
+
custom: null, // path to custom JS/TS file to include and re-export
|
|
25
25
|
},
|
|
26
26
|
exports: [
|
|
27
27
|
{
|
|
@@ -138,6 +138,8 @@ export function loadConfigFromCli(cliOpts = {}) {
|
|
|
138
138
|
typeof cliOpts.simd === 'boolean'
|
|
139
139
|
? cliOpts.simd
|
|
140
140
|
: (fileConfig.targets?.simd ?? DEFAULT_CONFIG.targets.simd),
|
|
141
|
+
simdFeatures: fileConfig.targets?.simdFeatures ?? null,
|
|
142
|
+
baselineFeatures: fileConfig.targets?.baselineFeatures ?? null,
|
|
141
143
|
},
|
|
142
144
|
|
|
143
145
|
inline:
|
|
@@ -182,6 +184,12 @@ export function loadConfigFromCli(cliOpts = {}) {
|
|
|
182
184
|
version:
|
|
183
185
|
fileConfig.wasmDelivery?.version ?? fileConfig.version ?? 'latest',
|
|
184
186
|
},
|
|
187
|
+
|
|
188
|
+
// SIMD variant configuration
|
|
189
|
+
simd: fileConfig.simd ?? null,
|
|
190
|
+
|
|
191
|
+
// Benchmark configuration
|
|
192
|
+
bench: fileConfig.bench ?? null,
|
|
185
193
|
}
|
|
186
194
|
|
|
187
195
|
return config
|
package/src/cli/emit.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs'
|
|
2
|
-
import { join } from 'node:path'
|
|
2
|
+
import { join, extname } from 'node:path'
|
|
3
|
+
import { createRequire } from 'node:module'
|
|
3
4
|
import { fileURLToPath } from 'node:url'
|
|
4
5
|
|
|
5
6
|
const UTIL_PATH = fileURLToPath(new URL('../js/util.js', import.meta.url))
|
|
7
|
+
const require = createRequire(import.meta.url)
|
|
8
|
+
const TS_EXTS = new Set(['.ts', '.tsx', '.cts', '.mts'])
|
|
6
9
|
|
|
7
10
|
export function buildWrapperIR(exportsList) {
|
|
8
11
|
return exportsList.map((entry) => {
|
|
@@ -112,51 +115,55 @@ export function createCore({ exportsList, autoInit, stream }) {
|
|
|
112
115
|
b.line('}')
|
|
113
116
|
b.blank()
|
|
114
117
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
b.line('
|
|
119
|
-
b.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
118
|
+
const needsDecoders = wrappersIR.some((w) => w.returnType !== 'bytes')
|
|
119
|
+
|
|
120
|
+
if (needsDecoders) {
|
|
121
|
+
b.line('function scalarSize(type) {')
|
|
122
|
+
b.indent(() => {
|
|
123
|
+
b.line('switch (type) {')
|
|
124
|
+
b.line(' case "f64": return 8;')
|
|
125
|
+
b.line(' case "f32":')
|
|
126
|
+
b.line(' case "i32":')
|
|
127
|
+
b.line(' case "u32": return 4;')
|
|
128
|
+
b.line(' case "i16":')
|
|
129
|
+
b.line(' case "u16": return 2;')
|
|
130
|
+
b.line(' case "i8":')
|
|
131
|
+
b.line(' case "u8": return 1;')
|
|
132
|
+
b.line(' case "u32_array":')
|
|
133
|
+
b.line(' case "i32_array":')
|
|
134
|
+
b.line(' case "f32_array": return 1024 * 1024;')
|
|
135
|
+
b.line(' default: return 0;')
|
|
136
|
+
b.line('}')
|
|
137
|
+
})
|
|
130
138
|
b.line('}')
|
|
131
|
-
|
|
132
|
-
b.line('}')
|
|
133
|
-
b.blank()
|
|
139
|
+
b.blank()
|
|
134
140
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
141
|
+
b.line('function decodeReturn(view, type) {')
|
|
142
|
+
b.indent(() => {
|
|
143
|
+
b.line('switch (type) {')
|
|
144
|
+
b.line(' case "f32": return view.getFloat32(0, true);')
|
|
145
|
+
b.line(' case "f64": return view.getFloat64(0, true);')
|
|
146
|
+
b.line(' case "i32": return view.getInt32(0, true);')
|
|
147
|
+
b.line(' case "u32": return view.getUint32(0, true);')
|
|
148
|
+
b.line(' case "i16": return view.getInt16(0, true);')
|
|
149
|
+
b.line(' case "u16": return view.getUint16(0, true);')
|
|
150
|
+
b.line(' case "i8": return view.getInt8(0);')
|
|
151
|
+
b.line(' case "u8": return view.getUint8(0);')
|
|
152
|
+
b.line(
|
|
153
|
+
' case "u32_array": return new Uint32Array(view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength));'
|
|
154
|
+
)
|
|
155
|
+
b.line(
|
|
156
|
+
' case "i32_array": return new Int32Array(view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength));'
|
|
157
|
+
)
|
|
158
|
+
b.line(
|
|
159
|
+
' case "f32_array": return new Float32Array(view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength));'
|
|
160
|
+
)
|
|
161
|
+
b.line(' default: return null;')
|
|
162
|
+
b.line('}')
|
|
163
|
+
})
|
|
156
164
|
b.line('}')
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
b.blank()
|
|
165
|
+
b.blank()
|
|
166
|
+
}
|
|
160
167
|
|
|
161
168
|
b.line('function callWasm(abi, input, outLen, reuse) {')
|
|
162
169
|
b.indent(() => {
|
|
@@ -445,7 +452,10 @@ export function code() {
|
|
|
445
452
|
}
|
|
446
453
|
|
|
447
454
|
export function createLoaderTypes({ exportFrom }) {
|
|
448
|
-
return `export
|
|
455
|
+
return `export interface InitOptions {
|
|
456
|
+
backend?: 'auto' | 'simd' | 'base';
|
|
457
|
+
}
|
|
458
|
+
export function init(imports?: WebAssembly.Imports, opts?: InitOptions): Promise<void>;
|
|
449
459
|
export * from "${exportFrom}";
|
|
450
460
|
`
|
|
451
461
|
}
|
|
@@ -457,14 +467,17 @@ export function createLoader({ exportFrom, autoInit, getBytesSrc }) {
|
|
|
457
467
|
: '\nregisterInit(init);'
|
|
458
468
|
|
|
459
469
|
return `import { setInstance, registerInit } from "./core.js";
|
|
460
|
-
import {
|
|
470
|
+
import { instantiateWithBackend } from "./util.js";
|
|
461
471
|
${getBytesSrc}
|
|
462
472
|
|
|
463
473
|
let _ready = null;
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
474
|
+
let _backend = null;
|
|
475
|
+
export function init(imports = {}, opts = {}) {
|
|
476
|
+
const backend = opts.backend || 'auto';
|
|
477
|
+
if (_ready && _backend === backend) return _ready;
|
|
478
|
+
_backend = backend;
|
|
479
|
+
return (_ready = (async () => {
|
|
480
|
+
const { instance } = await instantiateWithBackend({ getSimdBytes, getBaseBytes, imports, backend });
|
|
468
481
|
setInstance(instance);
|
|
469
482
|
})());
|
|
470
483
|
}
|
|
@@ -491,10 +504,14 @@ function createBrowserLoader({ name, autoInit, customJs, wasmDelivery }) {
|
|
|
491
504
|
const simdUrl = ${simdUrl};
|
|
492
505
|
const baseUrl = ${baseUrl};
|
|
493
506
|
|
|
494
|
-
async function
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
507
|
+
async function getSimdBytes() {
|
|
508
|
+
const res = await fetch(simdUrl);
|
|
509
|
+
return res.arrayBuffer();
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
async function getBaseBytes() {
|
|
513
|
+
const res = await fetch(baseUrl);
|
|
514
|
+
return res.arrayBuffer();
|
|
498
515
|
}
|
|
499
516
|
`
|
|
500
517
|
return createLoader({ exportFrom, autoInit, getBytesSrc })
|
|
@@ -509,9 +526,12 @@ import { fileURLToPath } from "node:url";
|
|
|
509
526
|
const simdPath = fileURLToPath(new URL("./wasm/${name}.simd.wasm", import.meta.url));
|
|
510
527
|
const basePath = fileURLToPath(new URL("./wasm/${name}.base.wasm", import.meta.url));
|
|
511
528
|
|
|
512
|
-
async function
|
|
513
|
-
|
|
514
|
-
|
|
529
|
+
async function getSimdBytes() {
|
|
530
|
+
return readFile(simdPath);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
async function getBaseBytes() {
|
|
534
|
+
return readFile(basePath);
|
|
515
535
|
}
|
|
516
536
|
`
|
|
517
537
|
return createLoader({ exportFrom, autoInit, getBytesSrc })
|
|
@@ -520,11 +540,15 @@ async function getWasmBytes() {
|
|
|
520
540
|
function createInlineLoader({ name, autoInit, customJs }) {
|
|
521
541
|
const exportFrom = customJs ? './custom.js' : './core.js'
|
|
522
542
|
const getBytesSrc = `
|
|
523
|
-
import { wasmBytes as
|
|
524
|
-
import { wasmBytes as
|
|
543
|
+
import { wasmBytes as _simdBytes } from "./wasm-inline/${name}.simd.wasm.js";
|
|
544
|
+
import { wasmBytes as _baseBytes } from "./wasm-inline/${name}.base.wasm.js";
|
|
525
545
|
|
|
526
|
-
async function
|
|
527
|
-
return
|
|
546
|
+
async function getSimdBytes() {
|
|
547
|
+
return _simdBytes;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
async function getBaseBytes() {
|
|
551
|
+
return _baseBytes;
|
|
528
552
|
}
|
|
529
553
|
`
|
|
530
554
|
return createLoader({ exportFrom, autoInit, getBytesSrc })
|
|
@@ -536,6 +560,38 @@ export const wasmBytes = new Uint8Array([${bytes.join(',')}]);
|
|
|
536
560
|
`
|
|
537
561
|
}
|
|
538
562
|
|
|
563
|
+
function loadCustomModule(crateDir, customJs) {
|
|
564
|
+
const customPath = join(crateDir, customJs)
|
|
565
|
+
const source = readFileSync(customPath, 'utf8')
|
|
566
|
+
const ext = extname(customJs).toLowerCase()
|
|
567
|
+
|
|
568
|
+
if (!TS_EXTS.has(ext)) return source
|
|
569
|
+
|
|
570
|
+
let ts
|
|
571
|
+
try {
|
|
572
|
+
ts = require('typescript')
|
|
573
|
+
} catch {
|
|
574
|
+
throw new Error(
|
|
575
|
+
"Custom TypeScript runtime requires the 'typescript' package. Install it with `npm install typescript` in your project."
|
|
576
|
+
)
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
const { outputText } = ts.transpileModule(source, {
|
|
580
|
+
fileName: customPath,
|
|
581
|
+
compilerOptions: {
|
|
582
|
+
module: ts.ModuleKind.ESNext,
|
|
583
|
+
target: ts.ScriptTarget.ES2020,
|
|
584
|
+
jsx: ts.JsxEmit.ReactJSX,
|
|
585
|
+
esModuleInterop: true,
|
|
586
|
+
allowSyntheticDefaultImports: true,
|
|
587
|
+
sourceMap: false,
|
|
588
|
+
},
|
|
589
|
+
reportDiagnostics: false,
|
|
590
|
+
})
|
|
591
|
+
|
|
592
|
+
return outputText
|
|
593
|
+
}
|
|
594
|
+
|
|
539
595
|
function writeInlineModules({
|
|
540
596
|
outDir,
|
|
541
597
|
artifactBaseName,
|
|
@@ -559,6 +615,7 @@ function writeInlineModules({
|
|
|
559
615
|
}
|
|
560
616
|
|
|
561
617
|
export function emitRuntime({
|
|
618
|
+
crateDir,
|
|
562
619
|
outDir,
|
|
563
620
|
artifactBaseName,
|
|
564
621
|
emitNode,
|
|
@@ -575,15 +632,15 @@ export function emitRuntime({
|
|
|
575
632
|
mkdirSync(outDir, { recursive: true })
|
|
576
633
|
|
|
577
634
|
if (customJs) {
|
|
578
|
-
const customJsContent =
|
|
635
|
+
const customJsContent = loadCustomModule(crateDir, customJs)
|
|
579
636
|
writeFileSync(join(outDir, 'custom.js'), customJsContent)
|
|
580
637
|
|
|
581
638
|
if (emitTypes) {
|
|
582
|
-
const customTsPath = customJs.replace(/\.
|
|
583
|
-
if (existsSync(join(
|
|
639
|
+
const customTsPath = customJs.replace(/\.[^.]+$/, '.d.ts')
|
|
640
|
+
if (existsSync(join(crateDir, customTsPath))) {
|
|
584
641
|
writeFileSync(
|
|
585
642
|
join(outDir, 'custom.d.ts'),
|
|
586
|
-
readFileSync(join(
|
|
643
|
+
readFileSync(join(crateDir, customTsPath), 'utf8')
|
|
587
644
|
)
|
|
588
645
|
}
|
|
589
646
|
}
|
package/src/cli/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { loadConfigFromCli, summarizeConfig } from './config.js'
|
|
|
3
3
|
import { buildArtifacts } from './build.js'
|
|
4
4
|
import { emitRuntime } from './emit.js'
|
|
5
5
|
import { updatePackageJson } from './pkg.js'
|
|
6
|
+
import { runBench } from './bench.js'
|
|
6
7
|
|
|
7
8
|
export async function runBuild(cliOpts) {
|
|
8
9
|
const cfg = loadConfigFromCli(cliOpts)
|
|
@@ -19,6 +20,7 @@ export async function runBuild(cliOpts) {
|
|
|
19
20
|
})
|
|
20
21
|
|
|
21
22
|
emitRuntime({
|
|
23
|
+
crateDir: cfg.crateDir,
|
|
22
24
|
outDir: cfg.outDir,
|
|
23
25
|
artifactBaseName: cfg.artifactBaseName,
|
|
24
26
|
emitNode: cfg.js.emit.node,
|
|
@@ -55,12 +57,19 @@ export async function runClean(cliOpts) {
|
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
|
|
60
|
+
export async function runBenchCmd(cliOpts) {
|
|
61
|
+
const cfg = loadConfigFromCli(cliOpts)
|
|
62
|
+
console.log('Configuration:', summarizeConfig(cfg))
|
|
63
|
+
await runBench(cfg, cliOpts)
|
|
64
|
+
}
|
|
65
|
+
|
|
58
66
|
export function printHelp() {
|
|
59
67
|
const help = `
|
|
60
68
|
wasm-bindgen-lite <command> [options]
|
|
61
69
|
|
|
62
70
|
Commands:
|
|
63
71
|
build Build wasm artifacts and emit JS loaders (default release)
|
|
72
|
+
bench Build variant matrix and run SIMD analysis
|
|
64
73
|
clean Remove the configured output directory
|
|
65
74
|
help Show this message
|
|
66
75
|
|
|
@@ -73,7 +82,27 @@ Options (for build):
|
|
|
73
82
|
--simd | --no-simd Build SIMD variant (default: simd on)
|
|
74
83
|
--wasm-opt | --no-wasm-opt Force enable/disable wasm-opt (default: auto detect)
|
|
75
84
|
--wasm-opt-args "<args>" Extra args, default "-Oz"
|
|
76
|
-
--no-update-package-json Do not modify package.json exports
|
|
85
|
+
--no-update-package-json Do not modify package.json exports
|
|
86
|
+
|
|
87
|
+
Options (for bench):
|
|
88
|
+
--crate <path> Crate root (default: .)
|
|
89
|
+
--config <path> Path to config JSON
|
|
90
|
+
--clean Clean output directory before building
|
|
91
|
+
--skip-build Skip building, use existing variants
|
|
92
|
+
|
|
93
|
+
SIMD Configuration (in wasm-bindgen-lite.config.json):
|
|
94
|
+
{
|
|
95
|
+
"simd": {
|
|
96
|
+
"features": {
|
|
97
|
+
"explicit-simd-encode": { "name": "encode" },
|
|
98
|
+
"explicit-simd-decode": { "name": "decode" }
|
|
99
|
+
},
|
|
100
|
+
"allFeature": "explicit-simd"
|
|
101
|
+
},
|
|
102
|
+
"bench": {
|
|
103
|
+
"outputDir": "bench_out"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
77
106
|
`
|
|
78
107
|
console.log(help)
|
|
79
108
|
}
|
package/src/js/browser-inline.js
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
|
-
import { wasmBytes as
|
|
2
|
-
import { wasmBytes as
|
|
1
|
+
import { wasmBytes as _simdBytes } from './wasm-inline/mod.simd.wasm.js'
|
|
2
|
+
import { wasmBytes as _baseBytes } from './wasm-inline/mod.base.wasm.js'
|
|
3
3
|
import { setInstance } from './core.js'
|
|
4
|
-
import {
|
|
4
|
+
import { instantiateWithBackend } from './util.js'
|
|
5
|
+
|
|
6
|
+
async function getSimdBytes() {
|
|
7
|
+
return _simdBytes
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function getBaseBytes() {
|
|
11
|
+
return _baseBytes
|
|
12
|
+
}
|
|
5
13
|
|
|
6
14
|
let _ready = null
|
|
15
|
+
let _backend = null
|
|
7
16
|
|
|
8
|
-
export function init(imports = {}) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
export function init(imports = {}, opts = {}) {
|
|
18
|
+
const backend = opts.backend || 'auto'
|
|
19
|
+
if (_ready && _backend === backend) return _ready
|
|
20
|
+
_backend = backend
|
|
21
|
+
return (_ready = (async () => {
|
|
22
|
+
const { instance } = await instantiateWithBackend({
|
|
23
|
+
getSimdBytes,
|
|
24
|
+
getBaseBytes,
|
|
25
|
+
imports,
|
|
26
|
+
backend,
|
|
27
|
+
})
|
|
15
28
|
setInstance(instance)
|
|
16
29
|
})())
|
|
17
30
|
}
|
package/src/js/browser.js
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
1
|
import { setInstance } from './core.js'
|
|
2
|
-
import {
|
|
2
|
+
import { instantiateWithBackend } from './util.js'
|
|
3
3
|
|
|
4
4
|
const simdUrl = new URL('./wasm/mod.simd.wasm', import.meta.url)
|
|
5
5
|
const baseUrl = new URL('./wasm/mod.base.wasm', import.meta.url)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
async function getSimdBytes() {
|
|
8
|
+
const res = await fetch(simdUrl)
|
|
9
|
+
return res.arrayBuffer()
|
|
10
|
+
}
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
fetch(baseUrl),
|
|
14
|
-
])
|
|
12
|
+
async function getBaseBytes() {
|
|
13
|
+
const res = await fetch(baseUrl)
|
|
14
|
+
return res.arrayBuffer()
|
|
15
|
+
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
baseRes.arrayBuffer(),
|
|
19
|
-
])
|
|
17
|
+
let _ready = null
|
|
18
|
+
let _backend = null
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
export function init(imports = {}, opts = {}) {
|
|
21
|
+
const backend = opts.backend || 'auto'
|
|
22
|
+
if (_ready && _backend === backend) return _ready
|
|
23
|
+
_backend = backend
|
|
24
|
+
return (_ready = (async () => {
|
|
25
|
+
const { instance } = await instantiateWithBackend({
|
|
26
|
+
getSimdBytes,
|
|
27
|
+
getBaseBytes,
|
|
28
|
+
imports,
|
|
29
|
+
backend,
|
|
30
|
+
})
|
|
26
31
|
setInstance(instance)
|
|
27
32
|
})())
|
|
28
33
|
}
|
package/src/js/node-inline.js
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
|
-
import { wasmBytes as
|
|
2
|
-
import { wasmBytes as
|
|
1
|
+
import { wasmBytes as _simdBytes } from './wasm-inline/mod.simd.wasm.js'
|
|
2
|
+
import { wasmBytes as _baseBytes } from './wasm-inline/mod.base.wasm.js'
|
|
3
3
|
import { setInstance } from './core.js'
|
|
4
|
-
import {
|
|
4
|
+
import { instantiateWithBackend } from './util.js'
|
|
5
|
+
|
|
6
|
+
async function getSimdBytes() {
|
|
7
|
+
return _simdBytes
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function getBaseBytes() {
|
|
11
|
+
return _baseBytes
|
|
12
|
+
}
|
|
5
13
|
|
|
6
14
|
let _ready = null
|
|
15
|
+
let _backend = null
|
|
7
16
|
|
|
8
|
-
export function init(imports = {}) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
export function init(imports = {}, opts = {}) {
|
|
18
|
+
const backend = opts.backend || 'auto'
|
|
19
|
+
if (_ready && _backend === backend) return _ready
|
|
20
|
+
_backend = backend
|
|
21
|
+
return (_ready = (async () => {
|
|
22
|
+
const { instance } = await instantiateWithBackend({
|
|
23
|
+
getSimdBytes,
|
|
24
|
+
getBaseBytes,
|
|
25
|
+
imports,
|
|
26
|
+
backend,
|
|
27
|
+
})
|
|
15
28
|
setInstance(instance)
|
|
16
29
|
})())
|
|
17
30
|
}
|
package/src/js/node.js
CHANGED
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises'
|
|
2
2
|
import { fileURLToPath } from 'node:url'
|
|
3
3
|
import { setInstance } from './core.js'
|
|
4
|
-
import {
|
|
4
|
+
import { instantiateWithBackend } from './util.js'
|
|
5
5
|
|
|
6
6
|
const simdPath = fileURLToPath(new URL('./wasm/mod.simd.wasm', import.meta.url))
|
|
7
7
|
const basePath = fileURLToPath(new URL('./wasm/mod.base.wasm', import.meta.url))
|
|
8
8
|
|
|
9
|
+
async function getSimdBytes() {
|
|
10
|
+
return readFile(simdPath)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function getBaseBytes() {
|
|
14
|
+
return readFile(basePath)
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
let _ready = null
|
|
18
|
+
let _backend = null
|
|
10
19
|
|
|
11
|
-
export function init(imports = {}) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
)
|
|
20
|
+
export function init(imports = {}, opts = {}) {
|
|
21
|
+
const backend = opts.backend || 'auto'
|
|
22
|
+
if (_ready && _backend === backend) return _ready
|
|
23
|
+
_backend = backend
|
|
24
|
+
return (_ready = (async () => {
|
|
25
|
+
const { instance } = await instantiateWithBackend({
|
|
26
|
+
getSimdBytes,
|
|
27
|
+
getBaseBytes,
|
|
28
|
+
imports,
|
|
29
|
+
backend,
|
|
30
|
+
})
|
|
22
31
|
setInstance(instance)
|
|
23
32
|
})())
|
|
24
33
|
}
|