porffor 0.55.28 → 0.55.32

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.
@@ -3,7 +3,7 @@ import { number, ieee754_binary64, signedLEB128, unsignedLEB128, encodeVector, r
3
3
  import { operatorOpcode } from './expression.js';
4
4
  import { BuiltinFuncs, BuiltinVars, importedFuncs, NULL, UNDEFINED } from './builtins.js';
5
5
  import { PrototypeFuncs } from './prototype.js';
6
- import { TYPES, TYPE_FLAGS, TYPE_NAMES, typeHasFlag } from './types.js';
6
+ import { TYPES, TYPE_FLAGS, TYPE_NAMES } from './types.js';
7
7
  import * as Rhemyn from '../rhemyn/compile.js';
8
8
  import parse from './parse.js';
9
9
  import { log } from './log.js';
@@ -1505,7 +1505,18 @@ const setType = (scope, name, type, noInfer = false) => {
1505
1505
  };
1506
1506
 
1507
1507
  const getLastType = scope => {
1508
- if (!scope.locals['#last_type']) return [ number(TYPES.number, Valtype.i32) ];
1508
+ if (!scope.locals['#last_type']) return [
1509
+ [ null, () => {
1510
+ if (scope.locals['#last_type']) {
1511
+ scope.gotLastType = true;
1512
+ return [
1513
+ [ Opcodes.local_get, localTmp(scope, '#last_type', Valtype.i32) ]
1514
+ ];
1515
+ }
1516
+
1517
+ return [ number(TYPES.number, Valtype.i32) ];
1518
+ } ]
1519
+ ];
1509
1520
 
1510
1521
  scope.gotLastType = true;
1511
1522
  return [
@@ -1664,7 +1675,7 @@ const getNodeType = (scope, node) => {
1664
1675
 
1665
1676
  const objectKnownType = knownType(scope, getNodeType(scope, node.object));
1666
1677
  if (objectKnownType != null) {
1667
- if (name === 'length' && typeHasFlag(objectKnownType, TYPE_FLAGS.length)) return TYPES.number;
1678
+ if (name === 'length' && (objectKnownType & TYPE_FLAGS.length) !== 0) return TYPES.number;
1668
1679
 
1669
1680
  if (node.computed) {
1670
1681
  if (objectKnownType === TYPES.string) return TYPES.string;
@@ -3653,7 +3664,7 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
3653
3664
 
3654
3665
  const type = getNodeType(scope, decl.left.object);
3655
3666
  const known = knownType(scope, type);
3656
- if (known != null && typeHasFlag(known, TYPE_FLAGS.length)) return [
3667
+ if (known != null && (known & TYPE_FLAGS.length) !== 0) return [
3657
3668
  ...out,
3658
3669
  ...optional([ Opcodes.local_tee, pointerTmp ]),
3659
3670
 
@@ -5678,7 +5689,7 @@ const generateMember = (scope, decl, _global, _name) => {
5678
5689
 
5679
5690
  const type = getNodeType(scope, object);
5680
5691
  const known = knownType(scope, type);
5681
- if (known != null && typeHasFlag(known, TYPE_FLAGS.length)) return [
5692
+ if (known != null && (known & TYPE_FLAGS.length) !== 0) return [
5682
5693
  ...out,
5683
5694
 
5684
5695
  [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
@@ -6655,6 +6666,7 @@ const generateFunc = (scope, decl, forceNoExpr = false) => {
6655
6666
  if (typedInput && decl.returnType) {
6656
6667
  const { type } = extractTypeAnnotation(decl.returnType);
6657
6668
  if (type != null) {
6669
+ typeUsed(func, type);
6658
6670
  func.returnType = type;
6659
6671
  func.returns = func.returnType === TYPES.undefined && !func.async && !func.generator ? [] : [ valtypeBinary ];
6660
6672
  }
package/compiler/index.js CHANGED
@@ -243,15 +243,12 @@ export default (code, module = undefined) => {
243
243
  if (target === 'native') {
244
244
  outFile ??= Prefs.native ? './porffor_tmp' : file.split('/').at(-1).split('.')[0];
245
245
 
246
- let compiler = Prefs.compiler ?? 'clang';
246
+ const compiler = (Prefs.compiler ?? 'clang').split(' ');
247
247
  const cO = Prefs._cO ?? 'O3';
248
248
 
249
- if (compiler === 'zig') compiler = [ 'zig', 'cc' ];
250
- else compiler = [ compiler ];
251
-
252
249
  const tmpfile = 'porffor_tmp.c';
253
250
  const args = [ ...compiler, tmpfile, '-o', outFile ?? (process.platform === 'win32' ? 'out.exe' : 'out'), '-' + cO ];
254
- if (compiler.includes('clang')) args.push('-flto=thin', '-march=native', '-ffast-math', '-fno-exceptions', '-fno-ident', '-fno-asynchronous-unwind-tables', '-ffunction-sections', '-fdata-sections');
251
+ if (compiler.includes('clang')) args.push('-lm', '-flto=thin', '-march=native', '-ffast-math', '-fno-exceptions', '-fno-ident', '-fno-asynchronous-unwind-tables', '-ffunction-sections', '-fdata-sections');
255
252
  if (Prefs.s) args.push('-s');
256
253
 
257
254
  if (logProgress) progressStart('compiling Wasm to C...');
package/compiler/types.js CHANGED
@@ -30,10 +30,7 @@ export const TYPE_NAMES = {
30
30
  [TYPES.bigint]: 'BigInt'
31
31
  };
32
32
 
33
- export const typeHasFlag = (type, flag) => (type & flag) !== 0;
34
-
35
- export const INTERNAL_TYPE_BASE = 0x10;
36
- let internalTypeIndex = INTERNAL_TYPE_BASE;
33
+ let internalTypeIndex = TYPES.object + 1;
37
34
  const registerInternalType = (name, flags = [], overrideType = undefined) => {
38
35
  let n = overrideType ?? internalTypeIndex++;
39
36
 
@@ -72,12 +69,13 @@ registerInternalType('BooleanObject');
72
69
  registerInternalType('NumberObject');
73
70
  registerInternalType('StringObject');
74
71
 
75
- for (const x of [ '', 'Aggregate', 'Type', 'Reference', 'Syntax', 'Range', 'Eval', 'URI', 'Test262', 'Todo' ])
76
- registerInternalType(`${x}Error`);
77
-
78
72
  registerInternalType('__Porffor_Generator');
79
73
  registerInternalType('__Porffor_AsyncGenerator');
80
74
 
75
+ // from here, remapped object types only
76
+ for (const x of [ '', 'Aggregate', 'Type', 'Reference', 'Syntax', 'Range', 'Eval', 'URI', 'Test262' ])
77
+ registerInternalType(`${x}Error`);
78
+
81
79
  if (Prefs.largestTypes) {
82
80
  const typeKeys = Object.keys(TYPES);
83
81
  const typeVals = Object.values(TYPES);
@@ -88,11 +86,11 @@ if (Prefs.largestTypes) {
88
86
  return [ val, key ];
89
87
  };
90
88
 
91
- const unflag = val => val & 0b00111111;
92
-
93
89
  const logType = (label, val, key) => console.log(`${label} ${key} - ${val} (0x${val.toString(16)}, 0b${val.toString(2).padStart(8, '0')})`);
94
90
 
95
- logType(`largest type: `, ...largestType(typeVals.map(unflag), typeKeys));
91
+ const largestUnflagged = largestType(typeVals.map(x => x & 0b00111111), typeKeys);
92
+ logType(`largest type: `, ...largestUnflagged);
96
93
  logType(`largest type w/ flags:`, ...largestType(typeVals, typeKeys));
94
+ console.log('types left:', 0b00111111 - largestUnflagged[0]);
97
95
  console.log();
98
96
  }
package/compiler/wrap.js CHANGED
@@ -311,8 +311,7 @@ ${flags & 0b0001 ? ` get func idx: ${get}
311
311
  case TYPES.rangeerror:
312
312
  case TYPES.evalerror:
313
313
  case TYPES.urierror:
314
- case TYPES.test262error:
315
- case TYPES.todoerror: {
314
+ case TYPES.test262error: {
316
315
  const obj = porfToJSValue({ memory, funcs, pages }, value, TYPES.object);
317
316
  const err = new (globalThis[TYPE_NAMES[type]] ?? Error)(obj.message);
318
317
 
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "An ahead-of-time JavaScript compiler",
4
- "version": "0.55.28",
4
+ "version": "0.55.32",
5
5
  "author": "Oliver Medhurst <honk@goose.icu>",
6
6
  "license": "MIT",
7
7
  "scripts": {},
8
8
  "dependencies": {
9
9
  "acorn": "^8.14.0",
10
- "node-repl-polyfill": "^0.1.1"
10
+ "node-repl-polyfill": "github:CanadaHonk/node-repl-polyfill"
11
11
  },
12
12
  "optionalDependencies": {
13
13
  "@babel/parser": "^7.24.4",
package/r.cjs CHANGED
@@ -1,8 +1,257 @@
1
- function foo() {
2
- return this;
1
+ Foo.prototype.baz = function baz() {};
2
+
3
+ function Foo() {
4
+ this.bar = 1;
3
5
  }
4
6
 
5
- console.log(foo());
7
+ Foo.prototype.bar = function bar() {};
8
+
9
+
10
+
11
+ // var EQUAL = 1;
12
+ // var NOT_EQUAL = -1;
13
+ // var UNKNOWN = 0;
14
+
15
+ // function setCache(cache, left, right, result) {
16
+ // var otherCache;
17
+
18
+ // otherCache = cache.get(left);
19
+ // if (!otherCache) cache.set(left, otherCache = new Map());
20
+ // otherCache.set(right, result);
21
+
22
+ // otherCache = cache.get(right);
23
+ // if (!otherCache) cache.set(right, otherCache = new Map());
24
+ // otherCache.set(left, result);
25
+ // }
26
+
27
+ // function getCache(cache, left, right) {
28
+ // var otherCache;
29
+ // var result;
30
+
31
+ // otherCache = cache.get(left);
32
+ // result = otherCache && otherCache.get(right);
33
+ // if (result) return result;
34
+
35
+ // otherCache = cache.get(right);
36
+ // result = otherCache && otherCache.get(left);
37
+ // if (result) return result;
38
+
39
+ // return UNKNOWN;
40
+ // }
41
+
42
+ // function cacheComparison(a, b, compare, cache) {
43
+ // var result = compare(a, b, cache);
44
+ // if (cache && (result === EQUAL || result === NOT_EQUAL)) {
45
+ // setCache(cache, a, b, result);
46
+ // }
47
+ // return result;
48
+ // }
49
+
50
+ // function isBoxed(value) {
51
+ // return value instanceof String
52
+ // || value instanceof Number
53
+ // || value instanceof Boolean
54
+ // || value instanceof Symbol;
55
+ // }
56
+
57
+ // function fail() {
58
+ // return NOT_EQUAL;
59
+ // }
60
+
61
+ // function compareIf(a, b, test, compare, cache) {
62
+ // return !test(a)
63
+ // ? !test(b) ? UNKNOWN : NOT_EQUAL
64
+ // : !test(b) ? NOT_EQUAL : cacheComparison(a, b, compare, cache);
65
+ // }
66
+
67
+ // function compareEquality(a, b, cache) {
68
+ // return compareIf(a, b, isOptional, compareOptionality)
69
+ // || compareIf(a, b, isPrimitiveEquatable, comparePrimitiveEquality)
70
+ // || compareIf(a, b, isObjectEquatable, compareObjectEquality, cache)
71
+ // || NOT_EQUAL;
72
+ // }
73
+
74
+ // function tryCompareStrictEquality(a, b) {
75
+ // return a === b ? EQUAL : UNKNOWN;
76
+ // }
77
+
78
+ // function tryCompareTypeOfEquality(a, b) {
79
+ // return typeof a !== typeof b ? NOT_EQUAL : UNKNOWN;
80
+ // }
81
+
82
+ // function tryCompareToStringTagEquality(a, b) {
83
+ // var aTag = Symbol.toStringTag in a ? a[Symbol.toStringTag] : undefined;
84
+ // var bTag = Symbol.toStringTag in b ? b[Symbol.toStringTag] : undefined;
85
+ // return aTag !== bTag ? NOT_EQUAL : UNKNOWN;
86
+ // }
87
+
88
+ // function isOptional(value) {
89
+ // return value === undefined
90
+ // || value === null;
91
+ // }
92
+
93
+ // function compareOptionality(a, b) {
94
+ // return tryCompareStrictEquality(a, b)
95
+ // || NOT_EQUAL;
96
+ // }
97
+
98
+ // function isPrimitiveEquatable(value) {
99
+ // switch (typeof value) {
100
+ // case 'string':
101
+ // case 'number':
102
+ // case 'boolean':
103
+ // case 'symbol':
104
+ // return true;
105
+ // default:
106
+ // return isBoxed(value);
107
+ // }
108
+ // }
109
+
110
+ // function comparePrimitiveEquality(a, b) {
111
+ // if (isBoxed(a)) a = a.valueOf();
112
+ // if (isBoxed(b)) b = b.valueOf();
113
+
114
+ // return tryCompareStrictEquality(a, b)
115
+ // || tryCompareTypeOfEquality(a, b)
116
+ // || compareIf(a, b, isNaNEquatable, compareNaNEquality)
117
+ // || NOT_EQUAL;
118
+ // }
119
+
120
+ // function isNaNEquatable(value) {
121
+ // return typeof value === 'number';
122
+ // }
123
+
124
+ // function compareNaNEquality(a, b) {
125
+ // return isNaN(a) && isNaN(b) ? EQUAL : NOT_EQUAL;
126
+ // }
127
+
128
+ // function isObjectEquatable(value) {
129
+ // return typeof value === 'object';
130
+ // }
131
+
132
+ // function compareObjectEquality(a, b, cache) {
133
+ // if (!cache) cache = new Map();
134
+
135
+ // return getCache(cache, a, b)
136
+ // || setCache(cache, a, b, EQUAL) // consider equal for now
137
+ // || cacheComparison(a, b, tryCompareStrictEquality, cache)
138
+ // || cacheComparison(a, b, tryCompareToStringTagEquality, cache)
139
+ // || compareIf(a, b, isValueOfEquatable, compareValueOfEquality)
140
+ // || compareIf(a, b, isToStringEquatable, compareToStringEquality)
141
+ // || compareIf(a, b, isArrayLikeEquatable, compareArrayLikeEquality, cache)
142
+ // || compareIf(a, b, isStructurallyEquatable, compareStructuralEquality, cache)
143
+ // || compareIf(a, b, isIterableEquatable, compareIterableEquality, cache)
144
+ // || cacheComparison(a, b, fail, cache);
145
+ // }
146
+
147
+ // function isValueOfEquatable(value) {
148
+ // return value instanceof Date;
149
+ // }
150
+
151
+ // function compareValueOfEquality(a, b) {
152
+ // return compareIf(a.valueOf(), b.valueOf(), isPrimitiveEquatable, comparePrimitiveEquality)
153
+ // || NOT_EQUAL;
154
+ // }
155
+
156
+ // function isToStringEquatable(value) {
157
+ // return value instanceof RegExp;
158
+ // }
159
+
160
+ // function compareToStringEquality(a, b) {
161
+ // return compareIf(a.toString(), b.toString(), isPrimitiveEquatable, comparePrimitiveEquality)
162
+ // || NOT_EQUAL;
163
+ // }
164
+
165
+ // function isArrayLikeEquatable(value) {
166
+ // return Array.isArray(value)
167
+ // || value instanceof Uint8Array
168
+ // || value instanceof Uint8ClampedArray
169
+ // || value instanceof Uint16Array
170
+ // || value instanceof Uint32Array
171
+ // || value instanceof Int8Array
172
+ // || value instanceof Int16Array
173
+ // || value instanceof Int32Array
174
+ // || value instanceof Float32Array
175
+ // || value instanceof Float64Array;
176
+ // }
177
+
178
+ // function compareArrayLikeEquality(a, b, cache) {
179
+ // if (a.length !== b.length) return NOT_EQUAL;
180
+ // for (var i = 0; i < a.length; i++) {
181
+ // if (compareEquality(a[i], b[i], cache) === NOT_EQUAL) {
182
+ // return NOT_EQUAL;
183
+ // }
184
+ // }
185
+ // return EQUAL;
186
+ // }
187
+
188
+ // function isStructurallyEquatable(value) {
189
+ // return !(value instanceof Promise // only comparable by reference
190
+ // || value instanceof WeakMap // only comparable by reference
191
+ // || value instanceof WeakSet // only comparable by reference
192
+ // || value instanceof Map // comparable via @@iterator
193
+ // || value instanceof Set); // comparable via @@iterator
194
+ // }
195
+
196
+ // function compareStructuralEquality(a, b, cache) {
197
+ // var aKeys = [];
198
+ // for (var key in a) aKeys.push(key);
199
+
200
+ // var bKeys = [];
201
+ // for (var key in b) bKeys.push(key);
202
+
203
+ // if (aKeys.length !== bKeys.length) {
204
+ // return NOT_EQUAL;
205
+ // }
206
+
207
+ // aKeys.sort();
208
+ // bKeys.sort();
209
+
210
+ // for (var i = 0; i < aKeys.length; i++) {
211
+ // var aKey = aKeys[i];
212
+ // var bKey = bKeys[i];
213
+ // if (compareEquality(aKey, bKey, cache) === NOT_EQUAL) {
214
+ // return NOT_EQUAL;
215
+ // }
216
+ // if (compareEquality(a[aKey], b[bKey], cache) === NOT_EQUAL) {
217
+ // return NOT_EQUAL;
218
+ // }
219
+ // }
220
+
221
+ // return EQUAL;
222
+ // }
223
+
224
+ // // hack: do iterables via for..of
225
+ // function isIterableEquatable(value) {
226
+ // try {
227
+ // for (const _ of value) { break; }
228
+ // return true;
229
+ // } catch {
230
+ // return false;
231
+ // }
232
+ // }
233
+
234
+ // function compareIterableEquality(a, b, cache) {
235
+ // let aValues = [];
236
+ // for (const x of a) aValues.push(x);
237
+
238
+ // let bValues = [];
239
+ // for (const x of b) bValues.push(x);
240
+
241
+ // return compareArrayLikeEquality(aValues, bValues, cache);
242
+ // }
243
+
244
+ // var __assert_deepEqual__compare = (a, b) => {
245
+ // return compareEquality(a, b) === EQUAL;
246
+ // };
247
+
248
+ // var __assert_deepEqual = (actual, expected) => {
249
+ // if (!assert.deepEqual._compare(actual, expected)) {
250
+ // throw new Test262Error('assert.deepEqual failed');
251
+ // }
252
+ // };
253
+
254
+ // __assert_deepEqual([], []);
6
255
 
7
256
  // let x = {};
8
257
  // x.__proto__ = { wow() { console.log(0); } };
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.55.28';
3
+ globalThis.version = '0.55.32';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {