porffor 0.55.21 → 0.55.23

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.
@@ -10,14 +10,6 @@ import { log } from './log.js';
10
10
  import { allocPage, allocStr } from './allocator.js';
11
11
  import './prefs.js';
12
12
 
13
- let globals = {};
14
- let tags = [];
15
- let funcs = [];
16
- let exceptions = [];
17
- let funcIndex = {};
18
- let currentFuncIndex = importedFuncs.length;
19
- let builtinFuncs = {}, builtinVars = {}, prototypeFuncs = {};
20
-
21
13
  class TodoError extends Error {
22
14
  constructor(message) {
23
15
  super(message);
@@ -46,7 +38,6 @@ const cacheAst = (decl, wasm) => {
46
38
  return wasm;
47
39
  };
48
40
 
49
- let indirectFuncs = [];
50
41
  let doNotMarkFuncRef = false;
51
42
  const funcRef = func => {
52
43
  if (!doNotMarkFuncRef) func.referenced = true;
@@ -1393,7 +1384,6 @@ const isExistingProtoFunc = name => {
1393
1384
  return false;
1394
1385
  };
1395
1386
 
1396
- let globalInfer;
1397
1387
  const getInferred = (scope, name, global = false) => {
1398
1388
  if (global) {
1399
1389
  if (globalInfer.has(name)) return globalInfer.get(name);
@@ -1549,7 +1539,7 @@ const getNodeType = (scope, node) => {
1549
1539
  return getType(scope, node.name);
1550
1540
  }
1551
1541
 
1552
- if (node.type === 'ObjectExpression') {
1542
+ if (node.type === 'ObjectExpression' || node.type === 'Super') {
1553
1543
  return TYPES.object;
1554
1544
  }
1555
1545
 
@@ -1581,24 +1571,6 @@ const getNodeType = (scope, node) => {
1581
1571
  if (Object.hasOwn(builtinFuncs, name) && builtinFuncs[name].returnType != null) return builtinFuncs[name].returnType;
1582
1572
  if (Object.hasOwn(internalConstrs, name) && internalConstrs[name].type != null) return internalConstrs[name].type;
1583
1573
 
1584
- // check if this is a prototype function
1585
- // if so and there is only one impl (eg charCodeAt)
1586
- // or all impls have the same return type
1587
- // use that return type as that is the only possibility
1588
- // (if non-matching type it would error out)
1589
- if (name.startsWith('__')) {
1590
- const spl = name.slice(2).split('_');
1591
-
1592
- const func = spl[spl.length - 1];
1593
- const protoFuncs = Object.keys(prototypeFuncs).filter(x => x != TYPES.bytestring && prototypeFuncs[x][func] != null);
1594
- if (
1595
- protoFuncs.length === 1 ||
1596
- (protoFuncs.length > 1 && protoFuncs.every(x => x.returnType === protoFuncs[0].returnType))
1597
- ) {
1598
- if (protoFuncs[0].returnType != null) return protoFuncs[0].returnType;
1599
- }
1600
- }
1601
-
1602
1574
  if (name.startsWith('__Porffor_wasm_')) {
1603
1575
  // todo: return undefined for non-returning ops
1604
1576
  return TYPES.number;
@@ -1870,29 +1842,6 @@ const createNewTarget = (scope, decl, idx = 0, force = false) => {
1870
1842
  ];
1871
1843
  };
1872
1844
 
1873
- const makeObject = (scope, obj) => {
1874
- const properties = [];
1875
- for (const x in obj) {
1876
- properties.push({
1877
- type: 'Property',
1878
- method: false,
1879
- shorthand: false,
1880
- computed: false,
1881
- key: {
1882
- type: 'Identifier',
1883
- name: x
1884
- },
1885
- value: obj[x],
1886
- kind: 'init'
1887
- });
1888
- }
1889
-
1890
- return generate(scope, {
1891
- type: 'ObjectExpression',
1892
- properties
1893
- });
1894
- };
1895
-
1896
1845
  const getObjProp = (obj, prop) => {
1897
1846
  if (typeof obj === 'string') obj = {
1898
1847
  type: 'Identifier',
@@ -1977,32 +1926,22 @@ const createThisArg = (scope, decl) => {
1977
1926
  number(TYPES.object, Valtype.i32)
1978
1927
  ];
1979
1928
 
1980
- // create new object with __proto__ set to callee prototype
1929
+ // create new object with prototype set to callee prototype
1981
1930
  const tmp = localTmp(scope, '#this_create_tmp');
1982
1931
  const proto = getObjProp(decl.callee, 'prototype');
1983
1932
 
1984
1933
  return [
1985
- ...makeObject(scope, {}),
1934
+ [ Opcodes.call, includeBuiltin(scope, '__Porffor_allocate').index ],
1935
+ Opcodes.i32_from_u,
1986
1936
  [ Opcodes.local_tee, tmp ],
1987
1937
  Opcodes.i32_to_u,
1988
-
1989
1938
  number(TYPES.object, Valtype.i32),
1990
1939
 
1991
- ...generate(scope, {
1992
- type: 'Literal',
1993
- value: '__proto__'
1994
- }),
1995
- Opcodes.i32_to_u,
1996
- number(TYPES.bytestring, Valtype.i32),
1997
-
1998
1940
  ...generate(scope, proto),
1941
+ Opcodes.i32_to_u,
1999
1942
  ...getNodeType(scope, proto),
2000
1943
 
2001
- // flags: writable
2002
- number(0b1000, Valtype.i32),
2003
- number(TYPES.number, Valtype.i32),
2004
-
2005
- [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_expr_initWithFlags').index ],
1944
+ [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_setPrototype').index ],
2006
1945
 
2007
1946
  [ Opcodes.local_get, tmp ],
2008
1947
  number(TYPES.object, Valtype.i32)
@@ -2363,30 +2302,34 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2363
2302
  const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${protoName}_tmp2`, protoFunc.local2) : -1;
2364
2303
 
2365
2304
  let optUnused = false;
2366
- const protoOut = protoFunc(getPointer, {
2367
- getCachedI32: () => [ [ Opcodes.local_get, lengthLocal ] ],
2368
- setCachedI32: () => [ [ Opcodes.local_set, lengthLocal ] ],
2369
- get: () => ArrayUtil.getLength(getPointer),
2370
- getI32: () => ArrayUtil.getLengthI32(getPointer),
2371
- set: value => ArrayUtil.setLength(getPointer, value),
2372
- setI32: value => ArrayUtil.setLengthI32(getPointer, value)
2373
- },
2374
- generate(scope, decl.arguments[0] ?? DEFAULT_VALUE()),
2375
- getNodeType(scope, decl.arguments[0] ?? DEFAULT_VALUE()),
2376
- protoLocal, protoLocal2,
2377
- bytes => [
2378
- number(bytes, Valtype.i32),
2379
- [ Opcodes.call, includeBuiltin(scope, '__Porffor_allocateBytes').index ]
2380
- ],
2381
- () => {
2382
- optUnused = true;
2383
- return unusedValue;
2305
+ const protoOut = protoFunc({
2306
+ pointer: getPointer,
2307
+ length: {
2308
+ getCachedI32: () => [ [ Opcodes.local_get, lengthLocal ] ],
2309
+ setCachedI32: () => [ [ Opcodes.local_set, lengthLocal ] ],
2310
+ get: () => ArrayUtil.getLength(getPointer),
2311
+ getI32: () => ArrayUtil.getLengthI32(getPointer),
2312
+ set: value => ArrayUtil.setLength(getPointer, value),
2313
+ setI32: value => ArrayUtil.setLengthI32(getPointer, value)
2314
+ },
2315
+ arg: generate(scope, decl.arguments[0] ?? DEFAULT_VALUE()),
2316
+ argType: getNodeType(scope, decl.arguments[0] ?? DEFAULT_VALUE()),
2317
+ iTmp: protoLocal,
2318
+ iTmp2: protoLocal2,
2319
+ alloc: bytes => [
2320
+ number(bytes, Valtype.i32),
2321
+ [ Opcodes.call, includeBuiltin(scope, '__Porffor_allocateBytes').index ]
2322
+ ],
2323
+ unusedValue: () => {
2324
+ optUnused = true;
2325
+ return unusedValue;
2326
+ },
2327
+ setType: type => setLastType(scope, type)
2384
2328
  });
2385
2329
 
2386
2330
  return [
2387
2331
  [ Opcodes.block, unusedValue ? Blocktype.void : valtypeBinary ],
2388
2332
  ...protoOut,
2389
- ...(unusedValue && optUnused ? [] : (protoFunc.returnType != null ? setLastType(scope, protoFunc.returnType) : setLastType(scope))),
2390
2333
  ...(unusedValue && !optUnused ? [ [ Opcodes.drop ] ] : []),
2391
2334
  [ Opcodes.end ]
2392
2335
  ];
@@ -2784,8 +2727,19 @@ const generateThis = (scope, decl) => {
2784
2727
  ];
2785
2728
  };
2786
2729
 
2787
- const generateSuper = (scope, decl) => generate(scope,
2788
- getObjProp(getObjProp({ type: 'ThisExpression', _noGlobalThis: true }, '__proto__'), '__proto__'));
2730
+ const generateSuper = (scope, decl) => generate(scope, {
2731
+ type: 'CallExpression',
2732
+ callee: { type: 'Identifier', name: '__Porffor_object_getPrototype' },
2733
+ arguments: [
2734
+ {
2735
+ type: 'CallExpression',
2736
+ callee: { type: 'Identifier', name: '__Porffor_object_getPrototype' },
2737
+ arguments: [
2738
+ { type: 'ThisExpression', _noGlobalThis: true }
2739
+ ]
2740
+ }
2741
+ ]
2742
+ });
2789
2743
 
2790
2744
  // bad hack for undefined and null working without additional logic
2791
2745
  const DEFAULT_VALUE = () => ({
@@ -2907,8 +2861,7 @@ const brTable = (input, bc, returns) => {
2907
2861
  for (let i = offset; i <= max; i++) {
2908
2862
  // if branch for this num, go to that block
2909
2863
  if (bc[i]) {
2910
- table.push(br);
2911
- br++;
2864
+ table.push(br++);
2912
2865
  continue;
2913
2866
  }
2914
2867
 
@@ -2945,9 +2898,6 @@ const brTable = (input, bc, returns) => {
2945
2898
  return out;
2946
2899
  };
2947
2900
 
2948
- let typeswitchDepth = 0;
2949
-
2950
- let usedTypes = new Set();
2951
2901
  const typeUsed = (scope, x) => {
2952
2902
  if (x == null) return;
2953
2903
  usedTypes.add(x);
@@ -3103,7 +3053,7 @@ const typeIsNotOneOf = (type, types, valtype = Valtype.i32) => {
3103
3053
  return out;
3104
3054
  };
3105
3055
 
3106
- const allocVar = (scope, name, global = false, type = true, redecl = false) => {
3056
+ const allocVar = (scope, name, global = false, type = true, redecl = false, i32 = false) => {
3107
3057
  const target = global ? globals : scope.locals;
3108
3058
 
3109
3059
  // already declared
@@ -3118,7 +3068,7 @@ const allocVar = (scope, name, global = false, type = true, redecl = false) => {
3118
3068
  }
3119
3069
 
3120
3070
  let idx = global ? globals['#ind']++ : scope.localInd++;
3121
- target[name] = { idx, type: valtypeBinary };
3071
+ target[name] = { idx, type: i32 ? Valtype.i32 : valtypeBinary };
3122
3072
 
3123
3073
  if (type) {
3124
3074
  let typeIdx = global ? globals['#ind']++ : scope.localInd++;
@@ -3600,7 +3550,6 @@ const memberTmpNames = scope => {
3600
3550
  };
3601
3551
 
3602
3552
  // COCTC: cross-object compile-time cache
3603
- let coctc = new Map();
3604
3553
  const coctcOffset = prop => {
3605
3554
  if (typeof prop === 'object') {
3606
3555
  if (
@@ -4427,7 +4376,6 @@ const generateConditional = (scope, decl) => {
4427
4376
  return out;
4428
4377
  };
4429
4378
 
4430
- let depth = [];
4431
4379
  const generateFor = (scope, decl) => {
4432
4380
  const out = [];
4433
4381
 
@@ -4903,7 +4851,7 @@ const generateForIn = (scope, decl) => {
4903
4851
 
4904
4852
  // get length
4905
4853
  [ Opcodes.local_get, pointer ],
4906
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
4854
+ [ Opcodes.i32_load16_u, 0, 0 ],
4907
4855
  [ Opcodes.local_tee, length ],
4908
4856
 
4909
4857
  [ Opcodes.if, Blocktype.void ]
@@ -4936,7 +4884,7 @@ const generateForIn = (scope, decl) => {
4936
4884
 
4937
4885
  // read key
4938
4886
  [ Opcodes.local_get, pointer ],
4939
- [ Opcodes.i32_load, 0, 5 ],
4887
+ [ Opcodes.i32_load, 0, 12 ],
4940
4888
  [ Opcodes.local_tee, tmp ],
4941
4889
 
4942
4890
  ...setType(scope, tmpName, [
@@ -4968,7 +4916,7 @@ const generateForIn = (scope, decl) => {
4968
4916
  // todo/perf: do not read key for non-enumerables
4969
4917
  // only run body if entry is enumerable
4970
4918
  [ Opcodes.local_get, pointer ],
4971
- [ Opcodes.i32_load8_u, 0, 17 ],
4919
+ [ Opcodes.i32_load8_u, 0, 24 ],
4972
4920
  [ Opcodes.i32_const, 0b0100 ],
4973
4921
  [ Opcodes.i32_and ],
4974
4922
  [ Opcodes.if, Blocktype.void ],
@@ -4976,9 +4924,9 @@ const generateForIn = (scope, decl) => {
4976
4924
  [ Opcodes.drop ],
4977
4925
  [ Opcodes.end ],
4978
4926
 
4979
- // increment pointer by 14
4927
+ // increment pointer by 18
4980
4928
  [ Opcodes.local_get, pointer ],
4981
- number(14, Valtype.i32),
4929
+ number(18, Valtype.i32),
4982
4930
  [ Opcodes.i32_add ],
4983
4931
  [ Opcodes.local_set, pointer ],
4984
4932
 
@@ -5364,9 +5312,6 @@ const generateMeta = (scope, decl) => {
5364
5312
  return todo(scope, `meta property object ${decl.meta.name} is not supported yet`, true);
5365
5313
  };
5366
5314
 
5367
- let pages = new Map();
5368
- let data = [];
5369
-
5370
5315
  const compileBytes = (val, itemType) => {
5371
5316
  switch (itemType) {
5372
5317
  case 'i8': return [ val % 256 ];
@@ -5805,60 +5750,6 @@ const generateMember = (scope, decl, _global, _name) => {
5805
5750
  if (known == null) extraBC = bc;
5806
5751
  }
5807
5752
 
5808
- if (decl.property.name === '__proto__') {
5809
- // todo: support optional
5810
- const bc = {};
5811
- const prototypes = Object.keys(builtinVars).filter(x => x.endsWith('_prototype'));
5812
-
5813
- const known = knownType(scope, getNodeType(scope, decl.object));
5814
- for (const x of prototypes) {
5815
- let type = TYPES[x.split('_prototype')[0].slice(2).toLowerCase()];
5816
- if (type == null) continue;
5817
-
5818
- // do not __proto__ primitive hack for objects or functions
5819
- if (type === TYPES.object || type === TYPES.function) continue;
5820
-
5821
- // hack: do not support primitives for Object.prototype.isPrototypeOf
5822
- if (scope.name === '__Object_prototype_isPrototypeOf') {
5823
- switch (type) {
5824
- case TYPES.boolean:
5825
- type = TYPES.booleanobject;
5826
- break;
5827
-
5828
- case TYPES.number:
5829
- type = TYPES.numberobject;
5830
- break;
5831
-
5832
- case TYPES.string:
5833
- type = TYPES.stringobject;
5834
- break;
5835
-
5836
- case TYPES.bytestring:
5837
- continue;
5838
- }
5839
- }
5840
-
5841
- const ident = {
5842
- type: 'Identifier',
5843
- name: x
5844
- };
5845
-
5846
- // hack: bytestrings should return string prototype
5847
- if (type === TYPES.bytestring) ident.name = '__String_prototype';
5848
-
5849
- bc[type] = () => [
5850
- ...generate(scope, ident),
5851
- ...setLastType(scope, getNodeType(scope, ident))
5852
- ];
5853
- if (type === known) return bc[type]();
5854
- }
5855
-
5856
- if (known == null) {
5857
- aliasPrimObjsBC(bc);
5858
- extraBC = bc;
5859
- }
5860
- }
5861
-
5862
5753
  const useCoctc = Prefs.coctc && coctcOffset(decl) > 0;
5863
5754
  const coctcObjTmp = useCoctc && localTmp(scope, '#coctc_obj' + uniqId(), Valtype.i32);
5864
5755
 
@@ -6028,7 +5919,7 @@ const generateMember = (scope, decl, _global, _name) => {
6028
5919
  }),
6029
5920
  } : {}),
6030
5921
 
6031
- [TYPES.undefined]: internalThrow(scope, 'TypeError', 'Cannot read property of undefined', true),
5922
+ [TYPES.undefined]: internalThrow(scope, 'TypeError', `Cannot read property of undefined`, true),
6032
5923
 
6033
5924
  // default: internalThrow(scope, 'TypeError', 'Unsupported member expression object', true)
6034
5925
  default: () => [
@@ -6183,10 +6074,25 @@ const generateClass = (scope, decl) => {
6183
6074
  // class Foo {}
6184
6075
  // class Bar extends Foo {}
6185
6076
  // Bar.__proto__ = Foo
6186
- // Bar.prototype.__proto__ = Foo.prototype
6187
- ...generate(scope, setObjProp(root, '__proto__', decl.superClass)),
6077
+ ...generate(scope, {
6078
+ type: 'CallExpression',
6079
+ callee: { type: 'Identifier', name: '__Porffor_object_setPrototype' },
6080
+ arguments: [
6081
+ root,
6082
+ decl.superClass
6083
+ ]
6084
+ }),
6188
6085
  [ Opcodes.drop ],
6189
- ...generate(scope, setObjProp(proto, '__proto__', getObjProp(decl.superClass, 'prototype'))),
6086
+
6087
+ // Bar.prototype.__proto__ = Foo.prototype
6088
+ ...generate(scope, {
6089
+ type: 'CallExpression',
6090
+ callee: { type: 'Identifier', name: '__Porffor_object_setPrototype' },
6091
+ arguments: [
6092
+ proto,
6093
+ getObjProp(decl.superClass, 'prototype')
6094
+ ]
6095
+ }),
6190
6096
  [ Opcodes.drop ]
6191
6097
  );
6192
6098
  }
@@ -6220,18 +6126,6 @@ const generateClass = (scope, decl) => {
6220
6126
  // default value to undefined
6221
6127
  value ??= DEFAULT_VALUE();
6222
6128
 
6223
- let outArr = out, outOp = 'push', outScope = scope;
6224
- if (type === 'PropertyDefinition' && !_static) {
6225
- // define in construction instead
6226
- outArr = func.wasm;
6227
- outOp = 'unshift';
6228
- object = {
6229
- type: 'ThisExpression',
6230
- _noGlobalThis: true
6231
- };
6232
- outScope = func;
6233
- }
6234
-
6235
6129
  if (isFuncType(value.type)) {
6236
6130
  let id = value.id;
6237
6131
 
@@ -6249,19 +6143,60 @@ const generateClass = (scope, decl) => {
6249
6143
  };
6250
6144
  }
6251
6145
 
6252
- outArr[outOp](
6253
- ...generate(outScope, object),
6254
- Opcodes.i32_to_u,
6255
- ...getNodeType(outScope, object),
6146
+ if (type === 'PropertyDefinition' && !_static) {
6147
+ // define in construction instead
6148
+ object = {
6149
+ type: 'ThisExpression',
6150
+ _noGlobalThis: true
6151
+ };
6256
6152
 
6257
- ...toPropertyKey(outScope, generate(outScope, k), getNodeType(outScope, k), computed, true),
6153
+ let computedTmp;
6154
+ if (computed) {
6155
+ // compute now, reference in construction
6156
+ computedTmp = allocVar(scope, `#class_computed_prop${uniqId()}`, true, true, false, true);
6258
6157
 
6259
- ...generate(outScope, value),
6260
- ...(initKind !== 'value' && initKind !== 'method' ? [ Opcodes.i32_to_u ] : []),
6261
- ...getNodeType(outScope, value),
6158
+ out.push(
6159
+ ...toPropertyKey(scope, generate(scope, k), getNodeType(scope, k), computed, true),
6160
+ [ Opcodes.global_set, computedTmp + 1 ],
6161
+ [ Opcodes.global_set, computedTmp ]
6162
+ );
6163
+ }
6262
6164
 
6263
- [ Opcodes.call, includeBuiltin(outScope, `__Porffor_object_class_${initKind}`).index ]
6264
- );
6165
+ func.wasm.unshift(
6166
+ ...generate(func, object),
6167
+ Opcodes.i32_to_u,
6168
+ ...getNodeType(func, object),
6169
+
6170
+ ...(computed ? [
6171
+ [ Opcodes.global_get, computedTmp ],
6172
+ [ Opcodes.global_get, computedTmp + 1 ],
6173
+ ] : [
6174
+ ...generate(func, k),
6175
+ Opcodes.i32_to_u,
6176
+ ...getNodeType(func, k)
6177
+ ]),
6178
+
6179
+ ...generate(func, value),
6180
+ ...(initKind !== 'value' && initKind !== 'method' ? [ Opcodes.i32_to_u ] : []),
6181
+ ...getNodeType(func, value),
6182
+
6183
+ [ Opcodes.call, includeBuiltin(func, `__Porffor_object_class_${initKind}`).index ]
6184
+ );
6185
+ } else {
6186
+ out.push(
6187
+ ...generate(scope, object),
6188
+ Opcodes.i32_to_u,
6189
+ ...getNodeType(scope, object),
6190
+
6191
+ ...toPropertyKey(scope, generate(scope, k), getNodeType(scope, k), computed, true),
6192
+
6193
+ ...generate(scope, value),
6194
+ ...(initKind !== 'value' && initKind !== 'method' ? [ Opcodes.i32_to_u ] : []),
6195
+ ...getNodeType(scope, value),
6196
+
6197
+ [ Opcodes.call, includeBuiltin(scope, `__Porffor_object_class_${initKind}`).index ]
6198
+ );
6199
+ }
6265
6200
  }
6266
6201
 
6267
6202
  delete scope.overrideThis;
@@ -6344,7 +6279,7 @@ const generateTaggedTemplate = (scope, decl, global = false, name = undefined, v
6344
6279
  return funcIndex[x];
6345
6280
  }
6346
6281
 
6347
- return scope.locals[x]?.idx ?? globals[x].idx;
6282
+ return scope.locals[x]?.idx ?? globals[x]?.idx ?? (log.warning('codegen', `unknown immediate in Porffor.wasm: ${x}`) || 0);
6348
6283
  }
6349
6284
 
6350
6285
  return n;
@@ -6418,7 +6353,6 @@ const objectHack = node => {
6418
6353
 
6419
6354
  // hack: block these properties as they can be accessed on functions
6420
6355
  if (node.object.name !== 'Porffor' && (node.property.name === 'length' || node.property.name === 'name' || node.property.name === 'call')) return abortOut;
6421
-
6422
6356
  if (node.property.name === '__proto__') return abortOut;
6423
6357
 
6424
6358
  let objectName = node.object.name;
@@ -6784,7 +6718,6 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6784
6718
  return [ func, out ];
6785
6719
  };
6786
6720
 
6787
- let largestBlockBody = 0;
6788
6721
  const generateBlock = (scope, decl) => {
6789
6722
  let out = [];
6790
6723
 
@@ -6792,10 +6725,8 @@ const generateBlock = (scope, decl) => {
6792
6725
  scope.inferTree.push(decl);
6793
6726
 
6794
6727
  let len = decl.body.length, j = 0;
6795
- if (len > largestBlockBody) largestBlockBody = len;
6796
6728
  for (let i = 0; i < len; i++) {
6797
6729
  const x = decl.body[i];
6798
- if (len >= largestBlockBody) globalThis.progress?.(`${i}/${len}`);
6799
6730
  if (isEmptyNode(x)) continue;
6800
6731
 
6801
6732
  if (j++ > 0) out.push([ Opcodes.drop ]);
@@ -6958,10 +6889,9 @@ const internalConstrs = {
6958
6889
  }
6959
6890
  };
6960
6891
 
6892
+ let globals, tags, exceptions, funcs, indirectFuncs, funcIndex, currentFuncIndex, depth, pages, data, typeswitchDepth, usedTypes, coctc, globalInfer, builtinFuncs, builtinVars, prototypeFuncs;
6961
6893
  export default program => {
6962
- globals = {
6963
- ['#ind']: 0
6964
- };
6894
+ globals = { ['#ind']: 0 };
6965
6895
  tags = [];
6966
6896
  exceptions = [];
6967
6897
  funcs = []; indirectFuncs = [];
@@ -6971,26 +6901,22 @@ export default program => {
6971
6901
  data = [];
6972
6902
  currentFuncIndex = importedFuncs.length;
6973
6903
  typeswitchDepth = 0;
6974
- largestBlockBody = 0;
6975
6904
  usedTypes = new Set([ TYPES.empty, TYPES.undefined, TYPES.number, TYPES.boolean, TYPES.function ]);
6976
6905
  coctc = new Map();
6977
6906
  globalInfer = new Map();
6978
6907
 
6979
- const valtypeInd = ['i32', 'i64', 'f64'].indexOf(valtype);
6980
-
6981
6908
  // set generic opcodes for current valtype
6909
+ const valtypeInd = ['i32', 'i64', 'f64'].indexOf(valtype);
6982
6910
  Opcodes.const = [ Opcodes.i32_const, Opcodes.i64_const, Opcodes.f64_const ][valtypeInd];
6983
6911
  Opcodes.eq = [ Opcodes.i32_eq, Opcodes.i64_eq, Opcodes.f64_eq ][valtypeInd];
6984
6912
  Opcodes.eqz = [ [ [ Opcodes.i32_eqz ] ], [ [ Opcodes.i64_eqz ] ], [ number(0), [ Opcodes.f64_eq ] ] ][valtypeInd];
6985
6913
  Opcodes.mul = [ Opcodes.i32_mul, Opcodes.i64_mul, Opcodes.f64_mul ][valtypeInd];
6986
6914
  Opcodes.add = [ Opcodes.i32_add, Opcodes.i64_add, Opcodes.f64_add ][valtypeInd];
6987
6915
  Opcodes.sub = [ Opcodes.i32_sub, Opcodes.i64_sub, Opcodes.f64_sub ][valtypeInd];
6988
-
6989
6916
  Opcodes.i32_to = [ [], [ Opcodes.i32_wrap_i64 ], Opcodes.i32_trunc_sat_f64_s ][valtypeInd];
6990
6917
  Opcodes.i32_to_u = [ [], [ Opcodes.i32_wrap_i64 ], Opcodes.i32_trunc_sat_f64_u ][valtypeInd];
6991
6918
  Opcodes.i32_from = [ [], [ Opcodes.i64_extend_i32_s ], [ Opcodes.f64_convert_i32_s ] ][valtypeInd];
6992
6919
  Opcodes.i32_from_u = [ [], [ Opcodes.i64_extend_i32_u ], [ Opcodes.f64_convert_i32_u ] ][valtypeInd];
6993
-
6994
6920
  Opcodes.load = [ Opcodes.i32_load, Opcodes.i64_load, Opcodes.f64_load ][valtypeInd];
6995
6921
  Opcodes.store = [ Opcodes.i32_store, Opcodes.i64_store, Opcodes.f64_store ][valtypeInd];
6996
6922
 
@@ -1,6 +1,6 @@
1
1
  import { Opcodes, Valtype } from './wasmSpec.js';
2
2
  import { read_signedLEB128, read_unsignedLEB128 } from './encoding.js';
3
- import { TYPES } from './types.js';
3
+ import { TYPES, TYPE_NAMES } from './types.js';
4
4
  import { log } from './log.js';
5
5
 
6
6
  import process from 'node:process';
@@ -41,7 +41,7 @@ const compile = async (file, _funcs) => {
41
41
  let first = source.slice(0, source.indexOf('\n'));
42
42
 
43
43
  if (first.startsWith('export default')) {
44
- source = await (await import('file://' + file)).default();
44
+ source = await (await import('file://' + file)).default({ TYPES, TYPE_NAMES });
45
45
  first = source.slice(0, source.indexOf('\n'));
46
46
  }
47
47
 
@@ -155,11 +155,10 @@ const compile = async (file, _funcs) => {
155
155
  }
156
156
 
157
157
  if (n[0] === Opcodes.throw) {
158
- if (!bodyHasTopLevelThrow && depth === 0) log.warning('codegen', `top-level throw in ${x.name}`);
159
-
160
158
  x.usesTag = true;
159
+ let id;
161
160
  if (y[0] === Opcodes.i32_const && n[1] === 0) {
162
- const id = read_signedLEB128(y.slice(1));
161
+ id = read_signedLEB128(y.slice(1));
163
162
  y.splice(0, 10, 'throw', exceptions[id].constructor, exceptions[id].message);
164
163
 
165
164
  // remove throw inst
@@ -167,6 +166,8 @@ const compile = async (file, _funcs) => {
167
166
  } else {
168
167
  n[1]--;
169
168
  }
169
+
170
+ if (!bodyHasTopLevelThrow && depth === 0) log.warning('codegen', `top-level throw in ${x.name} (${exceptions[id].constructor}: ${exceptions[id].message})`);
170
171
  }
171
172
 
172
173
  if (n[0] === Opcodes.catch) {