porffor 0.19.12 → 0.19.14
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/2c.js +1 -1
- package/compiler/allocators.js +3 -1
- package/compiler/builtins/annexb_string.js +11 -0
- package/compiler/builtins/console.ts +536 -2
- package/compiler/builtins/porffor.d.ts +9 -0
- package/compiler/builtins/symbol.ts +36 -28
- package/compiler/builtins/z_ecma262.ts +3 -1
- package/compiler/builtins/z_map.ts +8 -1
- package/compiler/builtins.js +0 -164
- package/compiler/codegen.js +97 -87
- package/compiler/decompile.js +4 -3
- package/compiler/generated_builtins.js +687 -548
- package/compiler/opt.js +0 -16
- package/compiler/precompile.js +48 -18
- package/compiler/wrap.js +1 -1
- package/package.json +1 -1
- package/runner/index.js +1 -1
- package/compiler/builtins/annexb_string.ts +0 -19
@@ -127,4 +127,11 @@ export const __Map_prototype_values = (_this: Map) => {
|
|
127
127
|
}
|
128
128
|
|
129
129
|
return out;
|
130
|
-
};
|
130
|
+
};
|
131
|
+
|
132
|
+
export const __Map_prototype_toString = (_this: Map) => {
|
133
|
+
const str: bytestring = '[object Map]';
|
134
|
+
return str;
|
135
|
+
}
|
136
|
+
|
137
|
+
export const __Map_prototype_toLocaleString = (_this: Map) => __Map_prototype_toString(_this);
|
package/compiler/builtins.js
CHANGED
@@ -261,170 +261,6 @@ export const BuiltinFuncs = function() {
|
|
261
261
|
constr: true
|
262
262
|
};
|
263
263
|
|
264
|
-
|
265
|
-
this.__Porffor_print = {
|
266
|
-
params: [ globalThis.precompile ? Valtype.f64 : valtypeBinary, Valtype.i32 ],
|
267
|
-
typedParams: true,
|
268
|
-
locals: [ Valtype.i32, Valtype.i32 ],
|
269
|
-
returns: [],
|
270
|
-
wasm: (scope, { typeSwitch, builtin }) => [
|
271
|
-
...typeSwitch(scope, [ [ Opcodes.local_get, 1 ] ], {
|
272
|
-
[TYPES.number]: [
|
273
|
-
[ Opcodes.local_get, 0 ],
|
274
|
-
[ Opcodes.call, importedFuncs.print ],
|
275
|
-
],
|
276
|
-
[TYPES.boolean]: [
|
277
|
-
[ Opcodes.local_get, 0 ],
|
278
|
-
Opcodes.i32_to_u,
|
279
|
-
[ Opcodes.if, Blocktype.void ],
|
280
|
-
...printStaticStr('true'),
|
281
|
-
[ Opcodes.else ],
|
282
|
-
...printStaticStr('false'),
|
283
|
-
[ Opcodes.end ]
|
284
|
-
],
|
285
|
-
[TYPES.string]: [
|
286
|
-
// simply print a string :))
|
287
|
-
// cache input pointer as i32
|
288
|
-
[ Opcodes.local_get, 0 ],
|
289
|
-
Opcodes.i32_to_u,
|
290
|
-
[ Opcodes.local_tee, 2 ],
|
291
|
-
|
292
|
-
// make end pointer
|
293
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
294
|
-
...number(ValtypeSize.i16, Valtype.i32),
|
295
|
-
[ Opcodes.i32_mul ],
|
296
|
-
|
297
|
-
[ Opcodes.local_get, 2 ],
|
298
|
-
[ Opcodes.i32_add ],
|
299
|
-
[ Opcodes.local_set, 3 ],
|
300
|
-
|
301
|
-
[ Opcodes.loop, Blocktype.void ],
|
302
|
-
|
303
|
-
// print current char
|
304
|
-
[ Opcodes.local_get, 2 ],
|
305
|
-
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
306
|
-
Opcodes.i32_from_u,
|
307
|
-
[ Opcodes.call, importedFuncs.printChar ],
|
308
|
-
|
309
|
-
// increment pointer by sizeof i16
|
310
|
-
[ Opcodes.local_get, 2 ],
|
311
|
-
...number(ValtypeSize.i16, Valtype.i32),
|
312
|
-
[ Opcodes.i32_add ],
|
313
|
-
[ Opcodes.local_tee, 2 ],
|
314
|
-
|
315
|
-
// if pointer != end pointer, loop
|
316
|
-
[ Opcodes.local_get, 3 ],
|
317
|
-
[ Opcodes.i32_ne ],
|
318
|
-
[ Opcodes.br_if, 0 ],
|
319
|
-
|
320
|
-
[ Opcodes.end ]
|
321
|
-
],
|
322
|
-
[TYPES.bytestring]: [
|
323
|
-
// simply print a (byte)string :))
|
324
|
-
// cache input pointer as i32
|
325
|
-
[ Opcodes.local_get, 0 ],
|
326
|
-
Opcodes.i32_to_u,
|
327
|
-
[ Opcodes.local_tee, 2 ],
|
328
|
-
|
329
|
-
// make end pointer
|
330
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
331
|
-
[ Opcodes.local_get, 2 ],
|
332
|
-
[ Opcodes.i32_add ],
|
333
|
-
[ Opcodes.local_set, 3 ],
|
334
|
-
|
335
|
-
[ Opcodes.loop, Blocktype.void ],
|
336
|
-
|
337
|
-
// print current char
|
338
|
-
[ Opcodes.local_get, 2 ],
|
339
|
-
[ Opcodes.i32_load8_u, Math.log2(ValtypeSize.i16) - 1, ValtypeSize.i32 ],
|
340
|
-
Opcodes.i32_from_u,
|
341
|
-
[ Opcodes.call, importedFuncs.printChar ],
|
342
|
-
|
343
|
-
// increment pointer
|
344
|
-
[ Opcodes.local_get, 2 ],
|
345
|
-
[ Opcodes.i32_const, 1 ],
|
346
|
-
[ Opcodes.i32_add ],
|
347
|
-
[ Opcodes.local_tee, 2 ],
|
348
|
-
|
349
|
-
// if pointer != end pointer, loop
|
350
|
-
[ Opcodes.local_get, 3 ],
|
351
|
-
[ Opcodes.i32_ne ],
|
352
|
-
[ Opcodes.br_if, 0 ],
|
353
|
-
|
354
|
-
[ Opcodes.end ]
|
355
|
-
],
|
356
|
-
[TYPES.array]: [
|
357
|
-
...printStaticStr('[ '),
|
358
|
-
|
359
|
-
// cache input pointer as i32
|
360
|
-
[ Opcodes.local_get, 0 ],
|
361
|
-
Opcodes.i32_to_u,
|
362
|
-
[ Opcodes.local_tee, 2 ],
|
363
|
-
|
364
|
-
// make end pointer
|
365
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
366
|
-
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
367
|
-
[ Opcodes.i32_mul ],
|
368
|
-
|
369
|
-
[ Opcodes.local_get, 2 ],
|
370
|
-
[ Opcodes.i32_add ],
|
371
|
-
[ Opcodes.local_set, 3 ],
|
372
|
-
|
373
|
-
[ Opcodes.loop, Blocktype.void ],
|
374
|
-
|
375
|
-
// print current array element
|
376
|
-
[ Opcodes.local_get, 2 ],
|
377
|
-
[ Opcodes.load, 0, ValtypeSize.i32 ],
|
378
|
-
|
379
|
-
[ Opcodes.local_get, 2 ],
|
380
|
-
[ Opcodes.i32_load8_u, 0, ValtypeSize.i32 + ValtypeSize[valtype] ],
|
381
|
-
|
382
|
-
[ Opcodes.call, builtin('__Porffor_print') ],
|
383
|
-
|
384
|
-
// increment pointer by sizeof valtype
|
385
|
-
[ Opcodes.local_get, 2 ],
|
386
|
-
...number(ValtypeSize[valtype] + 1, Valtype.i32),
|
387
|
-
[ Opcodes.i32_add ],
|
388
|
-
[ Opcodes.local_tee, 2 ],
|
389
|
-
|
390
|
-
// if pointer != end pointer, print separator and loop
|
391
|
-
[ Opcodes.local_get, 3 ],
|
392
|
-
[ Opcodes.i32_ne ],
|
393
|
-
[ Opcodes.if, Blocktype.void ],
|
394
|
-
...printStaticStr(', '),
|
395
|
-
[ Opcodes.br, 1 ],
|
396
|
-
[ Opcodes.end ],
|
397
|
-
|
398
|
-
[ Opcodes.end ],
|
399
|
-
|
400
|
-
...printStaticStr(' ]'),
|
401
|
-
],
|
402
|
-
[TYPES.undefined]: [
|
403
|
-
...printStaticStr('undefined')
|
404
|
-
],
|
405
|
-
[TYPES.function]: [
|
406
|
-
...printStaticStr('function () {}')
|
407
|
-
],
|
408
|
-
[TYPES.object]: [
|
409
|
-
[ Opcodes.local_get, 0 ],
|
410
|
-
Opcodes.i32_to_u,
|
411
|
-
[ Opcodes.if, Blocktype.void ],
|
412
|
-
...printStaticStr('{}'),
|
413
|
-
[ Opcodes.else ],
|
414
|
-
...printStaticStr('null'),
|
415
|
-
[ Opcodes.end ]
|
416
|
-
],
|
417
|
-
default: [
|
418
|
-
[ Opcodes.local_get, 0 ],
|
419
|
-
[ Opcodes.call, importedFuncs.print ],
|
420
|
-
]
|
421
|
-
}, Blocktype.void)
|
422
|
-
]
|
423
|
-
};
|
424
|
-
|
425
|
-
// todo: add more console funcs
|
426
|
-
|
427
|
-
|
428
264
|
this.isNaN = {
|
429
265
|
floatOnly: true,
|
430
266
|
params: [ valtypeBinary ],
|
package/compiler/codegen.js
CHANGED
@@ -442,7 +442,6 @@ const concatStrings = (scope, left, right, leftType, rightType, allBytestrings =
|
|
442
442
|
const out = localTmp(scope, 'concat_out_pointer', Valtype.i32);
|
443
443
|
|
444
444
|
if (!skipTypeCheck && !allBytestrings) includeBuiltin(scope, '__Porffor_bytestringToString');
|
445
|
-
includeBuiltin(scope, '__Porffor_print');
|
446
445
|
return [
|
447
446
|
// setup pointers
|
448
447
|
...(left.length === 0 ? [
|
@@ -489,7 +488,7 @@ const concatStrings = (scope, left, right, leftType, rightType, allBytestrings =
|
|
489
488
|
[ Opcodes.if, Blocktype.void ],
|
490
489
|
[ Opcodes.local_get, leftPointer ],
|
491
490
|
[ Opcodes.local_get, leftLength ],
|
492
|
-
[ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
|
491
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
|
493
492
|
[ Opcodes.local_set, leftPointer ],
|
494
493
|
[ Opcodes.end ],
|
495
494
|
|
@@ -499,7 +498,7 @@ const concatStrings = (scope, left, right, leftType, rightType, allBytestrings =
|
|
499
498
|
[ Opcodes.if, Blocktype.void ],
|
500
499
|
[ Opcodes.local_get, rightPointer ],
|
501
500
|
[ Opcodes.local_get, rightLength ],
|
502
|
-
[ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
|
501
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
|
503
502
|
[ Opcodes.local_set, rightPointer ],
|
504
503
|
[ Opcodes.end ]
|
505
504
|
]),
|
@@ -564,7 +563,6 @@ const compareStrings = (scope, left, right, leftType, rightType, allBytestrings
|
|
564
563
|
const indexEnd = localTmp(scope, 'compare_index_end', Valtype.i32);
|
565
564
|
|
566
565
|
if (!skipTypeCheck && !allBytestrings) includeBuiltin(scope, '__Porffor_bytestringToString');
|
567
|
-
includeBuiltin(scope, '__Porffor_print');
|
568
566
|
return [
|
569
567
|
// setup pointers
|
570
568
|
...(left.length === 0 ? [
|
@@ -606,7 +604,7 @@ const compareStrings = (scope, left, right, leftType, rightType, allBytestrings
|
|
606
604
|
[ Opcodes.if, Blocktype.void ],
|
607
605
|
[ Opcodes.local_get, leftPointer ],
|
608
606
|
[ Opcodes.local_get, leftLength ],
|
609
|
-
[ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
|
607
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
|
610
608
|
[ Opcodes.local_set, leftPointer ],
|
611
609
|
[ Opcodes.end ],
|
612
610
|
|
@@ -617,7 +615,7 @@ const compareStrings = (scope, left, right, leftType, rightType, allBytestrings
|
|
617
615
|
[ Opcodes.local_get, rightPointer ],
|
618
616
|
[ Opcodes.local_get, rightPointer ],
|
619
617
|
[ Opcodes.i32_load, 0, 0 ],
|
620
|
-
[ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
|
618
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
|
621
619
|
[ Opcodes.local_set, rightPointer ],
|
622
620
|
[ Opcodes.end ]
|
623
621
|
]),
|
@@ -953,7 +951,7 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
953
951
|
return finalize([
|
954
952
|
...left,
|
955
953
|
...right,
|
956
|
-
[ Opcodes.call, idx ]
|
954
|
+
[ Opcodes.call, ...unsignedLEB128(idx) ]
|
957
955
|
]);
|
958
956
|
}
|
959
957
|
|
@@ -1130,32 +1128,37 @@ const asmFuncToAsm = (scope, func) => {
|
|
1130
1128
|
}
|
1131
1129
|
|
1132
1130
|
if (idx == null) throw new Error(`builtin('${n}') failed to find a func (inside ${scope.name})`);
|
1133
|
-
return idx;
|
1131
|
+
return unsignedLEB128(idx);
|
1134
1132
|
},
|
1135
1133
|
glbl: (opcode, name, type) => {
|
1136
|
-
|
1134
|
+
const globalName = '#porf#' + name; // avoid potential name clashing with user js
|
1135
|
+
if (!globals[globalName]) {
|
1137
1136
|
const idx = globals['#ind']++;
|
1138
|
-
globals[
|
1137
|
+
globals[globalName] = { idx, type };
|
1139
1138
|
|
1140
1139
|
const tmpIdx = globals['#ind']++;
|
1141
|
-
globals[
|
1140
|
+
globals[globalName + '#glbl_inited'] = { idx: tmpIdx, type: Valtype.i32 };
|
1141
|
+
}
|
1142
1142
|
|
1143
|
-
|
1144
|
-
|
1143
|
+
const out = [
|
1144
|
+
[ opcode, globals[globalName].idx ]
|
1145
|
+
];
|
1146
|
+
|
1147
|
+
scope.initedGlobals ??= new Set();
|
1148
|
+
if (!scope.initedGlobals.has(name)) {
|
1149
|
+
scope.initedGlobals.add(name);
|
1150
|
+
if (scope.globalInits[name]) out.unshift(
|
1151
|
+
[ Opcodes.global_get, globals[globalName + '#glbl_inited'].idx ],
|
1145
1152
|
[ Opcodes.i32_eqz ],
|
1146
1153
|
[ Opcodes.if, Blocktype.void ],
|
1147
1154
|
...asmFuncToAsm(scope, scope.globalInits[name]),
|
1148
1155
|
...number(1, Valtype.i32),
|
1149
|
-
[ Opcodes.global_set,
|
1150
|
-
[ Opcodes.end ]
|
1151
|
-
|
1152
|
-
[ opcode, globals[name].idx ]
|
1153
|
-
];
|
1156
|
+
[ Opcodes.global_set, globals[globalName + '#glbl_inited'].idx ],
|
1157
|
+
[ Opcodes.end ]
|
1158
|
+
);
|
1154
1159
|
}
|
1155
1160
|
|
1156
|
-
return
|
1157
|
-
[ opcode, globals[name].idx ]
|
1158
|
-
];
|
1161
|
+
return out;
|
1159
1162
|
},
|
1160
1163
|
loc: (name, type) => {
|
1161
1164
|
if (!scope.locals[name]) {
|
@@ -1496,6 +1499,10 @@ const getNodeType = (scope, node) => {
|
|
1496
1499
|
return TYPES.number;
|
1497
1500
|
}
|
1498
1501
|
|
1502
|
+
if (node.type === 'UpdateExpression') {
|
1503
|
+
return TYPES.number;
|
1504
|
+
}
|
1505
|
+
|
1499
1506
|
if (node.type === 'MemberExpression') {
|
1500
1507
|
const name = node.property.name;
|
1501
1508
|
|
@@ -1609,8 +1616,7 @@ const countLeftover = wasm => {
|
|
1609
1616
|
};
|
1610
1617
|
|
1611
1618
|
const disposeLeftover = wasm => {
|
1612
|
-
|
1613
|
-
|
1619
|
+
const leftover = countLeftover(wasm);
|
1614
1620
|
for (let i = 0; i < leftover; i++) wasm.push([ Opcodes.drop ]);
|
1615
1621
|
};
|
1616
1622
|
|
@@ -1777,7 +1783,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1777
1783
|
...getNodeType(scope, decl.arguments[0]),
|
1778
1784
|
|
1779
1785
|
// call regex func
|
1780
|
-
[ Opcodes.call, idx ],
|
1786
|
+
[ Opcodes.call, ...unsignedLEB128(idx) ],
|
1781
1787
|
Opcodes.i32_from_u,
|
1782
1788
|
|
1783
1789
|
...setLastType(scope, Rhemyn.types[funcName])
|
@@ -1820,7 +1826,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1820
1826
|
...getNodeType(scope, target),
|
1821
1827
|
|
1822
1828
|
// call regex func
|
1823
|
-
[ Opcodes.call, idx ],
|
1829
|
+
[ Opcodes.call, ...unsignedLEB128(idx) ],
|
1824
1830
|
Opcodes.i32_from,
|
1825
1831
|
|
1826
1832
|
...setLastType(scope, Rhemyn.types[protoName])
|
@@ -2248,12 +2254,13 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2248
2254
|
if (args.length < paramCount) {
|
2249
2255
|
args = args.concat(new Array(paramCount - 1 - args.length).fill(DEFAULT_VALUE));
|
2250
2256
|
}
|
2257
|
+
|
2251
2258
|
const restArgs = args.slice(paramCount - 1);
|
2252
2259
|
args = args.slice(0, paramCount - 1);
|
2253
2260
|
args.push({
|
2254
2261
|
type: 'ArrayExpression',
|
2255
2262
|
elements: restArgs
|
2256
|
-
})
|
2263
|
+
});
|
2257
2264
|
}
|
2258
2265
|
|
2259
2266
|
if (func && args.length > paramCount) {
|
@@ -2289,7 +2296,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2289
2296
|
if (typedParams) out = out.concat(getNodeType(scope, arg));
|
2290
2297
|
}
|
2291
2298
|
|
2292
|
-
out.push([ Opcodes.call, idx ]);
|
2299
|
+
out.push([ Opcodes.call, ...unsignedLEB128(idx) ]);
|
2293
2300
|
|
2294
2301
|
if (!typedReturns) {
|
2295
2302
|
// let type;
|
@@ -2563,6 +2570,36 @@ const extractTypeAnnotation = decl => {
|
|
2563
2570
|
return { type, typeName, elementType };
|
2564
2571
|
};
|
2565
2572
|
|
2573
|
+
const setLocalWithType = (scope, name, isGlobal, decl, tee = false, overrideType = undefined) => {
|
2574
|
+
const local = isGlobal ? globals[name] : scope.locals[name];
|
2575
|
+
const out = Array.isArray(decl) ? decl : generate(scope, decl, isGlobal, name);
|
2576
|
+
|
2577
|
+
// optimize away last type usage
|
2578
|
+
// todo: detect last type then i32 conversion op
|
2579
|
+
const lastOp = out.at(-1);
|
2580
|
+
if (lastOp[0] === Opcodes.local_set && lastOp[1] === scope.locals['#last_type']?.idx) {
|
2581
|
+
out.pop();
|
2582
|
+
|
2583
|
+
const setOut = setType(scope, name, []);
|
2584
|
+
out.push(
|
2585
|
+
// drop if setType is empty
|
2586
|
+
...(setOut.length === 0 ? [ [ Opcodes.drop ] ] : setOut),
|
2587
|
+
|
2588
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
2589
|
+
...(tee ? [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ] : [])
|
2590
|
+
);
|
2591
|
+
} else {
|
2592
|
+
out.push(
|
2593
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
2594
|
+
...(tee ? [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ] : []),
|
2595
|
+
|
2596
|
+
...setType(scope, name, overrideType ?? getNodeType(scope, decl))
|
2597
|
+
);
|
2598
|
+
}
|
2599
|
+
|
2600
|
+
return out;
|
2601
|
+
};
|
2602
|
+
|
2566
2603
|
const generateVar = (scope, decl) => {
|
2567
2604
|
let out = [];
|
2568
2605
|
|
@@ -2715,17 +2752,19 @@ const generateVar = (scope, decl) => {
|
|
2715
2752
|
if (x.init) {
|
2716
2753
|
const alreadyArray = scope.arrays?.get(name) != null;
|
2717
2754
|
|
2718
|
-
|
2755
|
+
let newOut = generate(scope, x.init, global, name);
|
2719
2756
|
if (!alreadyArray && scope.arrays?.get(name) != null) {
|
2720
2757
|
// hack to set local as pointer before
|
2721
2758
|
newOut.unshift(...number(scope.arrays.get(name)), [ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
|
2722
2759
|
if (newOut.at(-1) == Opcodes.i32_from_u) newOut.pop();
|
2723
|
-
newOut.push(
|
2760
|
+
newOut.push(
|
2761
|
+
[ Opcodes.drop ],
|
2762
|
+
...setType(scope, name, getNodeType(scope, x.init))
|
2763
|
+
);
|
2724
2764
|
} else {
|
2725
|
-
newOut
|
2765
|
+
newOut = setLocalWithType(scope, name, global, newOut, false, getNodeType(scope, x.init));
|
2726
2766
|
}
|
2727
2767
|
|
2728
|
-
newOut.push(...setType(scope, name, getNodeType(scope, x.init)));
|
2729
2768
|
out = out.concat(newOut);
|
2730
2769
|
|
2731
2770
|
if (globalThis.precompile && global) {
|
@@ -2850,13 +2889,13 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2850
2889
|
[ Opcodes.local_get, localTmp(scope, '#objset_property') ],
|
2851
2890
|
...getNodeType(scope, property),
|
2852
2891
|
|
2853
|
-
[ Opcodes.call, funcIndex.__Map_prototype_get ],
|
2892
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_get) ],
|
2854
2893
|
...setLastType(scope)
|
2855
2894
|
], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
|
2856
2895
|
[ Opcodes.local_tee, newValueTmp ],
|
2857
2896
|
...getNodeType(scope, decl),
|
2858
2897
|
|
2859
|
-
[ Opcodes.call, funcIndex.__Map_prototype_set ],
|
2898
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_set) ],
|
2860
2899
|
[ Opcodes.drop ],
|
2861
2900
|
|
2862
2901
|
...setLastType(scope, getNodeType(scope, decl)),
|
@@ -3043,13 +3082,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3043
3082
|
}
|
3044
3083
|
|
3045
3084
|
if (op === '=') {
|
3046
|
-
return
|
3047
|
-
...generate(scope, decl.right, isGlobal, name),
|
3048
|
-
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
3049
|
-
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
3050
|
-
|
3051
|
-
...setType(scope, name, getNodeType(scope, decl.right))
|
3052
|
-
];
|
3085
|
+
return setLocalWithType(scope, name, isGlobal, decl.right, true);
|
3053
3086
|
}
|
3054
3087
|
|
3055
3088
|
if (op === '||' || op === '&&' || op === '??') {
|
@@ -3062,7 +3095,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3062
3095
|
...performOp(scope, op, [
|
3063
3096
|
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
3064
3097
|
], [
|
3065
|
-
...generate(scope, decl.right),
|
3098
|
+
...generate(scope, decl.right, isGlobal, name),
|
3066
3099
|
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
3067
3100
|
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
3068
3101
|
], getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
|
@@ -3072,13 +3105,12 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3072
3105
|
];
|
3073
3106
|
}
|
3074
3107
|
|
3075
|
-
return
|
3076
|
-
|
3077
|
-
[ isGlobal ? Opcodes.
|
3078
|
-
|
3079
|
-
|
3080
|
-
|
3081
|
-
];
|
3108
|
+
return setLocalWithType(
|
3109
|
+
scope, name, isGlobal,
|
3110
|
+
performOp(scope, op, [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ], generate(scope, decl.right), getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
|
3111
|
+
true,
|
3112
|
+
getNodeType(scope, decl)
|
3113
|
+
);
|
3082
3114
|
};
|
3083
3115
|
|
3084
3116
|
const ifIdentifierErrors = (scope, decl) => {
|
@@ -4134,16 +4166,19 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
4134
4166
|
const firstAssign = !scope.arrays.has(uniqueName);
|
4135
4167
|
if (firstAssign) scope.arrays.set(uniqueName, rawPtr);
|
4136
4168
|
|
4137
|
-
|
4169
|
+
const local = global ? globals[name] : scope.locals[name];
|
4170
|
+
if (
|
4171
|
+
Prefs.data && firstAssign && useRawElements &&
|
4172
|
+
(!globalThis.precompile || !global)
|
4173
|
+
) {
|
4138
4174
|
makeData(scope, elements, rawPtr, itemType, initEmpty);
|
4139
4175
|
|
4140
4176
|
// local value as pointer
|
4141
4177
|
return [ number(rawPtr, intOut ? Valtype.i32 : valtypeBinary), pointer ];
|
4142
4178
|
}
|
4143
4179
|
|
4144
|
-
|
4145
|
-
|
4146
|
-
if (pointerTmp != null) {
|
4180
|
+
if (local != null) {
|
4181
|
+
const pointerTmp = localTmp(scope, '#makearray_pointer_tmp', Valtype.i32);
|
4147
4182
|
out.push(
|
4148
4183
|
[ global ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
4149
4184
|
Opcodes.i32_to_u,
|
@@ -4312,7 +4347,7 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
|
|
4312
4347
|
...generate(scope, value),
|
4313
4348
|
...getNodeType(scope, value),
|
4314
4349
|
|
4315
|
-
[ Opcodes.call, funcIndex.__Map_prototype_set ],
|
4350
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_set) ],
|
4316
4351
|
|
4317
4352
|
[ Opcodes.drop ],
|
4318
4353
|
[ Opcodes.drop ]
|
@@ -4546,7 +4581,7 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
4546
4581
|
...propertyWasm,
|
4547
4582
|
...getNodeType(scope, property),
|
4548
4583
|
|
4549
|
-
[ Opcodes.call, funcIndex.__Map_prototype_get ],
|
4584
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_get) ],
|
4550
4585
|
...setLastType(scope)
|
4551
4586
|
],
|
4552
4587
|
|
@@ -4674,6 +4709,9 @@ const objectHack = node => {
|
|
4674
4709
|
const out = (() => {
|
4675
4710
|
if (node.computed || node.optional) return;
|
4676
4711
|
|
4712
|
+
// hack: block these properties as they can be accessed on functions
|
4713
|
+
if (node.property.name == "length" || node.property.name == "name") return;
|
4714
|
+
|
4677
4715
|
let objectName = node.object.name;
|
4678
4716
|
|
4679
4717
|
// if object is not identifier or another member exp, give up
|
@@ -4829,10 +4867,9 @@ const internalConstrs = {
|
|
4829
4867
|
}, global, name);
|
4830
4868
|
|
4831
4869
|
// new Array(n)
|
4832
|
-
|
4833
4870
|
const [ out, pointer ] = makeArray(scope, {
|
4834
4871
|
rawElements: new Array(0)
|
4835
|
-
}, global, name, true, undefined, true);
|
4872
|
+
}, global, name, true, undefined, true, true);
|
4836
4873
|
|
4837
4874
|
const arg = decl.arguments[0] ?? DEFAULT_VALUE;
|
4838
4875
|
|
@@ -4957,41 +4994,14 @@ const internalConstrs = {
|
|
4957
4994
|
length: 2
|
4958
4995
|
},
|
4959
4996
|
|
4960
|
-
|
4997
|
+
printStatic: {
|
4961
4998
|
generate: (scope, decl) => {
|
4962
|
-
const
|
4963
|
-
|
4964
|
-
for (let i = 0; i < decl.arguments.length; i++) {
|
4965
|
-
out.push(
|
4966
|
-
...generateCall(scope, {
|
4967
|
-
callee: {
|
4968
|
-
type: 'Identifier',
|
4969
|
-
name: '__Porffor_print'
|
4970
|
-
},
|
4971
|
-
arguments: [ decl.arguments[i] ]
|
4972
|
-
}),
|
4973
|
-
|
4974
|
-
// print space
|
4975
|
-
...(i !== decl.arguments.length - 1 ? [
|
4976
|
-
...number(32, globalThis.precompile ? Valtype.f64 : valtypeBinary),
|
4977
|
-
[ Opcodes.call, importedFuncs.printChar ]
|
4978
|
-
] : [])
|
4979
|
-
);
|
4980
|
-
}
|
4981
|
-
|
4982
|
-
// print newline
|
4983
|
-
out.push(
|
4984
|
-
...number(10, globalThis.precompile ? Valtype.f64 : valtypeBinary),
|
4985
|
-
[ Opcodes.call, importedFuncs.printChar ]
|
4986
|
-
);
|
4987
|
-
|
4988
|
-
out.push(...number(UNDEFINED));
|
4989
|
-
|
4990
|
-
return out;
|
4999
|
+
const str = decl.arguments[0].value;
|
5000
|
+
return printStaticStr(str);
|
4991
5001
|
},
|
4992
5002
|
type: TYPES.undefined,
|
4993
5003
|
notConstr: true,
|
4994
|
-
length:
|
5004
|
+
length: 1
|
4995
5005
|
}
|
4996
5006
|
};
|
4997
5007
|
|
package/compiler/decompile.js
CHANGED
@@ -89,10 +89,11 @@ export default (wasm, name = '', ind = 0, locals = {}, params = [], returns = []
|
|
89
89
|
}
|
90
90
|
|
91
91
|
if (inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) {
|
92
|
-
const
|
92
|
+
const idx = read_unsignedLEB128(inst.slice(1));
|
93
|
+
const callFunc = funcs.find(x => x.index === idx);
|
93
94
|
if (callFunc) out += ` ;; $${callFunc.name} ${makeSignature(callFunc.params, callFunc.returns)}`;
|
94
|
-
if (globalThis.importFuncs &&
|
95
|
-
const importFunc = importFuncs[
|
95
|
+
if (globalThis.importFuncs && idx < importFuncs.length) {
|
96
|
+
const importFunc = importFuncs[idx];
|
96
97
|
out += ` ;; import ${importFunc.name} ${makeSignature(typeof importFunc.params === 'object' ? importFunc.params : new Array(importFunc.params).fill(valtypeBinary), new Array(importFunc.returns).fill(valtypeBinary),)}`;
|
97
98
|
}
|
98
99
|
}
|