porffor 0.16.0-0e7f638da → 0.16.0-1a6e16aae
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/CONTRIBUTING.md +1 -1
- package/compiler/allocators/chunk.js +0 -0
- package/compiler/allocators/solo.js +0 -0
- package/compiler/allocators/static.js +41 -0
- package/compiler/codegen.js +46 -162
- package/compiler/cyclone.js +11 -11
- package/compiler/parse.js +1 -1
- package/compiler/precompile.js +3 -1
- package/compiler/prefs.js +1 -1
- package/compiler/wrap.js +1 -1
- package/package.json +2 -4
- package/runner/index.js +8 -3
package/CONTRIBUTING.md
CHANGED
@@ -26,7 +26,7 @@ You can also swap out `node` in the alias to use another runtime like Deno (`den
|
|
26
26
|
|
27
27
|
### Precompile
|
28
28
|
|
29
|
-
**If you update any file inside `compiler/builtins` you will need to do this for it to update inside Porffor otherwise your changes will have no effect.** Run
|
29
|
+
**If you update any file inside `compiler/builtins` you will need to do this for it to update inside Porffor otherwise your changes will have no effect.** Run `./porf precompile` to precompile. It may error during this, if so, you might have an error in your code or there could be a compiler error with Porffor (feel free to ask for help as soon as you encounter any errors with it).
|
30
30
|
|
31
31
|
<br>
|
32
32
|
|
File without changes
|
File without changes
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { Valtype } from '../wasmSpec.js';
|
2
|
+
import { number } from './embedding.js';
|
3
|
+
import { log } from './log.js';
|
4
|
+
import Prefs from './prefs.js';
|
5
|
+
|
6
|
+
let pages = new Set();
|
7
|
+
export const setup = () => {
|
8
|
+
pages = new Set();
|
9
|
+
};
|
10
|
+
|
11
|
+
const getAllocType = itemType => {
|
12
|
+
switch (itemType) {
|
13
|
+
case 'i8': return 'bytestring';
|
14
|
+
case 'i16': return 'string';
|
15
|
+
|
16
|
+
default: return 'array';
|
17
|
+
}
|
18
|
+
};
|
19
|
+
|
20
|
+
export const alloc = ({ scope }, name, itemType) => {
|
21
|
+
const reason = Prefs.scopedPageNames ? `${getAllocType(itemType)}: ${scope.name}/${name}` : `${getAllocType(itemType)}: ${name}`;
|
22
|
+
|
23
|
+
if (pages.has(reason)) return number(pages.get(reason).ind, Valtype.i32);
|
24
|
+
|
25
|
+
if (reason.startsWith('array:')) pages.hasArray = true;
|
26
|
+
if (reason.startsWith('string:')) pages.hasString = true;
|
27
|
+
if (reason.startsWith('bytestring:')) pages.hasByteString = true;
|
28
|
+
if (reason.includes('string:')) pages.hasAnyString = true;
|
29
|
+
|
30
|
+
const ind = pages.size;
|
31
|
+
pages.set(reason, { ind, type });
|
32
|
+
|
33
|
+
scope.pages ??= new Map();
|
34
|
+
scope.pages.set(reason, { ind, type });
|
35
|
+
|
36
|
+
if (Prefs.allocLog) log('alloc', `allocated new page of memory (${ind}) | ${reason} (type: ${type})`);
|
37
|
+
|
38
|
+
return number(ind, Valtype.i32);
|
39
|
+
};
|
40
|
+
|
41
|
+
export const getStaticPages = () => pages;
|
package/compiler/codegen.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Blocktype, Opcodes, Valtype,
|
1
|
+
import { Blocktype, Opcodes, Valtype, ValtypeSize } from './wasmSpec.js';
|
2
2
|
import { ieee754_binary64, signedLEB128, unsignedLEB128, encodeVector } from './encoding.js';
|
3
3
|
import { operatorOpcode } from './expression.js';
|
4
4
|
import { BuiltinFuncs, BuiltinVars, importedFuncs, NULL, UNDEFINED } from './builtins.js';
|
@@ -181,12 +181,6 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
|
|
181
181
|
continue;
|
182
182
|
}
|
183
183
|
|
184
|
-
if (asm[0] === 'memory') {
|
185
|
-
allocPage(scope, 'asm instrinsic');
|
186
|
-
// todo: add to store/load offset insts
|
187
|
-
continue;
|
188
|
-
}
|
189
|
-
|
190
184
|
let inst = Opcodes[asm[0].replace('.', '_')];
|
191
185
|
if (inst == null) throw new Error(`inline asm: inst ${asm[0]} not found`);
|
192
186
|
|
@@ -433,57 +427,6 @@ const concatStrings = (scope, left, right, global, name, assign = false, bytestr
|
|
433
427
|
const rightLength = localTmp(scope, 'concat_right_length', Valtype.i32);
|
434
428
|
const leftLength = localTmp(scope, 'concat_left_length', Valtype.i32);
|
435
429
|
|
436
|
-
if (assign && Prefs.aotPointerOpt) {
|
437
|
-
const pointer = scope.arrays?.get(name ?? '$undeclared');
|
438
|
-
|
439
|
-
return [
|
440
|
-
// setup right
|
441
|
-
...right,
|
442
|
-
Opcodes.i32_to_u,
|
443
|
-
[ Opcodes.local_set, rightPointer ],
|
444
|
-
|
445
|
-
// calculate length
|
446
|
-
...number(0, Valtype.i32), // base 0 for store later
|
447
|
-
|
448
|
-
...number(pointer, Valtype.i32),
|
449
|
-
[ Opcodes.i32_load, 0, ...unsignedLEB128(0) ],
|
450
|
-
[ Opcodes.local_tee, leftLength ],
|
451
|
-
|
452
|
-
[ Opcodes.local_get, rightPointer ],
|
453
|
-
[ Opcodes.i32_load, 0, ...unsignedLEB128(0) ],
|
454
|
-
[ Opcodes.local_tee, rightLength ],
|
455
|
-
|
456
|
-
[ Opcodes.i32_add ],
|
457
|
-
|
458
|
-
// store length
|
459
|
-
[ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, ...unsignedLEB128(pointer) ],
|
460
|
-
|
461
|
-
// copy right
|
462
|
-
// dst = out pointer + length size + current length * sizeof valtype
|
463
|
-
...number(pointer + ValtypeSize.i32, Valtype.i32),
|
464
|
-
|
465
|
-
[ Opcodes.local_get, leftLength ],
|
466
|
-
...number(bytestrings ? ValtypeSize.i8 : ValtypeSize.i16, Valtype.i32),
|
467
|
-
[ Opcodes.i32_mul ],
|
468
|
-
[ Opcodes.i32_add ],
|
469
|
-
|
470
|
-
// src = right pointer + length size
|
471
|
-
[ Opcodes.local_get, rightPointer ],
|
472
|
-
...number(ValtypeSize.i32, Valtype.i32),
|
473
|
-
[ Opcodes.i32_add ],
|
474
|
-
|
475
|
-
// size = right length * sizeof valtype
|
476
|
-
[ Opcodes.local_get, rightLength ],
|
477
|
-
...number(bytestrings ? ValtypeSize.i8 : ValtypeSize.i16, Valtype.i32),
|
478
|
-
[ Opcodes.i32_mul ],
|
479
|
-
|
480
|
-
[ ...Opcodes.memory_copy, 0x00, 0x00 ],
|
481
|
-
|
482
|
-
// return new string (page)
|
483
|
-
...number(pointer)
|
484
|
-
];
|
485
|
-
}
|
486
|
-
|
487
430
|
const leftPointer = localTmp(scope, 'concat_left_pointer', Valtype.i32);
|
488
431
|
|
489
432
|
// alloc/assign array
|
@@ -2115,7 +2058,6 @@ const brTable = (input, bc, returns) => {
|
|
2115
2058
|
}
|
2116
2059
|
|
2117
2060
|
for (let i = 0; i < count; i++) {
|
2118
|
-
// if (i === 0) out.push([ Opcodes.block, returns, 'br table start' ]);
|
2119
2061
|
if (i === 0) out.push([ Opcodes.block, returns ]);
|
2120
2062
|
else out.push([ Opcodes.block, Blocktype.void ]);
|
2121
2063
|
}
|
@@ -2149,10 +2091,8 @@ const brTable = (input, bc, returns) => {
|
|
2149
2091
|
[ Opcodes.br_table, ...encodeVector(table), 0 ]
|
2150
2092
|
);
|
2151
2093
|
|
2152
|
-
//
|
2153
|
-
// (
|
2154
|
-
// dm me and if you are correct and the first person
|
2155
|
-
// I will somehow shout you out or something
|
2094
|
+
// sort the wrong way and then reverse
|
2095
|
+
// so strings ('default') are at the start before any numbers
|
2156
2096
|
const orderedBc = keys.sort((a, b) => b - a).reverse();
|
2157
2097
|
|
2158
2098
|
br = count - 1;
|
@@ -2178,7 +2118,7 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary) => {
|
|
2178
2118
|
return bc[known] ?? bc.default;
|
2179
2119
|
}
|
2180
2120
|
|
2181
|
-
if (Prefs.
|
2121
|
+
if (Prefs.typeswitchBrtable)
|
2182
2122
|
return brTable(type, bc, returns);
|
2183
2123
|
|
2184
2124
|
const tmp = localTmp(scope, '#typeswitch_tmp' + (Prefs.typeswitchUniqueTmp ? randId() : ''), Valtype.i32);
|
@@ -2399,19 +2339,12 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2399
2339
|
|
2400
2340
|
// hack: .length setter
|
2401
2341
|
if (decl.left.type === 'MemberExpression' && decl.left.property.name === 'length') {
|
2402
|
-
const name = decl.left.object.name;
|
2403
|
-
const pointer = scope.arrays?.get(name);
|
2404
|
-
|
2405
|
-
const aotPointer = Prefs.aotPointerOpt && pointer != null;
|
2406
|
-
|
2407
2342
|
const newValueTmp = localTmp(scope, '__length_setter_tmp');
|
2408
2343
|
const pointerTmp = op === '=' ? null : localTmp(scope, '__member_setter_ptr_tmp', Valtype.i32);
|
2409
2344
|
|
2410
2345
|
return [
|
2411
|
-
...(
|
2412
|
-
|
2413
|
-
Opcodes.i32_to_u
|
2414
|
-
]),
|
2346
|
+
...generate(scope, decl.left.object),
|
2347
|
+
Opcodes.i32_to_u,
|
2415
2348
|
...(!pointerTmp ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
2416
2349
|
|
2417
2350
|
...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
@@ -2422,7 +2355,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2422
2355
|
[ Opcodes.local_tee, newValueTmp ],
|
2423
2356
|
|
2424
2357
|
Opcodes.i32_to_u,
|
2425
|
-
[ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1,
|
2358
|
+
[ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
2426
2359
|
|
2427
2360
|
[ Opcodes.local_get, newValueTmp ]
|
2428
2361
|
];
|
@@ -2430,21 +2363,14 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2430
2363
|
|
2431
2364
|
// arr[i]
|
2432
2365
|
if (decl.left.type === 'MemberExpression' && decl.left.computed) {
|
2433
|
-
const name = decl.left.object.name;
|
2434
|
-
const pointer = scope.arrays?.get(name);
|
2435
|
-
|
2436
|
-
const aotPointer = Prefs.aotPointerOpt && pointer != null;
|
2437
|
-
|
2438
2366
|
const newValueTmp = localTmp(scope, '__member_setter_val_tmp');
|
2439
2367
|
const pointerTmp = op === '=' ? -1 : localTmp(scope, '__member_setter_ptr_tmp', Valtype.i32);
|
2440
2368
|
|
2441
2369
|
return [
|
2442
2370
|
...typeSwitch(scope, getNodeType(scope, decl.left.object), {
|
2443
2371
|
[TYPES.array]: [
|
2444
|
-
...(
|
2445
|
-
|
2446
|
-
Opcodes.i32_to_u
|
2447
|
-
]),
|
2372
|
+
...generate(scope, decl.left.object),
|
2373
|
+
Opcodes.i32_to_u,
|
2448
2374
|
|
2449
2375
|
// get index as valtype
|
2450
2376
|
...generate(scope, decl.left.property),
|
@@ -2453,39 +2379,22 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2453
2379
|
// turn into byte offset by * valtypeSize (4 for i32, 8 for i64/f64)
|
2454
2380
|
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
2455
2381
|
[ Opcodes.i32_mul ],
|
2456
|
-
|
2382
|
+
[ Opcodes.i32_add ],
|
2457
2383
|
...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
2458
2384
|
|
2459
2385
|
...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
2460
2386
|
[ Opcodes.local_get, pointerTmp ],
|
2461
|
-
[ Opcodes.load, 0,
|
2387
|
+
[ Opcodes.load, 0, ValtypeSize.i32 ]
|
2462
2388
|
], generate(scope, decl.right), [
|
2463
2389
|
[ Opcodes.local_get, pointerTmp ],
|
2464
|
-
[ Opcodes.i32_load8_u, 0,
|
2390
|
+
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ]
|
2465
2391
|
], getNodeType(scope, decl.right), false, name, true)),
|
2466
2392
|
[ Opcodes.local_tee, newValueTmp ],
|
2467
2393
|
|
2468
|
-
[ Opcodes.store, 0,
|
2394
|
+
[ Opcodes.store, 0, ValtypeSize.i32 ]
|
2469
2395
|
],
|
2470
2396
|
|
2471
2397
|
default: internalThrow(scope, 'TypeError', `Cannot assign member with non-array`)
|
2472
|
-
|
2473
|
-
// [TYPES.string]: [
|
2474
|
-
// // turn into byte offset by * sizeof i16
|
2475
|
-
// ...number(ValtypeSize.i16, Valtype.i32),
|
2476
|
-
// [ Opcodes.i32_mul ],
|
2477
|
-
// ...(aotPointer ? [] : [ [ Opcodes.i32_add ] ]),
|
2478
|
-
// ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
2479
|
-
|
2480
|
-
// ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
2481
|
-
// [ Opcodes.local_get, pointerTmp ],
|
2482
|
-
// [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
|
2483
|
-
// ], generate(scope, decl.right), number(TYPES.string, Valtype.i32), getNodeType(scope, decl.right))),
|
2484
|
-
// [ Opcodes.local_tee, newValueTmp ],
|
2485
|
-
|
2486
|
-
// Opcodes.i32_to_u,
|
2487
|
-
// [ StoreOps.i16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
|
2488
|
-
// ]
|
2489
2398
|
}, Blocktype.void),
|
2490
2399
|
|
2491
2400
|
[ Opcodes.local_get, newValueTmp ]
|
@@ -3207,16 +3116,6 @@ const allocPage = (scope, reason, type) => {
|
|
3207
3116
|
return ind;
|
3208
3117
|
};
|
3209
3118
|
|
3210
|
-
// todo: add scope.pages
|
3211
|
-
const freePage = reason => {
|
3212
|
-
const { ind } = pages.get(reason);
|
3213
|
-
pages.delete(reason);
|
3214
|
-
|
3215
|
-
if (Prefs.allocLog) log('alloc', `freed page of memory (${ind}) | ${reason}`);
|
3216
|
-
|
3217
|
-
return ind;
|
3218
|
-
};
|
3219
|
-
|
3220
3119
|
const itemTypeToValtype = {
|
3221
3120
|
i32: 'i32',
|
3222
3121
|
i64: 'i64',
|
@@ -3291,7 +3190,7 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
3291
3190
|
const valtype = itemTypeToValtype[itemType];
|
3292
3191
|
const length = elements.length;
|
3293
3192
|
|
3294
|
-
if (
|
3193
|
+
if (Prefs.data && firstAssign && useRawElements) {
|
3295
3194
|
// if length is 0 memory/data will just be 0000... anyway
|
3296
3195
|
if (length !== 0) {
|
3297
3196
|
let bytes = compileBytes(length, 'i32');
|
@@ -3359,7 +3258,7 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
3359
3258
|
return [ out, pointer ];
|
3360
3259
|
};
|
3361
3260
|
|
3362
|
-
const storeArray = (scope, array, index, element
|
3261
|
+
const storeArray = (scope, array, index, element) => {
|
3363
3262
|
if (!Array.isArray(element)) element = generate(scope, element);
|
3364
3263
|
if (typeof index === 'number') index = number(index);
|
3365
3264
|
|
@@ -3371,26 +3270,25 @@ const storeArray = (scope, array, index, element, aotPointer = null) => {
|
|
3371
3270
|
Opcodes.i32_to_u,
|
3372
3271
|
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
3373
3272
|
[ Opcodes.i32_mul ],
|
3374
|
-
|
3375
|
-
|
3376
|
-
|
3377
|
-
|
3378
|
-
]),
|
3273
|
+
|
3274
|
+
...array,
|
3275
|
+
Opcodes.i32_to_u,
|
3276
|
+
[ Opcodes.i32_add ],
|
3379
3277
|
[ Opcodes.local_set, offset ],
|
3380
3278
|
|
3381
3279
|
// store value
|
3382
3280
|
[ Opcodes.local_get, offset ],
|
3383
3281
|
...generate(scope, element),
|
3384
|
-
[ Opcodes.store, 0,
|
3282
|
+
[ Opcodes.store, 0, ValtypeSize.i32 ],
|
3385
3283
|
|
3386
3284
|
// store type
|
3387
3285
|
[ Opcodes.local_get, offset ],
|
3388
3286
|
...getNodeType(scope, element),
|
3389
|
-
[ Opcodes.i32_store8, 0,
|
3287
|
+
[ Opcodes.i32_store8, 0, ValtypeSize.i32 + ValtypeSize[valtype] ]
|
3390
3288
|
];
|
3391
3289
|
};
|
3392
3290
|
|
3393
|
-
const loadArray = (scope, array, index
|
3291
|
+
const loadArray = (scope, array, index) => {
|
3394
3292
|
if (typeof index === 'number') index = number(index);
|
3395
3293
|
|
3396
3294
|
const offset = localTmp(scope, '#loadArray_offset', Valtype.i32);
|
@@ -3401,20 +3299,19 @@ const loadArray = (scope, array, index, aotPointer = null) => {
|
|
3401
3299
|
Opcodes.i32_to_u,
|
3402
3300
|
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
3403
3301
|
[ Opcodes.i32_mul ],
|
3404
|
-
|
3405
|
-
|
3406
|
-
|
3407
|
-
|
3408
|
-
]),
|
3302
|
+
|
3303
|
+
...array,
|
3304
|
+
Opcodes.i32_to_u,
|
3305
|
+
[ Opcodes.i32_add ],
|
3409
3306
|
[ Opcodes.local_set, offset ],
|
3410
3307
|
|
3411
3308
|
// load value
|
3412
3309
|
[ Opcodes.local_get, offset ],
|
3413
|
-
[ Opcodes.load, 0,
|
3310
|
+
[ Opcodes.load, 0, ValtypeSize.i32 ],
|
3414
3311
|
|
3415
3312
|
// load type
|
3416
3313
|
[ Opcodes.local_get, offset ],
|
3417
|
-
[ Opcodes.i32_load8_u, 0,
|
3314
|
+
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ]
|
3418
3315
|
];
|
3419
3316
|
};
|
3420
3317
|
|
@@ -3465,9 +3362,6 @@ const withType = (scope, wasm, type) => [
|
|
3465
3362
|
|
3466
3363
|
const generateMember = (scope, decl, _global, _name) => {
|
3467
3364
|
const name = decl.object.name;
|
3468
|
-
const pointer = scope.arrays?.get(name);
|
3469
|
-
|
3470
|
-
const aotPointer = Prefs.aotPointerOpt && pointer;
|
3471
3365
|
|
3472
3366
|
// hack: .name
|
3473
3367
|
if (decl.property.name === 'name') {
|
@@ -3508,12 +3402,10 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
3508
3402
|
if (Prefs.fastLength) {
|
3509
3403
|
// presume valid length object
|
3510
3404
|
return [
|
3511
|
-
...(
|
3512
|
-
|
3513
|
-
Opcodes.i32_to_u
|
3514
|
-
]),
|
3405
|
+
...generate(scope, decl.object),
|
3406
|
+
Opcodes.i32_to_u,
|
3515
3407
|
|
3516
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1,
|
3408
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
3517
3409
|
Opcodes.i32_from_u
|
3518
3410
|
];
|
3519
3411
|
}
|
@@ -3522,12 +3414,10 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
3522
3414
|
const known = knownType(scope, type);
|
3523
3415
|
if (known != null) {
|
3524
3416
|
if ([ TYPES.string, TYPES.bytestring, TYPES.array ].includes(known)) return [
|
3525
|
-
...(
|
3526
|
-
|
3527
|
-
Opcodes.i32_to_u
|
3528
|
-
]),
|
3417
|
+
...generate(scope, decl.object),
|
3418
|
+
Opcodes.i32_to_u,
|
3529
3419
|
|
3530
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1,
|
3420
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
3531
3421
|
Opcodes.i32_from_u
|
3532
3422
|
];
|
3533
3423
|
|
@@ -3537,12 +3427,10 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
3537
3427
|
return [
|
3538
3428
|
...typeIsOneOf(getNodeType(scope, decl.object), [ TYPES.string, TYPES.bytestring, TYPES.array ]),
|
3539
3429
|
[ Opcodes.if, valtypeBinary ],
|
3540
|
-
...(
|
3541
|
-
|
3542
|
-
Opcodes.i32_to_u
|
3543
|
-
]),
|
3430
|
+
...generate(scope, decl.object),
|
3431
|
+
Opcodes.i32_to_u,
|
3544
3432
|
|
3545
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1,
|
3433
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
3546
3434
|
Opcodes.i32_from_u,
|
3547
3435
|
|
3548
3436
|
...setLastType(scope, TYPES.number),
|
@@ -3594,7 +3482,7 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
3594
3482
|
|
3595
3483
|
return typeSwitch(scope, getNodeType(scope, decl.object), {
|
3596
3484
|
[TYPES.array]: [
|
3597
|
-
...loadArray(scope, object, property
|
3485
|
+
...loadArray(scope, object, property),
|
3598
3486
|
...setLastType(scope)
|
3599
3487
|
],
|
3600
3488
|
|
@@ -3611,14 +3499,12 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
3611
3499
|
...number(ValtypeSize.i16, Valtype.i32),
|
3612
3500
|
[ Opcodes.i32_mul ],
|
3613
3501
|
|
3614
|
-
...
|
3615
|
-
|
3616
|
-
|
3617
|
-
[ Opcodes.i32_add ]
|
3618
|
-
]),
|
3502
|
+
...object,
|
3503
|
+
Opcodes.i32_to_u,
|
3504
|
+
[ Opcodes.i32_add ],
|
3619
3505
|
|
3620
3506
|
// load current string ind {arg}
|
3621
|
-
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1,
|
3507
|
+
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
3622
3508
|
|
3623
3509
|
// store to new string ind 0
|
3624
3510
|
[ Opcodes.i32_store16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
|
@@ -3637,14 +3523,12 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
3637
3523
|
...property,
|
3638
3524
|
Opcodes.i32_to_u,
|
3639
3525
|
|
3640
|
-
...
|
3641
|
-
|
3642
|
-
|
3643
|
-
[ Opcodes.i32_add ]
|
3644
|
-
]),
|
3526
|
+
...object,
|
3527
|
+
Opcodes.i32_to_u,
|
3528
|
+
[ Opcodes.i32_add ],
|
3645
3529
|
|
3646
3530
|
// load current string ind {arg}
|
3647
|
-
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(
|
3531
|
+
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(ValtypeSize.i32) ],
|
3648
3532
|
|
3649
3533
|
// store to new string ind 0
|
3650
3534
|
[ Opcodes.i32_store8, 0, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
|
package/compiler/cyclone.js
CHANGED
@@ -246,7 +246,7 @@ export default wasm => {
|
|
246
246
|
const [ b, a ] = pop2();
|
247
247
|
const v = bool(a === b);
|
248
248
|
|
249
|
-
replaceVal(v, Valtype.
|
249
|
+
replaceVal(v, Valtype.i32);
|
250
250
|
push(v);
|
251
251
|
break;
|
252
252
|
}
|
@@ -255,7 +255,7 @@ export default wasm => {
|
|
255
255
|
const [ b, a ] = pop2();
|
256
256
|
const v = bool(a !== b);
|
257
257
|
|
258
|
-
replaceVal(v, Valtype.
|
258
|
+
replaceVal(v, Valtype.i32);
|
259
259
|
push(v);
|
260
260
|
break;
|
261
261
|
}
|
@@ -264,7 +264,7 @@ export default wasm => {
|
|
264
264
|
const [ b, a ] = pop2();
|
265
265
|
const v = bool(a < b);
|
266
266
|
|
267
|
-
replaceVal(v, Valtype.
|
267
|
+
replaceVal(v, Valtype.i32);
|
268
268
|
push(v);
|
269
269
|
break;
|
270
270
|
}
|
@@ -273,7 +273,7 @@ export default wasm => {
|
|
273
273
|
const [ b, a ] = pop2();
|
274
274
|
const v = bool(a <= b);
|
275
275
|
|
276
|
-
replaceVal(v, Valtype.
|
276
|
+
replaceVal(v, Valtype.i32);
|
277
277
|
push(v);
|
278
278
|
break;
|
279
279
|
}
|
@@ -282,7 +282,7 @@ export default wasm => {
|
|
282
282
|
const [ b, a ] = pop2();
|
283
283
|
const v = bool(a > b);
|
284
284
|
|
285
|
-
replaceVal(v, Valtype.
|
285
|
+
replaceVal(v, Valtype.i32);
|
286
286
|
push(v);
|
287
287
|
break;
|
288
288
|
}
|
@@ -291,7 +291,7 @@ export default wasm => {
|
|
291
291
|
const [ b, a ] = pop2();
|
292
292
|
const v = bool(a >= b);
|
293
293
|
|
294
|
-
replaceVal(v, Valtype.
|
294
|
+
replaceVal(v, Valtype.i32);
|
295
295
|
push(v);
|
296
296
|
break;
|
297
297
|
}
|
@@ -404,7 +404,7 @@ export default wasm => {
|
|
404
404
|
case Opcodes.f64_max: {
|
405
405
|
if (stack.length < 2) { empty(); break; };
|
406
406
|
const [ b, a ] = pop2();
|
407
|
-
const v = a
|
407
|
+
const v = Math.max(a, b);
|
408
408
|
|
409
409
|
replaceVal(v, Valtype.f64);
|
410
410
|
push(v);
|
@@ -467,9 +467,9 @@ export default wasm => {
|
|
467
467
|
// i32.const 1
|
468
468
|
// i32.add
|
469
469
|
// local.set 7 ;; $i (i32)
|
470
|
-
if (
|
471
|
-
(opcode >= 0xa0 && opcode <= 0xa3) || // main f64 math op
|
472
|
-
(opcode >= 0x61 && opcode <= 0x66) // main f64 eq op
|
470
|
+
if (i >= 2 &&
|
471
|
+
((opcode >= 0xa0 && opcode <= 0xa3) || // main f64 math op
|
472
|
+
(opcode >= 0x61 && opcode <= 0x66)) // main f64 eq op
|
473
473
|
) {
|
474
474
|
const o2 = wasm[i - 1][0];
|
475
475
|
if (o2 === Opcodes.f64_const) { // f64.const
|
@@ -500,7 +500,7 @@ export default wasm => {
|
|
500
500
|
}
|
501
501
|
}
|
502
502
|
|
503
|
-
if ((opcode === 0xfc02 || opcode === 0xfc03) && i
|
503
|
+
if ((opcode === 0xfc02 || opcode === 0xfc03) && i >= 3) { // i32.trunc_sat_f64_s/u
|
504
504
|
const o2 = wasm[i - 1][0];
|
505
505
|
if (
|
506
506
|
(o2 >= 0xa0 && o2 <= 0xa3) || // main f64 math op
|
package/compiler/parse.js
CHANGED
@@ -43,7 +43,7 @@ export default (input, flags) => {
|
|
43
43
|
webcompat: true,
|
44
44
|
|
45
45
|
// babel
|
46
|
-
plugins: types ? ['estree', 'typescript'] : ['estree'],
|
46
|
+
plugins: types || flags.includes('typed') ? ['estree', 'typescript'] : ['estree'],
|
47
47
|
|
48
48
|
// multiple
|
49
49
|
sourceType: flags.includes('module') ? 'module' : 'script',
|
package/compiler/precompile.js
CHANGED
@@ -26,7 +26,7 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
26
26
|
|
27
27
|
const porfCompile = (await import(`./index.js?_=${Date.now()}`)).default;
|
28
28
|
|
29
|
-
let { funcs, globals, data, exceptions } = porfCompile(source, ['module']);
|
29
|
+
let { funcs, globals, data, exceptions } = porfCompile(source, ['module', 'typed']);
|
30
30
|
|
31
31
|
const allocated = new Set();
|
32
32
|
|
@@ -87,6 +87,8 @@ const compile = async (file, [ _funcs, _globals ]) => {
|
|
87
87
|
};
|
88
88
|
|
89
89
|
const precompile = async () => {
|
90
|
+
if (globalThis._porf_loadParser) await globalThis._porf_loadParser('@babel/parser');
|
91
|
+
|
90
92
|
const dir = join(__dirname, 'builtins');
|
91
93
|
|
92
94
|
let funcs = [], globals = [];
|
package/compiler/prefs.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
const onByDefault = [ 'bytestring', 'treeshakeWasmImports', 'alwaysMemory', 'indirectCalls', 'optUnused' ];
|
1
|
+
const onByDefault = [ 'bytestring', 'treeshakeWasmImports', 'alwaysMemory', 'indirectCalls', 'optUnused', 'data', 'rmUnusedTypes' ];
|
2
2
|
|
3
3
|
let cache = {};
|
4
4
|
const obj = new Proxy({}, {
|
package/compiler/wrap.js
CHANGED
@@ -128,7 +128,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
|
|
128
128
|
|
129
129
|
if (source.includes?.('export ')) flags.push('module');
|
130
130
|
|
131
|
-
fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
131
|
+
// fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
132
132
|
|
133
133
|
times.push(performance.now() - t1);
|
134
134
|
if (Prefs.profileCompiler) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
|
package/package.json
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
{
|
2
2
|
"name": "porffor",
|
3
3
|
"description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
|
4
|
-
"version": "0.16.0-
|
4
|
+
"version": "0.16.0-1a6e16aae",
|
5
5
|
"author": "CanadaHonk",
|
6
6
|
"license": "MIT",
|
7
|
-
"scripts": {
|
8
|
-
"precompile": "node ./compiler/precompile.js"
|
9
|
-
},
|
7
|
+
"scripts": {},
|
10
8
|
"dependencies": {
|
11
9
|
"acorn": "^8.11.3",
|
12
10
|
"node-repl-polyfill": "^0.1.1"
|
package/runner/index.js
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
|
3
|
-
import compile from '../compiler/wrap.js';
|
4
2
|
import fs from 'node:fs';
|
5
3
|
|
6
4
|
const start = performance.now();
|
@@ -59,10 +57,15 @@ if (process.argv.includes('--help')) {
|
|
59
57
|
}
|
60
58
|
|
61
59
|
let file = process.argv.slice(2).find(x => x[0] !== '-');
|
62
|
-
if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(file)) {
|
60
|
+
if (['precompile', 'run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(file)) {
|
63
61
|
// remove this arg
|
64
62
|
process.argv.splice(process.argv.indexOf(file), 1);
|
65
63
|
|
64
|
+
if (file === 'precompile') {
|
65
|
+
await import('../compiler/precompile.js');
|
66
|
+
await new Promise(() => {}); // do nothing for the rest of this file
|
67
|
+
}
|
68
|
+
|
66
69
|
if (file === 'profile') {
|
67
70
|
await import('./profile.js');
|
68
71
|
await new Promise(() => {}); // do nothing for the rest of this file
|
@@ -105,6 +108,8 @@ if (!file) {
|
|
105
108
|
|
106
109
|
const source = fs.readFileSync(file, 'utf8');
|
107
110
|
|
111
|
+
const compile = (await import('../compiler/wrap.js')).default;
|
112
|
+
|
108
113
|
let cache = '';
|
109
114
|
const print = str => {
|
110
115
|
/* cache += str;
|