porffor 0.42.3 → 0.42.5

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.
@@ -121,20 +121,19 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
121
121
 
122
122
  const nameSection = Prefs.d ? customSection('name', encodeNames(funcs)) : [];
123
123
 
124
- const directFuncs = funcs.filter(x => !x.indirect);
124
+ const indirectFuncs = funcs.filter(x => x.indirect);
125
125
  const tableSection = !funcs.table ? [] : createSection(
126
126
  Section.table,
127
- encodeVector([ [ Reftype.funcref, 0x00, ...unsignedLEB128(directFuncs.length) ] ])
127
+ encodeVector([ [ Reftype.funcref, 0x00, ...unsignedLEB128(indirectFuncs.length) ] ])
128
128
  );
129
129
  time('table section');
130
130
 
131
- const emptyWrapperFunc = funcs.find(x => x.name === '#indirect#empty');
132
131
  const elementSection = !funcs.table ? [] : createSection(
133
132
  Section.element,
134
133
  encodeVector([ [
135
134
  0x00,
136
135
  Opcodes.i32_const, 0, Opcodes.end,
137
- ...encodeVector(directFuncs.map(x => unsignedLEB128((x.wrapperFunc ?? emptyWrapperFunc ?? x).asmIndex)))
136
+ ...encodeVector(indirectFuncs.map(x => unsignedLEB128(x.asmIndex)))
138
137
  ] ])
139
138
  );
140
139
  time('element section');
@@ -147,8 +146,8 @@ export default (funcs, globals, tags, pages, data, noTreeshake = false) => {
147
146
 
148
147
  // generate func lut data
149
148
  const bytes = [];
150
- for (let i = 0; i < directFuncs.length; i++) {
151
- const func = directFuncs[i];
149
+ for (let i = 0; i < indirectFuncs.length; i++) {
150
+ const func = indirectFuncs[i].wrapperOf;
152
151
  let name = func.name;
153
152
 
154
153
  // userland exposed .length
@@ -18,14 +18,14 @@ export default function({ builtinFuncs }, Prefs) {
18
18
  locals: [],
19
19
  returns: [ Valtype.i32 ],
20
20
  returnType: TYPES.object,
21
- wasm: (scope, { allocPage, makeString, generate, getNodeType, builtin, glbl }) => {
21
+ wasm: (scope, { allocPage, makeString, generate, getNodeType, builtin, funcRef, glbl }) => {
22
22
  if (globalThis.precompile) return [ [ 'get object', name ] ];
23
23
 
24
24
  // todo/perf: precompute bytes here instead of calling real funcs if we really care about perf later
25
25
 
26
26
  let ptr;
27
27
  if (existingFunc) {
28
- ptr = builtin(name, true);
28
+ ptr = funcRef(name)[0][1];
29
29
  } else {
30
30
  ptr = allocPage(scope, `builtin object: ${name}`);
31
31
  }
@@ -86,20 +86,11 @@ export default function({ builtinFuncs }, Prefs) {
86
86
  }
87
87
  };
88
88
 
89
- if (existingFunc) {
90
- this[name] = (scope, { builtin, funcRef }) => [
91
- [ Opcodes.call, builtin('#get_' + name) ],
92
- [ Opcodes.drop ],
93
- ...funcRef(name)
94
- ];
95
- this[name].type = TYPES.function;
96
- } else {
97
- this[name] = (scope, { builtin }) => [
98
- [ Opcodes.call, builtin('#get_' + name) ],
99
- Opcodes.i32_from_u
100
- ];
101
- this[name].type = TYPES.object;
102
- }
89
+ this[name] = (scope, { builtin }) => [
90
+ [ Opcodes.call, builtin('#get_' + name) ],
91
+ Opcodes.i32_from_u
92
+ ];
93
+ this[name].type = existingFunc ? TYPES.function : TYPES.object;
103
94
 
104
95
  for (const x in props) {
105
96
  const d = props[x];
@@ -79,7 +79,12 @@ const funcRef = func => {
79
79
  ],
80
80
  constr: true,
81
81
  internal: true,
82
- indirect: true
82
+ indirect: true,
83
+ wrapperOf: {
84
+ name: '',
85
+ jsLength: 0
86
+ },
87
+ indirectIndex: indirectFuncs.length
83
88
  };
84
89
 
85
90
  // check not being constructed
@@ -91,6 +96,8 @@ const funcRef = func => {
91
96
  [ Opcodes.end ]
92
97
  );
93
98
 
99
+ // have empty func as indirect funcs 0 and 1
100
+ indirectFuncs.push(emptyFunc);
94
101
  indirectFuncs.push(emptyFunc);
95
102
  }
96
103
 
@@ -142,7 +149,9 @@ const funcRef = func => {
142
149
  wasm,
143
150
  constr: true,
144
151
  internal: true,
145
- indirect: true
152
+ indirect: true,
153
+ wrapperOf: func,
154
+ indirectIndex: indirectFuncs.length
146
155
  };
147
156
 
148
157
  indirectFuncs.push(wrapperFunc);
@@ -163,7 +172,7 @@ const funcRef = func => {
163
172
  }
164
173
 
165
174
  return [
166
- [ Opcodes.const, func.index - importedFuncs.length ]
175
+ [ Opcodes.const, func.wrapperFunc.indirectIndex ]
167
176
  ];
168
177
  };
169
178
 
@@ -429,7 +438,7 @@ const generateIdent = (scope, decl) => {
429
438
  ];
430
439
  };
431
440
 
432
- return lookup(decl.name);
441
+ return lookup(decl.name, scope.identFailEarly);
433
442
  };
434
443
 
435
444
  const generateReturn = (scope, decl) => {
@@ -6022,20 +6031,8 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6022
6031
  generate() {
6023
6032
  if (func.wasm) return func.wasm;
6024
6033
 
6025
- let errorWasm = null;
6026
- if (decl.generator) {
6027
- errorWasm = todo(func, 'generator functions are not supported');
6028
- }
6029
-
6030
- if (errorWasm) {
6031
- return func.wasm = errorWasm.concat([
6032
- ...number(UNDEFINED),
6033
- ...number(TYPES.undefined, Valtype.i32)
6034
- ]);
6035
- }
6036
-
6037
6034
  // generating, stub _wasm
6038
- func.wasm = [];
6035
+ let wasm = func.wasm = [];
6039
6036
 
6040
6037
  let body = objectHack(decl.body);
6041
6038
  if (decl.type === 'ArrowFunctionExpression' && decl.expression) {
@@ -6046,24 +6043,72 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6046
6043
  };
6047
6044
  }
6048
6045
 
6049
- for (const x in defaultValues) {
6050
- prelude.push(
6051
- ...getType(func, x),
6046
+ func.identFailEarly = true;
6047
+ let localInd = args.length * 2;
6048
+ for (let i = 0; i < args.length; i++) {
6049
+ const { name, def, destr, type } = args[i];
6050
+
6051
+ func.localInd = i * 2;
6052
+ allocVar(func, name, false);
6053
+
6054
+ func.localInd = localInd;
6055
+ if (type) {
6056
+ const typeAnno = extractTypeAnnotation(type);
6057
+ addVarMetadata(func, name, false, typeAnno);
6058
+
6059
+ // automatically add throws if unexpected this type to builtins
6060
+ if (globalThis.precompile && i === 0 && func.name.includes('_prototype_') && [
6061
+ TYPES.date, TYPES.number, TYPES.promise, TYPES.symbol,
6062
+ TYPES.set, TYPES.map,
6063
+ TYPES.weakref, TYPES.weakset, TYPES.weakmap,
6064
+ TYPES.arraybuffer, TYPES.sharedarraybuffer, TYPES.dataview
6065
+ ].includes(typeAnno.type)) {
6066
+ let types = [ typeAnno.type ];
6067
+ if (typeAnno.type === TYPES.number) types.push(TYPES.numberobject);
6068
+ if (typeAnno.type === TYPES.string) types.push(TYPES.stringobject);
6069
+
6070
+ wasm.push(
6071
+ ...typeIsNotOneOf([ [ Opcodes.local_get, func.locals[name].idx + 1 ] ], types),
6072
+ [ Opcodes.if, Blocktype.void ],
6073
+ ...internalThrow(func, 'TypeError', `${unhackName(func.name)} expects 'this' to be a ${TYPE_NAMES[typeAnno.type]}`),
6074
+ [ Opcodes.end ]
6075
+ );
6076
+ }
6077
+
6078
+ // todo: if string, try converting to it to one
6079
+ }
6080
+
6081
+ if (def) wasm.push(
6082
+ ...getType(func, name),
6052
6083
  ...number(TYPES.undefined, Valtype.i32),
6053
6084
  [ Opcodes.i32_eq ],
6054
6085
  [ Opcodes.if, Blocktype.void ],
6055
- ...generate(func, defaultValues[x], false, x),
6056
- [ Opcodes.local_set, func.locals[x].idx ],
6086
+ ...generate(func, def, false, name),
6087
+ [ Opcodes.local_set, func.locals[name].idx ],
6057
6088
 
6058
- ...setType(func, x, getNodeType(func, defaultValues[x])),
6089
+ ...setType(func, name, getNodeType(func, def)),
6059
6090
  [ Opcodes.end ]
6060
6091
  );
6061
- }
6062
6092
 
6063
- for (const x in destructuredArgs) {
6064
- prelude.push(
6065
- ...generateVarDstr(func, 'var', destructuredArgs[x], { type: 'Identifier', name: x }, undefined, false)
6093
+ if (destr) wasm.push(
6094
+ ...generateVarDstr(func, 'var', destr, { type: 'Identifier', name }, undefined, false)
6066
6095
  );
6096
+
6097
+ localInd = func.localInd;
6098
+ }
6099
+
6100
+ func.identFailEarly = false;
6101
+
6102
+ if (globalThis.valtypeOverrides) {
6103
+ if (globalThis.valtypeOverrides.returns[name]) func.returns = globalThis.valtypeOverrides.returns[name];
6104
+ if (globalThis.valtypeOverrides.params[name]) {
6105
+ func.params = globalThis.valtypeOverrides.params[name];
6106
+
6107
+ const localsVals = Object.values(func.locals);
6108
+ for (let i = 0; i < func.params.length; i++) {
6109
+ localsVals[i].type = func.params[i];
6110
+ }
6111
+ }
6067
6112
  }
6068
6113
 
6069
6114
  if (decl.async && !decl.generator) {
@@ -6074,7 +6119,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6074
6119
  typeUsed(func, TYPES.promise);
6075
6120
  }
6076
6121
 
6077
- const wasm = prelude.concat(generate(func, body));
6122
+ wasm = wasm.concat(generate(func, body));
6078
6123
 
6079
6124
  if (func.async) {
6080
6125
  // make promise at the start
@@ -6177,17 +6222,12 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6177
6222
  }
6178
6223
  }
6179
6224
 
6180
- if (func.constr) {
6181
- allocVar(func, '#newtarget', false);
6182
- allocVar(func, '#this', false);
6183
- }
6225
+ const args = [];
6226
+ if (func.constr) args.push({ name: '#newtarget' }, { name: '#this' });
6184
6227
 
6185
- const prelude = [];
6186
- const defaultValues = {};
6187
- const destructuredArgs = {};
6188
6228
  let jsLength = 0;
6189
6229
  for (let i = 0; i < params.length; i++) {
6190
- let name;
6230
+ let name, def, destr;
6191
6231
  const x = params[i];
6192
6232
  switch (x.type) {
6193
6233
  case 'Identifier': {
@@ -6197,13 +6237,12 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6197
6237
  }
6198
6238
 
6199
6239
  case 'AssignmentPattern': {
6240
+ def = x.right;
6200
6241
  if (x.left.name) {
6201
6242
  name = x.left.name;
6202
- defaultValues[name] = x.right;
6203
6243
  } else {
6204
6244
  name = '#arg_dstr' + i;
6205
- destructuredArgs[name] = x.left;
6206
- defaultValues[name] = x.right;
6245
+ destr = x.left;
6207
6246
  }
6208
6247
 
6209
6248
  break;
@@ -6217,54 +6256,17 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6217
6256
 
6218
6257
  default:
6219
6258
  name = '#arg_dstr' + i;
6220
- destructuredArgs[name] = x;
6259
+ destr = x;
6221
6260
  jsLength++;
6222
6261
  break;
6223
6262
  }
6224
6263
 
6225
- allocVar(func, name, false);
6226
- if (typedInput && params[i].typeAnnotation) {
6227
- const typeAnno = extractTypeAnnotation(params[i]);
6228
- addVarMetadata(func, name, false, typeAnno);
6229
-
6230
- // automatically add throws if unexpected this type to builtins
6231
- if (globalThis.precompile && i === 0 && func.name.includes('_prototype_') && [
6232
- TYPES.date, TYPES.number, TYPES.promise, TYPES.symbol,
6233
- TYPES.set, TYPES.map,
6234
- TYPES.weakref, TYPES.weakset, TYPES.weakmap,
6235
- TYPES.arraybuffer, TYPES.sharedarraybuffer, TYPES.dataview
6236
- ].includes(typeAnno.type)) {
6237
- let types = [ typeAnno.type ];
6238
- if (typeAnno.type === TYPES.number) types.push(TYPES.numberobject);
6239
- if (typeAnno.type === TYPES.string) types.push(TYPES.stringobject);
6240
-
6241
- prelude.push(
6242
- ...typeIsNotOneOf([ [ Opcodes.local_get, func.locals[name].idx + 1 ] ], types),
6243
- [ Opcodes.if, Blocktype.void ],
6244
- ...internalThrow(func, 'TypeError', `${unhackName(func.name)} expects 'this' to be a ${TYPE_NAMES[typeAnno.type]}`),
6245
- [ Opcodes.end ]
6246
- );
6247
- }
6248
-
6249
- // todo: if string, try converting to it to one
6250
- }
6264
+ args.push({ name, def, destr, type: typedInput && params[i].typeAnnotation });
6251
6265
  }
6252
6266
 
6253
- func.params = Object.values(func.locals).map(x => x.type);
6267
+ func.params = new Array((params.length + (func.constr ? 2 : 0)) * 2).fill(0).map((_, i) => i % 2 ? Valtype.i32 : valtypeBinary);
6254
6268
  func.jsLength = jsLength;
6255
6269
 
6256
- if (globalThis.valtypeOverrides) {
6257
- if (globalThis.valtypeOverrides.returns[name]) func.returns = globalThis.valtypeOverrides.returns[name];
6258
- if (globalThis.valtypeOverrides.params[name]) {
6259
- func.params = globalThis.valtypeOverrides.params[name];
6260
-
6261
- const localsVals = Object.values(func.locals);
6262
- for (let i = 0; i < func.params.length; i++) {
6263
- localsVals[i].type = func.params[i];
6264
- }
6265
- }
6266
- }
6267
-
6268
6270
  // force generate for main
6269
6271
  if (name === 'main') func.generate();
6270
6272
 
package/compiler/wrap.js CHANGED
@@ -132,8 +132,7 @@ ${flags & 0b0001 ? ` get func idx: ${get}
132
132
  if (value < 0) {
133
133
  func = importedFuncs[value + importedFuncs.length];
134
134
  } else {
135
- value += importedFuncs.length;
136
- func = funcs.find(x => x.index === value);
135
+ func = funcs.find(x => x.wrapperFunc?.indirectIndex === value);
137
136
  }
138
137
 
139
138
  if (!func) return function () {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
4
- "version": "0.42.3+c5814d029",
4
+ "version": "0.42.5+a3af054f9",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runner/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.42.3+c5814d029';
3
+ globalThis.version = '0.42.5+a3af054f9';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {