watr 2.3.1 → 2.4.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/package.json +4 -4
- package/readme.md +12 -10
- package/src/compile.js +50 -24
- package/src/encode.js +2 -2
- package/src/parse.js +2 -1
- package/src/util.js +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "watr",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Ligth & fast WAT compiler",
|
|
5
5
|
"main": "watr.js",
|
|
6
6
|
"exports": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "git+https://github.com/
|
|
18
|
+
"url": "git+https://github.com/dy/watr.git"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
21
|
"src",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"author": "Dmitry Iv",
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"bugs": {
|
|
38
|
-
"url": "https://github.com/
|
|
38
|
+
"url": "https://github.com/dy/watr/issues"
|
|
39
39
|
},
|
|
40
|
-
"homepage": "https://github.com/
|
|
40
|
+
"homepage": "https://github.com/dy/watr#readme",
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"tst": "^7.3.0",
|
|
43
43
|
"wabt": "^1.0.28",
|
package/readme.md
CHANGED
|
@@ -3,15 +3,6 @@
|
|
|
3
3
|
Bare minimum wasm text compiler/formatter. A light & fast alternative to [wat2wasm](https://github.com/AssemblyScript/wabt.js).<br/>
|
|
4
4
|
Useful for hi-level languages or dynamic (in-browser) compilation.<br>
|
|
5
5
|
|
|
6
|
-
<!-- See [REPL](https://audio-lab.github.io/watr/repl.html).-->
|
|
7
|
-
|
|
8
|
-
| Size (gzipped) | Performance (op/s)
|
|
9
|
-
---|---|---
|
|
10
|
-
watr | 3.8 kb | 6000
|
|
11
|
-
[wat-compiler](https://github.com/stagas/wat-compiler) | 6 kb | 348
|
|
12
|
-
[wabt](https://github.com/AssemblyScript/wabt.js) | 300 kb | 574
|
|
13
|
-
<!-- [wassemble](https://github.com/wingo/wassemble) | ? kb | ? -->
|
|
14
|
-
|
|
15
6
|
## Usage
|
|
16
7
|
|
|
17
8
|
### Compile
|
|
@@ -77,16 +68,27 @@ parse(`(func (export "double") (param f64) (result f64) (f64.mul (local.get 0) (
|
|
|
77
68
|
// ]
|
|
78
69
|
```
|
|
79
70
|
|
|
71
|
+
<!-- See [REPL](https://audio-lab.github.io/watr/repl.html).-->
|
|
72
|
+
|
|
80
73
|
## Status
|
|
81
74
|
|
|
82
|
-
* [x]
|
|
75
|
+
* [x] core
|
|
83
76
|
* [x] [multi-value](https://github.com/WebAssembly/spec/blob/master/proposals/multi-value/Overview.md)
|
|
84
77
|
* [x] [bulk memory ops](https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md)
|
|
85
78
|
* [x] [simd](https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md)
|
|
79
|
+
* [x] [extended const](https://github.com/WebAssembly/extended-const/blob/main/proposals/extended-const/Overview.md)
|
|
86
80
|
* [ ] [multiple memories](https://github.com/WebAssembly/multi-memory/blob/master/proposals/multi-memory/Overview.md)
|
|
87
81
|
* [ ] [func refs](https://github.com/WebAssembly/function-references/blob/main/proposals/function-references/Overview.md)
|
|
88
82
|
* [ ] [gc](https://github.com/WebAssembly/gc)
|
|
89
83
|
|
|
84
|
+
## Alternatives
|
|
85
|
+
|
|
86
|
+
| Size (gzipped) | Performance (op/s)
|
|
87
|
+
---|---|---
|
|
88
|
+
watr | 5 kb | 6000
|
|
89
|
+
[wat-compiler](https://github.com/stagas/wat-compiler) | 6 kb | 348
|
|
90
|
+
[wabt](https://github.com/AssemblyScript/wabt.js) | 300 kb | 574
|
|
91
|
+
<!-- [wassemble](https://github.com/wingo/wassemble) | ? kb | ? -->
|
|
90
92
|
|
|
91
93
|
<!--
|
|
92
94
|
## Projects using watr
|
package/src/compile.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as encode from './encode.js'
|
|
|
2
2
|
import { uleb } from './encode.js'
|
|
3
3
|
import { OP, SECTION, ALIGN, TYPE, KIND } from './const.js'
|
|
4
4
|
import parse from './parse.js'
|
|
5
|
-
import { err
|
|
5
|
+
import { err } from './util.js'
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -139,9 +139,15 @@ const build = {
|
|
|
139
139
|
// (v128.load_lane_zero)
|
|
140
140
|
if (opCode <= 0x5b) immed.push(...uleb(args.shift()))
|
|
141
141
|
}
|
|
142
|
-
// (
|
|
143
|
-
else if (opCode ===
|
|
144
|
-
|
|
142
|
+
// (i8x16.shuffle 0 1 ... 15 a b)
|
|
143
|
+
else if (opCode === 0x0d) {
|
|
144
|
+
// i8, i16, i32 - bypass the encoding
|
|
145
|
+
for (let i = 0; i < 16; i++) immed.push(encode.i32.parse(args.shift()))
|
|
146
|
+
}
|
|
147
|
+
// (v128.const i32x4)
|
|
148
|
+
else if (opCode === 0x0c) {
|
|
149
|
+
args.unshift(op)
|
|
150
|
+
immed = consumeConst(args, ctx)
|
|
145
151
|
}
|
|
146
152
|
// (i8x16.extract_lane_s 0 ...)
|
|
147
153
|
else if (opCode >= 0x15 && opCode <= 0x22) {
|
|
@@ -310,8 +316,8 @@ const build = {
|
|
|
310
316
|
global([, ...args], ctx) {
|
|
311
317
|
let name = args[0][0] === '$' && args.shift()
|
|
312
318
|
if (name) ctx.global[name] = ctx.global.length
|
|
313
|
-
let [type, init] = args, mut = type[0] === 'mut' ? 1 : 0
|
|
314
|
-
ctx.global.push([TYPE[mut ? type[1] : type], mut, ...
|
|
319
|
+
let [type, [...init]] = args, mut = type[0] === 'mut' ? 1 : 0
|
|
320
|
+
ctx.global.push([TYPE[mut ? type[1] : type], mut, ...consumeConst(init, ctx), 0x0b])
|
|
315
321
|
},
|
|
316
322
|
|
|
317
323
|
// (table 1 2? funcref)
|
|
@@ -324,9 +330,9 @@ const build = {
|
|
|
324
330
|
},
|
|
325
331
|
|
|
326
332
|
// (elem (i32.const 0) $f1 $f2), (elem (global.get 0) $f1 $f2)
|
|
327
|
-
elem([, offset, ...elems], ctx) {
|
|
333
|
+
elem([, [...offset], ...elems], ctx) {
|
|
328
334
|
const tableIdx = 0 // FIXME: table index can be defined
|
|
329
|
-
ctx.elem.push([tableIdx, ...
|
|
335
|
+
ctx.elem.push([tableIdx, ...consumeConst(offset, ctx), 0x0b, ...uleb(elems.length), ...elems.flatMap(el => uleb(el[0] === '$' ? ctx.func[el] : el))])
|
|
330
336
|
},
|
|
331
337
|
|
|
332
338
|
// (export "name" (kind $name|idx))
|
|
@@ -379,7 +385,7 @@ const build = {
|
|
|
379
385
|
if (!offset && !mem) offset = inits.shift()
|
|
380
386
|
if (!offset) offset = ['i32.const', 0]
|
|
381
387
|
|
|
382
|
-
ctx.data.push([0, ...
|
|
388
|
+
ctx.data.push([0, ...consumeConst([...offset], ctx), 0x0b, ...str(inits.map(i => i[0] === '"' ? i.slice(1, -1) : i).join(''))])
|
|
383
389
|
},
|
|
384
390
|
|
|
385
391
|
// (start $main)
|
|
@@ -388,30 +394,50 @@ const build = {
|
|
|
388
394
|
}
|
|
389
395
|
}
|
|
390
396
|
|
|
391
|
-
//
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
397
|
+
// instantiation time const initializer
|
|
398
|
+
const consumeConst = (node, ctx) => {
|
|
399
|
+
let op = node.shift(), [type, cmd] = op.split('.')
|
|
400
|
+
|
|
401
|
+
// (global.get idx)
|
|
402
|
+
if (type === 'global') return [0x23, ...uleb(node[0][0] === '$' ? ctx.global[node[0]] : node[0])]
|
|
403
|
+
|
|
395
404
|
// (v128.const i32x4 1 2 3 4)
|
|
396
|
-
|
|
405
|
+
if (type === 'v128') return [0xfd, 0x0c, ...v128(node)]
|
|
406
|
+
|
|
407
|
+
// (i32.const 1)
|
|
408
|
+
if (cmd === 'const') return [0x41 + ['i32', 'i64', 'f32', 'f64'].indexOf(type), ...encode[type](node[0])]
|
|
409
|
+
|
|
410
|
+
// (i32.add a b), (i32.mult a b) etc
|
|
411
|
+
return [
|
|
412
|
+
...consumeConst(node.shift(), ctx),
|
|
413
|
+
...consumeConst(node.shift(), ctx),
|
|
414
|
+
OP.indexOf(op)
|
|
415
|
+
]
|
|
397
416
|
}
|
|
398
417
|
|
|
399
|
-
//
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
arr = new TypedArray[t](bytes.buffer)
|
|
418
|
+
// (v128.const i32x4 1 2 3 4)
|
|
419
|
+
const v128 = (args) => {
|
|
420
|
+
let [t, n] = args.shift().split('x'),
|
|
421
|
+
stride = t.slice(1) >>> 3 // i16 -> 2, f32 -> 4
|
|
422
|
+
|
|
423
|
+
n = +n
|
|
406
424
|
|
|
425
|
+
// i8, i16, i32 - bypass the encoding
|
|
426
|
+
if (t[0] === 'i') {
|
|
427
|
+
let arr = n === 16 ? new Uint8Array(16) : n === 8 ? new Uint16Array(8) : n === 4 ? new Uint32Array(4) : new BigInt64Array(2)
|
|
407
428
|
for (let i = 0; i < n; i++) {
|
|
408
429
|
arr[i] = encode[t].parse(args.shift())
|
|
409
430
|
}
|
|
431
|
+
return new Uint8Array(arr.buffer)
|
|
432
|
+
}
|
|
410
433
|
|
|
411
|
-
|
|
434
|
+
// f32, f64 - encode
|
|
435
|
+
let arr = new Uint8Array(16)
|
|
436
|
+
for (let i = 0; i < n; i++) {
|
|
437
|
+
arr.set(encode[t](args.shift()), i * stride)
|
|
412
438
|
}
|
|
413
|
-
|
|
414
|
-
return
|
|
439
|
+
|
|
440
|
+
return arr
|
|
415
441
|
}
|
|
416
442
|
|
|
417
443
|
// escape codes
|
package/src/encode.js
CHANGED
|
@@ -63,7 +63,7 @@ const byteView = new DataView(new BigInt64Array(1).buffer)
|
|
|
63
63
|
const F32_SIGN = 0x80000000, F32_NAN = 0x7f800000
|
|
64
64
|
export function f32(input, value, idx) {
|
|
65
65
|
if (~(idx = input.indexOf('nan:'))) {
|
|
66
|
-
value =
|
|
66
|
+
value = i32.parse(input.slice(idx + 4))
|
|
67
67
|
value |= F32_NAN
|
|
68
68
|
if (input[0] === '-') value |= F32_SIGN
|
|
69
69
|
byteView.setInt32(0, value)
|
|
@@ -84,7 +84,7 @@ export function f32(input, value, idx) {
|
|
|
84
84
|
const F64_SIGN = 0x8000000000000000n, F64_NAN = 0x7ff0000000000000n
|
|
85
85
|
export function f64(input, value, idx) {
|
|
86
86
|
if (~(idx = input.indexOf('nan:'))) {
|
|
87
|
-
value =
|
|
87
|
+
value = i64.parse(input.slice(idx + 4))
|
|
88
88
|
value |= F64_NAN
|
|
89
89
|
if (input[0] === '-') value |= F64_SIGN
|
|
90
90
|
byteView.setBigInt64(0, value)
|
package/src/parse.js
CHANGED
|
@@ -17,13 +17,14 @@ export default (str) => {
|
|
|
17
17
|
|
|
18
18
|
const parseLevel = () => {
|
|
19
19
|
for (let c, root; i < str.length;) {
|
|
20
|
+
|
|
20
21
|
c = str.charCodeAt(i)
|
|
21
22
|
if (c === DQUOTE) commit(), buf = str.slice(i++, i = str.indexOf('"', i) + 1), commit()
|
|
22
23
|
else if (c === OPAREN) {
|
|
23
24
|
if (str.charCodeAt(i + 1) === SEMIC) i = str.indexOf(';)', i) + 2 // (; ... ;)
|
|
24
25
|
else commit(), i++, (root = level).push(level = []), parseLevel(), level = root
|
|
25
26
|
}
|
|
26
|
-
else if (c === SEMIC) i = str.indexOf('\n', i) + 1 // ; ...
|
|
27
|
+
else if (c === SEMIC) i = str.indexOf('\n', i) + 1 || str.length // ; ...
|
|
27
28
|
else if (c <= SPACE) commit(), i++
|
|
28
29
|
else if (c === CPAREN) return commit(), i++
|
|
29
30
|
else buf += str[i++]
|
package/src/util.js
CHANGED