porffor 0.19.13 → 0.19.15
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 +14 -11
- package/compiler/builtins/symbol.ts +36 -28
- package/compiler/builtins/z_ecma262.ts +3 -1
- package/compiler/builtins.js +0 -164
- package/compiler/codegen.js +90 -54
- package/compiler/decompile.js +4 -3
- package/compiler/generated_builtins.js +550 -577
- 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
package/compiler/codegen.js
CHANGED
@@ -488,7 +488,7 @@ const concatStrings = (scope, left, right, leftType, rightType, allBytestrings =
|
|
488
488
|
[ Opcodes.if, Blocktype.void ],
|
489
489
|
[ Opcodes.local_get, leftPointer ],
|
490
490
|
[ Opcodes.local_get, leftLength ],
|
491
|
-
[ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
|
491
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
|
492
492
|
[ Opcodes.local_set, leftPointer ],
|
493
493
|
[ Opcodes.end ],
|
494
494
|
|
@@ -498,7 +498,7 @@ const concatStrings = (scope, left, right, leftType, rightType, allBytestrings =
|
|
498
498
|
[ Opcodes.if, Blocktype.void ],
|
499
499
|
[ Opcodes.local_get, rightPointer ],
|
500
500
|
[ Opcodes.local_get, rightLength ],
|
501
|
-
[ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
|
501
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
|
502
502
|
[ Opcodes.local_set, rightPointer ],
|
503
503
|
[ Opcodes.end ]
|
504
504
|
]),
|
@@ -604,7 +604,7 @@ const compareStrings = (scope, left, right, leftType, rightType, allBytestrings
|
|
604
604
|
[ Opcodes.if, Blocktype.void ],
|
605
605
|
[ Opcodes.local_get, leftPointer ],
|
606
606
|
[ Opcodes.local_get, leftLength ],
|
607
|
-
[ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
|
607
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
|
608
608
|
[ Opcodes.local_set, leftPointer ],
|
609
609
|
[ Opcodes.end ],
|
610
610
|
|
@@ -615,7 +615,7 @@ const compareStrings = (scope, left, right, leftType, rightType, allBytestrings
|
|
615
615
|
[ Opcodes.local_get, rightPointer ],
|
616
616
|
[ Opcodes.local_get, rightPointer ],
|
617
617
|
[ Opcodes.i32_load, 0, 0 ],
|
618
|
-
[ Opcodes.call, funcIndex.__Porffor_bytestringToString ],
|
618
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Porffor_bytestringToString) ],
|
619
619
|
[ Opcodes.local_set, rightPointer ],
|
620
620
|
[ Opcodes.end ]
|
621
621
|
]),
|
@@ -951,7 +951,7 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
951
951
|
return finalize([
|
952
952
|
...left,
|
953
953
|
...right,
|
954
|
-
[ Opcodes.call, idx ]
|
954
|
+
[ Opcodes.call, ...unsignedLEB128(idx) ]
|
955
955
|
]);
|
956
956
|
}
|
957
957
|
|
@@ -1128,32 +1128,37 @@ const asmFuncToAsm = (scope, func) => {
|
|
1128
1128
|
}
|
1129
1129
|
|
1130
1130
|
if (idx == null) throw new Error(`builtin('${n}') failed to find a func (inside ${scope.name})`);
|
1131
|
-
return idx;
|
1131
|
+
return unsignedLEB128(idx);
|
1132
1132
|
},
|
1133
1133
|
glbl: (opcode, name, type) => {
|
1134
|
-
|
1134
|
+
const globalName = '#porf#' + name; // avoid potential name clashing with user js
|
1135
|
+
if (!globals[globalName]) {
|
1135
1136
|
const idx = globals['#ind']++;
|
1136
|
-
globals[
|
1137
|
+
globals[globalName] = { idx, type };
|
1137
1138
|
|
1138
1139
|
const tmpIdx = globals['#ind']++;
|
1139
|
-
globals[
|
1140
|
+
globals[globalName + '#glbl_inited'] = { idx: tmpIdx, type: Valtype.i32 };
|
1141
|
+
}
|
1142
|
+
|
1143
|
+
const out = [
|
1144
|
+
[ opcode, globals[globalName].idx ]
|
1145
|
+
];
|
1140
1146
|
|
1141
|
-
|
1142
|
-
|
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 ],
|
1143
1152
|
[ Opcodes.i32_eqz ],
|
1144
1153
|
[ Opcodes.if, Blocktype.void ],
|
1145
1154
|
...asmFuncToAsm(scope, scope.globalInits[name]),
|
1146
1155
|
...number(1, Valtype.i32),
|
1147
|
-
[ Opcodes.global_set,
|
1148
|
-
[ Opcodes.end ]
|
1149
|
-
|
1150
|
-
[ opcode, globals[name].idx ]
|
1151
|
-
];
|
1156
|
+
[ Opcodes.global_set, globals[globalName + '#glbl_inited'].idx ],
|
1157
|
+
[ Opcodes.end ]
|
1158
|
+
);
|
1152
1159
|
}
|
1153
1160
|
|
1154
|
-
return
|
1155
|
-
[ opcode, globals[name].idx ]
|
1156
|
-
];
|
1161
|
+
return out;
|
1157
1162
|
},
|
1158
1163
|
loc: (name, type) => {
|
1159
1164
|
if (!scope.locals[name]) {
|
@@ -1494,6 +1499,10 @@ const getNodeType = (scope, node) => {
|
|
1494
1499
|
return TYPES.number;
|
1495
1500
|
}
|
1496
1501
|
|
1502
|
+
if (node.type === 'UpdateExpression') {
|
1503
|
+
return TYPES.number;
|
1504
|
+
}
|
1505
|
+
|
1497
1506
|
if (node.type === 'MemberExpression') {
|
1498
1507
|
const name = node.property.name;
|
1499
1508
|
|
@@ -1607,8 +1616,7 @@ const countLeftover = wasm => {
|
|
1607
1616
|
};
|
1608
1617
|
|
1609
1618
|
const disposeLeftover = wasm => {
|
1610
|
-
|
1611
|
-
|
1619
|
+
const leftover = countLeftover(wasm);
|
1612
1620
|
for (let i = 0; i < leftover; i++) wasm.push([ Opcodes.drop ]);
|
1613
1621
|
};
|
1614
1622
|
|
@@ -1775,7 +1783,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1775
1783
|
...getNodeType(scope, decl.arguments[0]),
|
1776
1784
|
|
1777
1785
|
// call regex func
|
1778
|
-
[ Opcodes.call, idx ],
|
1786
|
+
[ Opcodes.call, ...unsignedLEB128(idx) ],
|
1779
1787
|
Opcodes.i32_from_u,
|
1780
1788
|
|
1781
1789
|
...setLastType(scope, Rhemyn.types[funcName])
|
@@ -1818,7 +1826,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1818
1826
|
...getNodeType(scope, target),
|
1819
1827
|
|
1820
1828
|
// call regex func
|
1821
|
-
[ Opcodes.call, idx ],
|
1829
|
+
[ Opcodes.call, ...unsignedLEB128(idx) ],
|
1822
1830
|
Opcodes.i32_from,
|
1823
1831
|
|
1824
1832
|
...setLastType(scope, Rhemyn.types[protoName])
|
@@ -2246,12 +2254,13 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2246
2254
|
if (args.length < paramCount) {
|
2247
2255
|
args = args.concat(new Array(paramCount - 1 - args.length).fill(DEFAULT_VALUE));
|
2248
2256
|
}
|
2257
|
+
|
2249
2258
|
const restArgs = args.slice(paramCount - 1);
|
2250
2259
|
args = args.slice(0, paramCount - 1);
|
2251
2260
|
args.push({
|
2252
2261
|
type: 'ArrayExpression',
|
2253
2262
|
elements: restArgs
|
2254
|
-
})
|
2263
|
+
});
|
2255
2264
|
}
|
2256
2265
|
|
2257
2266
|
if (func && args.length > paramCount) {
|
@@ -2287,7 +2296,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2287
2296
|
if (typedParams) out = out.concat(getNodeType(scope, arg));
|
2288
2297
|
}
|
2289
2298
|
|
2290
|
-
out.push([ Opcodes.call, idx ]);
|
2299
|
+
out.push([ Opcodes.call, ...unsignedLEB128(idx) ]);
|
2291
2300
|
|
2292
2301
|
if (!typedReturns) {
|
2293
2302
|
// let type;
|
@@ -2561,6 +2570,36 @@ const extractTypeAnnotation = decl => {
|
|
2561
2570
|
return { type, typeName, elementType };
|
2562
2571
|
};
|
2563
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
|
+
|
2564
2603
|
const generateVar = (scope, decl) => {
|
2565
2604
|
let out = [];
|
2566
2605
|
|
@@ -2713,17 +2752,19 @@ const generateVar = (scope, decl) => {
|
|
2713
2752
|
if (x.init) {
|
2714
2753
|
const alreadyArray = scope.arrays?.get(name) != null;
|
2715
2754
|
|
2716
|
-
|
2755
|
+
let newOut = generate(scope, x.init, global, name);
|
2717
2756
|
if (!alreadyArray && scope.arrays?.get(name) != null) {
|
2718
2757
|
// hack to set local as pointer before
|
2719
2758
|
newOut.unshift(...number(scope.arrays.get(name)), [ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
|
2720
2759
|
if (newOut.at(-1) == Opcodes.i32_from_u) newOut.pop();
|
2721
|
-
newOut.push(
|
2760
|
+
newOut.push(
|
2761
|
+
[ Opcodes.drop ],
|
2762
|
+
...setType(scope, name, getNodeType(scope, x.init))
|
2763
|
+
);
|
2722
2764
|
} else {
|
2723
|
-
newOut
|
2765
|
+
newOut = setLocalWithType(scope, name, global, newOut, false, getNodeType(scope, x.init));
|
2724
2766
|
}
|
2725
2767
|
|
2726
|
-
newOut.push(...setType(scope, name, getNodeType(scope, x.init)));
|
2727
2768
|
out = out.concat(newOut);
|
2728
2769
|
|
2729
2770
|
if (globalThis.precompile && global) {
|
@@ -2848,13 +2889,13 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
2848
2889
|
[ Opcodes.local_get, localTmp(scope, '#objset_property') ],
|
2849
2890
|
...getNodeType(scope, property),
|
2850
2891
|
|
2851
|
-
[ Opcodes.call, funcIndex.__Map_prototype_get ],
|
2892
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_get) ],
|
2852
2893
|
...setLastType(scope)
|
2853
2894
|
], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
|
2854
2895
|
[ Opcodes.local_tee, newValueTmp ],
|
2855
2896
|
...getNodeType(scope, decl),
|
2856
2897
|
|
2857
|
-
[ Opcodes.call, funcIndex.__Map_prototype_set ],
|
2898
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_set) ],
|
2858
2899
|
[ Opcodes.drop ],
|
2859
2900
|
|
2860
2901
|
...setLastType(scope, getNodeType(scope, decl)),
|
@@ -3041,13 +3082,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3041
3082
|
}
|
3042
3083
|
|
3043
3084
|
if (op === '=') {
|
3044
|
-
return
|
3045
|
-
...generate(scope, decl.right, isGlobal, name),
|
3046
|
-
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
3047
|
-
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
3048
|
-
|
3049
|
-
...setType(scope, name, getNodeType(scope, decl.right))
|
3050
|
-
];
|
3085
|
+
return setLocalWithType(scope, name, isGlobal, decl.right, true);
|
3051
3086
|
}
|
3052
3087
|
|
3053
3088
|
if (op === '||' || op === '&&' || op === '??') {
|
@@ -3060,7 +3095,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3060
3095
|
...performOp(scope, op, [
|
3061
3096
|
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
3062
3097
|
], [
|
3063
|
-
...generate(scope, decl.right),
|
3098
|
+
...generate(scope, decl.right, isGlobal, name),
|
3064
3099
|
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
3065
3100
|
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
3066
3101
|
], getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
|
@@ -3070,13 +3105,12 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3070
3105
|
];
|
3071
3106
|
}
|
3072
3107
|
|
3073
|
-
return
|
3074
|
-
|
3075
|
-
[ isGlobal ? Opcodes.
|
3076
|
-
|
3077
|
-
|
3078
|
-
|
3079
|
-
];
|
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
|
+
);
|
3080
3114
|
};
|
3081
3115
|
|
3082
3116
|
const ifIdentifierErrors = (scope, decl) => {
|
@@ -4132,16 +4166,19 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
4132
4166
|
const firstAssign = !scope.arrays.has(uniqueName);
|
4133
4167
|
if (firstAssign) scope.arrays.set(uniqueName, rawPtr);
|
4134
4168
|
|
4135
|
-
|
4169
|
+
const local = global ? globals[name] : scope.locals[name];
|
4170
|
+
if (
|
4171
|
+
Prefs.data && firstAssign && useRawElements &&
|
4172
|
+
(!globalThis.precompile || !global)
|
4173
|
+
) {
|
4136
4174
|
makeData(scope, elements, rawPtr, itemType, initEmpty);
|
4137
4175
|
|
4138
4176
|
// local value as pointer
|
4139
4177
|
return [ number(rawPtr, intOut ? Valtype.i32 : valtypeBinary), pointer ];
|
4140
4178
|
}
|
4141
4179
|
|
4142
|
-
|
4143
|
-
|
4144
|
-
if (pointerTmp != null) {
|
4180
|
+
if (local != null) {
|
4181
|
+
const pointerTmp = localTmp(scope, '#makearray_pointer_tmp', Valtype.i32);
|
4145
4182
|
out.push(
|
4146
4183
|
[ global ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
4147
4184
|
Opcodes.i32_to_u,
|
@@ -4310,7 +4347,7 @@ const generateObject = (scope, decl, global = false, name = '$undeclared') => {
|
|
4310
4347
|
...generate(scope, value),
|
4311
4348
|
...getNodeType(scope, value),
|
4312
4349
|
|
4313
|
-
[ Opcodes.call, funcIndex.__Map_prototype_set ],
|
4350
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_set) ],
|
4314
4351
|
|
4315
4352
|
[ Opcodes.drop ],
|
4316
4353
|
[ Opcodes.drop ]
|
@@ -4544,7 +4581,7 @@ const generateMember = (scope, decl, _global, _name) => {
|
|
4544
4581
|
...propertyWasm,
|
4545
4582
|
...getNodeType(scope, property),
|
4546
4583
|
|
4547
|
-
[ Opcodes.call, funcIndex.__Map_prototype_get ],
|
4584
|
+
[ Opcodes.call, ...unsignedLEB128(funcIndex.__Map_prototype_get) ],
|
4548
4585
|
...setLastType(scope)
|
4549
4586
|
],
|
4550
4587
|
|
@@ -4830,10 +4867,9 @@ const internalConstrs = {
|
|
4830
4867
|
}, global, name);
|
4831
4868
|
|
4832
4869
|
// new Array(n)
|
4833
|
-
|
4834
4870
|
const [ out, pointer ] = makeArray(scope, {
|
4835
4871
|
rawElements: new Array(0)
|
4836
|
-
}, global, name, true, undefined, true);
|
4872
|
+
}, global, name, true, undefined, true, true);
|
4837
4873
|
|
4838
4874
|
const arg = decl.arguments[0] ?? DEFAULT_VALUE;
|
4839
4875
|
|
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
|
}
|