watr 2.2.3 → 2.2.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "watr",
3
- "version": "2.2.3",
3
+ "version": "2.2.5",
4
4
  "description": "Ligth & fast WAT compiler",
5
5
  "main": "watr.js",
6
6
  "exports": {
package/src/compile.js CHANGED
@@ -2,7 +2,7 @@ import { uleb, leb, bigleb, f64, f32 } from './util.js'
2
2
  import { OP, SECTION, ALIGN, TYPE, KIND } from './const.js'
3
3
  import parse from './parse.js'
4
4
 
5
- const OP_END = 0xb, OP_I32_CONST = 0x41, OP_I64_CONST = 0x42, OP_F32_CONST = 0x43, OP_F64_CONST = 0x44
5
+ const OP_END = 0xb, OP_I32_CONST = 0x41, OP_I64_CONST = 0x42, OP_F32_CONST = 0x43, OP_F64_CONST = 0x44, OP_SKIP = 0x6
6
6
 
7
7
  /**
8
8
  * Converts a WebAssembly Text Format (WAT) tree to a WebAssembly binary format (Wasm).
@@ -121,8 +121,21 @@ const build = {
121
121
 
122
122
  // NOTE: numeric comparison is faster than generic hash lookup
123
123
 
124
+
125
+ // bulk memory: (memory.init) (memory.copy) etc
126
+ // https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md#instruction-encoding
127
+ if (opCode >= 252) {
128
+ immed = [0xfc, opCode %= 252]
129
+ // memory.init idx, memory.drop idx, table.init idx, table.drop idx
130
+ if (!(opCode & 0b10)) immed.push(...uleb(args.shift()))
131
+ else immed.push(0)
132
+ // even opCodes (memory.init, memory.copy, table.init, table.copy) have 2nd predefined immediate
133
+ if (!(opCode & 0b1)) immed.push(0)
134
+ opCode = null // ignore opcode
135
+ }
136
+
124
137
  // binary/unary - just consume immed
125
- if (opCode >= 69 && opCode <= 252) { }
138
+ else if (opCode >= 69) { }
126
139
 
127
140
  // (i32.store align=n offset=m at value)
128
141
  else if (opCode >= 40 && opCode <= 62) {
@@ -161,7 +174,7 @@ const build = {
161
174
  immed = uleb(typeId), immed.push(0) // extra immediate indicates table idx (reserved)
162
175
  }
163
176
 
164
- // FIXME (memory.grow $idx?)
177
+ // FIXME multiple memory (memory.grow $idx?)
165
178
  else if (opCode == 63 || opCode == 64) {
166
179
  immed = [0]
167
180
  }
@@ -213,6 +226,10 @@ const build = {
213
226
  // (else xxx) -> else xxx
214
227
  if (group) while (args.length) nodes.unshift(args.pop())
215
228
  }
229
+ // (then)
230
+ else if (opCode === 6) {
231
+ opCode = null // ignore opcode
232
+ }
216
233
 
217
234
  // (end)
218
235
  else if (opCode == 0x0b) blocks.pop()
@@ -230,6 +247,7 @@ const build = {
230
247
  while (!Array.isArray(args[0])) id = args.shift(), immed.push(...uleb(id[0][0] === '$' ? blocks.length - blocks[id] : id))
231
248
  immed.unshift(...uleb(immed.length - 1))
232
249
  }
250
+ else if (opCode < 0) err(`Unknown instruction \`${op}\``)
233
251
 
234
252
  // if group (cmd im1 im2 arg1 arg2) - insert any remaining args first: arg1 arg2
235
253
  // because inline case has them in stack already
@@ -237,20 +255,7 @@ const build = {
237
255
  while (args.length) consume(args, out)
238
256
  }
239
257
 
240
- // ignore (then) and other unknown (-1) instructions
241
- if (opCode >= 0) {
242
- // bulk memory: (memory.init) (memory.copy) etc
243
- // https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md#instruction-encoding
244
- if (opCode >= 252) {
245
- opCode %= 252
246
- out.push(0xfc)
247
- immed = [0]
248
- // even opCodes (memory.init, memory.copy, table.init, table.copy) have 2 immediates
249
- if (!(opCode % 2)) immed.push(0)
250
- }
251
-
252
- out.push(opCode)
253
- }
258
+ if (opCode) out.push(opCode)
254
259
  if (immed) out.push(...immed)
255
260
  }
256
261
 
package/src/const.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // ref: https://github.com/stagas/wat-compiler/blob/main/lib/const.js
2
2
  // NOTE: squashing into a string doesn't save up gzipped size
3
3
  export const OP = [
4
- 'unreachable', 'nop', 'block', 'loop', 'if', 'else', , , , , ,
4
+ 'unreachable', 'nop', 'block', 'loop', 'if', 'else', 'then', , , , ,
5
5
  'end', 'br', 'br_if', 'br_table', 'return', 'call', 'call_indirect', , , , , , , , ,
6
6
  'drop', 'select', , , , ,
7
7
  'local.get', 'local.set', 'local.tee', 'global.get', 'global.set', , , ,
@@ -25,7 +25,8 @@ export const OP = [
25
25
  'i64.trunc_f32_s', 'i64.trunc_f32_u', 'i64.trunc_f64_s', 'i64.trunc_f64_u',
26
26
  'f32.convert_i32_s', 'f32.convert_i32_u', 'f32.convert_i64_s', 'f32.convert_i64_u', 'f32.demote_f64',
27
27
  'f64.convert_i32_s', 'f64.convert_i32_u', 'f64.convert_i64_s', 'f64.convert_i64_u', 'f64.promote_f32',
28
- 'i32.reinterpret_f32', 'i64.reinterpret_f64', 'f32.reinterpret_i32', 'f64.reinterpret_i64', , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , 'memory.init', 'data.drop', 'memory.copy', 'memory.fill', 'table.init', 'elem.drop', 'table.copy'
28
+ 'i32.reinterpret_f32', 'i64.reinterpret_f64', 'f32.reinterpret_i32', 'f64.reinterpret_i64', , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
29
+ 'memory.init', 'data.drop', 'memory.copy', 'memory.fill', 'table.init', 'elem.drop', 'table.copy'
29
30
  ],
30
31
  SECTION = { type: 1, import: 2, func: 3, table: 4, memory: 5, global: 6, export: 7, start: 8, elem: 9, code: 10, data: 11 },
31
32
  TYPE = { i32: 0x7f, i64: 0x7e, f32: 0x7d, f64: 0x7c, void: 0x40, func: 0x60, funcref: 0x70 },
package/src/util.js CHANGED
@@ -57,10 +57,9 @@ const flt = input => {
57
57
  input = input.replaceAll('_', '')
58
58
 
59
59
  // 0x1.5p3
60
- if (/^[+-]?0x/.test(input)) {
61
- let sign = input[0] === '-' ? (input = input.slice(1), -1) : 1,
62
- [sig, exp] = input.split(/p/i), [dec, fract] = sig.split('.')
63
- sig = parseInt(dec) + (fract ? parseInt(fract, 16) / (16 ** fract.length) : 0)
60
+ if (input.includes('0x')) {
61
+ let [sig, exp] = input.split(/p/i), [dec, fract] = sig.split('.'), sign = dec[0] === '-' ? -1 : 1
62
+ sig = parseInt(dec) * sign + (fract ? parseInt(fract, 16) / (16 ** fract.length) : 0)
64
63
  return sign * (exp ? sig * 2 ** parseInt(exp, 10) : sig);
65
64
  }
66
65