porffor 0.57.32 → 0.58.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.
@@ -61,14 +61,14 @@ export const UNDEFINED = 0;
61
61
  export const NULL = 0;
62
62
 
63
63
  export const BuiltinVars = function(ctx) {
64
- this.undefined = [ number(UNDEFINED) ];
64
+ this.undefined = () => [ number(UNDEFINED) ];
65
65
  this.undefined.type = TYPES.undefined;
66
66
 
67
- this.null = [ number(NULL) ];
67
+ this.null = () => [ number(NULL) ];
68
68
  this.null.type = TYPES.object;
69
69
 
70
- this.NaN = [ number(NaN) ];
71
- this.Infinity = [ number(Infinity) ];
70
+ this.NaN = () => [ number(NaN) ];
71
+ this.Infinity = () => [ number(Infinity) ];
72
72
 
73
73
  for (const x in TYPES) {
74
74
  this['__Porffor_TYPES_' + x] = () => [ number(TYPES[x]) ];
@@ -79,17 +79,17 @@ export const BuiltinVars = function(ctx) {
79
79
  ];
80
80
  this.__performance_timeOrigin.usesImports = true;
81
81
 
82
- this.__Uint8Array_BYTES_PER_ELEMENT = [ number(1) ];
83
- this.__Int8Array_BYTES_PER_ELEMENT = [ number(1) ];
84
- this.__Uint8ClampedArray_BYTES_PER_ELEMENT = [ number(1) ];
85
- this.__Uint16Array_BYTES_PER_ELEMENT = [ number(2) ];
86
- this.__Int16Array_BYTES_PER_ELEMENT = [ number(2) ];
87
- this.__Uint32Array_BYTES_PER_ELEMENT = [ number(4) ];
88
- this.__Int32Array_BYTES_PER_ELEMENT = [ number(4) ];
89
- this.__Float32Array_BYTES_PER_ELEMENT = [ number(4) ];
90
- this.__Float64Array_BYTES_PER_ELEMENT = [ number(8) ];
91
- this.__BigInt64Array_BYTES_PER_ELEMENT = [ number(8) ];
92
- this.__BigUint64Array_BYTES_PER_ELEMENT = [ number(8) ];
82
+ this.__Uint8Array_BYTES_PER_ELEMENT = () => [ number(1) ];
83
+ this.__Int8Array_BYTES_PER_ELEMENT = () => [ number(1) ];
84
+ this.__Uint8ClampedArray_BYTES_PER_ELEMENT = () => [ number(1) ];
85
+ this.__Uint16Array_BYTES_PER_ELEMENT = () => [ number(2) ];
86
+ this.__Int16Array_BYTES_PER_ELEMENT = () => [ number(2) ];
87
+ this.__Uint32Array_BYTES_PER_ELEMENT = () => [ number(4) ];
88
+ this.__Int32Array_BYTES_PER_ELEMENT = () => [ number(4) ];
89
+ this.__Float32Array_BYTES_PER_ELEMENT = () => [ number(4) ];
90
+ this.__Float64Array_BYTES_PER_ELEMENT = () => [ number(8) ];
91
+ this.__BigInt64Array_BYTES_PER_ELEMENT = () => [ number(8) ];
92
+ this.__BigUint64Array_BYTES_PER_ELEMENT = () => [ number(8) ];
93
93
 
94
94
  // well-known symbols
95
95
  for (const x of [
@@ -128,7 +128,7 @@ export const BuiltinFuncs = function() {
128
128
  locals: [],
129
129
  returns: [ valtypeBinary ],
130
130
  returnType: TYPES.boolean,
131
- wasm: [
131
+ wasm: () => [
132
132
  [ Opcodes.local_get, 0 ],
133
133
  [ Opcodes.local_get, 0 ],
134
134
  [ Opcodes.f64_ne ],
@@ -142,7 +142,7 @@ export const BuiltinFuncs = function() {
142
142
  locals: [ valtypeBinary ],
143
143
  returns: [ valtypeBinary ],
144
144
  returnType: TYPES.boolean,
145
- wasm: [
145
+ wasm: () => [
146
146
  [ Opcodes.local_get, 0 ],
147
147
  [ Opcodes.local_get, 0 ],
148
148
  [ Opcodes.f64_sub ],
@@ -160,7 +160,7 @@ export const BuiltinFuncs = function() {
160
160
  locals: [],
161
161
  returns: [ valtypeBinary ],
162
162
  returnType: TYPES.boolean,
163
- wasm: [
163
+ wasm: () => [
164
164
  [ Opcodes.local_get, 0 ],
165
165
  [ Opcodes.local_get, 0 ],
166
166
  [ Opcodes.f64_trunc ],
@@ -174,7 +174,7 @@ export const BuiltinFuncs = function() {
174
174
  locals: [],
175
175
  returns: [ valtypeBinary ],
176
176
  returnType: TYPES.boolean,
177
- wasm: [
177
+ wasm: () => [
178
178
  [ Opcodes.local_get, 0 ],
179
179
  [ Opcodes.local_get, 0 ],
180
180
  [ Opcodes.f64_trunc ],
@@ -206,7 +206,7 @@ export const BuiltinFuncs = function() {
206
206
  locals: [],
207
207
  returns: [ Valtype.f64 ],
208
208
  returnType: TYPES.number,
209
- wasm: [
209
+ wasm: () => [
210
210
  ...prefix,
211
211
  [ op ]
212
212
  ]
@@ -219,7 +219,7 @@ export const BuiltinFuncs = function() {
219
219
  locals: [],
220
220
  returns: [ valtypeBinary ],
221
221
  returnType: TYPES.number,
222
- wasm: [
222
+ wasm: () => [
223
223
  [ Opcodes.local_get, 0 ],
224
224
  Opcodes.i32_to_u,
225
225
  [ Opcodes.i32_clz ],
@@ -232,7 +232,7 @@ export const BuiltinFuncs = function() {
232
232
  locals: [],
233
233
  returns: [ valtypeBinary ],
234
234
  returnType: TYPES.number,
235
- wasm: [
235
+ wasm: () => [
236
236
  [ Opcodes.local_get, 0 ],
237
237
  [ Opcodes.f32_demote_f64 ],
238
238
  [ Opcodes.f64_promote_f32 ]
@@ -245,7 +245,7 @@ export const BuiltinFuncs = function() {
245
245
  locals: [],
246
246
  returns: [ valtypeBinary ],
247
247
  returnType: TYPES.number,
248
- wasm: [
248
+ wasm: () => [
249
249
  [ Opcodes.local_get, 0 ],
250
250
  Opcodes.i32_to,
251
251
  [ Opcodes.local_get, 1 ],
@@ -256,280 +256,252 @@ export const BuiltinFuncs = function() {
256
256
  };
257
257
 
258
258
  const prngSeed0 = (Math.random() * (2 ** 30)) | 0, prngSeed1 = (Math.random() * (2 ** 30)) | 0;
259
- const prng = ({
260
- 'lcg32': {
261
- globals: [ Valtype.i32 ],
262
- locals: [],
263
- returns: Valtype.i32,
264
- wasm: [
265
- // use glibc/musl's constants
266
- // seed = (MULTIPLIER * seed + INCREMENT) % MODULUS
267
- [ Opcodes.global_get, 0 ],
268
- number(1103515245, Valtype.i32),
269
- [ Opcodes.i32_mul ],
270
-
271
- // + INCREMENT
272
- number(12345, Valtype.i32),
273
- [ Opcodes.i32_add ],
274
-
275
- // % MODULUS
276
- number(0x7fffffff, Valtype.i32),
277
- [ Opcodes.i32_and ],
278
-
279
- // state0 =
280
- [ Opcodes.global_set, 0 ],
281
-
282
- // state0
283
- [ Opcodes.global_get, 0 ],
284
- ],
285
- },
286
-
287
- 'xorshift32+': {
288
- globals: [ Valtype.i32 ],
289
- locals: [ Valtype.i32 ],
290
- returns: Valtype.i32,
291
- wasm: [
292
- // setup: s1 = state0
293
- [ Opcodes.global_get, 0 ], // state0
294
- [ Opcodes.local_tee, 0 ], // s1
295
-
296
- // s1 ^= s1 << 13
297
- [ Opcodes.local_get, 0 ], // s1
298
- [ Opcodes.i32_const, 13 ],
299
- [ Opcodes.i32_shl ], // <<
300
- [ Opcodes.i32_xor ], // ^
301
- [ Opcodes.local_tee, 0 ], // s1
302
-
303
- // s1 ^= s1 >> 17
304
- [ Opcodes.local_get, 0 ], // s1
305
- [ Opcodes.i32_const, 17 ],
306
- [ Opcodes.i32_shr_s ], // >>
307
- [ Opcodes.i32_xor ], // ^
308
- [ Opcodes.local_tee, 0 ], // s1
309
-
310
- // s1 ^= s1 << 5
311
- [ Opcodes.local_get, 0 ], // s1
312
- [ Opcodes.i32_const, 5 ],
313
- [ Opcodes.i32_shl ], // <<
314
- [ Opcodes.i32_xor ], // ^
315
- [ Opcodes.local_tee, 0 ], // s1
316
-
317
- // state0 = s1
318
- [ Opcodes.global_set, 0 ],
319
-
320
- // s1
321
- [ Opcodes.local_get, 0 ],
322
- ],
323
- },
324
-
325
- 'xorshift64+': {
326
- globals: [ Valtype.i64 ],
327
- locals: [ Valtype.i64 ],
328
- returns: Valtype.i64,
329
- wasm: [
330
- // setup: s1 = state0
331
- [ Opcodes.global_get, 0 ], // state0
332
- [ Opcodes.local_tee, 0 ], // s1
333
-
334
- // s1 ^= s1 >> 12
335
- [ Opcodes.local_get, 0 ], // s1
336
- [ Opcodes.i64_const, 12 ],
337
- [ Opcodes.i64_shr_s ], // >>
338
- [ Opcodes.i64_xor ], // ^
339
- [ Opcodes.local_tee, 0 ], // s1
340
-
341
- // s1 ^= s1 << 25
342
- [ Opcodes.local_get, 0 ], // s1
343
- [ Opcodes.i64_const, 25 ],
344
- [ Opcodes.i64_shl ], // <<
345
- [ Opcodes.i64_xor ], // ^
346
- [ Opcodes.local_tee, 0 ], // s1
347
-
348
- // s1 ^= s1 >> 27
349
- [ Opcodes.local_get, 0 ], // s1
350
- [ Opcodes.i64_const, 27 ],
351
- [ Opcodes.i64_shr_s ], // >>
352
- [ Opcodes.i64_xor ], // ^
353
- [ Opcodes.local_tee, 0 ], // s1
354
-
355
- // state0 = s1
356
- [ Opcodes.global_set, 0 ],
357
-
358
- // s1
359
- [ Opcodes.local_get, 0 ],
360
- ],
361
- },
362
-
363
- 'xorshift128+': {
364
- globals: [ Valtype.i64, Valtype.i64 ],
365
- locals: [ Valtype.i64, Valtype.i64 ],
366
- returns: Valtype.i64,
367
- wasm: [
368
- // setup: s1 = state0, s0 = state1, state0 = s0
369
- [ Opcodes.global_get, 0 ], // state0
370
- [ Opcodes.local_tee, 0 ], // s1
371
- [ Opcodes.global_get, 1 ], // state1
372
- [ Opcodes.local_tee, 1, ], // s0
373
- [ Opcodes.global_set, 0 ], // state0
374
-
375
- // s1 ^= s1 << 23
376
- // [ Opcodes.local_get, 0 ], // s1
377
- [ Opcodes.local_get, 0 ], // s1
378
- [ Opcodes.i64_const, 23 ],
379
- [ Opcodes.i64_shl ], // <<
380
- [ Opcodes.i64_xor ], // ^
381
- [ Opcodes.local_set, 0 ], // s1
382
-
383
- // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
384
- // s1 ^ s0
385
- [ Opcodes.local_get, 0 ], // s1
386
- [ Opcodes.local_get, 1 ], // s0
387
- [ Opcodes.i64_xor ], // ^
388
-
389
- // ^ (s1 >> 17)
390
- [ Opcodes.local_get, 0 ], // s1
391
- [ Opcodes.i64_const, 17 ],
392
- [ Opcodes.i64_shr_u ], // >>
393
- [ Opcodes.i64_xor ], // ^
394
-
395
- // ^ (s0 >> 26)
396
- [ Opcodes.local_get, 1 ], // s0
397
- [ Opcodes.i64_const, 26 ],
398
- [ Opcodes.i64_shr_u ], // >>
399
- [ Opcodes.i64_xor ], // ^
400
-
401
- // state1 =
402
- [ Opcodes.global_set, 1 ],
403
-
404
- // state1 + s0
405
- [ Opcodes.global_get, 1 ], // state1
406
- [ Opcodes.local_get, 1 ], // s0
407
- [ Opcodes.i64_add ]
408
- ]
409
- },
410
-
411
- 'xoroshiro128+': {
412
- globals: [ Valtype.i64, Valtype.i64 ],
413
- locals: [ Valtype.i64, Valtype.i64, Valtype.i64 ],
414
- returns: Valtype.i64,
415
- wasm: [
416
- // setup: s1 = state1, s0 = state0
417
- [ Opcodes.global_get, 1 ], // state0
418
- [ Opcodes.local_tee, 0 ], // s1
419
- [ Opcodes.global_get, 0 ], // state1
420
- [ Opcodes.local_tee, 1, ], // s0
421
-
422
- // result = s0 + s1
423
- [ Opcodes.i64_add ],
424
- [ Opcodes.local_set, 2 ], // result
425
-
426
- // s1 ^= s0
427
- [ Opcodes.local_get, 0 ], // s1
428
- [ Opcodes.local_get, 1 ], // s0
429
- [ Opcodes.i64_xor ],
430
- [ Opcodes.local_set, 0 ], // s1
431
-
432
- // state0 = rotl(s0, 24) ^ s1 ^ (s1 << 16)
433
-
434
- // rotl(s0, 24) ^ s1
435
- [ Opcodes.local_get, 1 ], // s0
436
- number(24, Valtype.i64),
437
- [ Opcodes.i64_rotl ],
438
- [ Opcodes.local_get, 0 ], // s1
439
- [ Opcodes.i64_xor ],
440
-
441
- // ^ (s1 << 16)
442
- [ Opcodes.local_get, 0 ], // s1
443
- number(16, Valtype.i64),
444
- [ Opcodes.i64_shl ],
445
- [ Opcodes.i64_xor ],
446
-
447
- // state0 =
448
- [ Opcodes.global_set, 0 ], // state0
449
-
450
- // state1 = rotl(s1, 37)
451
- [ Opcodes.local_get, 0 ], // s1
452
- number(37, Valtype.i64),
453
- [ Opcodes.i64_rotl ],
454
- [ Opcodes.global_set, 1 ], // state1
455
-
456
- // result
457
- [ Opcodes.local_get, 2 ],
458
- ]
459
- },
460
-
461
- 'xoshiro128+': {
462
- globals: [ Valtype.i32, Valtype.i32, Valtype.i32, Valtype.i32 ],
463
- locals: [ Valtype.i32, Valtype.i32 ],
464
- returns: Valtype.i32,
465
- wasm: [
466
- // result = state0 + state3
467
- [ Opcodes.global_get, 0 ], // state0
468
- [ Opcodes.global_get, 3 ], // state0
469
- [ Opcodes.i32_add ],
470
- [ Opcodes.local_set, 0 ], // result
471
-
472
- // t = state1 << 9
473
- [ Opcodes.global_get, 1 ], // state1
474
- number(9, Valtype.i32),
475
- [ Opcodes.i32_shl ],
476
- [ Opcodes.local_set, 1 ], // t
477
-
478
- // state2 ^= state0
479
- [ Opcodes.global_get, 2 ], // state2
480
- [ Opcodes.global_get, 0 ], // state0
481
- [ Opcodes.i32_xor ],
482
- [ Opcodes.global_set, 2 ], // state2
483
-
484
- // state3 ^= state1
485
- [ Opcodes.global_get, 3 ], // state3
486
- [ Opcodes.global_get, 1 ], // state1
487
- [ Opcodes.i32_xor ],
488
- [ Opcodes.global_set, 3 ], // state3
489
-
490
- // state1 ^= state2
491
- [ Opcodes.global_get, 1 ], // state1
492
- [ Opcodes.global_get, 2 ], // state2
493
- [ Opcodes.i32_xor ],
494
- [ Opcodes.global_set, 1 ], // state1
495
-
496
- // state0 ^= state3
497
- [ Opcodes.global_get, 0 ], // state2
498
- [ Opcodes.global_get, 3 ], // state0
499
- [ Opcodes.i32_xor ],
500
- [ Opcodes.global_set, 0 ], // state2
501
-
502
- // state2 ^= t
503
- [ Opcodes.global_get, 2 ], // state2
504
- [ Opcodes.local_get, 1 ], // t
505
- [ Opcodes.i32_xor ],
506
- [ Opcodes.global_set, 2 ], // state2
507
-
508
- // state3 = rotl(state3, 11)
509
- [ Opcodes.global_get, 3 ], // state3
510
- number(11, Valtype.i32),
511
- [ Opcodes.i32_rotl ],
512
- [ Opcodes.global_set, 3 ], // state3
513
-
514
- // result
515
- [ Opcodes.local_get, 0 ],
516
- ]
517
- }
518
- })[Prefs.prng ?? 'xorshift128+'];
259
+ const prng = {
260
+ localNames: ['s1', 's0'],
261
+ ...({
262
+ 'xorshift32+': {
263
+ globalInits: { state0: prngSeed0 },
264
+ locals: [ Valtype.i32 ],
265
+ returns: Valtype.i32,
266
+ wasm: (scope, { glbl }) => [
267
+ // setup: s1 = state0
268
+ ...glbl(Opcodes.global_get, 'state0', Valtype.i32), // state0
269
+ [ Opcodes.local_tee, 0 ], // s1
270
+
271
+ // s1 ^= s1 << 13
272
+ [ Opcodes.local_get, 0 ], // s1
273
+ [ Opcodes.i32_const, 13 ],
274
+ [ Opcodes.i32_shl ], // <<
275
+ [ Opcodes.i32_xor ], // ^
276
+ [ Opcodes.local_tee, 0 ], // s1
277
+
278
+ // s1 ^= s1 >> 17
279
+ [ Opcodes.local_get, 0 ], // s1
280
+ [ Opcodes.i32_const, 17 ],
281
+ [ Opcodes.i32_shr_s ], // >>
282
+ [ Opcodes.i32_xor ], // ^
283
+ [ Opcodes.local_tee, 0 ], // s1
284
+
285
+ // s1 ^= s1 << 5
286
+ [ Opcodes.local_get, 0 ], // s1
287
+ [ Opcodes.i32_const, 5 ],
288
+ [ Opcodes.i32_shl ], // <<
289
+ [ Opcodes.i32_xor ], // ^
290
+ [ Opcodes.local_tee, 0 ], // s1
291
+
292
+ // state0 = s1
293
+ ...glbl(Opcodes.global_set, 'state0', Valtype.i32),
294
+
295
+ // s1
296
+ [ Opcodes.local_get, 0 ],
297
+ ],
298
+ },
299
+
300
+ 'xorshift64+': {
301
+ globalInits: { state0: prngSeed0 },
302
+ locals: [ Valtype.i64 ],
303
+ returns: Valtype.i64,
304
+ wasm: (scope, { glbl }) => [
305
+ // setup: s1 = state0
306
+ ...glbl(Opcodes.global_get, 'state0', Valtype.i64), // state0
307
+ [ Opcodes.local_tee, 0 ], // s1
308
+
309
+ // s1 ^= s1 >> 12
310
+ [ Opcodes.local_get, 0 ], // s1
311
+ [ Opcodes.i64_const, 12 ],
312
+ [ Opcodes.i64_shr_s ], // >>
313
+ [ Opcodes.i64_xor ], // ^
314
+ [ Opcodes.local_tee, 0 ], // s1
315
+
316
+ // s1 ^= s1 << 25
317
+ [ Opcodes.local_get, 0 ], // s1
318
+ [ Opcodes.i64_const, 25 ],
319
+ [ Opcodes.i64_shl ], // <<
320
+ [ Opcodes.i64_xor ], // ^
321
+ [ Opcodes.local_tee, 0 ], // s1
322
+
323
+ // s1 ^= s1 >> 27
324
+ [ Opcodes.local_get, 0 ], // s1
325
+ [ Opcodes.i64_const, 27 ],
326
+ [ Opcodes.i64_shr_s ], // >>
327
+ [ Opcodes.i64_xor ], // ^
328
+ [ Opcodes.local_tee, 0 ], // s1
329
+
330
+ // state0 = s1
331
+ ...glbl(Opcodes.global_set, 'state0', Valtype.i64),
332
+
333
+ // s1
334
+ [ Opcodes.local_get, 0 ],
335
+ ],
336
+ },
337
+
338
+ 'xorshift128+': {
339
+ globalInits: { state0: prngSeed0, state1: prngSeed1 },
340
+ locals: [ Valtype.i64, Valtype.i64 ],
341
+ returns: Valtype.i64,
342
+ wasm: (scope, { glbl }) => [
343
+ // setup: s1 = state0, s0 = state1, state0 = s0
344
+ ...glbl(Opcodes.global_get, 'state0', Valtype.i64), // state0
345
+ [ Opcodes.local_tee, 0 ], // s1
346
+ ...glbl(Opcodes.global_get, 'state1', Valtype.i64), // state1
347
+ [ Opcodes.local_tee, 1, ], // s0
348
+ ...glbl(Opcodes.global_set, 'state0', Valtype.i64), // state0
349
+
350
+ // s1 ^= s1 << 23
351
+ // [ Opcodes.local_get, 0 ], // s1
352
+ [ Opcodes.local_get, 0 ], // s1
353
+ [ Opcodes.i64_const, 23 ],
354
+ [ Opcodes.i64_shl ], // <<
355
+ [ Opcodes.i64_xor ], // ^
356
+ [ Opcodes.local_set, 0 ], // s1
357
+
358
+ // state1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
359
+ // s1 ^ s0
360
+ [ Opcodes.local_get, 0 ], // s1
361
+ [ Opcodes.local_get, 1 ], // s0
362
+ [ Opcodes.i64_xor ], // ^
363
+
364
+ // ^ (s1 >> 17)
365
+ [ Opcodes.local_get, 0 ], // s1
366
+ [ Opcodes.i64_const, 17 ],
367
+ [ Opcodes.i64_shr_u ], // >>
368
+ [ Opcodes.i64_xor ], // ^
369
+
370
+ // ^ (s0 >> 26)
371
+ [ Opcodes.local_get, 1 ], // s0
372
+ [ Opcodes.i64_const, 26 ],
373
+ [ Opcodes.i64_shr_u ], // >>
374
+ [ Opcodes.i64_xor ], // ^
375
+
376
+ // state1 =
377
+ ...glbl(Opcodes.global_set, 'state1', Valtype.i64),
378
+
379
+ // state1 + s0
380
+ ...glbl(Opcodes.global_get, 'state1', Valtype.i64), // state1
381
+ [ Opcodes.local_get, 1 ], // s0
382
+ [ Opcodes.i64_add ]
383
+ ]
384
+ },
385
+
386
+ 'xoroshiro128+': {
387
+ globalInits: { state0: prngSeed0, state1: prngSeed1 },
388
+ locals: [ Valtype.i64, Valtype.i64, Valtype.i64 ],
389
+ returns: Valtype.i64,
390
+ wasm: (scope, { glbl }) => [
391
+ // setup: s1 = state1, s0 = state0
392
+ ...glbl(Opcodes.global_get, 'state1', Valtype.i64), // state0
393
+ [ Opcodes.local_tee, 0 ], // s1
394
+ ...glbl(Opcodes.global_get, 'state0', Valtype.i64), // state1
395
+ [ Opcodes.local_tee, 1, ], // s0
396
+
397
+ // result = s0 + s1
398
+ [ Opcodes.i64_add ],
399
+ [ Opcodes.local_set, 2 ], // result
400
+
401
+ // s1 ^= s0
402
+ [ Opcodes.local_get, 0 ], // s1
403
+ [ Opcodes.local_get, 1 ], // s0
404
+ [ Opcodes.i64_xor ],
405
+ [ Opcodes.local_set, 0 ], // s1
406
+
407
+ // state0 = rotl(s0, 24) ^ s1 ^ (s1 << 16)
408
+
409
+ // rotl(s0, 24) ^ s1
410
+ [ Opcodes.local_get, 1 ], // s0
411
+ number(24, Valtype.i64),
412
+ [ Opcodes.i64_rotl ],
413
+ [ Opcodes.local_get, 0 ], // s1
414
+ [ Opcodes.i64_xor ],
415
+
416
+ // ^ (s1 << 16)
417
+ [ Opcodes.local_get, 0 ], // s1
418
+ number(16, Valtype.i64),
419
+ [ Opcodes.i64_shl ],
420
+ [ Opcodes.i64_xor ],
421
+
422
+ // state0 =
423
+ ...glbl(Opcodes.global_set, 'state0', Valtype.i64), // state0
424
+
425
+ // state1 = rotl(s1, 37)
426
+ [ Opcodes.local_get, 0 ], // s1
427
+ number(37, Valtype.i64),
428
+ [ Opcodes.i64_rotl ],
429
+ ...glbl(Opcodes.global_set, 'state1', Valtype.i64), // state1
430
+
431
+ // result
432
+ [ Opcodes.local_get, 2 ],
433
+ ]
434
+ },
435
+
436
+ 'xoshiro128+': {
437
+ globalInits: { state0: prngSeed0, state1: prngSeed1, state2: (prngSeed0 * 17) | 0, state3: (prngSeed1 * 31) | 0 },
438
+ locals: [ Valtype.i32, Valtype.i32 ],
439
+ returns: Valtype.i32,
440
+ wasm: (scope, { glbl }) => [
441
+ // result = state0 + state3
442
+ ...glbl(Opcodes.global_get, 'state0', Valtype.i32), // state0
443
+ ...glbl(Opcodes.global_get, 'state3', Valtype.i32), // state0
444
+ [ Opcodes.i32_add ],
445
+ [ Opcodes.local_set, 0 ], // result
446
+
447
+ // t = state1 << 9
448
+ ...glbl(Opcodes.global_get, 'state1', Valtype.i32), // state1
449
+ number(9, Valtype.i32),
450
+ [ Opcodes.i32_shl ],
451
+ [ Opcodes.local_set, 1 ], // t
452
+
453
+ // state2 ^= state0
454
+ ...glbl(Opcodes.global_get, 'state2', Valtype.i32), // state2
455
+ ...glbl(Opcodes.global_get, 'state0', Valtype.i32), // state0
456
+ [ Opcodes.i32_xor ],
457
+ ...glbl(Opcodes.global_set, 'state2', Valtype.i32), // state2
458
+
459
+ // state3 ^= state1
460
+ ...glbl(Opcodes.global_get, 'state3', Valtype.i32), // state3
461
+ ...glbl(Opcodes.global_get, 'state1', Valtype.i32), // state1
462
+ [ Opcodes.i32_xor ],
463
+ ...glbl(Opcodes.global_set, 'state3', Valtype.i32), // state3
464
+
465
+ // state1 ^= state2
466
+ ...glbl(Opcodes.global_get, 'state1', Valtype.i32), // state1
467
+ ...glbl(Opcodes.global_get, 'state2', Valtype.i32), // state2
468
+ [ Opcodes.i32_xor ],
469
+ ...glbl(Opcodes.global_set, 'state1', Valtype.i32), // state1
470
+
471
+ // state0 ^= state3
472
+ ...glbl(Opcodes.global_get, 'state0', Valtype.i32), // state2
473
+ ...glbl(Opcodes.global_get, 'state3', Valtype.i32), // state0
474
+ [ Opcodes.i32_xor ],
475
+ ...glbl(Opcodes.global_set, 'state0', Valtype.i32), // state2
476
+
477
+ // state2 ^= t
478
+ ...glbl(Opcodes.global_get, 'state2', Valtype.i32), // state2
479
+ [ Opcodes.local_get, 1 ], // t
480
+ [ Opcodes.i32_xor ],
481
+ ...glbl(Opcodes.global_set, 'state2', Valtype.i32), // state2
482
+
483
+ // state3 = rotl(state3, 11)
484
+ ...glbl(Opcodes.global_get, 'state3', Valtype.i32), // state3
485
+ number(11, Valtype.i32),
486
+ [ Opcodes.i32_rotl ],
487
+ ...glbl(Opcodes.global_set, 'state3', Valtype.i32), // state3
488
+
489
+ // result
490
+ [ Opcodes.local_get, 0 ],
491
+ ]
492
+ }
493
+ })[Prefs.prng ?? 'xorshift128+']
494
+ }
519
495
 
520
496
  if (!prng) throw new Error(`unknown prng algo: ${Prefs.prng}`);
521
497
 
522
498
  this.__Math_random = {
499
+ ...prng,
523
500
  params: [],
524
- locals: prng.locals,
525
- localNames: [ 's1', 's0' ],
526
- globals: prng.globals,
527
- globalNames: [ 'state0', 'state1' ],
528
- globalInits: [ prngSeed0, prngSeed1 ],
529
501
  returns: [ Valtype.f64 ],
530
502
  returnType: TYPES.number,
531
- wasm: [
532
- ...prng.wasm,
503
+ wasm: (scope, utils) => [
504
+ ...prng.wasm(scope, utils),
533
505
  ...(prng.returns === Valtype.i64 ? [
534
506
  number((1 << 53) - 1, Valtype.i64),
535
507
  [ Opcodes.i64_and ],
@@ -555,17 +527,12 @@ export const BuiltinFuncs = function() {
555
527
  };
556
528
 
557
529
  this.__Porffor_randomByte = {
530
+ ...prng,
558
531
  params: [],
559
- locals: prng.locals,
560
- localNames: [ 's1', 's0' ],
561
- globals: prng.globals,
562
- globalNames: [ 'state0', 'state1' ],
563
- globalInits: [ prngSeed0, prngSeed1 ],
564
532
  returns: [ Valtype.i32 ],
565
533
  returnType: TYPES.number,
566
- wasm: [
567
- ...prng.wasm,
568
-
534
+ wasm: (scope, utils) => [
535
+ ...prng.wasm(scope, utils),
569
536
  ...(prng.returns === Valtype.i64 ? [
570
537
  // the lowest bits of the output generated by xorshift128+ have low quality
571
538
  number(56, Valtype.i64),
@@ -584,7 +551,7 @@ export const BuiltinFuncs = function() {
584
551
  locals: [],
585
552
  returns: [ valtypeBinary ],
586
553
  returnType: TYPES.number,
587
- wasm: [
554
+ wasm: () => [
588
555
  [ Opcodes.local_get, 0 ],
589
556
  number(Math.PI / 180),
590
557
  [ Opcodes.f64_mul ]
@@ -596,7 +563,7 @@ export const BuiltinFuncs = function() {
596
563
  locals: [],
597
564
  returns: [ valtypeBinary ],
598
565
  returnType: TYPES.number,
599
- wasm: [
566
+ wasm: () => [
600
567
  [ Opcodes.local_get, 0 ],
601
568
  number(180 / Math.PI),
602
569
  [ Opcodes.f64_mul ]
@@ -609,7 +576,7 @@ export const BuiltinFuncs = function() {
609
576
  localNames: [ 'x', 'lower', 'upper' ],
610
577
  returns: [ valtypeBinary ],
611
578
  returnType: TYPES.number,
612
- wasm: [
579
+ wasm: () => [
613
580
  [ Opcodes.local_get, 0 ],
614
581
  [ Opcodes.local_get, 1 ],
615
582
  [ Opcodes.f64_max ],
@@ -624,7 +591,7 @@ export const BuiltinFuncs = function() {
624
591
  localNames: [ 'x', 'inLow', 'inHigh', 'outLow', 'outHigh' ],
625
592
  returns: [ valtypeBinary ],
626
593
  returnType: TYPES.number,
627
- wasm: [
594
+ wasm: () => [
628
595
  // (x − inLow) * (outHigh − outLow) / (inHigh - inLow) + outLow
629
596
  [ Opcodes.local_get, 0 ],
630
597
  [ Opcodes.local_get, 1 ],
@@ -653,7 +620,7 @@ export const BuiltinFuncs = function() {
653
620
  locals: [],
654
621
  returns: [ valtypeBinary ],
655
622
  returnType: TYPES.boolean,
656
- wasm: [
623
+ wasm: () => [
657
624
  [ Opcodes.local_get, 0 ],
658
625
  number(0),
659
626
  [ Opcodes.f64_le ],
@@ -667,7 +634,7 @@ export const BuiltinFuncs = function() {
667
634
  locals: [],
668
635
  returns: [ valtypeBinary ],
669
636
  returnType: TYPES.number,
670
- wasm: [
637
+ wasm: () => [
671
638
  [ Opcodes.call, importedFuncs.time ]
672
639
  ]
673
640
  };
@@ -694,7 +661,7 @@ export const BuiltinFuncs = function() {
694
661
  locals: [],
695
662
  returns: [],
696
663
  returnType: TYPES.undefined,
697
- wasm: [
664
+ wasm: () => [
698
665
  [ Opcodes.local_get, 1 ],
699
666
  [ Opcodes.local_get, 0 ],
700
667
  number(pageSize, Valtype.i32),
@@ -708,7 +675,7 @@ export const BuiltinFuncs = function() {
708
675
  locals: [],
709
676
  returns: [ Valtype.i32 ],
710
677
  returnType: TYPES.number,
711
- wasm: [
678
+ wasm: () => [
712
679
  number(1, Valtype.i32),
713
680
  [ Opcodes.memory_grow, 0 ],
714
681
  number(PageSize, Valtype.i32),
@@ -718,39 +685,37 @@ export const BuiltinFuncs = function() {
718
685
  chunk: {
719
686
  params: [],
720
687
  locals: [],
721
- globals: [ Valtype.i32, Valtype.i32 ],
722
- globalNames: [ 'chunkPtr', 'chunkOffset' ],
723
- globalInits: [ 0, 100 * PageSize ],
688
+ globalInits: { chunkPtr: 0, chunkOffset: 100 * PageSize },
724
689
  returns: [ Valtype.i32 ],
725
690
  returnType: TYPES.number,
726
- wasm: [
691
+ wasm: (scope, { glbl }) => [
727
692
  // if chunkOffset >= chunks:
728
- [ Opcodes.global_get, 1 ],
693
+ ...glbl(Opcodes.global_get, 'chunkOffset', Valtype.i32),
729
694
  number(PageSize * (Prefs.allocatorChunks ?? 16), Valtype.i32),
730
695
  [ Opcodes.i32_ge_s ],
731
696
  [ Opcodes.if, Valtype.i32 ],
732
697
  // chunkOffset = 1 page
733
698
  number(pageSize, Valtype.i32),
734
- [ Opcodes.global_set, 1 ],
699
+ ...glbl(Opcodes.global_set, 'chunkOffset', Valtype.i32),
735
700
 
736
701
  // return chunkPtr = allocated
737
702
  number(Prefs.allocatorChunks ?? 16, Valtype.i32),
738
703
  [ Opcodes.memory_grow, 0 ],
739
704
  number(PageSize, Valtype.i32),
740
705
  [ Opcodes.i32_mul ],
741
- [ Opcodes.global_set, 0 ],
742
- [ Opcodes.global_get, 0 ],
706
+ ...glbl(Opcodes.global_set, 'chunkPtr', Valtype.i32),
707
+ ...glbl(Opcodes.global_get, 'chunkPtr', Valtype.i32),
743
708
  [ Opcodes.else ],
744
709
  // return chunkPtr + chunkOffset
745
- [ Opcodes.global_get, 0 ],
746
- [ Opcodes.global_get, 1 ],
710
+ ...glbl(Opcodes.global_get, 'chunkPtr', Valtype.i32),
711
+ ...glbl(Opcodes.global_get, 'chunkOffset', Valtype.i32),
747
712
  [ Opcodes.i32_add ],
748
713
 
749
714
  // chunkOffset += 1 page
750
715
  number(pageSize, Valtype.i32),
751
- [ Opcodes.global_get, 1 ],
716
+ ...glbl(Opcodes.global_get, 'chunkOffset', Valtype.i32),
752
717
  [ Opcodes.i32_add ],
753
- [ Opcodes.global_set, 1 ],
718
+ ...glbl(Opcodes.global_set, 'chunkOffset', Valtype.i32),
754
719
  [ Opcodes.end ]
755
720
  ]
756
721
  }
@@ -759,36 +724,34 @@ export const BuiltinFuncs = function() {
759
724
  this.__Porffor_allocateBytes = {
760
725
  params: [ Valtype.i32 ],
761
726
  locals: [],
762
- globals: [ Valtype.i32, Valtype.i32 ],
763
- globalNames: [ 'currentPtr', 'bytesWritten' ],
764
- globalInits: [ 0, pageSize ], // init to pageSize so we always allocate on first call
727
+ globalInits: { currentPtr: 0, bytesWritten: pageSize }, // init to pageSize so we always allocate on first call
765
728
  returns: [ Valtype.i32 ],
766
729
  returnType: TYPES.number,
767
- wasm: (scope, { builtin }) => [
730
+ wasm: (scope, { builtin, glbl }) => [
768
731
  // if bytesWritten >= pageSize:
769
- [ Opcodes.global_get, 1 ],
732
+ ...glbl(Opcodes.global_get, 'bytesWritten', Valtype.i32),
770
733
  number(pageSize, Valtype.i32),
771
734
  [ Opcodes.i32_ge_s ],
772
735
  [ Opcodes.if, Valtype.i32 ],
773
736
  // bytesWritten = bytesToAllocate
774
737
  [ Opcodes.local_get, 0 ],
775
- [ Opcodes.global_set, 1 ],
738
+ ...glbl(Opcodes.global_set, 'bytesWritten', Valtype.i32),
776
739
 
777
740
  // return currentPtr = newly allocated page
778
741
  [ Opcodes.call, builtin('__Porffor_allocate') ],
779
- [ Opcodes.global_set, 0 ],
780
- [ Opcodes.global_get, 0 ],
742
+ ...glbl(Opcodes.global_set, 'currentPtr', Valtype.i32),
743
+ ...glbl(Opcodes.global_get, 'currentPtr', Valtype.i32),
781
744
  [ Opcodes.else ],
782
745
  // return currentPtr + bytesWritten
783
- [ Opcodes.global_get, 0 ],
784
- [ Opcodes.global_get, 1 ],
746
+ ...glbl(Opcodes.global_get, 'currentPtr', Valtype.i32),
747
+ ...glbl(Opcodes.global_get, 'bytesWritten', Valtype.i32),
785
748
  [ Opcodes.i32_add ],
786
749
 
787
750
  // bytesWritten += bytesToAllocate
788
751
  [ Opcodes.local_get, 0 ],
789
- [ Opcodes.global_get, 1 ],
752
+ ...glbl(Opcodes.global_get, 'bytesWritten', Valtype.i32),
790
753
  [ Opcodes.i32_add ],
791
- [ Opcodes.global_set, 1 ],
754
+ ...glbl(Opcodes.global_set, 'bytesWritten', Valtype.i32),
792
755
  [ Opcodes.end ]
793
756
  ]
794
757
  };
@@ -893,7 +856,7 @@ export const BuiltinFuncs = function() {
893
856
  params: [ Valtype.f64 ],
894
857
  returns: [ Valtype.i32 ],
895
858
  returnType: TYPES.number,
896
- wasm: [
859
+ wasm: () => [
897
860
  // extract exponent bits from f64 with bit manipulation
898
861
  [ Opcodes.local_get, 0 ],
899
862
  [ Opcodes.i64_reinterpret_f64 ],