jz 0.5.1 → 0.6.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.
Files changed (80) hide show
  1. package/README.md +288 -314
  2. package/bench/README.md +319 -0
  3. package/bench/bench.svg +112 -0
  4. package/cli.js +32 -24
  5. package/index.js +177 -55
  6. package/interop.js +88 -159
  7. package/jz.svg +5 -0
  8. package/jzify/arguments.js +97 -0
  9. package/jzify/bundler.js +382 -0
  10. package/jzify/classes.js +328 -0
  11. package/jzify/hoist-vars.js +177 -0
  12. package/jzify/index.js +51 -0
  13. package/jzify/names.js +37 -0
  14. package/jzify/switch.js +106 -0
  15. package/jzify/transform.js +349 -0
  16. package/layout.js +179 -0
  17. package/module/array.js +322 -153
  18. package/module/collection.js +603 -145
  19. package/module/console.js +55 -43
  20. package/module/core.js +266 -153
  21. package/module/date.js +15 -3
  22. package/module/function.js +73 -6
  23. package/module/index.js +2 -1
  24. package/module/json.js +226 -61
  25. package/module/math.js +414 -186
  26. package/module/number.js +306 -60
  27. package/module/object.js +448 -184
  28. package/module/regex.js +255 -25
  29. package/module/schema.js +24 -6
  30. package/module/simd.js +85 -0
  31. package/module/string.js +586 -220
  32. package/module/symbol.js +1 -1
  33. package/module/timer.js +9 -14
  34. package/module/typedarray.js +45 -48
  35. package/package.json +41 -12
  36. package/src/abi/index.js +39 -23
  37. package/src/abi/string.js +38 -41
  38. package/src/ast.js +460 -0
  39. package/src/autoload.js +26 -24
  40. package/src/bridge.js +111 -0
  41. package/src/compile/analyze-scans.js +661 -0
  42. package/src/compile/analyze.js +1565 -0
  43. package/src/compile/emit-assign.js +408 -0
  44. package/src/compile/emit.js +3201 -0
  45. package/src/compile/flow-types.js +103 -0
  46. package/src/{compile.js → compile/index.js} +497 -125
  47. package/src/{infer.js → compile/infer.js} +27 -98
  48. package/src/{narrow.js → compile/narrow.js} +302 -96
  49. package/src/compile/plan/advise.js +316 -0
  50. package/src/compile/plan/common.js +150 -0
  51. package/src/compile/plan/index.js +118 -0
  52. package/src/compile/plan/inline.js +679 -0
  53. package/src/compile/plan/literals.js +984 -0
  54. package/src/compile/plan/loops.js +472 -0
  55. package/src/compile/plan/scope.js +573 -0
  56. package/src/compile/program-facts.js +404 -0
  57. package/src/ctx.js +176 -58
  58. package/src/ir.js +540 -171
  59. package/src/kind-traits.js +105 -0
  60. package/src/kind.js +462 -0
  61. package/src/op-policy.js +57 -0
  62. package/src/{optimize.js → optimize/index.js} +1106 -446
  63. package/src/optimize/vectorize.js +1874 -0
  64. package/src/param-reps.js +65 -0
  65. package/src/parse.js +44 -0
  66. package/src/{prepare.js → prepare/index.js} +589 -202
  67. package/src/reps.js +115 -0
  68. package/src/resolve.js +12 -3
  69. package/src/static.js +199 -0
  70. package/src/type.js +647 -0
  71. package/src/{assemble.js → wat/assemble.js} +86 -48
  72. package/src/wat/optimize.js +3760 -0
  73. package/transform.js +21 -0
  74. package/wasi.js +47 -5
  75. package/src/analyze.js +0 -3818
  76. package/src/emit.js +0 -3040
  77. package/src/jzify.js +0 -1580
  78. package/src/plan.js +0 -2132
  79. package/src/vectorize.js +0 -1088
  80. /package/src/{codegen.js → wat/codegen.js} +0 -0
package/module/console.js CHANGED
@@ -23,16 +23,13 @@
23
23
  * @module console
24
24
  */
25
25
 
26
- import { typed, asF64, asI64, mkPtrIR, NULL_NAN, UNDEF_NAN } from '../src/ir.js'
27
- import { emit } from '../src/emit.js'
28
- import { valTypeOf, VAL, exprType } from '../src/analyze.js'
26
+ import { typed, asF64, asI64, mkPtrIR, NULL_NAN, UNDEF_NAN, FALSE_NAN, TRUE_NAN } from '../src/ir.js'
27
+ import { emit, deps, reg, hostImport } from '../src/bridge.js'
28
+ import { valTypeOf } from '../src/kind.js'
29
+ import { exprType } from '../src/type.js'
30
+ import { VAL } from '../src/reps.js'
29
31
  import { inc, PTR, LAYOUT } from '../src/ctx.js'
30
32
 
31
- const addImportOnce = (ctx, mod, name, fn) => {
32
- if (ctx.module.imports.some(i => i[1] === `"${mod}"` && i[2] === `"${name}"`)) return
33
- ctx.module.imports.push(['import', `"${mod}"`, `"${name}"`, fn])
34
- }
35
-
36
33
  // Template-literal concat chains (`a${x}b`) lower to ['()', ['.', X, 'concat'], Y]
37
34
  // in prepare. Walking left from the chain root recovers the parts in order; if the
38
35
  // base is a `['str', ...]` it's a template-shaped chain (vs an arbitrary user
@@ -52,7 +49,7 @@ const flattenTemplateConcat = (node) => {
52
49
  }
53
50
 
54
51
  const setupWasi = (ctx) => {
55
- Object.assign(ctx.core.stdlibDeps, {
52
+ deps({
56
53
  __write_val: ['__ptr_type', '__write_str', '__write_num', '__write_int', '__write_byte', '__static_str'],
57
54
  __write_num: ['__ftoa', '__write_str'],
58
55
  __write_int: ['__itoa', '__mkstr', '__write_str'],
@@ -60,10 +57,10 @@ const setupWasi = (ctx) => {
60
57
  __read_stdin: ['__mkstr'],
61
58
  })
62
59
 
63
- const needFdWrite = () => addImportOnce(ctx, 'wasi_snapshot_preview1', 'fd_write',
60
+ const needFdWrite = () => hostImport('wasi_snapshot_preview1', 'fd_write',
64
61
  ['func', '$__fd_write', ['param', 'i32'], ['param', 'i32'], ['param', 'i32'], ['param', 'i32'], ['result', 'i32']])
65
62
 
66
- const needFdRead = () => addImportOnce(ctx, 'wasi_snapshot_preview1', 'fd_read',
63
+ const needFdRead = () => hostImport('wasi_snapshot_preview1', 'fd_read',
67
64
  ['func', '$__fd_read', ['param', 'i32'], ['param', 'i32'], ['param', 'i32'], ['param', 'i32'], ['result', 'i32']])
68
65
 
69
66
  ctx.core.stdlib['__write_str'] = `(func $__write_str (param $fd i32) (param $ptr i64)
@@ -114,6 +111,10 @@ const setupWasi = (ctx) => {
114
111
  (then (call $__write_str (local.get $fd) (i64.reinterpret_f64 (call $__static_str (i32.const 5)))) (return)))
115
112
  (if (i64.eq (local.get $val) (i64.const ${UNDEF_NAN}))
116
113
  (then (call $__write_str (local.get $fd) (i64.reinterpret_f64 (call $__static_str (i32.const 6)))) (return)))
114
+ (if (i64.eq (local.get $val) (i64.const ${TRUE_NAN}))
115
+ (then (call $__write_str (local.get $fd) (i64.reinterpret_f64 (call $__static_str (i32.const 3)))) (return)))
116
+ (if (i64.eq (local.get $val) (i64.const ${FALSE_NAN}))
117
+ (then (call $__write_str (local.get $fd) (i64.reinterpret_f64 (call $__static_str (i32.const 4)))) (return)))
117
118
  (local.set $type (call $__ptr_type (local.get $val)))
118
119
  (if (i32.eqz (local.get $type))
119
120
  (then (call $__write_str (local.get $fd) (i64.reinterpret_f64 (call $__static_str (i32.const 0)))) (return)))
@@ -123,28 +124,36 @@ const setupWasi = (ctx) => {
123
124
  (if (result i32) (i32.eq (local.get $type) (i32.const 1))
124
125
  (then (i32.const 7)) (else (i32.const 8)))))))`
125
126
 
126
- ctx.core.stdlib['__read_stdin'] = `(func $__read_stdin (result f64)
127
- (local $iov i32) (local $nio i32) (local $buf i32) (local $total i32) (local $n i32)
127
+ reg('readStdin', {
128
+ deps: ['__read_stdin'],
129
+ wat: `(func $__read_stdin (result f64)
130
+ (local $iov i32) (local $nio i32) (local $buf i32) (local $cap i32)
131
+ (local $total i32) (local $n i32) (local $new i32)
128
132
  (local.set $iov (call $__alloc (i32.const 8)))
129
133
  (local.set $nio (call $__alloc (i32.const 4)))
130
- (local.set $buf (call $__alloc (i32.const 65536)))
134
+ (local.set $cap (i32.const 65536))
135
+ (local.set $buf (call $__alloc (local.get $cap)))
131
136
  (local.set $total (i32.const 0))
132
137
  (block $eof (loop $read
138
+ (if (i32.ge_u (local.get $total) (local.get $cap))
139
+ (then
140
+ (local.set $new (call $__alloc (i32.shl (local.get $cap) (i32.const 1))))
141
+ (memory.copy (local.get $new) (local.get $buf) (local.get $total))
142
+ (local.set $buf (local.get $new))
143
+ (local.set $cap (i32.shl (local.get $cap) (i32.const 1)))))
133
144
  (i32.store (local.get $iov) (i32.add (local.get $buf) (local.get $total)))
134
- (i32.store offset=4 (local.get $iov) (i32.sub (i32.const 65536) (local.get $total)))
145
+ (i32.store offset=4 (local.get $iov) (i32.sub (local.get $cap) (local.get $total)))
135
146
  (drop (call $__fd_read (i32.const 0) (local.get $iov) (i32.const 1) (local.get $nio)))
136
147
  (local.set $n (i32.load (local.get $nio)))
137
148
  (br_if $eof (i32.eqz (local.get $n)))
138
149
  (local.set $total (i32.add (local.get $total) (local.get $n)))
139
- (br_if $eof (i32.ge_s (local.get $total) (i32.const 65536)))
140
150
  (br $read)))
141
- (call $__mkstr (local.get $buf) (local.get $total)))`
142
-
143
- ctx.core.emit['readStdin'] = () => {
144
- needFdRead()
145
- inc('__read_stdin')
146
- return typed(['call', '$__read_stdin'], 'f64')
147
- }
151
+ (call $__mkstr (local.get $buf) (local.get $total)))`,
152
+ emit: () => {
153
+ needFdRead()
154
+ return typed(['call', '$__read_stdin'], 'f64')
155
+ },
156
+ })
148
157
 
149
158
  const makeConsole = (method, fd) => {
150
159
  ctx.core.emit[`console.${method}`] = (...args) => {
@@ -186,31 +195,34 @@ const setupWasi = (ctx) => {
186
195
  makeConsole('warn', 2)
187
196
  makeConsole('error', 2)
188
197
 
189
- const needClock = () => addImportOnce(ctx, 'wasi_snapshot_preview1', 'clock_time_get',
198
+ const needClock = () => hostImport('wasi_snapshot_preview1', 'clock_time_get',
190
199
  ['func', '$__clock_time_get', ['param', 'i32'], ['param', 'i64'], ['param', 'i32'], ['result', 'i32']])
191
200
 
192
- ctx.core.stdlib['__time_ms'] = `(func $__time_ms (param $clock i32) (result f64)
201
+ reg('Date.now', {
202
+ deps: ['__time_ms'],
203
+ wat: `(func $__time_ms (param $clock i32) (result f64)
193
204
  (drop (call $__clock_time_get (local.get $clock) (i64.const 1000) (i32.const 0)))
194
- (f64.div (f64.convert_i64_u (i64.load (i32.const 0))) (f64.const 1000000)))`
195
-
196
- ctx.core.emit['Date.now'] = () => {
197
- needClock()
198
- inc('__time_ms')
199
- return typed(['call', '$__time_ms', ['i32.const', 0]], 'f64')
200
- }
201
- ctx.core.emit['performance.now'] = () => {
202
- needClock()
203
- inc('__time_ms')
204
- return typed(['call', '$__time_ms', ['i32.const', 1]], 'f64')
205
- }
205
+ (f64.div (f64.convert_i64_u (i64.load (i32.const 0))) (f64.const 1000000)))`,
206
+ emit: () => {
207
+ needClock()
208
+ return typed(['call', '$__time_ms', ['i32.const', 0]], 'f64')
209
+ },
210
+ })
211
+ reg('performance.now', {
212
+ deps: ['__time_ms'],
213
+ emit: () => {
214
+ needClock()
215
+ return typed(['call', '$__time_ms', ['i32.const', 1]], 'f64')
216
+ },
217
+ })
206
218
  ctx.core.emit['console.now'] = ctx.core.emit['Date.now']
207
219
  ctx.core.emit['console.perfNow'] = ctx.core.emit['performance.now']
208
220
  }
209
221
 
210
222
  const setupJsHost = (ctx) => {
211
- const needPrint = () => addImportOnce(ctx, 'env', 'print',
223
+ const needPrint = () => hostImport('env', 'print',
212
224
  ['func', '$__print', ['param', 'i64'], ['param', 'i32'], ['param', 'i32']])
213
- const needNow = () => addImportOnce(ctx, 'env', 'now',
225
+ const needNow = () => hostImport('env', 'now',
214
226
  ['func', '$__now', ['param', 'i32'], ['result', 'f64']])
215
227
 
216
228
  // Empty SSO string ("") for zero-arg console.log() — host reads as "".
@@ -255,14 +267,14 @@ const setupJsHost = (ctx) => {
255
267
  makeConsole('warn', 2)
256
268
  makeConsole('error', 2)
257
269
 
258
- ctx.core.emit['Date.now'] = () => {
270
+ reg('Date.now', [], () => {
259
271
  needNow()
260
272
  return typed(['call', '$__now', ['i32.const', 0]], 'f64')
261
- }
262
- ctx.core.emit['performance.now'] = () => {
273
+ })
274
+ reg('performance.now', [], () => {
263
275
  needNow()
264
276
  return typed(['call', '$__now', ['i32.const', 1]], 'f64')
265
- }
277
+ })
266
278
  ctx.core.emit['console.now'] = ctx.core.emit['Date.now']
267
279
  ctx.core.emit['console.perfNow'] = ctx.core.emit['performance.now']
268
280
  }