porffor 0.37.6 → 0.37.8
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/allocators.js +0 -5
- package/compiler/builtins_precompiled.js +1289 -702
- package/compiler/codegen.js +206 -154
- package/compiler/opt.js +0 -113
- package/compiler/precompile.js +11 -6
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/codegen.js
CHANGED
@@ -390,6 +390,8 @@ const generateReturn = (scope, decl) => {
|
|
390
390
|
const arg = decl.argument ?? DEFAULT_VALUE();
|
391
391
|
|
392
392
|
if (scope.async) {
|
393
|
+
typeUsed(scope, TYPES.promise);
|
394
|
+
|
393
395
|
return [
|
394
396
|
// resolve promise with return value
|
395
397
|
[ Opcodes.local_get, scope.locals['#async_out_promise'].idx ],
|
@@ -589,7 +591,7 @@ const truthy = (scope, wasm, type, intIn = false, intOut = false, forceTruthyMod
|
|
589
591
|
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
590
592
|
|
591
593
|
...typeSwitch(scope, type, [
|
592
|
-
[ [ TYPES.string, TYPES.bytestring ], [
|
594
|
+
[ [ TYPES.string, TYPES.bytestring ], () => [
|
593
595
|
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
594
596
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
595
597
|
|
@@ -643,7 +645,7 @@ const falsy = (scope, wasm, type, intIn = false, intOut = false, forceTruthyMode
|
|
643
645
|
...(!useTmp ? [] : [ [ Opcodes.local_set, tmp ] ]),
|
644
646
|
|
645
647
|
...typeSwitch(scope, type, [
|
646
|
-
[ [ TYPES.string, TYPES.bytestring ], [
|
648
|
+
[ [ TYPES.string, TYPES.bytestring ], () => [
|
647
649
|
...(!useTmp ? [] : [ [ Opcodes.local_get, tmp ] ]),
|
648
650
|
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
649
651
|
|
@@ -689,17 +691,6 @@ const nullish = (scope, wasm, type, intIn = false, intOut = false) => {
|
|
689
691
|
];
|
690
692
|
};
|
691
693
|
|
692
|
-
const stringOnly = wasm => {
|
693
|
-
if (!Array.isArray(wasm[0])) return [ ...wasm, 'string_only' ];
|
694
|
-
if (wasm.length === 1) return [ [ ...wasm[0], 'string_only' ] ];
|
695
|
-
|
696
|
-
return [
|
697
|
-
[ ...wasm[0], 'string_only|start' ],
|
698
|
-
...wasm.slice(1, -1),
|
699
|
-
[ ...wasm[wasm.length - 1], 'string_only|end' ]
|
700
|
-
];
|
701
|
-
}
|
702
|
-
|
703
694
|
const performOp = (scope, op, left, right, leftType, rightType, _global = false, _name = '$undeclared', assign = false) => {
|
704
695
|
if (op === '||' || op === '&&' || op === '??') {
|
705
696
|
return performLogicOp(scope, op, left, right, leftType, rightType);
|
@@ -787,7 +778,7 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
787
778
|
tmpLeft = localTmp(scope, '__tmpop_left');
|
788
779
|
tmpRight = localTmp(scope, '__tmpop_right');
|
789
780
|
|
790
|
-
ops.unshift(
|
781
|
+
ops.unshift(
|
791
782
|
// if left or right are string or bytestring
|
792
783
|
...leftType,
|
793
784
|
...number(TYPE_FLAGS.parity, Valtype.i32),
|
@@ -808,18 +799,18 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
808
799
|
[ Opcodes.end ],
|
809
800
|
|
810
801
|
...setLastType(scope, TYPES.number)
|
811
|
-
|
802
|
+
);
|
812
803
|
|
813
804
|
// add a surrounding block
|
814
|
-
startOut.push(
|
815
|
-
endOut.unshift(
|
805
|
+
startOut.push([ Opcodes.block, Valtype.f64 ]);
|
806
|
+
endOut.unshift([ Opcodes.end ]);
|
816
807
|
}
|
817
808
|
|
818
809
|
if ((op === '===' || op === '==' || op === '!==' || op === '!=') && (knownLeft == null && knownRight == null)) {
|
819
810
|
tmpLeft = localTmp(scope, '__tmpop_left');
|
820
811
|
tmpRight = localTmp(scope, '__tmpop_right');
|
821
812
|
|
822
|
-
ops.unshift(
|
813
|
+
ops.unshift(
|
823
814
|
// if left or right are string or bytestring
|
824
815
|
...leftType,
|
825
816
|
...number(TYPE_FLAGS.parity, Valtype.i32),
|
@@ -839,18 +830,18 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
839
830
|
...(op === '!==' || op === '!=' ? [ [ Opcodes.i32_eqz ] ] : []),
|
840
831
|
[ Opcodes.br, 1 ],
|
841
832
|
[ Opcodes.end ]
|
842
|
-
|
833
|
+
);
|
843
834
|
|
844
835
|
// add a surrounding block
|
845
|
-
startOut.push(
|
846
|
-
endOut.unshift(
|
836
|
+
startOut.push([ Opcodes.block, Valtype.i32 ]);
|
837
|
+
endOut.unshift([ Opcodes.end ]);
|
847
838
|
}
|
848
839
|
|
849
840
|
return finalize([
|
850
841
|
...left,
|
851
|
-
...(tmpLeft != null ?
|
842
|
+
...(tmpLeft != null ? [ [ Opcodes.local_tee, tmpLeft ] ] : []),
|
852
843
|
...right,
|
853
|
-
...(tmpRight != null ?
|
844
|
+
...(tmpRight != null ? [ [ Opcodes.local_tee, tmpRight ] ] : []),
|
854
845
|
...ops
|
855
846
|
]);
|
856
847
|
};
|
@@ -944,7 +935,6 @@ const asmFuncToAsm = (scope, func) => {
|
|
944
935
|
builtin: (n, offset = false) => {
|
945
936
|
let idx = funcIndex[n] ?? importedFuncs[n];
|
946
937
|
if (idx == null && builtinFuncs[n]) {
|
947
|
-
// console.log(scope.name, '->', n);
|
948
938
|
includeBuiltin(scope, n);
|
949
939
|
idx = funcIndex[n];
|
950
940
|
}
|
@@ -1002,11 +992,21 @@ const asmFuncToAsm = (scope, func) => {
|
|
1002
992
|
}
|
1003
993
|
|
1004
994
|
return scope.locals[name].idx;
|
995
|
+
},
|
996
|
+
t: (types, wasm) => {
|
997
|
+
if (types.some(x => usedTypes.has(x))) {
|
998
|
+
return wasm();
|
999
|
+
} else {
|
1000
|
+
return [ [ null, () => {
|
1001
|
+
if (types.some(x => usedTypes.has(x))) return wasm();
|
1002
|
+
return [];
|
1003
|
+
} ] ];
|
1004
|
+
}
|
1005
1005
|
}
|
1006
1006
|
});
|
1007
1007
|
};
|
1008
1008
|
|
1009
|
-
const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTypes = [], globals: globalTypes = [], globalInits = [], returns = [], returnType, localNames = [], globalNames = [], data: _data = [], table = false, constr = false, hasRestArgument = false } = {}) => {
|
1009
|
+
const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTypes = [], globals: globalTypes = [], globalInits = [], returns = [], returnType, localNames = [], globalNames = [], data: _data = [], table = false, constr = false, hasRestArgument = false, usedTypes = [] } = {}) => {
|
1010
1010
|
if (wasm == null) { // called with no builtin
|
1011
1011
|
log.warning('codegen', `${name} has no built-in!`);
|
1012
1012
|
wasm = [];
|
@@ -1080,6 +1080,8 @@ const asmFunc = (name, { wasm, params = [], typedParams = false, locals: localTy
|
|
1080
1080
|
|
1081
1081
|
if (hasRestArgument) func.hasRestArgument = true;
|
1082
1082
|
|
1083
|
+
for (const x of usedTypes) typeUsed(func, x);
|
1084
|
+
|
1083
1085
|
func.wasm = wasm;
|
1084
1086
|
|
1085
1087
|
return func;
|
@@ -1161,6 +1163,8 @@ const getType = (scope, _name) => {
|
|
1161
1163
|
};
|
1162
1164
|
|
1163
1165
|
const setType = (scope, _name, type) => {
|
1166
|
+
typeUsed(scope, knownType(scope, type));
|
1167
|
+
|
1164
1168
|
const name = mapName(_name);
|
1165
1169
|
|
1166
1170
|
const out = typeof type === 'number' ? number(type, Valtype.i32) : type;
|
@@ -1200,10 +1204,13 @@ const getLastType = scope => {
|
|
1200
1204
|
return [ [ Opcodes.local_get, localTmp(scope, '#last_type', Valtype.i32) ] ];
|
1201
1205
|
};
|
1202
1206
|
|
1203
|
-
const setLastType = (scope, type = []) =>
|
1204
|
-
|
1205
|
-
[
|
1206
|
-
|
1207
|
+
const setLastType = (scope, type = []) => {
|
1208
|
+
typeUsed(scope, knownType(scope, type));
|
1209
|
+
return [
|
1210
|
+
...(typeof type === 'number' ? number(type, Valtype.i32) : type),
|
1211
|
+
[ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
|
1212
|
+
];
|
1213
|
+
};
|
1207
1214
|
|
1208
1215
|
const getNodeType = (scope, node) => {
|
1209
1216
|
let guess = null;
|
@@ -1426,6 +1433,8 @@ const getNodeType = (scope, node) => {
|
|
1426
1433
|
const out = typeof ret === 'number' ? number(ret, Valtype.i32) : ret;
|
1427
1434
|
if (guess != null) out.guess = typeof guess === 'number' ? number(guess, Valtype.i32) : guess;
|
1428
1435
|
|
1436
|
+
typeUsed(scope, knownType(scope, out));
|
1437
|
+
|
1429
1438
|
return out;
|
1430
1439
|
};
|
1431
1440
|
|
@@ -1468,7 +1477,7 @@ const countLeftover = wasm => {
|
|
1468
1477
|
|
1469
1478
|
if (depth === 0)
|
1470
1479
|
if ([Opcodes.throw, Opcodes.drop, Opcodes.local_set, Opcodes.global_set].includes(inst[0])) count--;
|
1471
|
-
else if ([
|
1480
|
+
else if ([Opcodes.i32_eqz, Opcodes.i64_eqz, Opcodes.f64_ceil, Opcodes.f64_floor, Opcodes.f64_trunc, Opcodes.f64_nearest, Opcodes.f64_sqrt, Opcodes.local_tee, Opcodes.i32_wrap_i64, Opcodes.i64_extend_i32_s, Opcodes.i64_extend_i32_u, Opcodes.f32_demote_f64, Opcodes.f64_promote_f32, Opcodes.f64_convert_i32_s, Opcodes.f64_convert_i32_u, Opcodes.i32_clz, Opcodes.i32_ctz, Opcodes.i32_popcnt, Opcodes.f64_neg, Opcodes.end, Opcodes.i32_trunc_sat_f64_s[0], Opcodes.i32x4_extract_lane, Opcodes.i16x8_extract_lane, Opcodes.i32_load, Opcodes.i64_load, Opcodes.f64_load, Opcodes.f32_load, Opcodes.v128_load, Opcodes.i32_load16_u, Opcodes.i32_load16_s, Opcodes.i32_load8_u, Opcodes.i32_load8_s, Opcodes.memory_grow].includes(inst[0]) && (inst[0] !== 0xfc || inst[1] < 0x04)) {}
|
1472
1481
|
else if ([Opcodes.local_get, Opcodes.global_get, Opcodes.f64_const, Opcodes.i32_const, Opcodes.i64_const, Opcodes.v128_const, Opcodes.memory_size].includes(inst[0])) count++;
|
1473
1482
|
else if ([Opcodes.i32_store, Opcodes.i64_store, Opcodes.f64_store, Opcodes.f32_store, Opcodes.i32_store16, Opcodes.i32_store8].includes(inst[0])) count -= 2;
|
1474
1483
|
else if (inst[0] === Opcodes.memory_copy[0] && (inst[1] === Opcodes.memory_copy[1] || inst[1] === Opcodes.memory_init[1])) count -= 3;
|
@@ -1949,7 +1958,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1949
1958
|
const type = TYPES[x.split('_prototype_')[0].slice(2).toLowerCase()];
|
1950
1959
|
if (type == null) continue;
|
1951
1960
|
|
1952
|
-
protoBC[type] = generate(scope, {
|
1961
|
+
protoBC[type] = () => generate(scope, {
|
1953
1962
|
type: 'CallExpression',
|
1954
1963
|
callee: {
|
1955
1964
|
type: 'Identifier',
|
@@ -1988,8 +1997,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
1988
1997
|
const usePointerCache = !Object.values(protoCands).every(x => x.noPointerCache === true);
|
1989
1998
|
const getPointer = usePointerCache ? [ [ Opcodes.local_get, pointerLocal ] ] : rawPointer;
|
1990
1999
|
|
1991
|
-
|
1992
|
-
let lengthI32CacheUsed = false;
|
2000
|
+
const useLengthCache = true; // basically every prototype uses it
|
1993
2001
|
for (const x in protoCands) {
|
1994
2002
|
const protoFunc = protoCands[x];
|
1995
2003
|
if (protoFunc.noArgRetLength && decl.arguments.length === 0) {
|
@@ -2000,63 +2008,64 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2000
2008
|
continue;
|
2001
2009
|
}
|
2002
2010
|
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
+
protoBC[x] = () => {
|
2012
|
+
const protoLocal = protoFunc.local ? localTmp(scope, `__${protoName}_tmp`, protoFunc.local) : -1;
|
2013
|
+
const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${protoName}_tmp2`, protoFunc.local2) : -1;
|
2014
|
+
|
2015
|
+
let optUnused = false;
|
2016
|
+
const protoOut = protoFunc(getPointer, {
|
2017
|
+
getCachedI32: () => [ [ Opcodes.local_get, lengthLocal ] ],
|
2018
|
+
setCachedI32: () => [ [ Opcodes.local_set, lengthLocal ] ],
|
2019
|
+
get: () => RTArrayUtil.getLength(getPointer),
|
2020
|
+
getI32: () => RTArrayUtil.getLengthI32(getPointer),
|
2021
|
+
set: value => RTArrayUtil.setLength(getPointer, value),
|
2022
|
+
setI32: value => RTArrayUtil.setLengthI32(getPointer, value)
|
2011
2023
|
},
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
];
|
2024
|
+
generate(scope, decl.arguments[0] ?? DEFAULT_VALUE()),
|
2025
|
+
getNodeType(scope, decl.arguments[0] ?? DEFAULT_VALUE()),
|
2026
|
+
protoLocal, protoLocal2,
|
2027
|
+
(length, itemType) => {
|
2028
|
+
return makeArray(scope, {
|
2029
|
+
rawElements: new Array(length)
|
2030
|
+
}, _global, _name, true, itemType, true);
|
2031
|
+
},
|
2032
|
+
() => {
|
2033
|
+
optUnused = true;
|
2034
|
+
return unusedValue;
|
2035
|
+
});
|
2036
|
+
|
2037
|
+
return [
|
2038
|
+
[ Opcodes.block, unusedValue ? Blocktype.void : valtypeBinary ],
|
2039
|
+
...protoOut,
|
2040
|
+
...(unusedValue && optUnused ? [] : (protoFunc.returnType != null ? setLastType(scope, protoFunc.returnType) : setLastType(scope))),
|
2041
|
+
...(unusedValue && !optUnused ? [ [ Opcodes.drop ] ] : []),
|
2042
|
+
[ Opcodes.end ]
|
2043
|
+
];
|
2044
|
+
};
|
2034
2045
|
}
|
2035
2046
|
|
2036
|
-
// todo: if some cands use optUnused and some don't, we will probably crash
|
2037
|
-
|
2038
2047
|
return [
|
2039
2048
|
...(usePointerCache ? [
|
2040
2049
|
...rawPointer,
|
2041
2050
|
[ Opcodes.local_set, pointerLocal ],
|
2042
2051
|
] : []),
|
2043
2052
|
|
2044
|
-
...(
|
2053
|
+
...(useLengthCache ? [
|
2045
2054
|
...RTArrayUtil.getLengthI32(getPointer),
|
2046
2055
|
[ Opcodes.local_set, lengthLocal ],
|
2047
|
-
]),
|
2056
|
+
] : []),
|
2048
2057
|
|
2049
2058
|
...typeSwitch(scope, getNodeType(scope, target), {
|
2050
2059
|
...protoBC,
|
2051
2060
|
|
2052
2061
|
// TODO: error better
|
2053
|
-
default: internalThrow(scope, 'TypeError', `'${protoName}' proto func tried to be called on a type without an impl
|
2054
|
-
},
|
2062
|
+
default: internalThrow(scope, 'TypeError', `'${protoName}' proto func tried to be called on a type without an impl`, !unusedValue)
|
2063
|
+
}, unusedValue ? Blocktype.void : valtypeBinary),
|
2055
2064
|
];
|
2056
2065
|
}
|
2057
2066
|
|
2058
2067
|
if (Object.keys(protoBC).length > 0) {
|
2059
|
-
let def = internalThrow(scope, 'TypeError', `'${protoName}' proto func tried to be called on a type without an impl
|
2068
|
+
let def = internalThrow(scope, 'TypeError', `'${protoName}' proto func tried to be called on a type without an impl`, true);
|
2060
2069
|
|
2061
2070
|
// fallback to object prototype impl as a basic prototype chain hack
|
2062
2071
|
if (protoBC[TYPES.object]) def = protoBC[TYPES.object];
|
@@ -2193,7 +2202,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2193
2202
|
[ Opcodes.local_set, localTmp(scope, '#indirect_callee') ],
|
2194
2203
|
|
2195
2204
|
...typeSwitch(scope, getNodeType(scope, decl.callee), {
|
2196
|
-
[TYPES.function]: [
|
2205
|
+
[TYPES.function]: () => [
|
2197
2206
|
...out,
|
2198
2207
|
|
2199
2208
|
[ Opcodes.local_get, localTmp(scope, '#indirect_callee') ],
|
@@ -2332,7 +2341,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
|
|
2332
2341
|
[ Opcodes.local_set, localTmp(scope, '#indirect_callee') ],
|
2333
2342
|
|
2334
2343
|
...typeSwitch(scope, getNodeType(scope, callee), {
|
2335
|
-
[TYPES.function]: [
|
2344
|
+
[TYPES.function]: () => [
|
2336
2345
|
...out,
|
2337
2346
|
|
2338
2347
|
[ Opcodes.local_get, localTmp(scope, '#indirect_callee') ],
|
@@ -2584,6 +2593,8 @@ const unhackName = name => {
|
|
2584
2593
|
};
|
2585
2594
|
|
2586
2595
|
const knownType = (scope, type) => {
|
2596
|
+
if (typeof type === 'number') return type;
|
2597
|
+
|
2587
2598
|
if (type.length === 1 && type[0][0] === Opcodes.i32_const) {
|
2588
2599
|
return read_signedLEB128(type[0].slice(1));
|
2589
2600
|
}
|
@@ -2692,6 +2703,16 @@ const brTable = (input, bc, returns) => {
|
|
2692
2703
|
|
2693
2704
|
let typeswitchDepth = 0;
|
2694
2705
|
|
2706
|
+
let usedTypes = new Set();
|
2707
|
+
const typeUsed = (scope, x) => {
|
2708
|
+
if (x == null) return;
|
2709
|
+
usedTypes.add(x);
|
2710
|
+
|
2711
|
+
// console.log(scope.name, TYPE_NAMES[x]);
|
2712
|
+
|
2713
|
+
scope.usedTypes ??= new Set();
|
2714
|
+
scope.usedTypes.add(x);
|
2715
|
+
};
|
2695
2716
|
const typeSwitch = (scope, type, bc, returns = valtypeBinary, fallthrough = false) => {
|
2696
2717
|
const known = knownType(scope, type);
|
2697
2718
|
if (known != null) {
|
@@ -2704,13 +2725,14 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary, fallthrough = fals
|
|
2704
2725
|
}
|
2705
2726
|
|
2706
2727
|
if (Array.isArray(type)) {
|
2707
|
-
if (type.includes(known)) return wasm;
|
2708
|
-
} else if (type === known) return wasm;
|
2728
|
+
if (type.includes(known)) return typeof wasm === 'function' ? wasm() : wasm;
|
2729
|
+
} else if (type === known) return typeof wasm === 'function' ? wasm() : wasm;
|
2709
2730
|
}
|
2710
2731
|
|
2711
|
-
return def;
|
2732
|
+
return typeof def === 'function' ? def() : def;
|
2712
2733
|
} else {
|
2713
|
-
|
2734
|
+
const wasm = bc[known] ?? bc.default;
|
2735
|
+
return typeof wasm === 'function' ? wasm() : wasm;
|
2714
2736
|
}
|
2715
2737
|
}
|
2716
2738
|
|
@@ -2720,7 +2742,7 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary, fallthrough = fals
|
|
2720
2742
|
}
|
2721
2743
|
|
2722
2744
|
const tmp = localTmp(scope, `#typeswitch_tmp${++typeswitchDepth}${Prefs.typeswitchUniqueTmp ? uniqId() : ''}`, Valtype.i32);
|
2723
|
-
|
2745
|
+
let out = [
|
2724
2746
|
...type,
|
2725
2747
|
[ Opcodes.local_set, tmp ],
|
2726
2748
|
[ Opcodes.block, returns ]
|
@@ -2732,46 +2754,67 @@ const typeSwitch = (scope, type, bc, returns = valtypeBinary, fallthrough = fals
|
|
2732
2754
|
if (!Array.isArray(bc)) {
|
2733
2755
|
def = bc.default;
|
2734
2756
|
bc = Object.entries(bc);
|
2757
|
+
|
2758
|
+
// turn keys back into numbers from keys
|
2759
|
+
for (const x of bc) {
|
2760
|
+
if (x[0] !== 'default') x[0] = +x[0];
|
2761
|
+
}
|
2735
2762
|
}
|
2736
2763
|
|
2737
2764
|
for (let i = 0; i < bc.length; i++) {
|
2738
|
-
let [
|
2739
|
-
if (
|
2740
|
-
def = wasm;
|
2765
|
+
let [ types, wasm ] = bc[i];
|
2766
|
+
if (types === 'default') {
|
2767
|
+
def = typeof wasm === 'function' ? wasm() : wasm;
|
2741
2768
|
continue;
|
2742
2769
|
}
|
2770
|
+
if (!Array.isArray(types)) types = [ types ];
|
2771
|
+
|
2772
|
+
const add = () => {
|
2773
|
+
if (typeof wasm === 'function') wasm = wasm();
|
2743
2774
|
|
2744
|
-
|
2745
|
-
for (let j = 0; j < type.length; j++) {
|
2775
|
+
for (let j = 0; j < types.length; j++) {
|
2746
2776
|
out.push(
|
2747
2777
|
[ Opcodes.local_get, tmp ],
|
2748
|
-
...number(
|
2778
|
+
...number(types[j], Valtype.i32),
|
2749
2779
|
[ Opcodes.i32_eq ]
|
2750
2780
|
);
|
2751
2781
|
|
2752
2782
|
if (j > 0) out.push([ Opcodes.i32_or ]);
|
2753
2783
|
}
|
2754
|
-
|
2784
|
+
|
2755
2785
|
out.push(
|
2756
|
-
[ Opcodes.
|
2757
|
-
|
2758
|
-
|
2786
|
+
[ Opcodes.if, Blocktype.void ],
|
2787
|
+
...wasm,
|
2788
|
+
...(fallthrough ? [] : [ [ Opcodes.br, 1 ] ]),
|
2789
|
+
[ Opcodes.end ]
|
2759
2790
|
);
|
2760
|
-
}
|
2791
|
+
};
|
2761
2792
|
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
[
|
2767
|
-
|
2793
|
+
if (globalThis.precompile) {
|
2794
|
+
// just magic precompile things™
|
2795
|
+
out.push([ null, 'typeswitch case start', types ]);
|
2796
|
+
add();
|
2797
|
+
out.push([ null, 'typeswitch case end' ]);
|
2798
|
+
} else {
|
2799
|
+
if (types.some(x => usedTypes.has(x))) {
|
2800
|
+
// type already used, just add it now
|
2801
|
+
add();
|
2802
|
+
} else {
|
2803
|
+
// type not used, add callback
|
2804
|
+
out.push([ null, () => {
|
2805
|
+
out = [];
|
2806
|
+
if (types.some(x => usedTypes.has(x))) add();
|
2807
|
+
return out;
|
2808
|
+
}]);
|
2809
|
+
}
|
2810
|
+
}
|
2768
2811
|
}
|
2769
2812
|
|
2770
2813
|
// default
|
2771
2814
|
if (def) out.push(...def);
|
2772
2815
|
else if (returns !== Blocktype.void) out.push(...number(0, returns));
|
2773
2816
|
|
2774
|
-
out.push([ Opcodes.end
|
2817
|
+
out.push([ Opcodes.end ]);
|
2775
2818
|
|
2776
2819
|
typeswitchDepth--;
|
2777
2820
|
|
@@ -2921,6 +2964,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
2921
2964
|
|
2922
2965
|
const typed = typedInput && pattern.typeAnnotation;
|
2923
2966
|
let idx = allocVar(scope, name, global, !(typed && extractTypeAnnotation(pattern).type != null));
|
2967
|
+
addVarMetadata(scope, name, global, { kind });
|
2924
2968
|
|
2925
2969
|
if (typed) {
|
2926
2970
|
addVarMetadata(scope, name, global, extractTypeAnnotation(pattern));
|
@@ -3268,7 +3312,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3268
3312
|
|
3269
3313
|
// todo: review last type usage here
|
3270
3314
|
...typeSwitch(scope, getNodeType(scope, object), {
|
3271
|
-
[TYPES.array]: [
|
3315
|
+
[TYPES.array]: () => [
|
3272
3316
|
...objectWasm,
|
3273
3317
|
Opcodes.i32_to_u,
|
3274
3318
|
|
@@ -3300,7 +3344,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3300
3344
|
],
|
3301
3345
|
|
3302
3346
|
...wrapBC({
|
3303
|
-
[TYPES.uint8array]: [
|
3347
|
+
[TYPES.uint8array]: () => [
|
3304
3348
|
[ Opcodes.i32_add ],
|
3305
3349
|
...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
3306
3350
|
|
@@ -3314,7 +3358,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3314
3358
|
Opcodes.i32_to_u,
|
3315
3359
|
[ Opcodes.i32_store8, 0, 4 ]
|
3316
3360
|
],
|
3317
|
-
[TYPES.uint8clampedarray]: [
|
3361
|
+
[TYPES.uint8clampedarray]: () => [
|
3318
3362
|
[ Opcodes.i32_add ],
|
3319
3363
|
...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
3320
3364
|
|
@@ -3332,7 +3376,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3332
3376
|
Opcodes.i32_to_u,
|
3333
3377
|
[ Opcodes.i32_store8, 0, 4 ]
|
3334
3378
|
],
|
3335
|
-
[TYPES.int8array]: [
|
3379
|
+
[TYPES.int8array]: () => [
|
3336
3380
|
[ Opcodes.i32_add ],
|
3337
3381
|
...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
3338
3382
|
|
@@ -3346,7 +3390,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3346
3390
|
Opcodes.i32_to,
|
3347
3391
|
[ Opcodes.i32_store8, 0, 4 ]
|
3348
3392
|
],
|
3349
|
-
[TYPES.uint16array]: [
|
3393
|
+
[TYPES.uint16array]: () => [
|
3350
3394
|
...number(2, Valtype.i32),
|
3351
3395
|
[ Opcodes.i32_mul ],
|
3352
3396
|
[ Opcodes.i32_add ],
|
@@ -3362,7 +3406,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3362
3406
|
Opcodes.i32_to_u,
|
3363
3407
|
[ Opcodes.i32_store16, 0, 4 ]
|
3364
3408
|
],
|
3365
|
-
[TYPES.int16array]: [
|
3409
|
+
[TYPES.int16array]: () => [
|
3366
3410
|
...number(2, Valtype.i32),
|
3367
3411
|
[ Opcodes.i32_mul ],
|
3368
3412
|
[ Opcodes.i32_add ],
|
@@ -3378,7 +3422,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3378
3422
|
Opcodes.i32_to,
|
3379
3423
|
[ Opcodes.i32_store16, 0, 4 ]
|
3380
3424
|
],
|
3381
|
-
[TYPES.uint32array]: [
|
3425
|
+
[TYPES.uint32array]: () => [
|
3382
3426
|
...number(4, Valtype.i32),
|
3383
3427
|
[ Opcodes.i32_mul ],
|
3384
3428
|
[ Opcodes.i32_add ],
|
@@ -3394,7 +3438,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3394
3438
|
Opcodes.i32_to_u,
|
3395
3439
|
[ Opcodes.i32_store, 0, 4 ]
|
3396
3440
|
],
|
3397
|
-
[TYPES.int32array]: [
|
3441
|
+
[TYPES.int32array]: () => [
|
3398
3442
|
...number(4, Valtype.i32),
|
3399
3443
|
[ Opcodes.i32_mul ],
|
3400
3444
|
[ Opcodes.i32_add ],
|
@@ -3410,7 +3454,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3410
3454
|
Opcodes.i32_to,
|
3411
3455
|
[ Opcodes.i32_store, 0, 4 ]
|
3412
3456
|
],
|
3413
|
-
[TYPES.float32array]: [
|
3457
|
+
[TYPES.float32array]: () => [
|
3414
3458
|
...number(4, Valtype.i32),
|
3415
3459
|
[ Opcodes.i32_mul ],
|
3416
3460
|
[ Opcodes.i32_add ],
|
@@ -3426,7 +3470,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3426
3470
|
[ Opcodes.f32_demote_f64 ],
|
3427
3471
|
[ Opcodes.f32_store, 0, 4 ]
|
3428
3472
|
],
|
3429
|
-
[TYPES.float64array]: [
|
3473
|
+
[TYPES.float64array]: () => [
|
3430
3474
|
...number(8, Valtype.i32),
|
3431
3475
|
[ Opcodes.i32_mul ],
|
3432
3476
|
[ Opcodes.i32_add ],
|
@@ -3520,6 +3564,9 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3520
3564
|
];
|
3521
3565
|
}
|
3522
3566
|
|
3567
|
+
// check not const
|
3568
|
+
if (local.metadata?.kind === 'const') return internalThrow(scope, 'TypeError', `Cannot assign to constant variable ${name}`, true);
|
3569
|
+
|
3523
3570
|
if (op === '=') {
|
3524
3571
|
return setLocalWithType(scope, name, isGlobal, decl.right, true);
|
3525
3572
|
}
|
@@ -3662,16 +3709,15 @@ const generateUnary = (scope, decl) => {
|
|
3662
3709
|
disposeLeftover(out);
|
3663
3710
|
|
3664
3711
|
out.push(...typeSwitch(scope, overrideType ?? getNodeType(scope, decl.argument), [
|
3665
|
-
[ TYPES.number, makeString(scope, 'number', false, '#typeof_result') ],
|
3666
|
-
[ TYPES.boolean, makeString(scope, 'boolean', false, '#typeof_result') ],
|
3667
|
-
[ TYPES.string, makeString(scope, 'string', false, '#typeof_result') ],
|
3668
|
-
[ [ TYPES.undefined, TYPES.empty ], makeString(scope, 'undefined', false, '#typeof_result') ],
|
3669
|
-
[ TYPES.function, makeString(scope, 'function', false, '#typeof_result') ],
|
3670
|
-
[ TYPES.symbol, makeString(scope, 'symbol', false, '#typeof_result') ],
|
3671
|
-
[ TYPES.bytestring, makeString(scope, 'string', false, '#typeof_result') ],
|
3712
|
+
[ TYPES.number, () => makeString(scope, 'number', false, '#typeof_result') ],
|
3713
|
+
[ TYPES.boolean, () => makeString(scope, 'boolean', false, '#typeof_result') ],
|
3714
|
+
[ [ TYPES.string, TYPES.bytestring ], () => makeString(scope, 'string', false, '#typeof_result') ],
|
3715
|
+
[ [ TYPES.undefined, TYPES.empty ], () => makeString(scope, 'undefined', false, '#typeof_result') ],
|
3716
|
+
[ TYPES.function, () => makeString(scope, 'function', false, '#typeof_result') ],
|
3717
|
+
[ TYPES.symbol, () => makeString(scope, 'symbol', false, '#typeof_result') ],
|
3672
3718
|
|
3673
3719
|
// object and internal types
|
3674
|
-
[ 'default', makeString(scope, 'object', false, '#typeof_result') ],
|
3720
|
+
[ 'default', () => makeString(scope, 'object', false, '#typeof_result') ],
|
3675
3721
|
]));
|
3676
3722
|
|
3677
3723
|
return out;
|
@@ -3921,7 +3967,7 @@ const generateForOf = (scope, decl) => {
|
|
3921
3967
|
// set type for local
|
3922
3968
|
// todo: optimize away counter and use end pointer
|
3923
3969
|
out.push(...typeSwitch(scope, iterType, {
|
3924
|
-
[TYPES.array]: [
|
3970
|
+
[TYPES.array]: () => [
|
3925
3971
|
[ Opcodes.loop, Blocktype.void ],
|
3926
3972
|
|
3927
3973
|
[ Opcodes.local_get, pointer ],
|
@@ -3962,7 +4008,7 @@ const generateForOf = (scope, decl) => {
|
|
3962
4008
|
[ Opcodes.end ]
|
3963
4009
|
],
|
3964
4010
|
|
3965
|
-
[TYPES.string]: [
|
4011
|
+
[TYPES.string]: () => [
|
3966
4012
|
...setType(scope, tmpName, TYPES.string),
|
3967
4013
|
|
3968
4014
|
// allocate out string
|
@@ -4017,7 +4063,7 @@ const generateForOf = (scope, decl) => {
|
|
4017
4063
|
[ Opcodes.end ],
|
4018
4064
|
[ Opcodes.end ]
|
4019
4065
|
],
|
4020
|
-
[TYPES.bytestring]: [
|
4066
|
+
[TYPES.bytestring]: () => [
|
4021
4067
|
...setType(scope, tmpName, TYPES.bytestring),
|
4022
4068
|
|
4023
4069
|
// allocate out string
|
@@ -4069,7 +4115,7 @@ const generateForOf = (scope, decl) => {
|
|
4069
4115
|
[ Opcodes.end ]
|
4070
4116
|
],
|
4071
4117
|
|
4072
|
-
[TYPES.set]: [
|
4118
|
+
[TYPES.set]: () => [
|
4073
4119
|
[ Opcodes.loop, Blocktype.void ],
|
4074
4120
|
|
4075
4121
|
[ Opcodes.local_get, pointer ],
|
@@ -4111,25 +4157,25 @@ const generateForOf = (scope, decl) => {
|
|
4111
4157
|
],
|
4112
4158
|
|
4113
4159
|
...wrapBC({
|
4114
|
-
[TYPES.uint8array]: [
|
4160
|
+
[TYPES.uint8array]: () => [
|
4115
4161
|
[ Opcodes.i32_add ],
|
4116
4162
|
|
4117
4163
|
[ Opcodes.i32_load8_u, 0, 4 ],
|
4118
4164
|
Opcodes.i32_from_u
|
4119
4165
|
],
|
4120
|
-
[TYPES.uint8clampedarray]: [
|
4166
|
+
[TYPES.uint8clampedarray]: () => [
|
4121
4167
|
[ Opcodes.i32_add ],
|
4122
4168
|
|
4123
4169
|
[ Opcodes.i32_load8_u, 0, 4 ],
|
4124
4170
|
Opcodes.i32_from_u
|
4125
4171
|
],
|
4126
|
-
[TYPES.int8array]: [
|
4172
|
+
[TYPES.int8array]: () => [
|
4127
4173
|
[ Opcodes.i32_add ],
|
4128
4174
|
|
4129
4175
|
[ Opcodes.i32_load8_s, 0, 4 ],
|
4130
4176
|
Opcodes.i32_from
|
4131
4177
|
],
|
4132
|
-
[TYPES.uint16array]: [
|
4178
|
+
[TYPES.uint16array]: () => [
|
4133
4179
|
...number(2, Valtype.i32),
|
4134
4180
|
[ Opcodes.i32_mul ],
|
4135
4181
|
[ Opcodes.i32_add ],
|
@@ -4137,7 +4183,7 @@ const generateForOf = (scope, decl) => {
|
|
4137
4183
|
[ Opcodes.i32_load16_u, 0, 4 ],
|
4138
4184
|
Opcodes.i32_from_u
|
4139
4185
|
],
|
4140
|
-
[TYPES.int16array]: [
|
4186
|
+
[TYPES.int16array]: () => [
|
4141
4187
|
...number(2, Valtype.i32),
|
4142
4188
|
[ Opcodes.i32_mul ],
|
4143
4189
|
[ Opcodes.i32_add ],
|
@@ -4145,7 +4191,7 @@ const generateForOf = (scope, decl) => {
|
|
4145
4191
|
[ Opcodes.i32_load16_s, 0, 4 ],
|
4146
4192
|
Opcodes.i32_from
|
4147
4193
|
],
|
4148
|
-
[TYPES.uint32array]: [
|
4194
|
+
[TYPES.uint32array]: () => [
|
4149
4195
|
...number(4, Valtype.i32),
|
4150
4196
|
[ Opcodes.i32_mul ],
|
4151
4197
|
[ Opcodes.i32_add ],
|
@@ -4153,7 +4199,7 @@ const generateForOf = (scope, decl) => {
|
|
4153
4199
|
[ Opcodes.i32_load, 0, 4 ],
|
4154
4200
|
Opcodes.i32_from_u
|
4155
4201
|
],
|
4156
|
-
[TYPES.int32array]: [
|
4202
|
+
[TYPES.int32array]: () => [
|
4157
4203
|
...number(4, Valtype.i32),
|
4158
4204
|
[ Opcodes.i32_mul ],
|
4159
4205
|
[ Opcodes.i32_add ],
|
@@ -4161,7 +4207,7 @@ const generateForOf = (scope, decl) => {
|
|
4161
4207
|
[ Opcodes.i32_load, 0, 4 ],
|
4162
4208
|
Opcodes.i32_from
|
4163
4209
|
],
|
4164
|
-
[TYPES.float32array]: [
|
4210
|
+
[TYPES.float32array]: () => [
|
4165
4211
|
...number(4, Valtype.i32),
|
4166
4212
|
[ Opcodes.i32_mul ],
|
4167
4213
|
[ Opcodes.i32_add ],
|
@@ -4169,7 +4215,7 @@ const generateForOf = (scope, decl) => {
|
|
4169
4215
|
[ Opcodes.f32_load, 0, 4 ],
|
4170
4216
|
[ Opcodes.f64_promote_f32 ]
|
4171
4217
|
],
|
4172
|
-
[TYPES.float64array]: [
|
4218
|
+
[TYPES.float64array]: () => [
|
4173
4219
|
...number(8, Valtype.i32),
|
4174
4220
|
[ Opcodes.i32_mul ],
|
4175
4221
|
[ Opcodes.i32_add ],
|
@@ -4348,7 +4394,7 @@ const generateForIn = (scope, decl) => {
|
|
4348
4394
|
[TYPES.object]: out,
|
4349
4395
|
|
4350
4396
|
// wrap for of object.keys
|
4351
|
-
default: generate(scope, {
|
4397
|
+
default: () => generate(scope, {
|
4352
4398
|
type: 'ForOfStatement',
|
4353
4399
|
left: decl.left,
|
4354
4400
|
body: decl.body,
|
@@ -4414,8 +4460,7 @@ const generateSwitch = (scope, decl) => {
|
|
4414
4460
|
types.push(type);
|
4415
4461
|
|
4416
4462
|
if (consequent.length !== 0) {
|
4417
|
-
|
4418
|
-
bc.push([ types, o ]);
|
4463
|
+
bc.push([ types, () => generate(scope, { type: 'BlockStatement', body: consequent }) ]);
|
4419
4464
|
types = [];
|
4420
4465
|
}
|
4421
4466
|
}
|
@@ -4685,11 +4730,6 @@ const allocPage = (scope, reason, type) => {
|
|
4685
4730
|
const ptr = i => i === 0 ? 16 : (i * pageSize);
|
4686
4731
|
if (pages.has(reason)) return ptr(pages.get(reason).ind);
|
4687
4732
|
|
4688
|
-
if (reason.startsWith('array:')) pages.hasArray = true;
|
4689
|
-
if (reason.startsWith('string:')) pages.hasString = true;
|
4690
|
-
if (reason.startsWith('bytestring:')) pages.hasByteString = true;
|
4691
|
-
if (reason.includes('string:')) pages.hasAnyString = true;
|
4692
|
-
|
4693
4733
|
const ind = pages.size;
|
4694
4734
|
pages.set(reason, { ind, type });
|
4695
4735
|
|
@@ -4771,14 +4811,6 @@ const printStaticStr = str => {
|
|
4771
4811
|
};
|
4772
4812
|
|
4773
4813
|
const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty = false, itemType = valtype, intOut = false, typed = false) => {
|
4774
|
-
if (itemType !== 'i16' && itemType !== 'i8') {
|
4775
|
-
pages.hasArray = true;
|
4776
|
-
} else {
|
4777
|
-
pages.hasAnyString = true;
|
4778
|
-
if (itemType === 'i8') pages.hasByteString = true;
|
4779
|
-
else pages.hasString = true;
|
4780
|
-
}
|
4781
|
-
|
4782
4814
|
const out = [];
|
4783
4815
|
|
4784
4816
|
const uniqueName = name === '$undeclared' ? name + uniqId() : name;
|
@@ -5121,11 +5153,19 @@ const withType = (scope, wasm, type) => [
|
|
5121
5153
|
const wrapBC = (bc, { prelude = [], postlude = [] } = {}) => {
|
5122
5154
|
const out = {};
|
5123
5155
|
for (const x in bc) {
|
5124
|
-
|
5125
|
-
|
5126
|
-
|
5127
|
-
|
5128
|
-
|
5156
|
+
if (typeof bc[x] === 'function') {
|
5157
|
+
out[x] = () => [
|
5158
|
+
...prelude,
|
5159
|
+
...bc[x](),
|
5160
|
+
...postlude
|
5161
|
+
];
|
5162
|
+
} else {
|
5163
|
+
out[x] = [
|
5164
|
+
...prelude,
|
5165
|
+
...bc[x],
|
5166
|
+
...postlude
|
5167
|
+
];
|
5168
|
+
}
|
5129
5169
|
}
|
5130
5170
|
|
5131
5171
|
return out;
|
@@ -5316,12 +5356,12 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5316
5356
|
const propertyWasm = [ [ Opcodes.local_get, localTmp(scope, '#member_prop') ] ];
|
5317
5357
|
|
5318
5358
|
const out = typeSwitch(scope, getNodeType(scope, object), {
|
5319
|
-
[TYPES.array]: [
|
5359
|
+
[TYPES.array]: () => [
|
5320
5360
|
...loadArray(scope, objectWasm, propertyWasm),
|
5321
5361
|
...setLastType(scope)
|
5322
5362
|
],
|
5323
5363
|
|
5324
|
-
[TYPES.string]: [
|
5364
|
+
[TYPES.string]: () => [
|
5325
5365
|
// allocate out string
|
5326
5366
|
[ Opcodes.call, includeBuiltin(scope, '__Porffor_allocate').index ],
|
5327
5367
|
[ Opcodes.local_tee, localTmp(scope, '#member_allocd', Valtype.i32) ],
|
@@ -5355,7 +5395,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5355
5395
|
...setLastType(scope, TYPES.string)
|
5356
5396
|
],
|
5357
5397
|
|
5358
|
-
[TYPES.bytestring]: [
|
5398
|
+
[TYPES.bytestring]: () => [
|
5359
5399
|
// allocate out string
|
5360
5400
|
[ Opcodes.call, includeBuiltin(scope, '__Porffor_allocate').index ],
|
5361
5401
|
[ Opcodes.local_tee, localTmp(scope, '#member_allocd', Valtype.i32) ],
|
@@ -5467,7 +5507,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
|
|
5467
5507
|
[TYPES.undefined]: internalThrow(scope, 'TypeError', 'Cannot read property of undefined', true),
|
5468
5508
|
|
5469
5509
|
// default: internalThrow(scope, 'TypeError', 'Unsupported member expression object', true)
|
5470
|
-
default: [
|
5510
|
+
default: () => [
|
5471
5511
|
...objectWasm,
|
5472
5512
|
Opcodes.i32_to_u,
|
5473
5513
|
...getNodeType(scope, object),
|
@@ -6186,6 +6226,7 @@ export default program => {
|
|
6186
6226
|
data = [];
|
6187
6227
|
currentFuncIndex = importedFuncs.length;
|
6188
6228
|
typeswitchDepth = 0;
|
6229
|
+
usedTypes = new Set([ TYPES.empty, TYPES.undefined, TYPES.number, TYPES.boolean, TYPES.function ]);
|
6189
6230
|
|
6190
6231
|
const valtypeInd = ['i32', 'i64', 'f64'].indexOf(valtype);
|
6191
6232
|
|
@@ -6226,8 +6267,6 @@ export default program => {
|
|
6226
6267
|
|
6227
6268
|
const [ main ] = generateFunc({}, program);
|
6228
6269
|
|
6229
|
-
delete globals['#ind'];
|
6230
|
-
|
6231
6270
|
// if wanted and blank main func and other exports, remove it
|
6232
6271
|
if (Prefs.rmBlankMain && main.wasm.length === 0 && funcs.some(x => x.export)) funcs.splice(main.index - importedFuncs.length, 1);
|
6233
6272
|
|
@@ -6235,7 +6274,16 @@ export default program => {
|
|
6235
6274
|
// todo: these should just be deleted once able
|
6236
6275
|
for (let i = 0; i < funcs.length; i++) {
|
6237
6276
|
const f = funcs[i];
|
6238
|
-
if (f.
|
6277
|
+
if (f.wasm) {
|
6278
|
+
// run callbacks
|
6279
|
+
const wasm = f.wasm;
|
6280
|
+
for (let j = 0; j < wasm.length; j++) {
|
6281
|
+
const o = wasm[j];
|
6282
|
+
if (o[0] === null && typeof o[1] === 'function') {
|
6283
|
+
wasm.splice(j--, 1, ...o[1]());
|
6284
|
+
}
|
6285
|
+
}
|
6286
|
+
|
6239
6287
|
continue;
|
6240
6288
|
}
|
6241
6289
|
|
@@ -6282,5 +6330,9 @@ export default program => {
|
|
6282
6330
|
// }
|
6283
6331
|
// }
|
6284
6332
|
|
6333
|
+
delete globals['#ind'];
|
6334
|
+
|
6335
|
+
// console.log([...usedTypes].map(x => TYPE_NAMES[x]));
|
6336
|
+
|
6285
6337
|
return { funcs, globals, tags, exceptions, pages, data };
|
6286
6338
|
};
|