porffor 0.2.0-fdf0fc5 → 0.14.0-032e4ad08

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.
Files changed (48) hide show
  1. package/CONTRIBUTING.md +9 -3
  2. package/README.md +17 -14
  3. package/asur/index.js +1 -1
  4. package/byg/index.js +3 -24
  5. package/compiler/2c.js +66 -54
  6. package/compiler/assemble.js +51 -11
  7. package/compiler/builtins/annexb_string.js +10 -10
  8. package/compiler/builtins/annexb_string.ts +4 -3
  9. package/compiler/builtins/array.ts +85 -9
  10. package/compiler/builtins/base64.ts +2 -1
  11. package/compiler/builtins/boolean.ts +2 -2
  12. package/compiler/builtins/crypto.ts +2 -1
  13. package/compiler/builtins/date.ts +2 -3
  14. package/compiler/builtins/error.js +22 -0
  15. package/compiler/builtins/escape.ts +2 -3
  16. package/compiler/builtins/function.ts +1 -1
  17. package/compiler/builtins/int.ts +1 -1
  18. package/compiler/builtins/math.ts +410 -0
  19. package/compiler/builtins/number.ts +4 -7
  20. package/compiler/builtins/object.ts +1 -1
  21. package/compiler/builtins/porffor.d.ts +9 -8
  22. package/compiler/builtins/set.ts +197 -3
  23. package/compiler/builtins/string.ts +2 -1
  24. package/compiler/builtins/symbol.ts +62 -0
  25. package/compiler/builtins.js +41 -15
  26. package/compiler/codegen.js +653 -366
  27. package/compiler/decompile.js +3 -3
  28. package/compiler/embedding.js +2 -2
  29. package/compiler/encoding.js +0 -14
  30. package/compiler/expression.js +1 -1
  31. package/compiler/generated_builtins.js +771 -187
  32. package/compiler/index.js +5 -11
  33. package/compiler/opt.js +7 -7
  34. package/compiler/parse.js +2 -4
  35. package/compiler/precompile.js +18 -25
  36. package/compiler/prefs.js +6 -2
  37. package/compiler/prototype.js +185 -162
  38. package/compiler/wasmSpec.js +5 -0
  39. package/compiler/wrap.js +150 -90
  40. package/package.json +1 -1
  41. package/porffor_tmp.c +202 -0
  42. package/runner/compare.js +0 -1
  43. package/runner/debug.js +1 -6
  44. package/runner/index.js +5 -4
  45. package/runner/profiler.js +15 -42
  46. package/runner/repl.js +20 -10
  47. package/runner/sizes.js +2 -2
  48. package/runner/version.js +10 -8
package/compiler/wrap.js CHANGED
@@ -1,12 +1,106 @@
1
+ import { encodeVector, encodeLocal } from './encoding.js';
2
+ import { importedFuncs } from './builtins.js';
1
3
  import compile from './index.js';
2
4
  import decompile from './decompile.js';
3
- import { encodeVector, encodeLocal } from './encoding.js';
4
- import Prefs from './prefs.js';
5
- import { log } from './log.js';
6
5
  import { TYPES } from './types.js';
6
+ import { log } from './log.js';
7
+ import Prefs from './prefs.js';
7
8
 
8
9
  const bold = x => `\u001b[1m${x}\u001b[0m`;
9
10
 
11
+ const porfToJSValue = ({ memory, funcs, pages }, value, type) => {
12
+ switch (type) {
13
+ case TYPES.boolean: return Boolean(value);
14
+ case TYPES.undefined: return undefined;
15
+ case TYPES.object: return value === 0 ? null : {};
16
+
17
+ case TYPES.function: {
18
+ let func;
19
+ if (value < 0) {
20
+ func = importedFuncs[value + importedFuncs.length];
21
+ } else {
22
+ func = funcs.find(x => ((x.originalIndex ?? x.index) - importedFuncs.length) === value);
23
+ }
24
+
25
+ if (!func) return function () {};
26
+
27
+ // make fake empty func for repl/etc
28
+ return {[func.name]() {}}[func.name];
29
+ }
30
+
31
+ case TYPES.string: {
32
+ const length = (new Int32Array(memory.buffer, value, 1))[0];
33
+ return Array.from(new Uint16Array(memory.buffer, value + 4, length)).map(x => String.fromCharCode(x)).join('');
34
+ }
35
+
36
+ case TYPES.bytestring: {
37
+ const length = (new Int32Array(memory.buffer, value, 1))[0];
38
+ return Array.from(new Uint8Array(memory.buffer, value + 4, length)).map(x => String.fromCharCode(x)).join('');
39
+ }
40
+
41
+ case TYPES.array: {
42
+ const length = (new Int32Array(memory.buffer, value, 1))[0];
43
+
44
+ const out = [];
45
+ for (let i = 0; i < length; i++) {
46
+ const offset = value + 4 + (i * 9);
47
+
48
+ // have to slice because of memory alignment (?)
49
+ const v = (new Float64Array(memory.buffer.slice(offset, offset + 8), 0, 1))[0];
50
+ const t = (new Uint8Array(memory.buffer, offset + 8, 1))[0];
51
+
52
+ // console.log(`reading value at index ${i}...`)
53
+ // console.log(' memory:', Array.from(new Uint8Array(memory.buffer, offset, 9)).map(x => x.toString(16).padStart(2, '0')).join(' '));
54
+ // console.log(' read:', { value: v, type: t }, '\n');
55
+
56
+ out.push(porfToJSValue({ memory, funcs, pages }, v, t));
57
+ }
58
+
59
+ return out;
60
+ }
61
+
62
+ case TYPES.date: {
63
+ const t = (new Float64Array(memory.buffer, value, 1))[0];
64
+ return new Date(t);
65
+ }
66
+
67
+ case TYPES.set: {
68
+ const size = (new Int32Array(memory.buffer, value, 1))[0];
69
+
70
+ const out = new Set();
71
+ for (let i = 0; i < size; i++) {
72
+ const offset = value + 4 + (i * 9);
73
+
74
+ // have to slice because of memory alignment (?)
75
+ const v = (new Float64Array(memory.buffer.slice(offset, offset + 8), 0, 1))[0];
76
+ const t = (new Uint8Array(memory.buffer, offset + 8, 1))[0];
77
+
78
+ // console.log(`reading value at index ${i}...`)
79
+ // console.log(' memory:', Array.from(new Uint8Array(memory.buffer, offset, 9)).map(x => x.toString(16).padStart(2, '0')).join(' '));
80
+ // console.log(' read:', { value: v, type: t }, '\n');
81
+
82
+ out.add(porfToJSValue({ memory, funcs, pages }, v, t));
83
+ }
84
+
85
+ return out;
86
+ }
87
+
88
+ case TYPES.symbol: {
89
+ const descStore = pages.get('bytestring: __Porffor_symbol_descStore/ptr').ind * pageSize;
90
+ const offset = descStore + 4 + ((value - 1) * 9);
91
+
92
+ const v = (new Float64Array(memory.buffer.slice(offset, offset + 8), 0, 1))[0];
93
+ const t = (new Uint8Array(memory.buffer, offset + 8, 1))[0];
94
+
95
+ const desc = porfToJSValue({ memory, funcs, pages }, v, t);
96
+
97
+ return Symbol(desc);
98
+ }
99
+
100
+ default: return value;
101
+ }
102
+ };
103
+
10
104
  export default async (source, flags = [ 'module' ], customImports = {}, print = str => process.stdout.write(str)) => {
11
105
  const times = [];
12
106
 
@@ -22,40 +116,12 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
22
116
  times.push(performance.now() - t1);
23
117
  if (Prefs.profileCompiler) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
24
118
 
25
- const t2 = performance.now();
26
-
27
- let instance;
28
- try {
29
- let wasmEngine = WebAssembly;
30
- if (Prefs.asur) {
31
- log.warning('wrap', 'using our !experimental! asur wasm engine instead of host to run');
32
- wasmEngine = await import('../asur/index.js');
33
- }
34
-
35
- 0, { instance } = await wasmEngine.instantiate(wasm, {
36
- '': {
37
- p: valtype === 'i64' ? i => print(Number(i).toString()) : i => print(i.toString()),
38
- c: valtype === 'i64' ? i => print(String.fromCharCode(Number(i))) : i => print(String.fromCharCode(i)),
39
- t: () => performance.now(),
40
- u: () => performance.timeOrigin,
41
- y: () => {},
42
- z: () => {},
43
- ...customImports
44
- }
45
- });
46
- } catch (e) {
47
- // only backtrace for runner, not test262/etc
48
- if (!process.argv[1].includes('/runner')) throw e;
49
-
50
- const funcInd = parseInt(e.message.match(/function #([0-9]+) /)?.[1]);
51
- const blobOffset = parseInt(e.message.split('@')?.[1]);
52
-
53
- if (!funcInd) throw e;
119
+ const backtrace = (funcInd, blobOffset) => {
120
+ if (funcInd == null || blobOffset == null) return false;
54
121
 
55
122
  // convert blob offset -> function wasm offset.
56
123
  // this is not good code and is somewhat duplicated
57
124
  // I just want it to work for debugging, I don't care about perf/yes
58
-
59
125
  const func = funcs.find(x => x.index === funcInd);
60
126
  const locals = Object.values(func.locals).sort((a, b) => a.idx - b.idx).slice(func.params.length).sort((a, b) => a.idx - b.idx);
61
127
 
@@ -73,7 +139,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
73
139
 
74
140
  if (typeCount !== 0) localDecl.push(encodeLocal(typeCount, lastType));
75
141
 
76
- const toFind = encodeVector(localDecl).concat(func.wasm.flat().filter(x => x != null && x <= 0xff).slice(0, 40));
142
+ const toFind = encodeVector(localDecl).concat(func.wasm.flat().filter(x => x != null && x <= 0xff).slice(0, 60));
77
143
 
78
144
  let i = 0;
79
145
  for (; i < wasm.length; i++) {
@@ -88,7 +154,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
88
154
  if (!mismatch) break;
89
155
  }
90
156
 
91
- if (i === wasm.length) throw e;
157
+ if (i === wasm.length) return false;
92
158
 
93
159
  const offset = (blobOffset - i) + encodeVector(localDecl).length;
94
160
 
@@ -99,7 +165,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
99
165
  if (cumLen === offset) break;
100
166
  }
101
167
 
102
- if (cumLen !== offset) throw e;
168
+ if (cumLen !== offset) return false;
103
169
 
104
170
  i -= 1;
105
171
 
@@ -124,6 +190,38 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
124
190
  console.log(decomp.join('\n'));
125
191
  console.log('\x1B[90m...\x1B[0m\n');
126
192
 
193
+ return true;
194
+ };
195
+
196
+ const t2 = performance.now();
197
+
198
+ let instance;
199
+ try {
200
+ let wasmEngine = WebAssembly;
201
+ if (Prefs.asur) {
202
+ log.warning('wrap', 'using our !experimental! asur wasm engine instead of host to run');
203
+ wasmEngine = await import('../asur/index.js');
204
+ }
205
+
206
+ 0, { instance } = await wasmEngine.instantiate(wasm, {
207
+ '': {
208
+ p: valtype === 'i64' ? i => print(Number(i).toString()) : i => print(i.toString()),
209
+ c: valtype === 'i64' ? i => print(String.fromCharCode(Number(i))) : i => print(String.fromCharCode(i)),
210
+ t: () => performance.now(),
211
+ u: () => performance.timeOrigin,
212
+ y: () => {},
213
+ z: () => {},
214
+ ...customImports
215
+ }
216
+ });
217
+ } catch (e) {
218
+ // only backtrace for runner, not test262/etc
219
+ if (!process.argv[1].includes('/runner')) throw e;
220
+
221
+ const funcInd = parseInt(e.message.match(/function #([0-9]+) /)?.[1]);
222
+ const blobOffset = parseInt(e.message.split('@')?.[1]);
223
+
224
+ backtrace(funcInd, blobOffset);
127
225
  throw e;
128
226
  }
129
227
 
@@ -131,6 +229,7 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
131
229
  if (Prefs.profileCompiler) console.log(`instantiated in ${times[1].toFixed(2)}ms`);
132
230
 
133
231
  const exports = {};
232
+ const rawValues = process.argv.includes('-i');
134
233
 
135
234
  const exceptTag = instance.exports['0'], memory = instance.exports['$'];
136
235
  for (const x in instance.exports) {
@@ -148,62 +247,12 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
148
247
 
149
248
  exports[func.name] = function() {
150
249
  try {
151
- const _ret = exp.apply(this, arguments);
152
-
153
- if (_ret == null) return undefined;
154
-
155
- const [ ret, type ] = _ret;
156
-
157
- // if (ret >= typeBase && ret <= typeBase + 8) return ret > (typeBase + 7) ? 'object' : TYPES[ret];
158
-
159
- switch (type) {
160
- case TYPES.boolean: return Boolean(ret);
161
- case TYPES.undefined: return undefined;
162
- case TYPES.object: return ret === 0 ? null : {};
163
-
164
- case TYPES.string: {
165
- const pointer = ret;
166
- const length = (new Int32Array(memory.buffer, pointer, 1))[0];
250
+ const ret = exp.apply(this, arguments);
251
+ if (ret == null) return undefined;
167
252
 
168
- return Array.from(new Uint16Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
169
- }
253
+ if (rawValues) return { value: ret[0], type: ret[1], js: porfToJSValue({ memory, funcs, pages }, ret[0], ret[1]) };
170
254
 
171
- case TYPES.function: {
172
- // wasm func index, including all imports
173
- const func = funcs.find(x => (x.originalIndex ?? x.index) === ret);
174
- // if (!func) return ret;
175
- if (!func) return function () {};
176
-
177
- // make fake empty func for repl/etc
178
- return {[func.name]() {}}[func.name];
179
- }
180
-
181
- case TYPES.array: {
182
- const pointer = ret;
183
- const length = (new Int32Array(memory.buffer, pointer, 1))[0];
184
-
185
- // have to slice because of memory alignment
186
- const buf = memory.buffer.slice(pointer + 4, pointer + 4 + 8 * length);
187
-
188
- return Array.from(new Float64Array(buf));
189
- }
190
-
191
- case TYPES.bytestring: {
192
- const pointer = ret;
193
- const length = (new Int32Array(memory.buffer, pointer, 1))[0];
194
-
195
- return Array.from(new Uint8Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
196
- }
197
-
198
- case TYPES.date: {
199
- const pointer = ret;
200
- const value = (new Float64Array(memory.buffer, pointer, 1))[0];
201
-
202
- return new Date(value);
203
- }
204
-
205
- default: return ret;
206
- }
255
+ return porfToJSValue({ memory, funcs, pages }, ret[0], ret[1]);
207
256
  } catch (e) {
208
257
  if (e.is && e.is(exceptTag)) {
209
258
  const exceptId = e.getArg(exceptTag, 0);
@@ -218,6 +267,17 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
218
267
  throw new constructor(exception.message);
219
268
  }
220
269
 
270
+ if (e instanceof WebAssembly.RuntimeError) {
271
+ // only backtrace for runner, not test262/etc
272
+ if (!process.argv[1].includes('/runner')) throw e;
273
+
274
+ const match = e.stack.match(/wasm-function\[([0-9]+)\]:([0-9a-z]+)/) ?? [];
275
+ const funcInd = parseInt(match[1]);
276
+ const blobOffset = parseInt(match[2]);
277
+
278
+ backtrace(funcInd, blobOffset);
279
+ }
280
+
221
281
  throw e;
222
282
  }
223
283
  };
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.2.0-fdf0fc5",
4
+ "version": "0.14.0-032e4ad08",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {
package/porffor_tmp.c ADDED
@@ -0,0 +1,202 @@
1
+ #include <stdint.h>
2
+ #include <string.h>
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+
6
+ typedef uint8_t i8;
7
+ typedef uint16_t i16;
8
+ typedef int32_t i32;
9
+ typedef uint32_t u32;
10
+ typedef int64_t i64;
11
+ typedef uint64_t u64;
12
+ typedef float f32;
13
+ typedef double f64;
14
+
15
+ f64 NAN = 0e+0/0e+0;
16
+
17
+ struct ReturnValue {
18
+ f64 value;
19
+ i32 type;
20
+ };
21
+
22
+ char _memory[131072];
23
+
24
+ int _argc; char** _argv;
25
+ i32 i32_load(i32 align, i32 offset, i32 pointer) {
26
+ i32 out;
27
+ memcpy(&out, _memory + offset + pointer, sizeof(out));
28
+ return out;
29
+ }
30
+
31
+ i32 i32_load8_u(i32 align, i32 offset, i32 pointer) {
32
+ i8 out;
33
+ memcpy(&out, _memory + offset + pointer, sizeof(out));
34
+ return out;
35
+ }
36
+
37
+ void i32_store(i32 align, i32 offset, i32 pointer, i32 value) {
38
+ memcpy(_memory + offset + pointer, &value, sizeof(value));
39
+ }
40
+
41
+ void __Porffor_readArgv(u32 index, u32 outPtr) {
42
+ if (index >= _argc) {
43
+ printf("expected %d arguments\n", index);
44
+ exit(1);
45
+ }
46
+
47
+ char* arg = _argv[index];
48
+
49
+ u32 read = 0;
50
+ char* out = _memory + outPtr + 4;
51
+ char ch;
52
+ while ((ch = *(arg++)) != 0) {
53
+ out[read++] = ch;
54
+ }
55
+
56
+ memcpy(_memory + outPtr, &read, sizeof(read));
57
+ }
58
+ void __Porffor_readFile(u32 pathPtr, u32 outPtr) {
59
+ char* path = _memory + pathPtr + 4;
60
+ FILE* fp = fopen(path, "r");
61
+ if (fp == NULL) {
62
+ printf("failed to open file: %s\n", path);
63
+ exit(1);
64
+ }
65
+
66
+ u32 read = 0;
67
+ char* out = _memory + outPtr + 4;
68
+ char ch;
69
+ while ((ch = fgetc(fp)) != EOF) {
70
+ out[read++] = ch;
71
+ }
72
+
73
+ fclose(fp);
74
+
75
+ memcpy(_memory + outPtr, &read, sizeof(read));
76
+ }
77
+
78
+ f64 out = 0;
79
+ i32 outdtype = 0;
80
+
81
+ void __Porffor_print(f64 x, i32 y) {
82
+ i32 a = 0;
83
+ i32 b = 0;
84
+ i32 dtypeswitch_tmp = 0;
85
+
86
+ dtypeswitch_tmp = y;
87
+ // block
88
+ // if
89
+ if (dtypeswitch_tmp == 0) {
90
+ printf("%g\n", x);
91
+ goto j0;
92
+ }
93
+ // end
94
+ j1:;
95
+ // if
96
+ if (dtypeswitch_tmp == 1) {
97
+ // if
98
+ if (((u32)x) != 0) {
99
+ printf("%c", (int)(1.16e+2));
100
+ printf("%c", (int)(1.14e+2));
101
+ printf("%c", (int)(1.17e+2));
102
+ printf("%c", (int)(1.01e+2));
103
+ } else {
104
+ printf("%c", (int)(1.02e+2));
105
+ printf("%c", (int)(9.7e+1));
106
+ printf("%c", (int)(1.08e+2));
107
+ printf("%c", (int)(1.15e+2));
108
+ printf("%c", (int)(1.01e+2));
109
+ }
110
+ // end
111
+ j3:;
112
+ goto j0;
113
+ }
114
+ // end
115
+ j2:;
116
+ // if
117
+ if (dtypeswitch_tmp == 3) {
118
+ printf("%c", (int)(1.17e+2));
119
+ printf("%c", (int)(1.1e+2));
120
+ printf("%c", (int)(1e+2));
121
+ printf("%c", (int)(1.01e+2));
122
+ printf("%c", (int)(1.02e+2));
123
+ printf("%c", (int)(1.05e+2));
124
+ printf("%c", (int)(1.1e+2));
125
+ printf("%c", (int)(1.01e+2));
126
+ printf("%c", (int)(1e+2));
127
+ goto j0;
128
+ }
129
+ // end
130
+ j4:;
131
+ // if
132
+ if (dtypeswitch_tmp == 4) {
133
+ // if
134
+ if (((u32)x) != 0) {
135
+ printf("%c", (int)(1.23e+2));
136
+ printf("%c", (int)(1.25e+2));
137
+ } else {
138
+ printf("%c", (int)(1.1e+2));
139
+ printf("%c", (int)(1.17e+2));
140
+ printf("%c", (int)(1.08e+2));
141
+ printf("%c", (int)(1.08e+2));
142
+ }
143
+ // end
144
+ j6:;
145
+ goto j0;
146
+ }
147
+ // end
148
+ j5:;
149
+ // if
150
+ if (dtypeswitch_tmp == 5) {
151
+ printf("%c", (int)(1.02e+2));
152
+ printf("%c", (int)(1.17e+2));
153
+ printf("%c", (int)(1.1e+2));
154
+ printf("%c", (int)(9.9e+1));
155
+ printf("%c", (int)(1.16e+2));
156
+ printf("%c", (int)(1.05e+2));
157
+ printf("%c", (int)(1.11e+2));
158
+ printf("%c", (int)(1.1e+2));
159
+ printf("%c", (int)(3.2e+1));
160
+ printf("%c", (int)(4e+1));
161
+ printf("%c", (int)(4.1e+1));
162
+ printf("%c", (int)(3.2e+1));
163
+ printf("%c", (int)(1.23e+2));
164
+ printf("%c", (int)(1.25e+2));
165
+ goto j0;
166
+ }
167
+ // end
168
+ j7:;
169
+ // if
170
+ if (dtypeswitch_tmp == 18) {
171
+ a = (u32)x;
172
+ b = i32_load(1, 0, a) + a;
173
+ // loop
174
+ j9:;
175
+ printf("%c", (int)((f64)(i32_load8_u(0, 4, a))));
176
+ a = a + 1;
177
+ if (a != b) {
178
+ goto j9;
179
+ }
180
+ // end
181
+ goto j0;
182
+ }
183
+ // end
184
+ j8:;
185
+ printf("%g\n", x);
186
+ // end
187
+ j0:;
188
+ }
189
+
190
+ int main(int argc, char* argv[]) {
191
+ _argc = argc; _argv = argv;
192
+
193
+ out = 1e+0;
194
+ outdtype = 18;
195
+ i32_store(1, 0, 65536, 0);
196
+ __Porffor_readArgv((u32)(0e+0), (u32)(6.5536e+4));
197
+ __Porffor_readFile((u32)(undefined), (u32)(out));
198
+ __Porffor_print(out, outdtype);
199
+ printf("%c", (int)(1e+1));
200
+
201
+ return 0;
202
+ }
package/runner/compare.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { execSync } from 'node:child_process';
2
- import { pathToFileURL } from 'node:url';
3
2
  import fs from 'node:fs';
4
3
 
5
4
  const [ commitsAgo, file ] = process.argv.slice(2);
package/runner/debug.js CHANGED
@@ -1,9 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import compile from '../compiler/wrap.js';
4
- import fs from 'node:fs';
5
-
6
4
  import Byg from '../byg/index.js';
5
+ import fs from 'node:fs';
7
6
 
8
7
  const file = process.argv.slice(2).find(x => x[0] !== '-');
9
8
  let source = fs.readFileSync(file, 'utf8');
@@ -19,7 +18,6 @@ source = source.replace(/^\s*(function|const)\s*([a-zA-Z0-9]+)(\s*=\s*)?\([^)]*\
19
18
 
20
19
  const lines = source.split('\n');
21
20
  for (let i = 0; i < lines.length; i++) {
22
- // lines[line] = lines[line].replace(/^[^\n}]*;$/, _ => `profile(${line});${_}`);
23
21
  if (lines[i].trim().replace('}', '') !== '') lines[i] = `profile1(Porffor.wasm.i32.const(${i}));` + lines[i];
24
22
  }
25
23
  source = lines.join('\n');
@@ -35,8 +33,6 @@ const byg = Byg({
35
33
  }
36
34
  });
37
35
 
38
- // console.log(source);
39
-
40
36
  let stepIn = false, stepOut = false;
41
37
  const callStack = [];
42
38
 
@@ -72,7 +68,6 @@ try {
72
68
  [
73
69
  {
74
70
  x: termWidth - 1 - 40 - 6,
75
- // y: () => termHeight - 20 - 1 - 4,
76
71
  y: () => 4,
77
72
  width: 40,
78
73
  height: 20,
package/runner/index.js CHANGED
@@ -25,7 +25,7 @@ if (process.argv.includes('--help')) {
25
25
  console.log(`Usage: \x1B[1mporf [command] path/to/script.js [...prefs] [...args]\x1B[0m`);
26
26
 
27
27
  // commands
28
- console.log(`\n\u001b[4mCommands\x1B[0m`);
28
+ console.log(`\n\x1B[1mCommands:\x1B[0m`);
29
29
  for (const [ cmd, [ color, desc ] ] of Object.entries({
30
30
  run: [ 34, 'Run a JS file' ],
31
31
  wasm: [ 34, 'Compile a JS file to a Wasm binary\n' ],
@@ -60,8 +60,10 @@ if (process.argv.includes('--help')) {
60
60
 
61
61
  let file = process.argv.slice(2).find(x => x[0] !== '-');
62
62
  if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(file)) {
63
+ // remove this arg
64
+ process.argv.splice(process.argv.indexOf(file), 1);
65
+
63
66
  if (file === 'profile') {
64
- process.argv.splice(process.argv.indexOf(file), 1);
65
67
  await import('./profiler.js');
66
68
  await new Promise(() => {}); // do nothing for the rest of this file
67
69
  }
@@ -75,12 +77,11 @@ if (['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(fi
75
77
  }
76
78
 
77
79
  if (file === 'debug') {
78
- process.argv.splice(process.argv.indexOf(file), 1);
79
80
  await import('./debug.js');
80
81
  await new Promise(() => {}); // do nothing for the rest of this file
81
82
  }
82
83
 
83
- file = process.argv.slice(process.argv.indexOf(file) + 1).find(x => x[0] !== '-');
84
+ file = process.argv.slice(2).find(x => x[0] !== '-');
84
85
 
85
86
  const nonOptOutFile = process.argv.slice(process.argv.indexOf(file) + 1).find(x => x[0] !== '-');
86
87
  if (nonOptOutFile) {
@@ -3,22 +3,12 @@
3
3
  import compile from '../compiler/wrap.js';
4
4
  import fs from 'node:fs';
5
5
 
6
- import Prefs from '../compiler/prefs.js';
7
-
8
- // const fast = Prefs.profiler === 'fast';
9
- const fast = !Prefs.experimentalProfiler;
10
-
11
6
  const file = process.argv.slice(2).find(x => x[0] !== '-');
12
7
  let source = fs.readFileSync(file, 'utf8');
13
8
 
14
9
  let profileId = 0;
15
- // source = fast ? source.replace(/^[^\n}]*;$/mg, _ => `profile(${profileId++});${_}profile(${profileId++});`) : source.replace(/^[^\n}]*;$/mg, _ => `profile(${profileId++});profile(${profileId++});${_}profile(${profileId++});`);
16
- // source = fast ? source.replace(/^[^\n}]*;$/mg, _ => `profile(Porffor.wasm.i32.const(${profileId++}));${_}profile(Porffor.wasm.i32.const(${profileId++}));`) : source.replace(/^[^\n}]*;$/mg, _ => `profile(${profileId++});profile(${profileId++});${_}profile(${profileId++});`);
17
- source = fast ? source.replace(/^[^\n}]*;$/mg, _ => `profile1(Porffor.wasm.i32.const(${profileId}));${_}profile2(Porffor.wasm.i32.const(${profileId++}));`) : source.replace(/^[^\n}]*;$/mg, _ => `profile(${profileId++});profile(${profileId++});${_}profile(${profileId++});`);
10
+ source = source.replace(/^[^\n}]*;$/mg, _ => `profile1(Porffor.wasm.i32.const(${profileId}));${_}profile2(Porffor.wasm.i32.const(${profileId++}));`)
18
11
 
19
- // console.log(source);
20
-
21
- // let tmp = new Array(profileId).fill(0);
22
12
  let tmp = new Array(profileId).fill(0);
23
13
  let times = new Array(profileId).fill(0);
24
14
  let samples = 0;
@@ -31,31 +21,19 @@ let last = 0;
31
21
 
32
22
  try {
33
23
  const { exports } = await compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
34
- y: fast ? n => {
24
+ y: n => {
35
25
  tmp[n] = performance.now();
36
- } : n => { /* todo */ },
37
- z: fast ? n => {
38
- times[n] += performance.now() - tmp[n];
39
- } : n => { /* todo */ }
40
- // z: fast ? n => {
41
- // if (n % 2) {
42
- // tmp[n] += performance.now() - tmp[n - 1];
43
- // } else {
44
- // tmp[n] = performance.now();
45
- // }
46
- // } : n => {
47
- // if (n % 3 === 2) {
48
- // tmp[n] += (performance.now() - tmp[n - 1]) - (tmp[n - 1] - tmp[n - 2]);
49
- // samples++;
50
-
51
- // if (performance.now() > last) {
52
- // process.stdout.write(`\r${spinner[spin++ % 4]} running: collected ${samples} samples...`);
53
- // last = performance.now() + 100;
54
- // }
55
- // } else {
56
- // tmp[n] = performance.now();
57
- // }
58
- // }
26
+ },
27
+ z: n => {
28
+ const t = performance.now();
29
+ times[n] += t - tmp[n];
30
+
31
+ samples++;
32
+ if (t > last) {
33
+ process.stdout.write(`\r${spinner[spin++ % 4]} running: collected ${samples} samples...`);
34
+ last = t + 100;
35
+ }
36
+ }
59
37
  });
60
38
 
61
39
  const start = performance.now();
@@ -64,14 +42,11 @@ try {
64
42
 
65
43
  const total = performance.now() - start;
66
44
 
67
- console.log(`\n${fast ? '' : `samples: ${samples}\n`}total: ${total}ms\n\n` + source.split('\n').map(x => {
45
+ console.log(`\ntotal: ${total}ms\nsamples: ${samples}\n\n\n` + source.split('\n').map(x => {
68
46
  let time = 0;
69
47
  if (x.startsWith('profile')) {
70
- // const id = parseInt(x.slice(8, x.indexOf(')')));
71
- // const id = parseInt(x.slice(31, x.indexOf(')') + 1));
72
48
  const id = parseInt(x.slice(32, x.indexOf(')')));
73
- // time = fast ? tmp[id + 1] : tmp[id + 2];
74
- time = fast ? times[id] : tmp[id + 2];
49
+ time = times[id]
75
50
  }
76
51
 
77
52
  let color = [ 0, 0, 0 ];
@@ -85,8 +60,6 @@ try {
85
60
 
86
61
  const ansiColor = `2;${color[0]};${color[1]};${color[2]}m`;
87
62
 
88
- // const line = x.replace(/profile\([0-9]+\);/g, '');
89
- // const line = x.replace(/profile\(Porffor.wasm.i32.const\([0-9]+\)\);/g, '');
90
63
  const line = x.replace(/profile[0-9]\(Porffor.wasm.i32.const\([0-9]+\)\);/g, '');
91
64
 
92
65
  if (percents) return `\x1b[48;${ansiColor}\x1b[97m${time ? ((time * 100).toFixed(0).padStart(4, ' ') + '%') : ' '}\x1b[0m\x1b[38;${ansiColor}▌\x1b[0m ${line}`;