porffor 0.60.10 → 0.60.12

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.
@@ -73,17 +73,6 @@ export const allocStr = (scope, str, bytestring) => {
73
73
  return allocBytes(scope, str, bytes);
74
74
  };
75
75
 
76
- const todo = (scope, msg, expectsValue = undefined) => {
77
- msg = `todo: ${msg}`;
78
-
79
- switch (Prefs.todoTime ?? 'runtime') {
80
- case 'compile':
81
- throw new Error(msg);
82
-
83
- case 'runtime':
84
- return internalThrow(scope, 'Error', msg, expectsValue);
85
- }
86
- };
87
76
 
88
77
  const isFuncType = type =>
89
78
  type === 'FunctionDeclaration' || type === 'FunctionExpression' || type === 'ArrowFunctionExpression' ||
@@ -107,7 +96,7 @@ const funcRef = func => {
107
96
 
108
97
  func.generate?.();
109
98
 
110
- const wrapperArgc = Prefs.indirectWrapperArgc ?? 10;
99
+ const wrapperArgc = Prefs.indirectWrapperArgc ?? 16;
111
100
  if (!func.wrapperFunc) {
112
101
  const locals = {
113
102
  ['#length']: { idx: 0, type: Valtype.i32 }
@@ -202,11 +191,11 @@ const funcRef = func => {
202
191
  wasm.push(
203
192
  [ Opcodes.local_get, array ],
204
193
  [ Opcodes.local_get, 5 + i * 2 ],
205
- [ Opcodes.f64_store, 0, offset ],
194
+ [ Opcodes.f64_store, 0, ...unsignedLEB128(offset) ],
206
195
 
207
196
  [ Opcodes.local_get, array ],
208
197
  [ Opcodes.local_get, 6 + i * 2 ],
209
- [ Opcodes.i32_store8, 0, offset + 8 ],
198
+ [ Opcodes.i32_store8, 0, ...unsignedLEB128(offset + 8) ],
210
199
  );
211
200
  offset += 9;
212
201
  }
@@ -443,7 +432,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
443
432
  return cacheAst(decl, generateTaggedTemplate(scope, decl, global, name, valueUnused));
444
433
 
445
434
  case 'ExportNamedDeclaration':
446
- if (!decl.declaration) return todo(scope, 'unsupported export declaration', true);
435
+ if (!decl.declaration) return internalThrow(scope, 'Error', 'porffor: unsupported export declaration', true);
447
436
 
448
437
  const funcsBefore = funcs.map(x => x.name);
449
438
  generate(scope, decl.declaration);
@@ -469,6 +458,12 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
469
458
  if (Prefs.d) log.warning('codegen', 'with is not supported, treating as expression');
470
459
  return cacheAst(decl, generate(scope, decl.body));
471
460
 
461
+ case 'PrivateIdentifier':
462
+ return cacheAst(decl, generate(scope, {
463
+ type: 'Literal',
464
+ value: privateIDName(decl.name)
465
+ }));
466
+
472
467
  case 'TSEnumDeclaration':
473
468
  return cacheAst(decl, generateEnum(scope, decl));
474
469
 
@@ -479,7 +474,7 @@ const generate = (scope, decl, global = false, name = undefined, valueUnused = f
479
474
  return cacheAst(decl, [ number(UNDEFINED) ]);
480
475
  }
481
476
 
482
- return cacheAst(decl, todo(scope, `no generation for ${decl.type}!`, true));
477
+ return cacheAst(decl, internalThrow(scope, 'Error', `porffor: no generation for ${decl.type}`, true));
483
478
  }
484
479
  };
485
480
 
@@ -905,8 +900,6 @@ const performLogicOp = (scope, op, left, right, leftType, rightType) => {
905
900
  '??': nullish
906
901
  };
907
902
 
908
- if (!checks[op]) return todo(scope, `logic operator ${op} not implemented yet`, true);
909
-
910
903
  // generic structure for {a} OP {b}
911
904
  // _ = {a}; if (OP_CHECK) {b} else _
912
905
 
@@ -1286,7 +1279,6 @@ const performOp = (scope, op, left, right, leftType, rightType) => {
1286
1279
 
1287
1280
  // some complex ops are implemented in funcs
1288
1281
  if (typeof ops === 'function') return finalize(asmFuncToAsm(scope, ops, { left, right }));
1289
- if (!ops) return todo(scope, `operator ${op} not implemented yet`, true);
1290
1282
  if (!Array.isArray(ops)) ops = [ ops ];
1291
1283
  ops = [ ops ];
1292
1284
 
@@ -1950,6 +1942,13 @@ const getNodeType = (scope, node) => {
1950
1942
  return getNodeType(scope, node.body);
1951
1943
  }
1952
1944
 
1945
+ if (node.type === 'PrivateIdentifier') {
1946
+ return getNodeType(scope, {
1947
+ type: 'Literal',
1948
+ value: privateIDName(node.name)
1949
+ });
1950
+ }
1951
+
1953
1952
  if (node.type.endsWith('Statement') || node.type.endsWith('Declaration')) {
1954
1953
  return TYPES.undefined;
1955
1954
  }
@@ -2021,8 +2020,6 @@ const generateLiteral = (scope, decl, global, name) => {
2021
2020
  ]
2022
2021
  });
2023
2022
  }
2024
-
2025
- return todo(scope, `cannot generate literal of type ${typeof decl.value}`, true);
2026
2023
  };
2027
2024
 
2028
2025
  const generateExp = (scope, decl) => {
@@ -2561,7 +2558,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2561
2558
  funcs.table = true;
2562
2559
  scope.table = true;
2563
2560
 
2564
- const wrapperArgc = Prefs.indirectWrapperArgc ?? 10;
2561
+ const wrapperArgc = Prefs.indirectWrapperArgc ?? 16;
2565
2562
  const underflow = wrapperArgc - args.length;
2566
2563
  for (let i = 0; i < underflow; i++) args.push(DEFAULT_VALUE());
2567
2564
  if (args.length > wrapperArgc) args = args.slice(0, wrapperArgc);
@@ -2629,14 +2626,14 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2629
2626
 
2630
2627
  ...typeSwitch(scope, getNodeType(scope, callee), {
2631
2628
  [TYPES.function]: () => [
2632
- number(10 - underflow, Valtype.i32),
2629
+ number(wrapperArgc - underflow, Valtype.i32),
2633
2630
  ...forceDuoValtype(scope, newTargetWasm, Valtype.f64),
2634
2631
  ...forceDuoValtype(scope, thisWasm, Valtype.f64),
2635
2632
  ...out,
2636
2633
 
2637
2634
  [ Opcodes.local_get, calleeLocal ],
2638
2635
  Opcodes.i32_to_u,
2639
- [ Opcodes.call_indirect, args.length + 2, 0, ],
2636
+ [ Opcodes.call_indirect, args.length + 2, 0 ],
2640
2637
  ...setLastType(scope)
2641
2638
  ],
2642
2639
 
@@ -3525,8 +3522,6 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3525
3522
  ]
3526
3523
  }, undefined, global)
3527
3524
  );
3528
- } else {
3529
- return todo(scope, `${prop.type} is not supported in object patterns`);
3530
3525
  }
3531
3526
  }
3532
3527
 
@@ -3567,8 +3562,6 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
3567
3562
  }),
3568
3563
  [ Opcodes.drop ]
3569
3564
  ];
3570
-
3571
- return todo(scope, `variable declarators of type ${pattern.type} are not supported yet`);
3572
3565
  }
3573
3566
 
3574
3567
  const generateVar = (scope, decl) => {
@@ -3637,7 +3630,7 @@ const memberTmpNames = scope => {
3637
3630
  };
3638
3631
 
3639
3632
  // todo: generate this array procedurally
3640
- const builtinPrototypeGets = ['size', 'description', 'byteLength', 'byteOffset', 'buffer', 'detached', 'resizable', 'growable', 'maxByteLength', 'name', 'message', 'constructor', 'source', 'flags', 'global', 'ignoreCase', 'multiline', 'dotAll', 'unicode', 'sticky', 'hasIndices', 'unicodeSets'];
3633
+ const builtinPrototypeGets = ['size', 'description', 'byteLength', 'byteOffset', 'buffer', 'detached', 'resizable', 'growable', 'maxByteLength', 'name', 'message', 'constructor', 'source', 'flags', 'global', 'ignoreCase', 'multiline', 'dotAll', 'unicode', 'sticky', 'hasIndices', 'unicodeSets', 'lastIndex'];
3641
3634
 
3642
3635
  const ctHash = prop => {
3643
3636
  if (!Prefs.ctHash || !prop ||
@@ -4437,8 +4430,6 @@ const generateUnary = (scope, decl) => {
4437
4430
  return out;
4438
4431
  }
4439
4432
  }
4440
-
4441
- return todo(scope, `unary operator ${decl.operator} not implemented yet`, true);
4442
4433
  };
4443
4434
 
4444
4435
  const generateUpdate = (scope, decl, _global, _name, valueUnused = false) => {
@@ -5564,7 +5555,8 @@ const generateMeta = (scope, decl) => {
5564
5555
  return [ number(UNDEFINED) ];
5565
5556
  }
5566
5557
 
5567
- return todo(scope, `meta property object ${decl.meta.name} is not supported yet`, true);
5558
+ // todo: import.meta
5559
+ return internalThrow(scope, 'Error', `porffor: meta property ${decl.meta.name}.${decl.property.name} is not supported yet`, true);
5568
5560
  };
5569
5561
 
5570
5562
  const compileBytes = (val, itemType) => {
@@ -57,7 +57,7 @@ const compile = async (file, _funcs) => {
57
57
  first = source.slice(0, source.indexOf('\n'));
58
58
  }
59
59
 
60
- let args = ['--module', '--todo-time=compile', '--truthy=no_nan_negative', '--no-rm-unused-types', '--fast-length', '--parse-types', '--opt-types', '--no-passive-data', '--active-data', '--no-treeshake-wasm-imports', '--no-coctc'];
60
+ let args = ['--module', '--truthy=no_nan_negative', '--no-rm-unused-types', '--fast-length', '--parse-types', '--opt-types', '--no-passive-data', '--active-data', '--no-treeshake-wasm-imports', '--no-coctc'];
61
61
  if (first.startsWith('// @porf')) {
62
62
  args = first.slice('// @porf '.length).split(' ').concat(args);
63
63
  }
@@ -88,6 +88,7 @@ const compile = async (file, _funcs) => {
88
88
  const body = globalThis.funcBodies[x.name];
89
89
  const bodyHasTopLevelThrow = body?.body && body.body.some(x => x.type === 'ThrowStatement');
90
90
 
91
+ if (x.name === '_eval') x.name = 'eval';
91
92
  if (x.data) {
92
93
  x.data = x.data.reduce((acc, x) => { acc[data[x].page] = data[x].bytes; return acc; }, {});
93
94
  }
@@ -278,7 +279,7 @@ ${funcs.map(x => {
278
279
  const name = x.name.includes('#') ? `['${x.name}']` : `.${x.name}`;
279
280
 
280
281
  const returnTypes = [...(x.returnTypes ?? [])].filter(x => ![ TYPES.undefined, TYPES.number, TYPES.boolean, TYPES.function ].includes(x));
281
- return `x${name} = {
282
+ return `x${name}={
282
283
  wasm:${rewriteWasm(x.wasm)},
283
284
  params:${JSON.stringify(x.params)},typedParams:1,returns:${JSON.stringify(x.returns)},${x.returnType != null ? `returnType:${JSON.stringify(x.returnType)},` : ''}${returnTypes.length > 0 ? `returnTypes:${JSON.stringify(returnTypes)},` : ''}jsLength:${x.jsLength},
284
285
  locals:${JSON.stringify(locals.slice(x.params.length).map(x => x[1].type))},localNames:${JSON.stringify(locals.map(x => x[0]))},
package/deno.lock ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "version": "5",
3
+ "redirects": {
4
+ "https://esm.sh/acorn": "https://esm.sh/acorn@8.14.0"
5
+ },
6
+ "remote": {
7
+ "https://esm.sh/acorn@8.14.0": "b5a42b450cfd514709a3f855bfb1d886104d9c72a01b7d111e6e26c86e5f41e2",
8
+ "https://esm.sh/acorn@8.14.0/denonext/acorn.mjs": "669c981ded732a02351d5e6b1f6d5641d71a8d5165c0fed93be7f40c676be0b8"
9
+ },
10
+ "workspace": {
11
+ "packageJson": {
12
+ "dependencies": [
13
+ "npm:acorn@^8.15.0",
14
+ "npm:node-repl-polyfill@~0.1.2"
15
+ ]
16
+ }
17
+ }
18
+ }
package/foo.js CHANGED
@@ -1,34 +1,40 @@
1
- // benchmark.js
2
- const ITER = 50_000_000; // 50 million iterations
3
- const key = "a";
1
+ // Function.prototype;
2
+ // // Object.defineProperty(Function.prototype, "prop", {
3
+ // // value: 1001,
4
+ // // writable: false,
5
+ // // enumerable: false,
6
+ // // configurable: true
7
+ // // });
8
+ // var funObj = function() {};
9
+ // // console.log(Function.prototype.hasOwnProperty);
10
+ // // console.log(Function.prototype.hasOwnProperty === Object.prototype.hasOwnProperty);
11
+ // // console.log(Object.getPrototypeOf(funObj) === Function.prototype);
12
+ // // console.log(Object.getPrototypeOf(Object.getPrototypeOf(funObj)) === Object.prototype);
13
+ // console.log(funObj.hasOwnProperty);
4
14
 
5
- // Create a null-prototype object
6
- const o = Object.create(null);
7
- o[key] = 123;
15
+ // // console.log(funObj.hasOwnProperty("prop"), false, 'funObj.hasOwnProperty("prop")');
8
16
 
9
- // --- Benchmark "in" ---
10
- const t1 = Date.now();
11
- for (let i = 0; i < ITER; i++) {
12
- if (key in o) {
13
- // noop
14
- }
15
- }
16
- console.log(`in: ${Date.now() - t1}ms`);
17
+ var FACTORY = function() {
18
+ this.aproperty = 1;
19
+ };
17
20
 
18
- // --- Benchmark Object.hasOwn ---
19
- const t2 = Date.now();
20
- for (let i = 0; i < ITER; i++) {
21
- if (Object.hasOwn(o, key)) {
22
- // noop
23
- }
24
- }
25
- console.log(`Object.hasOwn: ${Date.now() - t2}ms`);
21
+ var instance = new FACTORY;
26
22
 
27
- // --- Benchmark o[k] ---
28
- const t3 = Date.now();
29
- for (let i = 0; i < ITER; i++) {
30
- if (o[key] !== undefined) {
31
- // noop
32
- }
33
- }
34
- console.log(`o[k]: ${Date.now() - t3}ms`);
23
+ console.log(instance.__proto__ == FACTORY.prototype);
24
+ console.log(instance.__proto__.__proto__ == Object.prototype);
25
+ console.log(instance.hasOwnProperty);
26
+ console.log(instance.__proto__.hasOwnProperty);
27
+ console.log(instance.__proto__.__proto__.hasOwnProperty);
28
+ console.log()
29
+
30
+ console.log(
31
+ typeof Object.prototype.hasOwnProperty,
32
+ "function",
33
+ 'The value of `typeof Object.prototype.hasOwnProperty` is expected to be "function"'
34
+ );
35
+
36
+ console.log(
37
+ typeof instance.hasOwnProperty,
38
+ "function",
39
+ 'The value of `typeof instance.hasOwnProperty` is expected to be "function"'
40
+ );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "An ahead-of-time JavaScript compiler",
4
- "version": "0.60.10",
4
+ "version": "0.60.12",
5
5
  "author": "Oliver Medhurst <honk@goose.icu>",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runtime/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.60.10';
3
+ globalThis.version = '0.60.12';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {