porffor 0.17.0-a818353a5 → 0.17.0-b4e7f7ee0
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.
- package/compiler/2c.js +28 -11
- package/compiler/builtins/array.ts +22 -0
- package/compiler/builtins/math.ts +6 -2
- package/compiler/builtins/set.ts +2 -9
- package/compiler/builtins/typedarray.js +42 -0
- package/compiler/builtins.js +25 -0
- package/compiler/codegen.js +412 -24
- package/compiler/generated_builtins.js +316 -134
- package/compiler/pgo.js +9 -1
- package/compiler/types.js +31 -5
- package/compiler/wasmSpec.js +2 -0
- package/compiler/wrap.js +20 -5
- package/package.json +1 -1
- package/rhemyn/README.md +7 -4
- package/rhemyn/compile.js +129 -55
- package/runner/debug.js +1 -1
- package/runner/index.js +3 -3
- package/runner/profile.js +1 -1
- package/runner/repl.js +16 -11
package/compiler/pgo.js
CHANGED
@@ -91,7 +91,9 @@ export const run = obj => {
|
|
91
91
|
},
|
92
92
|
w: (ind, outPtr) => { // readArgv
|
93
93
|
const pgoInd = process.argv.indexOf('--pgo');
|
94
|
-
|
94
|
+
let args = process.argv.slice(pgoInd);
|
95
|
+
args = args.slice(args.findIndex(x => !x.startsWith('-')) + 1);
|
96
|
+
|
95
97
|
const str = args[ind - 1];
|
96
98
|
if (pgoInd === -1 || !str) {
|
97
99
|
if (Prefs.pgoLog) console.log('\nPGO warning: script was expecting arguments, please specify args to use for PGO after --pgo arg');
|
@@ -100,6 +102,9 @@ export const run = obj => {
|
|
100
102
|
|
101
103
|
writeByteStr(exports.$, outPtr, str);
|
102
104
|
return str.length;
|
105
|
+
},
|
106
|
+
q: (pathPtr, outPtr) => {
|
107
|
+
return -1;
|
103
108
|
}
|
104
109
|
}, () => {});
|
105
110
|
|
@@ -179,6 +184,9 @@ export const run = obj => {
|
|
179
184
|
|
180
185
|
log = '';
|
181
186
|
for (const x of funcs) {
|
187
|
+
// skip pgo opt for main()
|
188
|
+
if (x.name === 'main') continue;
|
189
|
+
|
182
190
|
const wasmFunc = wasmFuncs.find(y => y.name === x.name);
|
183
191
|
|
184
192
|
let targets = [];
|
package/compiler/types.js
CHANGED
@@ -20,10 +20,26 @@ export const TYPE_NAMES = {
|
|
20
20
|
[TYPES.bigint]: 'BigInt'
|
21
21
|
};
|
22
22
|
|
23
|
+
// flags
|
24
|
+
export const TYPE_FLAGS = {
|
25
|
+
// iterable: 0b10000000,
|
26
|
+
length: 0b01000000,
|
27
|
+
};
|
28
|
+
|
29
|
+
// TYPES.string |= TYPE_FLAGS.iterable;
|
30
|
+
TYPES.string |= TYPE_FLAGS.length;
|
31
|
+
|
32
|
+
export const typeHasFlag = (type, flag) => (type & flag) !== 0;
|
33
|
+
|
23
34
|
export const INTERNAL_TYPE_BASE = 0x10;
|
24
35
|
let internalTypeIndex = INTERNAL_TYPE_BASE;
|
25
|
-
const registerInternalType = name => {
|
26
|
-
|
36
|
+
const registerInternalType = (name, flags = []) => {
|
37
|
+
let n = internalTypeIndex++;
|
38
|
+
|
39
|
+
for (const x of flags) {
|
40
|
+
if (TYPE_FLAGS[x]) n |= TYPE_FLAGS[x];
|
41
|
+
}
|
42
|
+
|
27
43
|
TYPES[name.toLowerCase()] = n;
|
28
44
|
TYPE_NAMES[n] = name;
|
29
45
|
};
|
@@ -31,8 +47,18 @@ const registerInternalType = name => {
|
|
31
47
|
// note: when adding a new internal type, please also add a deserializer to wrap.js
|
32
48
|
// (it is okay to add a throw todo deserializer for wips)
|
33
49
|
|
34
|
-
registerInternalType('Array');
|
50
|
+
registerInternalType('Array', ['iterable', 'length']);
|
35
51
|
registerInternalType('RegExp');
|
36
|
-
registerInternalType('ByteString');
|
52
|
+
registerInternalType('ByteString', ['iterable', 'length']);
|
37
53
|
registerInternalType('Date');
|
38
|
-
registerInternalType('Set');
|
54
|
+
registerInternalType('Set', ['iterable']);
|
55
|
+
|
56
|
+
registerInternalType('Uint8Array', ['iterable', 'length']);
|
57
|
+
registerInternalType('Int8Array', ['iterable', 'length']);
|
58
|
+
registerInternalType('Uint8ClampedArray', ['iterable', 'length']);
|
59
|
+
registerInternalType('Uint16Array', ['iterable', 'length']);
|
60
|
+
registerInternalType('Int16Array', ['iterable', 'length']);
|
61
|
+
registerInternalType('Uint32Array', ['iterable', 'length']);
|
62
|
+
registerInternalType('Int32Array', ['iterable', 'length']);
|
63
|
+
registerInternalType('Float32Array', ['iterable', 'length']);
|
64
|
+
registerInternalType('Float64Array', ['iterable', 'length']);
|
package/compiler/wasmSpec.js
CHANGED
@@ -68,6 +68,7 @@ export const Opcodes = {
|
|
68
68
|
|
69
69
|
i32_load: 0x28,
|
70
70
|
i64_load: 0x29,
|
71
|
+
f32_load: 0x2a,
|
71
72
|
f64_load: 0x2b,
|
72
73
|
|
73
74
|
i32_load8_s: 0x2c,
|
@@ -82,6 +83,7 @@ export const Opcodes = {
|
|
82
83
|
|
83
84
|
i32_store: 0x36,
|
84
85
|
i64_store: 0x37,
|
86
|
+
f32_store: 0x38,
|
85
87
|
f64_store: 0x39,
|
86
88
|
|
87
89
|
i32_store8: 0x3a,
|
package/compiler/wrap.js
CHANGED
@@ -2,7 +2,7 @@ import { encodeVector, encodeLocal } from './encoding.js';
|
|
2
2
|
import { importedFuncs } from './builtins.js';
|
3
3
|
import compile from './index.js';
|
4
4
|
import decompile from './decompile.js';
|
5
|
-
import { TYPES } from './types.js';
|
5
|
+
import { TYPES, TYPE_NAMES } from './types.js';
|
6
6
|
import { log } from './log.js';
|
7
7
|
import Prefs from './prefs.js';
|
8
8
|
|
@@ -115,6 +115,19 @@ const porfToJSValue = ({ memory, funcs, pages }, value, type) => {
|
|
115
115
|
return Symbol(desc);
|
116
116
|
}
|
117
117
|
|
118
|
+
case TYPES.uint8array:
|
119
|
+
case TYPES.int8array:
|
120
|
+
case TYPES.uint8clampedarray:
|
121
|
+
case TYPES.uint16array:
|
122
|
+
case TYPES.int16array:
|
123
|
+
case TYPES.uint32array:
|
124
|
+
case TYPES.int32array:
|
125
|
+
case TYPES.float32array:
|
126
|
+
case TYPES.float64array: {
|
127
|
+
const length = (new Int32Array(memory.buffer, value, 1))[0];
|
128
|
+
return new globalThis[TYPE_NAMES[type]](memory.buffer, value + 4, length);
|
129
|
+
}
|
130
|
+
|
118
131
|
default: return value;
|
119
132
|
}
|
120
133
|
};
|
@@ -127,7 +140,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
|
|
127
140
|
|
128
141
|
globalThis.porfDebugInfo = { funcs, globals };
|
129
142
|
|
130
|
-
if (process.argv[1].includes('/runner') && source.includes?.('export ')) flags.push('module');
|
143
|
+
// if (process.argv[1].includes('/runner') && source.includes?.('export ')) flags.push('module');
|
131
144
|
|
132
145
|
// fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
133
146
|
|
@@ -235,8 +248,10 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
|
|
235
248
|
y: () => {},
|
236
249
|
z: () => {},
|
237
250
|
w: (ind, outPtr) => { // readArgv
|
238
|
-
|
239
|
-
|
251
|
+
let args = process.argv.slice(2);
|
252
|
+
args = args.slice(args.findIndex(x => !x.startsWith('-')) + 1);
|
253
|
+
|
254
|
+
const str = args[ind - 1];
|
240
255
|
if (!str) return -1;
|
241
256
|
|
242
257
|
writeByteStr(memory, outPtr, str);
|
@@ -244,7 +259,7 @@ export default (source, flags = [ 'module' ], customImports = {}, print = str =>
|
|
244
259
|
},
|
245
260
|
q: (pathPtr, outPtr) => { // readFile
|
246
261
|
try {
|
247
|
-
const path = readByteStr(memory, pathPtr);
|
262
|
+
const path = pathPtr === 0 ? 0 : readByteStr(memory, pathPtr);
|
248
263
|
const contents = fs.readFileSync(path, 'utf8');
|
249
264
|
writeByteStr(memory, outPtr, contents);
|
250
265
|
return contents.length;
|
package/package.json
CHANGED
package/rhemyn/README.md
CHANGED
@@ -24,13 +24,16 @@ Made for use with Porffor but could possibly be adapted, implementation/library
|
|
24
24
|
- 🟢 digit, not digit (eg `\d\D`)
|
25
25
|
- 🟢 word, not word (eg `\w\W`)
|
26
26
|
- 🟢 whitespace, not whitespace (eg `\s\S`)
|
27
|
-
-
|
28
|
-
-
|
29
|
-
-
|
30
|
-
-
|
27
|
+
- 🟡 quantifiers
|
28
|
+
- 🟡 star (eg `a*`)
|
29
|
+
- 🟡 plus (eg `a+`)
|
30
|
+
- 🟡 optional (eg `a?`)
|
31
31
|
- 🟠 lazy modifier (eg `a*?`)
|
32
32
|
- 🔴 n repetitions (eg `a{4}`)
|
33
33
|
- 🔴 n-m repetitions (eg `a{2,4}`)
|
34
|
+
- 🟠 groups
|
35
|
+
- 🟠 capturing groups (`(a)`)
|
36
|
+
- 🔴 non-capturing groups (`(?:a)`)
|
34
37
|
- 🔴 assertions
|
35
38
|
- 🔴 beginning (eg `^a`)
|
36
39
|
- 🔴 end (eg `a$`)
|
package/rhemyn/compile.js
CHANGED
@@ -12,13 +12,12 @@ const Counter = 3; // what char we are running on
|
|
12
12
|
const Pointer = 4; // next char BYTE pointer
|
13
13
|
const Length = 5;
|
14
14
|
const Tmp = 6;
|
15
|
+
const QuantifierTmp = 7; // the temporary variable used for quanitifers
|
15
16
|
|
16
|
-
let exprLastGet = false;
|
17
17
|
const generate = (node, negated = false, get = true, stringSize = 2, func = 'test') => {
|
18
18
|
let out = [];
|
19
19
|
switch (node.type) {
|
20
20
|
case 'Expression':
|
21
|
-
exprLastGet = false;
|
22
21
|
out = [
|
23
22
|
// set length local
|
24
23
|
[ Opcodes.local_get, BasePointer ],
|
@@ -32,46 +31,40 @@ const generate = (node, negated = false, get = true, stringSize = 2, func = 'tes
|
|
32
31
|
[ Opcodes.local_set, IterPointer ],
|
33
32
|
|
34
33
|
[ Opcodes.loop, Blocktype.void ],
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
[ Opcodes.local_tee, Counter ],
|
70
|
-
|
71
|
-
[ Opcodes.local_get, Length ],
|
72
|
-
[ Opcodes.i32_ne ],
|
73
|
-
|
74
|
-
[ Opcodes.br_if, 0 ],
|
34
|
+
// reset pointer as iter pointer
|
35
|
+
[ Opcodes.local_get, IterPointer ],
|
36
|
+
[ Opcodes.local_set, Pointer ],
|
37
|
+
|
38
|
+
[ Opcodes.block, Blocktype.void ],
|
39
|
+
// generate checks
|
40
|
+
...node.body.flatMap(x => generate(x, negated, true, stringSize, func)),
|
41
|
+
|
42
|
+
// reached end without branching out, successful match
|
43
|
+
...({
|
44
|
+
test: number(1, Valtype.i32),
|
45
|
+
search: [
|
46
|
+
[ Opcodes.local_get, Counter ]
|
47
|
+
]
|
48
|
+
})[func],
|
49
|
+
[ Opcodes.return ],
|
50
|
+
[ Opcodes.end ],
|
51
|
+
|
52
|
+
// increment iter pointer by string size
|
53
|
+
[ Opcodes.local_get, IterPointer ],
|
54
|
+
...number(stringSize, Valtype.i32),
|
55
|
+
[ Opcodes.i32_add ],
|
56
|
+
[ Opcodes.local_set, IterPointer ],
|
57
|
+
|
58
|
+
// increment counter by 1, check if eq length, if not loop
|
59
|
+
[ Opcodes.local_get, Counter ],
|
60
|
+
...number(1, Valtype.i32),
|
61
|
+
[ Opcodes.i32_add ],
|
62
|
+
[ Opcodes.local_tee, Counter ],
|
63
|
+
|
64
|
+
[ Opcodes.local_get, Length ],
|
65
|
+
[ Opcodes.i32_ne ],
|
66
|
+
|
67
|
+
[ Opcodes.br_if, 0 ],
|
75
68
|
[ Opcodes.end ],
|
76
69
|
|
77
70
|
// no match, return 0
|
@@ -110,12 +103,12 @@ const generate = (node, negated = false, get = true, stringSize = 2, func = 'tes
|
|
110
103
|
return out;
|
111
104
|
};
|
112
105
|
|
113
|
-
const getNextChar = (stringSize) => [
|
106
|
+
const getNextChar = (stringSize, peek = false) => [
|
114
107
|
// get char from pointer
|
115
108
|
[ Opcodes.local_get, Pointer ],
|
116
109
|
[ stringSize == 2 ? Opcodes.i32_load16_u : Opcodes.i32_load8_u, 0, 0 ],
|
117
110
|
|
118
|
-
...(
|
111
|
+
...(peek ? [] : [
|
119
112
|
// pointer += string size
|
120
113
|
[ Opcodes.local_get, Pointer ],
|
121
114
|
...number(stringSize, Valtype.i32),
|
@@ -134,11 +127,81 @@ const checkFailure = () => [
|
|
134
127
|
[ Opcodes.br_if, 0 ]
|
135
128
|
];
|
136
129
|
|
137
|
-
const
|
130
|
+
const wrapQuantifier = (node, method, get, stringSize) => {
|
131
|
+
const [ min, max ] = node.quantifier;
|
138
132
|
return [
|
139
|
-
|
133
|
+
// initalize our temp value (number of matched characters)
|
134
|
+
...number(0, Valtype.i32),
|
135
|
+
[Opcodes.local_set, QuantifierTmp],
|
136
|
+
|
137
|
+
// start loop
|
138
|
+
[Opcodes.loop, Blocktype.void],
|
139
|
+
[ Opcodes.block, Blocktype.void ],
|
140
|
+
// if counter + tmp == length, break
|
141
|
+
[ Opcodes.local_get, Counter ],
|
142
|
+
[ Opcodes.local_get, QuantifierTmp ],
|
143
|
+
[ Opcodes.i32_add ],
|
144
|
+
[ Opcodes.local_get, Length ],
|
145
|
+
[ Opcodes.i32_eq ],
|
146
|
+
[ Opcodes.br_if, 0 ],
|
147
|
+
|
148
|
+
// if doesn't match, break
|
149
|
+
...method,
|
150
|
+
[Opcodes.br_if, 0 ],
|
151
|
+
...(get ? [
|
152
|
+
// pointer += stringSize
|
153
|
+
[ Opcodes.local_get, Pointer ],
|
154
|
+
...number(stringSize, Valtype.i32),
|
155
|
+
[ Opcodes.i32_add ],
|
156
|
+
[ Opcodes.local_set, Pointer ]
|
157
|
+
] : []),
|
158
|
+
|
159
|
+
// if maximum was reached, break
|
160
|
+
...(max ? [
|
161
|
+
[ Opcodes.local_get, QuantifierTmp ],
|
162
|
+
...number(max, Valtype.i32),
|
163
|
+
[ Opcodes.i32_eq ],
|
164
|
+
[ Opcodes.br_if, 0 ]
|
165
|
+
] : []),
|
166
|
+
|
167
|
+
[ Opcodes.local_get, QuantifierTmp ],
|
168
|
+
...number(1, Valtype.i32),
|
169
|
+
[ Opcodes.i32_add ],
|
170
|
+
[ Opcodes.local_set, QuantifierTmp ],
|
171
|
+
[ Opcodes.br, 1 ],
|
172
|
+
[ Opcodes.end ],
|
173
|
+
[ Opcodes.end ],
|
174
|
+
|
175
|
+
// if less than minimum, fail
|
176
|
+
[Opcodes.local_get, QuantifierTmp],
|
177
|
+
...number(min, Valtype.i32),
|
178
|
+
[Opcodes.i32_lt_s],
|
179
|
+
...(get ? checkFailure(): []),
|
180
|
+
|
181
|
+
// counter += tmp - 1
|
182
|
+
[ Opcodes.local_get, QuantifierTmp ],
|
183
|
+
...number(1, Valtype.i32),
|
184
|
+
[ Opcodes.i32_sub ],
|
185
|
+
[ Opcodes.local_get, Counter ],
|
186
|
+
[ Opcodes.i32_add ],
|
187
|
+
[ Opcodes.local_set, Counter ]
|
188
|
+
];
|
189
|
+
}
|
190
|
+
|
191
|
+
const generateChar = (node, negated, get, stringSize) => {
|
192
|
+
const hasQuantifier = !!node.quantifier;
|
193
|
+
const out = [
|
194
|
+
...(get ? getNextChar(stringSize, hasQuantifier) : []),
|
140
195
|
...number(node.char.charCodeAt(0), Valtype.i32),
|
141
196
|
negated ? [ Opcodes.i32_eq ] : [ Opcodes.i32_ne ],
|
197
|
+
];
|
198
|
+
|
199
|
+
if (node.quantifier) {
|
200
|
+
return wrapQuantifier(node, out, get, stringSize);
|
201
|
+
}
|
202
|
+
|
203
|
+
return [
|
204
|
+
...out,
|
142
205
|
...(get ? checkFailure(): [])
|
143
206
|
];
|
144
207
|
};
|
@@ -146,21 +209,31 @@ const generateChar = (node, negated, get, stringSize) => {
|
|
146
209
|
const generateSet = (node, negated, get, stringSize) => {
|
147
210
|
// for a single char we do not need a tmp, it is like just
|
148
211
|
const singleChar = node.body.length === 1 && node.body[0].type === 'Character';
|
212
|
+
if (singleChar) return generateChar(node.body[0], negated, get, stringSize)
|
149
213
|
|
150
|
-
|
151
|
-
|
152
|
-
|
214
|
+
const hasQuantifier = !!node.quantifier;
|
215
|
+
|
216
|
+
const out = [
|
217
|
+
...(get ? getNextChar(stringSize, hasQuantifier) : []),
|
218
|
+
[ Opcodes.local_set, Tmp ],
|
153
219
|
];
|
154
220
|
|
155
221
|
for (const x of node.body) {
|
156
|
-
out
|
157
|
-
|
158
|
-
...(singleChar ? [] : [ [ Opcodes.local_get, Tmp ] ]),
|
222
|
+
out.push(
|
223
|
+
[ Opcodes.local_get, Tmp ],
|
159
224
|
...generate(x, negated, false, stringSize)
|
160
|
-
|
225
|
+
);
|
161
226
|
}
|
162
227
|
|
163
|
-
if (node.body.length > 0)
|
228
|
+
if (node.body.length > 0) {
|
229
|
+
for (let i = 0; i < node.body.length - 1; i++) {
|
230
|
+
out.push(negated ? [ Opcodes.i32_or ] : [ Opcodes.i32_and ])
|
231
|
+
}
|
232
|
+
};
|
233
|
+
|
234
|
+
if (hasQuantifier) {
|
235
|
+
return wrapQuantifier(node, out, get, stringSize);
|
236
|
+
}
|
164
237
|
|
165
238
|
return [
|
166
239
|
...out,
|
@@ -196,7 +269,7 @@ const wrapFunc = (regex, func, name, index) => {
|
|
196
269
|
const parsed = parse(regex);
|
197
270
|
|
198
271
|
return outputFunc([
|
199
|
-
[ Opcodes.local_get,
|
272
|
+
[ Opcodes.local_get, IterPointer ],
|
200
273
|
...number(TYPES.string, Valtype.i32),
|
201
274
|
[ Opcodes.i32_eq ],
|
202
275
|
[ Opcodes.if, Valtype.i32 ],
|
@@ -229,5 +302,6 @@ const outputFunc = (wasm, name, index) => ({
|
|
229
302
|
pointer: { idx: 4, type: Valtype.i32 },
|
230
303
|
length: { idx: 5, type: Valtype.i32 },
|
231
304
|
tmp: { idx: 6, type: Valtype.i32 },
|
305
|
+
quantifierTmp: { idx: 7, type: Valtype.i32 },
|
232
306
|
}
|
233
307
|
});
|
package/runner/debug.js
CHANGED
@@ -43,7 +43,7 @@ let lastLine;
|
|
43
43
|
let output = '';
|
44
44
|
|
45
45
|
try {
|
46
|
-
const { exports } =
|
46
|
+
const { exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
|
47
47
|
y: n => {
|
48
48
|
if (callStarts[callStarts.length - 1] === n - 1) {
|
49
49
|
// end of call
|
package/runner/index.js
CHANGED
@@ -130,14 +130,14 @@ const print = str => {
|
|
130
130
|
let runStart;
|
131
131
|
try {
|
132
132
|
if (process.argv.includes('-b')) {
|
133
|
-
const { wasm, exports } =
|
133
|
+
const { wasm, exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
|
134
134
|
|
135
135
|
runStart = performance.now();
|
136
136
|
if (!process.argv.includes('--no-run')) exports.main();
|
137
137
|
|
138
138
|
console.log(`\n\nwasm size: ${wasm.byteLength} bytes`);
|
139
139
|
} else {
|
140
|
-
const { exports } =
|
140
|
+
const { exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {}, print);
|
141
141
|
|
142
142
|
runStart = performance.now();
|
143
143
|
if (!process.argv.includes('--no-run')) exports.main();
|
@@ -146,7 +146,7 @@ try {
|
|
146
146
|
} catch (e) {
|
147
147
|
// if (cache) process.stdout.write(cache);
|
148
148
|
let out = e;
|
149
|
-
if (!process.argv.includes('-i') && e.
|
149
|
+
if (!process.argv.includes('-i') && Object.getPrototypeOf(e).message != null) out = `${e.constructor.name}${e.message != null ? `: ${e.message}` : ''}`;
|
150
150
|
console.error(out);
|
151
151
|
}
|
152
152
|
|
package/runner/profile.js
CHANGED
@@ -20,7 +20,7 @@ let spin = 0;
|
|
20
20
|
let last = 0;
|
21
21
|
|
22
22
|
try {
|
23
|
-
const { exports } =
|
23
|
+
const { exports } = compile(source, process.argv.includes('--module') ? [ 'module' ] : [], {
|
24
24
|
y: n => {
|
25
25
|
tmp[n] = performance.now();
|
26
26
|
},
|
package/runner/repl.js
CHANGED
@@ -40,10 +40,9 @@ let lastMemory, lastPages;
|
|
40
40
|
const PageSize = 65536;
|
41
41
|
const memoryToString = mem => {
|
42
42
|
let out = '';
|
43
|
-
const pages = lastPages.length;
|
44
43
|
const wasmPages = mem.buffer.byteLength / PageSize;
|
45
44
|
|
46
|
-
out += `\x1B[1mallocated ${mem.buffer.byteLength / 1024}
|
45
|
+
out += `\x1B[1mallocated ${mem.buffer.byteLength / 1024}KiB\x1B[0m (using ${wasmPages} Wasm page${wasmPages === 1 ? '' : 's'})\n\n`;
|
47
46
|
|
48
47
|
const buf = new Uint8Array(mem.buffer);
|
49
48
|
|
@@ -55,10 +54,16 @@ const memoryToString = mem => {
|
|
55
54
|
}
|
56
55
|
|
57
56
|
out += `\x1B[0m\x1B[1m name${' '.repeat(longestName - 4)} \x1B[0m\x1B[90m│\x1B[0m\x1B[1m type${' '.repeat(longestType - 4)} \x1B[0m\x1B[90m│\x1B[0m\x1B[1m memory\x1B[0m\n`; // ─
|
58
|
-
for (let i = 0; i <
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
for (let i = 0; i < wasmPages; i++) {
|
58
|
+
if (lastPages[i]) {
|
59
|
+
const [ type, name ] = lastPages[i].split(': ');
|
60
|
+
// out += `\x1B[36m${lastPages[i].replace(':', '\x1B[90m:\x1B[34m')}\x1B[90m${' '.repeat(longestName - lastPages[i].length)} | \x1B[0m`;
|
61
|
+
out += ` \x1B[34m${name}${' '.repeat(longestName - name.length)} \x1B[90m│\x1B[0m \x1B[36m${type}${' '.repeat(longestType - type.length)} \x1B[90m│\x1B[0m `;
|
62
|
+
} else {
|
63
|
+
const type = '???';
|
64
|
+
const name = '???';
|
65
|
+
out += ` \x1B[34m${name}${' '.repeat(longestName - name.length)} \x1B[90m│\x1B[0m \x1B[36m${type}${' '.repeat(longestType - type.length)} \x1B[90m│\x1B[0m `;
|
66
|
+
}
|
62
67
|
|
63
68
|
for (let j = 0; j < 40; j++) {
|
64
69
|
const val = buf[i * pageSize + j];
|
@@ -75,13 +80,13 @@ const memoryToString = mem => {
|
|
75
80
|
};
|
76
81
|
|
77
82
|
let prev = '';
|
78
|
-
const run =
|
83
|
+
const run = (source, _context, _filename, callback, run = true) => {
|
79
84
|
// hack: print "secret" before latest code ran to only enable printing for new code
|
80
85
|
|
81
86
|
let toRun = (prev ? (prev + `;\nprint(-0x1337);\n`) : '') + source.trim();
|
82
87
|
|
83
88
|
let shouldPrint = !prev;
|
84
|
-
const { exports, pages } =
|
89
|
+
const { exports, pages } = compile(toRun, [], {}, str => {
|
85
90
|
if (shouldPrint) process.stdout.write(str);
|
86
91
|
if (str === '-4919') shouldPrint = true;
|
87
92
|
});
|
@@ -122,12 +127,12 @@ replServer.defineCommand('memory', {
|
|
122
127
|
});
|
123
128
|
replServer.defineCommand('asm', {
|
124
129
|
help: 'Log Wasm decompiled bytecode',
|
125
|
-
|
130
|
+
action() {
|
126
131
|
this.clearBufferedCommand();
|
127
132
|
|
128
133
|
try {
|
129
134
|
process.argv.push('--opt-funcs');
|
130
|
-
|
135
|
+
run('', null, null, () => {}, false);
|
131
136
|
process.argv.pop();
|
132
137
|
} catch { }
|
133
138
|
|
@@ -136,7 +141,7 @@ replServer.defineCommand('asm', {
|
|
136
141
|
});
|
137
142
|
replServer.defineCommand('js', {
|
138
143
|
help: 'Log JS being actually ran',
|
139
|
-
|
144
|
+
action() {
|
140
145
|
this.clearBufferedCommand();
|
141
146
|
console.log(prev);
|
142
147
|
this.displayPrompt();
|