porffor 0.57.32 → 0.57.33
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/compiler/builtins.js +294 -331
- package/compiler/builtins_objects.js +28 -31
- package/compiler/builtins_precompiled.js +8 -8
- package/compiler/codegen.js +96 -63
- package/package.json +1 -1
- package/runtime/index.js +2 -2
package/compiler/builtins.js
CHANGED
@@ -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
|
-
'
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
[
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
742
|
-
|
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
|
-
|
746
|
-
|
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
|
-
|
716
|
+
...glbl(Opcodes.global_get, 'chunkOffset', Valtype.i32),
|
752
717
|
[ Opcodes.i32_add ],
|
753
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
780
|
-
|
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
|
-
|
784
|
-
|
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
|
-
|
752
|
+
...glbl(Opcodes.global_get, 'bytesWritten', Valtype.i32),
|
790
753
|
[ Opcodes.i32_add ],
|
791
|
-
|
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 ],
|
@@ -2,7 +2,7 @@ import { Blocktype, Opcodes, Valtype } from './wasmSpec.js';
|
|
2
2
|
import { TYPES } from './types.js';
|
3
3
|
import { number } from './encoding.js';
|
4
4
|
|
5
|
-
export default function({ builtinFuncs }, Prefs) {
|
5
|
+
export default function ({ builtinFuncs }, Prefs) {
|
6
6
|
const makePrefix = name => (name.startsWith('__') ? '' : '__') + name + '_';
|
7
7
|
|
8
8
|
const done = new Set();
|
@@ -72,16 +72,15 @@ export default function({ builtinFuncs }, Prefs) {
|
|
72
72
|
continue;
|
73
73
|
}
|
74
74
|
|
75
|
-
let
|
75
|
+
let add = true;
|
76
|
+
if (existingFunc && (x === 'prototype' || x === 'constructor')) add = false;
|
76
77
|
|
78
|
+
let flags = 0b0000;
|
77
79
|
const d = props[x];
|
78
80
|
if (d.configurable) flags |= 0b0010;
|
79
81
|
if (d.enumerable) flags |= 0b0100;
|
80
82
|
if (d.writable) flags |= 0b1000;
|
81
83
|
|
82
|
-
// hack: do not generate objects inside of objects as it causes issues atm
|
83
|
-
if (this[prefix + x]?.type === TYPES.object && this[prefix + x] !== this.null) value = { type: 'ObjectExpression', properties: [] };
|
84
|
-
|
85
84
|
out.push(
|
86
85
|
[ Opcodes.local_get, 0 ],
|
87
86
|
number(TYPES.object, Valtype.i32),
|
@@ -96,7 +95,7 @@ export default function({ builtinFuncs }, Prefs) {
|
|
96
95
|
number(flags, Valtype.i32),
|
97
96
|
number(TYPES.number, Valtype.i32),
|
98
97
|
|
99
|
-
[ Opcodes.call, builtin('__Porffor_object_fastAdd') ]
|
98
|
+
[ Opcodes.call, builtin(add ? '__Porffor_object_fastAdd' : '__Porffor_object_define') ]
|
100
99
|
);
|
101
100
|
}
|
102
101
|
|
@@ -170,11 +169,20 @@ export default function({ builtinFuncs }, Prefs) {
|
|
170
169
|
const prefix = makePrefix(name);
|
171
170
|
return builtinFuncKeys.filter(x => x.startsWith(prefix)).map(x => x.slice(prefix.length)).filter(x => !x.startsWith('prototype_'));
|
172
171
|
};
|
173
|
-
const autoFuncs = name =>
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
172
|
+
const autoFuncs = name => ({
|
173
|
+
...props({
|
174
|
+
writable: true,
|
175
|
+
enumerable: false,
|
176
|
+
configurable: true
|
177
|
+
}, autoFuncKeys(name)),
|
178
|
+
...(this[`__${name}_prototype`] ? {
|
179
|
+
prototype: {
|
180
|
+
writable: false,
|
181
|
+
enumerable: false,
|
182
|
+
configurable: false
|
183
|
+
}
|
184
|
+
} : {})
|
185
|
+
});
|
178
186
|
|
179
187
|
object('Math', {
|
180
188
|
...props({
|
@@ -248,28 +256,16 @@ export default function({ builtinFuncs }, Prefs) {
|
|
248
256
|
NaN: NaN,
|
249
257
|
POSITIVE_INFINITY: Infinity,
|
250
258
|
NEGATIVE_INFINITY: -Infinity,
|
251
|
-
|
252
259
|
MAX_VALUE: valtype === 'i32' ? 2147483647 : 1.7976931348623157e+308,
|
253
260
|
MIN_VALUE: valtype === 'i32' ? -2147483648 : 5e-324,
|
254
|
-
|
255
261
|
MAX_SAFE_INTEGER: valtype === 'i32' ? 2147483647 : 9007199254740991,
|
256
262
|
MIN_SAFE_INTEGER: valtype === 'i32' ? -2147483648 : -9007199254740991,
|
257
|
-
|
258
263
|
EPSILON: 2.220446049250313e-16
|
259
264
|
}),
|
260
265
|
|
261
266
|
...autoFuncs('Number')
|
262
267
|
});
|
263
268
|
|
264
|
-
object('Reflect', autoFuncs('Reflect'));
|
265
|
-
object('Object', autoFuncs('Object'));
|
266
|
-
object('JSON', autoFuncs('JSON'));
|
267
|
-
object('Promise', autoFuncs('Promise'));
|
268
|
-
object('Array', autoFuncs('Array'));
|
269
|
-
object('Symbol', autoFuncs('Symbol'));
|
270
|
-
object('Date', autoFuncs('Date'));
|
271
|
-
object('Atomics', autoFuncs('Atomics'));
|
272
|
-
|
273
269
|
// these technically not spec compliant as it should be classes or non-enumerable but eh
|
274
270
|
object('navigator', {
|
275
271
|
...props({
|
@@ -286,13 +282,15 @@ export default function({ builtinFuncs }, Prefs) {
|
|
286
282
|
'crypto',
|
287
283
|
'performance',
|
288
284
|
]) {
|
289
|
-
object(x, {
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
285
|
+
object(x, props({
|
286
|
+
writable: true,
|
287
|
+
enumerable: true,
|
288
|
+
configurable: true
|
289
|
+
}, autoFuncKeys(x).slice(0, 12)));
|
290
|
+
}
|
291
|
+
|
292
|
+
for (const x of [ 'Array', 'ArrayBuffer', 'Atomics', 'Date', 'Error', 'JSON', 'Object', 'Promise', 'Reflect', 'String', 'Symbol', 'Uint8Array', 'Int8Array', 'Uint8ClampedArray', 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array', 'BigInt64Array', 'BigUint64Array', 'SharedArrayBuffer', 'BigInt', 'Boolean', 'DataView', 'AggregateError', 'TypeError', 'ReferenceError', 'SyntaxError', 'RangeError', 'EvalError', 'URIError', 'Function', 'Map', 'RegExp', 'Set', 'WeakMap', 'WeakRef', 'WeakSet' ]) {
|
293
|
+
object(x, autoFuncs(x));
|
296
294
|
}
|
297
295
|
|
298
296
|
const enumerableGlobals = [ 'atob', 'btoa', 'performance', 'crypto', 'navigator' ];
|
@@ -334,7 +332,6 @@ export default function({ builtinFuncs }, Prefs) {
|
|
334
332
|
|
335
333
|
if (Prefs.logMissingObjects) for (const x of Object.keys(builtinFuncs).concat(Object.keys(this))) {
|
336
334
|
if (!x.startsWith('__')) continue;
|
337
|
-
|
338
335
|
const name = x.split('_').slice(2, -1).join('_');
|
339
336
|
|
340
337
|
let t = globalThis;
|
@@ -1631,7 +1631,7 @@ locals:[127,124],localNames:["#newtarget","#newtarget#type","#this","#this#type"
|
|
1631
1631
|
constr:1,
|
1632
1632
|
}
|
1633
1633
|
this.__Error_prototype_constructor$get = {
|
1634
|
-
wasm:(_,{
|
1634
|
+
wasm:(_,{builtin})=>eval("[[16,builtin('#get_Error')],[184],[65,6],[15]]"),
|
1635
1635
|
params:[124,127],typedParams:1,returns:[124,127],
|
1636
1636
|
locals:[],localNames:["_this","_this#type"],
|
1637
1637
|
}
|
@@ -1657,7 +1657,7 @@ locals:[127,124],localNames:["#newtarget","#newtarget#type","#this","#this#type"
|
|
1657
1657
|
constr:1,
|
1658
1658
|
}
|
1659
1659
|
this.__AggregateError_prototype_constructor$get = {
|
1660
|
-
wasm:(_,{
|
1660
|
+
wasm:(_,{builtin})=>eval("[[16,builtin('#get_AggregateError')],[184],[65,6],[15]]"),
|
1661
1661
|
params:[124,127],typedParams:1,returns:[124,127],
|
1662
1662
|
locals:[],localNames:["_this","_this#type"],
|
1663
1663
|
}
|
@@ -1683,7 +1683,7 @@ locals:[127,124],localNames:["#newtarget","#newtarget#type","#this","#this#type"
|
|
1683
1683
|
constr:1,
|
1684
1684
|
}
|
1685
1685
|
this.__TypeError_prototype_constructor$get = {
|
1686
|
-
wasm:(_,{
|
1686
|
+
wasm:(_,{builtin})=>eval("[[16,builtin('#get_TypeError')],[184],[65,6],[15]]"),
|
1687
1687
|
params:[124,127],typedParams:1,returns:[124,127],
|
1688
1688
|
locals:[],localNames:["_this","_this#type"],
|
1689
1689
|
}
|
@@ -1709,7 +1709,7 @@ locals:[127,124],localNames:["#newtarget","#newtarget#type","#this","#this#type"
|
|
1709
1709
|
constr:1,
|
1710
1710
|
}
|
1711
1711
|
this.__ReferenceError_prototype_constructor$get = {
|
1712
|
-
wasm:(_,{
|
1712
|
+
wasm:(_,{builtin})=>eval("[[16,builtin('#get_ReferenceError')],[184],[65,6],[15]]"),
|
1713
1713
|
params:[124,127],typedParams:1,returns:[124,127],
|
1714
1714
|
locals:[],localNames:["_this","_this#type"],
|
1715
1715
|
}
|
@@ -1735,7 +1735,7 @@ locals:[127,124],localNames:["#newtarget","#newtarget#type","#this","#this#type"
|
|
1735
1735
|
constr:1,
|
1736
1736
|
}
|
1737
1737
|
this.__SyntaxError_prototype_constructor$get = {
|
1738
|
-
wasm:(_,{
|
1738
|
+
wasm:(_,{builtin})=>eval("[[16,builtin('#get_SyntaxError')],[184],[65,6],[15]]"),
|
1739
1739
|
params:[124,127],typedParams:1,returns:[124,127],
|
1740
1740
|
locals:[],localNames:["_this","_this#type"],
|
1741
1741
|
}
|
@@ -1761,7 +1761,7 @@ locals:[127,124],localNames:["#newtarget","#newtarget#type","#this","#this#type"
|
|
1761
1761
|
constr:1,
|
1762
1762
|
}
|
1763
1763
|
this.__RangeError_prototype_constructor$get = {
|
1764
|
-
wasm:(_,{
|
1764
|
+
wasm:(_,{builtin})=>eval("[[16,builtin('#get_RangeError')],[184],[65,6],[15]]"),
|
1765
1765
|
params:[124,127],typedParams:1,returns:[124,127],
|
1766
1766
|
locals:[],localNames:["_this","_this#type"],
|
1767
1767
|
}
|
@@ -1787,7 +1787,7 @@ locals:[127,124],localNames:["#newtarget","#newtarget#type","#this","#this#type"
|
|
1787
1787
|
constr:1,
|
1788
1788
|
}
|
1789
1789
|
this.__EvalError_prototype_constructor$get = {
|
1790
|
-
wasm:(_,{
|
1790
|
+
wasm:(_,{builtin})=>eval("[[16,builtin('#get_EvalError')],[184],[65,6],[15]]"),
|
1791
1791
|
params:[124,127],typedParams:1,returns:[124,127],
|
1792
1792
|
locals:[],localNames:["_this","_this#type"],
|
1793
1793
|
}
|
@@ -1813,7 +1813,7 @@ locals:[127,124],localNames:["#newtarget","#newtarget#type","#this","#this#type"
|
|
1813
1813
|
constr:1,
|
1814
1814
|
}
|
1815
1815
|
this.__URIError_prototype_constructor$get = {
|
1816
|
-
wasm:(_,{
|
1816
|
+
wasm:(_,{builtin})=>eval("[[16,builtin('#get_URIError')],[184],[65,6],[15]]"),
|
1817
1817
|
params:[124,127],typedParams:1,returns:[124,127],
|
1818
1818
|
locals:[],localNames:["_this","_this#type"],
|
1819
1819
|
}
|
package/compiler/codegen.js
CHANGED
@@ -1294,15 +1294,21 @@ const asmFuncToAsm = (scope, func, extra) => func(scope, {
|
|
1294
1294
|
scope.initedGlobals ??= new Set();
|
1295
1295
|
if (!scope.initedGlobals.has(name)) {
|
1296
1296
|
scope.initedGlobals.add(name);
|
1297
|
-
if (scope.globalInits?.[name])
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1297
|
+
if (scope.globalInits?.[name]) {
|
1298
|
+
if (typeof scope.globalInits[name] === 'function') {
|
1299
|
+
out.unshift(
|
1300
|
+
[ Opcodes.global_get, globals[globalName + '#glbl_inited'].idx ],
|
1301
|
+
[ Opcodes.i32_eqz ],
|
1302
|
+
[ Opcodes.if, Blocktype.void ],
|
1303
|
+
...asmFuncToAsm(scope, scope.globalInits[name]),
|
1304
|
+
number(1, Valtype.i32),
|
1305
|
+
[ Opcodes.global_set, globals[globalName + '#glbl_inited'].idx ],
|
1306
|
+
[ Opcodes.end ]
|
1307
|
+
);
|
1308
|
+
} else {
|
1309
|
+
globals[globalName].init = scope.globalInits[name];
|
1310
|
+
}
|
1311
|
+
}
|
1306
1312
|
}
|
1307
1313
|
|
1308
1314
|
return out;
|
@@ -1332,7 +1338,7 @@ const asmFuncToAsm = (scope, func, extra) => func(scope, {
|
|
1332
1338
|
allocPage: (scope, name) => allocPage({ scope, pages }, name)
|
1333
1339
|
}, extra);
|
1334
1340
|
|
1335
|
-
const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTypes = [],
|
1341
|
+
const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTypes = [], globalInits = {}, returns = [], returnType, localNames = [], globalNames = [], table = false, constr = false, hasRestArgument = false, usesTag = false, usesImports = false, returnTypes } = {}) => {
|
1336
1342
|
if (wasm == null) { // called with no built-in
|
1337
1343
|
log.warning('codegen', `${name} has no built-in!`);
|
1338
1344
|
wasm = [];
|
@@ -1364,28 +1370,8 @@ const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTy
|
|
1364
1370
|
funcs.push(func);
|
1365
1371
|
funcIndex[name] = func.index;
|
1366
1372
|
|
1367
|
-
if (
|
1368
|
-
|
1369
|
-
else wasm = asmFuncToAsm(func, wasm);
|
1370
|
-
}
|
1371
|
-
|
1372
|
-
if (globalTypes.length !== 0) {
|
1373
|
-
// offset global ops for base global idx
|
1374
|
-
let baseGlobalIdx, i = 0;
|
1375
|
-
for (const type of globalTypes) {
|
1376
|
-
if (baseGlobalIdx === undefined) baseGlobalIdx = globals['#ind'];
|
1377
|
-
|
1378
|
-
globals[globalNames[i] ?? `${name}_global_${i}`] = { idx: globals['#ind']++, type, init: globalInits[i] ?? 0 };
|
1379
|
-
i++;
|
1380
|
-
}
|
1381
|
-
|
1382
|
-
for (let i = 0; i < wasm.length; i++) {
|
1383
|
-
const inst = wasm[i];
|
1384
|
-
if (inst[0] === Opcodes.global_get || inst[0] === Opcodes.global_set) {
|
1385
|
-
inst[1] += baseGlobalIdx;
|
1386
|
-
}
|
1387
|
-
}
|
1388
|
-
}
|
1373
|
+
if (globalThis.precompile) wasm = [];
|
1374
|
+
else wasm = asmFuncToAsm(func, wasm);
|
1389
1375
|
|
1390
1376
|
if (table) funcs.table = true;
|
1391
1377
|
if (usesTag) {
|
@@ -2546,14 +2532,13 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2546
2532
|
[ Opcodes.local_get, calleeLocal ],
|
2547
2533
|
Opcodes.i32_to_u,
|
2548
2534
|
[ Opcodes.call_indirect, args.length + 2, 0 ],
|
2549
|
-
...setLastType(scope)
|
2550
|
-
...(globalThis.precompile && valtypeBinary === Valtype.i32 ? [ Opcodes.i32_trunc_sat_f64_s ] : [])
|
2535
|
+
...setLastType(scope)
|
2551
2536
|
],
|
2552
2537
|
|
2553
|
-
default: decl.optional ? withType(scope, [ number(UNDEFINED) ], TYPES.undefined)
|
2538
|
+
default: decl.optional ? withType(scope, [ number(UNDEFINED, Valtype.f64) ], TYPES.undefined)
|
2554
2539
|
: internalThrow(scope, 'TypeError', `${unhackName(name)} is not a function`, Valtype.f64)
|
2555
2540
|
}, Valtype.f64),
|
2556
|
-
...(valtypeBinary === Valtype.i32
|
2541
|
+
...(valtypeBinary === Valtype.i32 ? [ Opcodes.i32_trunc_sat_f64_s ] : [])
|
2557
2542
|
];
|
2558
2543
|
}
|
2559
2544
|
|
@@ -3639,6 +3624,71 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3639
3624
|
|
3640
3625
|
const op = decl.operator.slice(0, -1) || '=';
|
3641
3626
|
|
3627
|
+
// short-circuit behavior for logical assignment operators
|
3628
|
+
if (op === '||' || op === '&&' || op === '??') {
|
3629
|
+
// for logical assignment ops, it is not left @= right -> left = left @ right
|
3630
|
+
// instead, left @ (left = right)
|
3631
|
+
// eg, x &&= y -> x && (x = y)
|
3632
|
+
if (local !== undefined) {
|
3633
|
+
// fast path: just assigning to a local
|
3634
|
+
setInferred(scope, name, knownType(scope, getNodeType(scope, decl)), isGlobal);
|
3635
|
+
return [
|
3636
|
+
...performOp(scope, op, [
|
3637
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
3638
|
+
], [
|
3639
|
+
...generate(scope, decl.right, isGlobal, name),
|
3640
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
3641
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
3642
|
+
], getType(scope, name), getNodeType(scope, decl.right)),
|
3643
|
+
...setType(scope, name, getLastType(scope), true)
|
3644
|
+
];
|
3645
|
+
} else if (type === 'MemberExpression' && decl.left.computed) {
|
3646
|
+
// special path: cache properties for computed members so they are not evaluated twice
|
3647
|
+
// eg, x[y] &&= z -> (a = y, x[a] = (x[a] = z))
|
3648
|
+
const propTmp = localTmp(scope, '#logical_prop');
|
3649
|
+
const propTypeTmp = localTmp(scope, '#logical_prop#type', Valtype.i32);
|
3650
|
+
|
3651
|
+
const member = {
|
3652
|
+
type: 'MemberExpression',
|
3653
|
+
object: decl.left.object,
|
3654
|
+
property: { type: 'Identifier', name: '#logical_prop' },
|
3655
|
+
computed: true
|
3656
|
+
};
|
3657
|
+
|
3658
|
+
return [
|
3659
|
+
...generate(scope, decl.left.property),
|
3660
|
+
[ Opcodes.local_set, propTmp ],
|
3661
|
+
...getNodeType(scope, decl.left.property),
|
3662
|
+
[ Opcodes.local_set, propTypeTmp ],
|
3663
|
+
|
3664
|
+
...generate(scope, {
|
3665
|
+
type: 'LogicalExpression',
|
3666
|
+
operator: op,
|
3667
|
+
left: member,
|
3668
|
+
right: {
|
3669
|
+
type: 'AssignmentExpression',
|
3670
|
+
operator: '=',
|
3671
|
+
left: member,
|
3672
|
+
right: decl.right
|
3673
|
+
}
|
3674
|
+
}, _global, _name, valueUnused)
|
3675
|
+
];
|
3676
|
+
} else {
|
3677
|
+
// other: generate as LogicalExpression
|
3678
|
+
return generate(scope, {
|
3679
|
+
type: 'LogicalExpression',
|
3680
|
+
operator: op,
|
3681
|
+
left: decl.left,
|
3682
|
+
right: {
|
3683
|
+
type: 'AssignmentExpression',
|
3684
|
+
operator: '=',
|
3685
|
+
left: decl.left,
|
3686
|
+
right: decl.right
|
3687
|
+
}
|
3688
|
+
}, _global, _name, valueUnused);
|
3689
|
+
}
|
3690
|
+
}
|
3691
|
+
|
3642
3692
|
// hack: .length setter
|
3643
3693
|
if (type === 'MemberExpression' && decl.left.property.name === 'length' && !decl._internalAssign) {
|
3644
3694
|
const newValueTmp = !valueUnused && localTmp(scope, '__length_setter_tmp');
|
@@ -4074,27 +4124,6 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
4074
4124
|
return out;
|
4075
4125
|
}
|
4076
4126
|
|
4077
|
-
if (op === '||' || op === '&&' || op === '??') {
|
4078
|
-
// todo: is this needed?
|
4079
|
-
// for logical assignment ops, it is not left @= right ~= left = left @ right
|
4080
|
-
// instead, left @ (left = right)
|
4081
|
-
// eg, x &&= y ~= x && (x = y)
|
4082
|
-
|
4083
|
-
setInferred(scope, name, knownType(scope, getNodeType(scope, decl)), isGlobal);
|
4084
|
-
|
4085
|
-
return [
|
4086
|
-
...performOp(scope, op, [
|
4087
|
-
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
4088
|
-
], [
|
4089
|
-
...generate(scope, decl.right, isGlobal, name),
|
4090
|
-
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
4091
|
-
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
4092
|
-
], getType(scope, name), getNodeType(scope, decl.right)),
|
4093
|
-
|
4094
|
-
...setType(scope, name, getLastType(scope), true)
|
4095
|
-
];
|
4096
|
-
}
|
4097
|
-
|
4098
4127
|
const out = setLocalWithType(
|
4099
4128
|
scope, name, isGlobal,
|
4100
4129
|
performOp(scope, op, [
|
@@ -7089,7 +7118,7 @@ const internalConstrs = {
|
|
7089
7118
|
}
|
7090
7119
|
};
|
7091
7120
|
|
7092
|
-
let globals, tags, exceptions, funcs, indirectFuncs, funcIndex, currentFuncIndex, depth, pages, data, typeswitchDepth, usedTypes, coctc, globalInfer, builtinFuncs, builtinVars, prototypeFuncs;
|
7121
|
+
let globals, tags, exceptions, funcs, indirectFuncs, funcIndex, currentFuncIndex, depth, pages, data, typeswitchDepth, usedTypes, coctc, globalInfer, builtinFuncs, builtinVars, prototypeFuncs, lastValtype;
|
7093
7122
|
export default program => {
|
7094
7123
|
globals = { ['#ind']: 0 };
|
7095
7124
|
tags = [];
|
@@ -7119,12 +7148,16 @@ export default program => {
|
|
7119
7148
|
Opcodes.load = valtypeBinary === Valtype.i32 ? Opcodes.i32_load : Opcodes.f64_load;
|
7120
7149
|
Opcodes.store = valtypeBinary === Valtype.i32 ? Opcodes.i32_store : Opcodes.f64_store;
|
7121
7150
|
|
7122
|
-
|
7123
|
-
|
7124
|
-
|
7151
|
+
// keep builtins between compiles as much as possible
|
7152
|
+
if (lastValtype !== valtypeBinary) {
|
7153
|
+
lastValtype = valtypeBinary;
|
7154
|
+
builtinFuncs = new BuiltinFuncs();
|
7155
|
+
builtinVars = new BuiltinVars({ builtinFuncs });
|
7156
|
+
prototypeFuncs = new PrototypeFuncs();
|
7125
7157
|
|
7126
|
-
|
7127
|
-
|
7158
|
+
const getObjectName = x => x.startsWith('__') && x.slice(2, x.indexOf('_', 2));
|
7159
|
+
objectHackers = ['assert', 'compareArray', 'Test262Error', ...new Set(Object.keys(builtinFuncs).map(getObjectName).concat(Object.keys(builtinVars).map(getObjectName)).filter(x => x))];
|
7160
|
+
}
|
7128
7161
|
|
7129
7162
|
const [ main ] = generateFunc({}, {
|
7130
7163
|
type: 'Program',
|
package/package.json
CHANGED
package/runtime/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
import fs from 'node:fs';
|
3
|
-
globalThis.version = '0.57.
|
3
|
+
globalThis.version = '0.57.33';
|
4
4
|
|
5
5
|
// deno compat
|
6
6
|
if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
|
@@ -68,7 +68,7 @@ if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
68
68
|
'exception-mode': 'Exception mode to use (lut|\x1B[1mstack\x1B[0m)',
|
69
69
|
'fast-length': 'Non-compliant optimization to make .length faster',
|
70
70
|
'profile-compiler': 'Log general compiler performance (on by default when compiling to a file)',
|
71
|
-
prng: 'PRNG algorithm to use (
|
71
|
+
prng: 'PRNG algorithm to use (xorshift32+|xorshift64+|\x1B[1mxorshift128+\x1B[0m|xoroshiro128+|xoshiro128+)'
|
72
72
|
})) {
|
73
73
|
flag = '-' + flag;
|
74
74
|
if (flag.length > 3) flag = '-' + flag;
|