porffor 0.48.6 → 0.48.7

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.
@@ -164,7 +164,8 @@ const funcRef = func => {
164
164
  [ Opcodes.local_get, 0 ], // new.target value
165
165
  Opcodes.i32_to_u,
166
166
  [ Opcodes.if, Blocktype.void ], // if value is non-zero
167
- ...internalThrow(wrapperFunc, 'TypeError', `${unhackName(func.name)} is not a constructor`), // throw type error
167
+ // ...internalThrow(wrapperFunc, 'TypeError', `${unhackName(func.name)} is not a constructor`), // throw type error
168
+ ...internalThrow(wrapperFunc, 'TypeError', `Function is not a constructor`), // throw type error
168
169
  [ Opcodes.end ]
169
170
  );
170
171
  }
@@ -1730,7 +1731,11 @@ const generateSequence = (scope, decl) => {
1730
1731
  };
1731
1732
 
1732
1733
  const generateChain = (scope, decl) => {
1733
- return generate(scope, decl.expression);
1734
+ scope.chainMembers = 0;
1735
+ const out = generate(scope, decl.expression);
1736
+ scope.chainMembers = null;
1737
+
1738
+ return out;
1734
1739
  };
1735
1740
 
1736
1741
  const ArrayUtil = {
@@ -1859,6 +1864,21 @@ const aliasPrimObjsBC = bc => {
1859
1864
  add(TYPES.string, TYPES.stringobject);
1860
1865
  };
1861
1866
 
1867
+ const typeIsIterable = wasm => [
1868
+ // array, set, string, bytestring, generator
1869
+ ...typeIsOneOf(wasm, [ TYPES.array, TYPES.set, TYPES.string, TYPES.bytestring, TYPES.__porffor_generator ]),
1870
+ // typed array
1871
+ ...wasm,
1872
+ ...number(TYPES.uint8array, Valtype.i32),
1873
+ [ Opcodes.i32_ge_s ],
1874
+ ...wasm,
1875
+ ...number(TYPES.float64array, Valtype.i32),
1876
+ [ Opcodes.i32_le_s ],
1877
+ [ Opcodes.i32_and ],
1878
+ [ Opcodes.i32_or ],
1879
+ [ Opcodes.i32_eqz ],
1880
+ ];
1881
+
1862
1882
  const createThisArg = (scope, decl) => {
1863
1883
  const name = decl.callee?.name;
1864
1884
  if (decl._new) {
@@ -2273,6 +2293,36 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2273
2293
  }
2274
2294
  }
2275
2295
 
2296
+ let args = decl.arguments.slice();
2297
+ if (args.at(-1)?.type === 'SpreadElement') {
2298
+ // hack: support spread element if last by doing essentially:
2299
+ // const foo = () => ...;
2300
+ // foo(a, b, ...c) -> _ = c; foo(a, b, _[0], _[1], ...)
2301
+ const arg = args.at(-1).argument;
2302
+ out.push(
2303
+ ...generate(scope, arg),
2304
+ [ Opcodes.local_set, localTmp(scope, '#spread') ],
2305
+ ...getNodeType(scope, arg),
2306
+ [ Opcodes.local_set, localTmp(scope, '#spread#type', Valtype.i32) ],
2307
+
2308
+ ...typeIsIterable([ [ Opcodes.local_get, localTmp(scope, '#spread#type', Valtype.i32) ] ]),
2309
+ [ Opcodes.if, Blocktype.void ],
2310
+ ...internalThrow(scope, 'TypeError', 'Cannot spread a non-iterable'),
2311
+ [ Opcodes.end ]
2312
+ );
2313
+
2314
+ args.pop();
2315
+ for (let i = 0; i < 8; i++) {
2316
+ args.push({
2317
+ type: 'MemberExpression',
2318
+ object: { type: 'Identifier', name: '#spread' },
2319
+ property: { type: 'Literal', value: i },
2320
+ computed: true,
2321
+ optional: false
2322
+ });
2323
+ }
2324
+ }
2325
+
2276
2326
  let idx;
2277
2327
  if (Object.hasOwn(funcIndex, name)) {
2278
2328
  idx = funcIndex[name];
@@ -2350,11 +2400,9 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2350
2400
  funcs.table = true;
2351
2401
  scope.table = true;
2352
2402
 
2353
- let args = decl.arguments;
2354
2403
  const wrapperArgc = Prefs.indirectWrapperArgc ?? 8;
2355
- if (args.length < wrapperArgc) {
2356
- args = args.concat(new Array(wrapperArgc - args.length).fill(DEFAULT_VALUE()));
2357
- }
2404
+ const underflow = wrapperArgc - args.length;
2405
+ for (let i = 0; i < underflow; i++) args.push(DEFAULT_VALUE());
2358
2406
 
2359
2407
  for (let i = 0; i < args.length; i++) {
2360
2408
  const arg = args[i];
@@ -2442,7 +2490,6 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2442
2490
  return internalThrow(scope, 'TypeError', `${unhackName(name)} is not a constructor`, true);
2443
2491
  }
2444
2492
 
2445
- let args = [...decl.arguments];
2446
2493
  const internalProtoFunc = func && func.internal && func.name.includes('_prototype_');
2447
2494
  if (!globalThis.precompile && internalProtoFunc && !decl._protoInternalCall) {
2448
2495
  // just function called, not as prototype, add this to start
@@ -2455,34 +2502,10 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2455
2502
  paramOffset += 4;
2456
2503
  }
2457
2504
 
2458
- if (args.at(-1)?.type === 'SpreadElement') {
2459
- // hack: support spread element if last by doing essentially:
2460
- // const foo = (a, b, c, d) => ...
2461
- // foo(a, b, ...c) -> _ = c; foo(a, b, _[0], _[1])
2462
- const arg = args.at(-1).argument;
2463
- out.push(
2464
- ...generate(scope, arg),
2465
- [ Opcodes.local_set, localTmp(scope, '#spread') ],
2466
- ...getNodeType(scope, arg),
2467
- [ Opcodes.local_set, localTmp(scope, '#spread#type', Valtype.i32) ]
2468
- );
2469
-
2470
- args.pop();
2471
- const leftover = paramCount - args.length;
2472
- for (let i = 0; i < leftover; i++) {
2473
- args.push({
2474
- type: 'MemberExpression',
2475
- object: { type: 'Identifier', name: '#spread' },
2476
- property: { type: 'Literal', value: i },
2477
- computed: true,
2478
- optional: false
2479
- });
2480
- }
2481
- }
2482
-
2483
2505
  if (func && args.length < paramCount) {
2484
2506
  // too little args, push undefineds
2485
- args = args.concat(new Array(paramCount - (func.hasRestArgument ? 1 : 0) - args.length).fill(DEFAULT_VALUE()));
2507
+ const underflow = paramCount - (func.hasRestArgument ? 1 : 0) - args.length;
2508
+ for (let i = 0; i < underflow; i++) args.push(DEFAULT_VALUE());
2486
2509
  }
2487
2510
 
2488
2511
  if (func && func.hasRestArgument) {
@@ -3126,7 +3149,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3126
3149
  let out = generateVarDstr(scope, 'const', tmpName, init, defaultValue, false);
3127
3150
 
3128
3151
  let i = 0;
3129
- const elements = [...pattern.elements];
3152
+ const elements = pattern.elements.slice();
3130
3153
  for (const e of elements) {
3131
3154
  switch (e?.type) {
3132
3155
  case 'RestElement': { // let [ ...foo ] = []
@@ -3187,24 +3210,11 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3187
3210
 
3188
3211
  out = out.concat([
3189
3212
  // check tmp is iterable
3190
- // array or string or bytestring
3191
- ...typeIsOneOf(getType(scope, tmpName), [ TYPES.array, TYPES.string, TYPES.bytestring, TYPES.__porffor_generator ]),
3192
- // typed array
3193
- ...getType(scope, tmpName),
3194
- ...number(TYPES.uint8array, Valtype.i32),
3195
- [ Opcodes.i32_ge_s ],
3196
- ...getType(scope, tmpName),
3197
- ...number(TYPES.float64array, Valtype.i32),
3198
- [ Opcodes.i32_le_s ],
3199
- [ Opcodes.i32_and ],
3200
- [ Opcodes.i32_or ],
3201
- [ Opcodes.i32_eqz ],
3213
+ ...typeIsIterable(getType(scope, tmpName)),
3202
3214
  [ Opcodes.if, Blocktype.void ],
3203
3215
  ...internalThrow(scope, 'TypeError', 'Cannot array destructure a non-iterable'),
3204
3216
  [ Opcodes.end ],
3205
-
3206
- ...decls
3207
- ]);
3217
+ ], decls);
3208
3218
 
3209
3219
  return out;
3210
3220
  }
@@ -3214,7 +3224,7 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3214
3224
  const tmpName = '#destructure' + uniqId();
3215
3225
  let out = generateVarDstr(scope, 'const', tmpName, init, defaultValue, false);
3216
3226
 
3217
- const properties = [...pattern.properties];
3227
+ const properties = pattern.properties.slice();
3218
3228
  const usedProps = [];
3219
3229
  for (const prop of properties) {
3220
3230
  if (prop.type == 'Property') { // let { foo } = {}
@@ -3277,10 +3287,8 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3277
3287
  [ Opcodes.i32_or ],
3278
3288
  [ Opcodes.if, Blocktype.void ],
3279
3289
  ...internalThrow(scope, 'TypeError', 'Cannot object destructure undefined or null'),
3280
- [ Opcodes.end ],
3281
-
3282
- ...decls
3283
- ]);
3290
+ [ Opcodes.end ]
3291
+ ], decls);
3284
3292
 
3285
3293
  return out;
3286
3294
  }
@@ -4125,18 +4133,7 @@ const generateForOf = (scope, decl) => {
4125
4133
  [ Opcodes.local_set, counter ],
4126
4134
 
4127
4135
  // check tmp is iterable
4128
- // array or string or bytestring
4129
- ...typeIsOneOf(iterType, [ TYPES.array, TYPES.set, TYPES.string, TYPES.bytestring, TYPES.__porffor_generator ]),
4130
- // typed array
4131
- ...iterType,
4132
- ...number(TYPES.uint8array, Valtype.i32),
4133
- [ Opcodes.i32_ge_s ],
4134
- ...iterType,
4135
- ...number(TYPES.float64array, Valtype.i32),
4136
- [ Opcodes.i32_le_s ],
4137
- [ Opcodes.i32_and ],
4138
- [ Opcodes.i32_or ],
4139
- [ Opcodes.i32_eqz ],
4136
+ ...typeIsIterable(iterType),
4140
4137
  [ Opcodes.if, Blocktype.void ],
4141
4138
  ...internalThrow(scope, 'TypeError', `Tried for..of on non-iterable type`),
4142
4139
  [ Opcodes.end ],
@@ -5284,7 +5281,7 @@ const countLength = (func, name = undefined) => {
5284
5281
  return count;
5285
5282
  };
5286
5283
 
5287
- const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) => {
5284
+ const generateMember = (scope, decl, _global, _name) => {
5288
5285
  let final = [], finalEnd, extraBC = {};
5289
5286
  let name = decl.object.name;
5290
5287
 
@@ -5302,6 +5299,8 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5302
5299
  const object = decl.object;
5303
5300
  const property = getProperty(decl);
5304
5301
 
5302
+ let chainCount = scope.chainMembers != null ? ++scope.chainMembers : 0;
5303
+
5305
5304
  // generate now so type is gotten correctly later (it gets cached)
5306
5305
  generate(scope, object);
5307
5306
 
@@ -5640,7 +5639,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5640
5639
  if (decl.optional) {
5641
5640
  out.unshift(
5642
5641
  [ Opcodes.block, valtypeBinary ],
5643
- ...(_objectWasm ? _objectWasm : generate(scope, object)),
5642
+ ...generate(scope, object),
5644
5643
  [ Opcodes.local_tee, localTmp(scope, '#member_obj') ],
5645
5644
  ...(scope.locals['#member_obj#type'] ? [
5646
5645
  ...getNodeType(scope, object),
@@ -5651,7 +5650,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5651
5650
  [ Opcodes.if, Blocktype.void ],
5652
5651
  ...setLastType(scope, TYPES.undefined),
5653
5652
  ...number(0),
5654
- [ Opcodes.br, 1 ],
5653
+ [ Opcodes.br, chainCount ],
5655
5654
  [ Opcodes.end ],
5656
5655
 
5657
5656
  ...generate(scope, property, false, '#member_prop'),
@@ -5663,7 +5662,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5663
5662
  );
5664
5663
  } else {
5665
5664
  out.unshift(
5666
- ...(_objectWasm ? _objectWasm : generate(scope, object)),
5665
+ ...generate(scope, object),
5667
5666
  [ Opcodes.local_set, localTmp(scope, '#member_obj') ],
5668
5667
  ...(scope.locals['#member_obj#type'] ? [
5669
5668
  ...getNodeType(scope, object),
@@ -5673,6 +5672,17 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5673
5672
  ...generate(scope, property, false, '#member_prop'),
5674
5673
  [ Opcodes.local_set, localTmp(scope, '#member_prop') ]
5675
5674
  );
5675
+
5676
+ // todo: maybe this just needs 1 block?
5677
+ if (chainCount > 0) {
5678
+ out.unshift(
5679
+ [ Opcodes.block, valtypeBinary ]
5680
+ );
5681
+
5682
+ out.push(
5683
+ [ Opcodes.end ]
5684
+ );
5685
+ }
5676
5686
  }
5677
5687
 
5678
5688
  if (final.length > 0) {
@@ -6153,7 +6163,9 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6153
6163
  typeUsed(func, TYPES.promise);
6154
6164
  }
6155
6165
 
6156
- wasm = wasm.concat(generate(func, body));
6166
+ const preface = wasm;
6167
+ wasm = generate(func, body);
6168
+ wasm.unshift(...preface);
6157
6169
 
6158
6170
  if (func.generator) {
6159
6171
  // make generator at the start
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.48.6",
4
+ "version": "0.48.7",
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.48.6';
3
+ globalThis.version = '0.48.7';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {