porffor 0.0.0-a2afb57 → 0.0.0-afb21d1
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/README.md +1 -1
- package/compiler/builtins.js +14 -11
- package/compiler/parse.js +0 -1
- package/package.json +1 -1
- package/rhemyn/compile.js +213 -213
- package/runner/index.js +3 -5
- package/runner/info.js +2 -37
- package/c +0 -0
- package/c.exe +0 -0
- package/compiler/builtins/base64.js +0 -92
- package/cool.exe +0 -0
- package/g +0 -0
- package/g.exe +0 -0
- package/hi.c +0 -37
- package/out +0 -0
- package/out.exe +0 -0
- package/porf.cmd +0 -2
- package/r.js +0 -39
- package/runner/transform.js +0 -15
- package/sw.js +0 -26
- package/t.js +0 -31
- package/tmp.c +0 -61
package/README.md
CHANGED
package/compiler/builtins.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import { Blocktype, Opcodes, Valtype } from "./wasmSpec.js";
|
2
2
|
import { number, i32x4 } from "./embedding.js";
|
3
|
-
import { signedLEB128 } from "./encoding.js";
|
4
3
|
|
5
4
|
export const importedFuncs = [
|
6
5
|
{
|
@@ -416,13 +415,13 @@ export const BuiltinFuncs = function() {
|
|
416
415
|
wasm: [
|
417
416
|
// setup: s1 = state0, s0 = state1, state0 = s0
|
418
417
|
[ Opcodes.global_get, 0 ], // state0
|
419
|
-
[ Opcodes.
|
418
|
+
[ Opcodes.local_tee, 0 ], // s1
|
420
419
|
[ Opcodes.global_get, 1 ], // state1
|
421
420
|
[ Opcodes.local_tee, 1, ], // s0
|
422
421
|
[ Opcodes.global_set, 0 ], // state0
|
423
422
|
|
424
423
|
// s1 ^= s1 << 23
|
425
|
-
[ Opcodes.local_get, 0 ], // s1
|
424
|
+
// [ Opcodes.local_get, 0 ], // s1
|
426
425
|
[ Opcodes.local_get, 0 ], // s1
|
427
426
|
[ Opcodes.i64_const, 23 ],
|
428
427
|
[ Opcodes.i64_shl ], // <<
|
@@ -452,20 +451,24 @@ export const BuiltinFuncs = function() {
|
|
452
451
|
|
453
452
|
// you thought it was over? now we need the result as a f64 between 0-1 :)
|
454
453
|
|
455
|
-
//
|
454
|
+
// state1 + s0
|
456
455
|
[ Opcodes.global_get, 1 ], // state1
|
457
456
|
[ Opcodes.local_get, 1 ], // s0
|
458
457
|
[ Opcodes.i64_add ],
|
459
458
|
|
460
|
-
|
461
|
-
|
459
|
+
// should we >> 12 here?
|
460
|
+
// it feels like it but it breaks values
|
461
|
+
|
462
|
+
// | 0x3FF0000000000000
|
463
|
+
[ Opcodes.i64_const, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xf8, 0x3f ],
|
464
|
+
[ Opcodes.i64_or ],
|
462
465
|
|
463
|
-
//
|
464
|
-
[ Opcodes.
|
466
|
+
// bit cast as f64
|
467
|
+
[ Opcodes.f64_reinterpret_i64 ],
|
465
468
|
|
466
|
-
//
|
467
|
-
...number(1
|
468
|
-
[ Opcodes.
|
469
|
+
// - 1
|
470
|
+
...number(1),
|
471
|
+
[ Opcodes.f64_sub ],
|
469
472
|
]
|
470
473
|
};
|
471
474
|
|
package/compiler/parse.js
CHANGED
package/package.json
CHANGED
package/rhemyn/compile.js
CHANGED
@@ -1,214 +1,214 @@
|
|
1
|
-
import { Blocktype, Opcodes, Valtype, PageSize, ValtypeSize } from '../compiler/wasmSpec.js';
|
2
|
-
import { number } from '../compiler/embedding.js';
|
3
|
-
import { signedLEB128, unsignedLEB128 } from '../compiler/encoding.js';
|
4
|
-
import parse from './parse.js';
|
5
|
-
|
6
|
-
// local indexes
|
7
|
-
const BasePointer = 0; // base string pointer
|
8
|
-
const IterPointer = 1; // this iteration base pointer
|
9
|
-
const EndPointer = 2; // pointer for the end
|
10
|
-
const Counter = 3; // what char we are running on
|
11
|
-
const Pointer = 4; // next char BYTE pointer
|
12
|
-
const Length = 5;
|
13
|
-
const Tmp = 6;
|
14
|
-
|
15
|
-
let exprLastGet = false;
|
16
|
-
const generate = (node, negated = false, get = true, func = 'test') => {
|
17
|
-
let out = [];
|
18
|
-
switch (node.type) {
|
19
|
-
case 'Expression':
|
20
|
-
exprLastGet = false;
|
21
|
-
out = [
|
22
|
-
// set length local
|
23
|
-
[ Opcodes.local_get, BasePointer ],
|
24
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
25
|
-
[ Opcodes.local_set, Length ],
|
26
|
-
|
27
|
-
// set iter pointer local as base + sizeof i32 initially
|
28
|
-
[ Opcodes.local_get, BasePointer ],
|
29
|
-
...number(ValtypeSize.i32, Valtype.i32),
|
30
|
-
[ Opcodes.i32_add ],
|
31
|
-
[ Opcodes.local_set, IterPointer ],
|
32
|
-
|
33
|
-
[ Opcodes.loop, Blocktype.void ],
|
34
|
-
|
35
|
-
// reset pointer as iter pointer
|
36
|
-
[ Opcodes.local_get, IterPointer ],
|
37
|
-
[ Opcodes.local_set, Pointer ],
|
38
|
-
|
39
|
-
[ Opcodes.block, Blocktype.void ],
|
40
|
-
|
41
|
-
// generate checks
|
42
|
-
...node.body.flatMap((x, i) => {
|
43
|
-
exprLastGet = x.type !== 'Group' && i === (node.body.length - 1);
|
44
|
-
return generate(x, negated);
|
45
|
-
}),
|
46
|
-
|
47
|
-
// reached end without branching out, successful match
|
48
|
-
...({
|
49
|
-
test: number(1, Valtype.i32),
|
50
|
-
search: [
|
51
|
-
[ Opcodes.local_get, Counter ]
|
52
|
-
]
|
53
|
-
})[func],
|
54
|
-
[ Opcodes.return ],
|
55
|
-
|
56
|
-
[ Opcodes.end ],
|
57
|
-
|
58
|
-
// increment iter pointer by sizeof i16
|
59
|
-
[ Opcodes.local_get, IterPointer ],
|
60
|
-
...number(ValtypeSize.i16, Valtype.i32),
|
61
|
-
[ Opcodes.i32_add ],
|
62
|
-
[ Opcodes.local_set, IterPointer ],
|
63
|
-
|
64
|
-
// increment counter by 1, check if eq length, if not loop
|
65
|
-
[ Opcodes.local_get, Counter ],
|
66
|
-
...number(1, Valtype.i32),
|
67
|
-
[ Opcodes.i32_add ],
|
68
|
-
[ Opcodes.local_tee, Counter ],
|
69
|
-
|
70
|
-
[ Opcodes.local_get, Length ],
|
71
|
-
[ Opcodes.i32_ne ],
|
72
|
-
|
73
|
-
[ Opcodes.br_if, 0 ],
|
74
|
-
[ Opcodes.end ],
|
75
|
-
|
76
|
-
// no match, return 0
|
77
|
-
...number(({
|
78
|
-
test: 0,
|
79
|
-
search: -1
|
80
|
-
})[func], Valtype.i32)
|
81
|
-
];
|
82
|
-
|
83
|
-
if (globalThis.regexLog) {
|
84
|
-
const underline = x => `\u001b[4m\u001b[1m${x}\u001b[0m`;
|
85
|
-
console.log(`\n${underline('ast')}`);
|
86
|
-
console.log(node);
|
87
|
-
console.log(`\n${underline('wasm bytecode')}\n` + decompile(out) + '\n');
|
88
|
-
}
|
89
|
-
|
90
|
-
break;
|
91
|
-
|
92
|
-
case 'Character':
|
93
|
-
out = generateChar(node, node.negated ^ negated, get);
|
94
|
-
break;
|
95
|
-
|
96
|
-
case 'Set':
|
97
|
-
out = generateSet(node, node.negated, get);
|
98
|
-
break;
|
99
|
-
|
100
|
-
case 'Group':
|
101
|
-
out = generateGroup(node, negated, get);
|
102
|
-
break;
|
103
|
-
|
104
|
-
case 'Range':
|
105
|
-
out = generateRange(node, negated, get);
|
106
|
-
break;
|
107
|
-
}
|
108
|
-
|
109
|
-
return out;
|
110
|
-
};
|
111
|
-
|
112
|
-
const getNextChar = () => [
|
113
|
-
// get char from pointer
|
114
|
-
[ Opcodes.local_get, Pointer ],
|
115
|
-
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(0) ],
|
116
|
-
|
117
|
-
...(exprLastGet ? [] : [
|
118
|
-
// pointer += sizeof i16
|
119
|
-
[ Opcodes.local_get, Pointer ],
|
120
|
-
...number(ValtypeSize.i16, Valtype.i32),
|
121
|
-
[ Opcodes.i32_add ],
|
122
|
-
[ Opcodes.local_set, Pointer ]
|
123
|
-
])
|
124
|
-
];
|
125
|
-
|
126
|
-
const checkFailure = () => [
|
127
|
-
// surely we do not need to do this for every single mismatch, right?
|
128
|
-
/* [ Opcodes.if, Blocktype.void ],
|
129
|
-
...number(0, Valtype.i32),
|
130
|
-
[ Opcodes.return ],
|
131
|
-
[ Opcodes.end ], */
|
132
|
-
|
133
|
-
[ Opcodes.br_if, 0 ]
|
134
|
-
];
|
135
|
-
|
136
|
-
const generateChar = (node, negated, get) => {
|
137
|
-
return [
|
138
|
-
...(get ? getNextChar() : []),
|
139
|
-
...number(node.char.charCodeAt(0), Valtype.i32),
|
140
|
-
negated ? [ Opcodes.i32_eq ] : [ Opcodes.i32_ne ],
|
141
|
-
...(get ? checkFailure(): [])
|
142
|
-
];
|
143
|
-
};
|
144
|
-
|
145
|
-
const generateSet = (node, negated, get) => {
|
146
|
-
// for a single char we do not need a tmp, it is like just
|
147
|
-
const singleChar = node.body.length === 1 && node.body[0].type === 'Character';
|
148
|
-
|
149
|
-
let out = [
|
150
|
-
...(get ? getNextChar() : []),
|
151
|
-
...(singleChar ? [] : [ [ Opcodes.local_set, Tmp ] ]),
|
152
|
-
];
|
153
|
-
|
154
|
-
for (const x of node.body) {
|
155
|
-
out = [
|
156
|
-
...out,
|
157
|
-
...(singleChar ? [] : [ [ Opcodes.local_get, Tmp ] ]),
|
158
|
-
...generate(x, negated, false)
|
159
|
-
];
|
160
|
-
}
|
161
|
-
|
162
|
-
out = out.concat(new Array(node.body.length - 1).fill(negated ? [ Opcodes.i32_or ] : [ Opcodes.i32_and ]));
|
163
|
-
|
164
|
-
return [
|
165
|
-
...out,
|
166
|
-
...checkFailure()
|
167
|
-
];
|
168
|
-
};
|
169
|
-
|
170
|
-
const generateRange = (node, negated, get) => {
|
171
|
-
return [
|
172
|
-
...(get ? getNextChar() : []),
|
173
|
-
...(get ? [ [ Opcodes.local_tee, Tmp ] ] : []),
|
174
|
-
|
175
|
-
...number(node.from.charCodeAt(0), Valtype.i32),
|
176
|
-
// negated ? [ Opcodes.i32_lt_s ] : [ Opcodes.i32_ge_s ],
|
177
|
-
negated ? [ Opcodes.i32_ge_s ] : [ Opcodes.i32_lt_s ],
|
178
|
-
|
179
|
-
[ Opcodes.local_get, Tmp ],
|
180
|
-
...number(node.to.charCodeAt(0), Valtype.i32),
|
181
|
-
// negated ? [ Opcodes.i32_gt_s ] : [ Opcodes.i32_le_s ],
|
182
|
-
negated ? [ Opcodes.i32_le_s ] : [ Opcodes.i32_gt_s ],
|
183
|
-
|
184
|
-
negated ? [ Opcodes.i32_and ] : [ Opcodes.i32_or ],
|
185
|
-
...(get ? checkFailure(): [])
|
186
|
-
];
|
187
|
-
};
|
188
|
-
|
189
|
-
const generateGroup = (node, negated, get) => {
|
190
|
-
|
191
|
-
};
|
192
|
-
|
193
|
-
export const test = (regex, index = 0, name = 'regex_test_' + regex) => outputFunc(generate(parse(regex), false, true, 'test'), name, index);
|
194
|
-
export const search = (regex, index = 0, name = 'regex_search_' + regex) => outputFunc(generate(parse(regex), false, true, 'search'), name, index);
|
195
|
-
|
196
|
-
const outputFunc = (wasm, name, index) => ({
|
197
|
-
name,
|
198
|
-
index,
|
199
|
-
wasm,
|
200
|
-
|
201
|
-
export: true,
|
202
|
-
params: [ Valtype.i32 ],
|
203
|
-
returns: [ Valtype.i32 ],
|
204
|
-
returnType: 0xffffffffffff1, // boolean - todo: do not hardcode this
|
205
|
-
locals: {
|
206
|
-
basePointer: { idx: 0, type: Valtype.i32 },
|
207
|
-
iterPointer: { idx: 1, type: Valtype.i32 },
|
208
|
-
endPointer: { idx: 2, type: Valtype.i32 },
|
209
|
-
counter: { idx: 3, type: Valtype.i32 },
|
210
|
-
pointer: { idx: 4, type: Valtype.i32 },
|
211
|
-
length: { idx: 5, type: Valtype.i32 },
|
212
|
-
tmp: { idx: 6, type: Valtype.i32 },
|
213
|
-
}
|
1
|
+
import { Blocktype, Opcodes, Valtype, PageSize, ValtypeSize } from '../compiler/wasmSpec.js';
|
2
|
+
import { number } from '../compiler/embedding.js';
|
3
|
+
import { signedLEB128, unsignedLEB128 } from '../compiler/encoding.js';
|
4
|
+
import parse from './parse.js';
|
5
|
+
|
6
|
+
// local indexes
|
7
|
+
const BasePointer = 0; // base string pointer
|
8
|
+
const IterPointer = 1; // this iteration base pointer
|
9
|
+
const EndPointer = 2; // pointer for the end
|
10
|
+
const Counter = 3; // what char we are running on
|
11
|
+
const Pointer = 4; // next char BYTE pointer
|
12
|
+
const Length = 5;
|
13
|
+
const Tmp = 6;
|
14
|
+
|
15
|
+
let exprLastGet = false;
|
16
|
+
const generate = (node, negated = false, get = true, func = 'test') => {
|
17
|
+
let out = [];
|
18
|
+
switch (node.type) {
|
19
|
+
case 'Expression':
|
20
|
+
exprLastGet = false;
|
21
|
+
out = [
|
22
|
+
// set length local
|
23
|
+
[ Opcodes.local_get, BasePointer ],
|
24
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, ...unsignedLEB128(0) ],
|
25
|
+
[ Opcodes.local_set, Length ],
|
26
|
+
|
27
|
+
// set iter pointer local as base + sizeof i32 initially
|
28
|
+
[ Opcodes.local_get, BasePointer ],
|
29
|
+
...number(ValtypeSize.i32, Valtype.i32),
|
30
|
+
[ Opcodes.i32_add ],
|
31
|
+
[ Opcodes.local_set, IterPointer ],
|
32
|
+
|
33
|
+
[ Opcodes.loop, Blocktype.void ],
|
34
|
+
|
35
|
+
// reset pointer as iter pointer
|
36
|
+
[ Opcodes.local_get, IterPointer ],
|
37
|
+
[ Opcodes.local_set, Pointer ],
|
38
|
+
|
39
|
+
[ Opcodes.block, Blocktype.void ],
|
40
|
+
|
41
|
+
// generate checks
|
42
|
+
...node.body.flatMap((x, i) => {
|
43
|
+
exprLastGet = x.type !== 'Group' && i === (node.body.length - 1);
|
44
|
+
return generate(x, negated);
|
45
|
+
}),
|
46
|
+
|
47
|
+
// reached end without branching out, successful match
|
48
|
+
...({
|
49
|
+
test: number(1, Valtype.i32),
|
50
|
+
search: [
|
51
|
+
[ Opcodes.local_get, Counter ]
|
52
|
+
]
|
53
|
+
})[func],
|
54
|
+
[ Opcodes.return ],
|
55
|
+
|
56
|
+
[ Opcodes.end ],
|
57
|
+
|
58
|
+
// increment iter pointer by sizeof i16
|
59
|
+
[ Opcodes.local_get, IterPointer ],
|
60
|
+
...number(ValtypeSize.i16, Valtype.i32),
|
61
|
+
[ Opcodes.i32_add ],
|
62
|
+
[ Opcodes.local_set, IterPointer ],
|
63
|
+
|
64
|
+
// increment counter by 1, check if eq length, if not loop
|
65
|
+
[ Opcodes.local_get, Counter ],
|
66
|
+
...number(1, Valtype.i32),
|
67
|
+
[ Opcodes.i32_add ],
|
68
|
+
[ Opcodes.local_tee, Counter ],
|
69
|
+
|
70
|
+
[ Opcodes.local_get, Length ],
|
71
|
+
[ Opcodes.i32_ne ],
|
72
|
+
|
73
|
+
[ Opcodes.br_if, 0 ],
|
74
|
+
[ Opcodes.end ],
|
75
|
+
|
76
|
+
// no match, return 0
|
77
|
+
...number(({
|
78
|
+
test: 0,
|
79
|
+
search: -1
|
80
|
+
})[func], Valtype.i32)
|
81
|
+
];
|
82
|
+
|
83
|
+
if (globalThis.regexLog) {
|
84
|
+
const underline = x => `\u001b[4m\u001b[1m${x}\u001b[0m`;
|
85
|
+
console.log(`\n${underline('ast')}`);
|
86
|
+
console.log(node);
|
87
|
+
console.log(`\n${underline('wasm bytecode')}\n` + decompile(out) + '\n');
|
88
|
+
}
|
89
|
+
|
90
|
+
break;
|
91
|
+
|
92
|
+
case 'Character':
|
93
|
+
out = generateChar(node, node.negated ^ negated, get);
|
94
|
+
break;
|
95
|
+
|
96
|
+
case 'Set':
|
97
|
+
out = generateSet(node, node.negated, get);
|
98
|
+
break;
|
99
|
+
|
100
|
+
case 'Group':
|
101
|
+
out = generateGroup(node, negated, get);
|
102
|
+
break;
|
103
|
+
|
104
|
+
case 'Range':
|
105
|
+
out = generateRange(node, negated, get);
|
106
|
+
break;
|
107
|
+
}
|
108
|
+
|
109
|
+
return out;
|
110
|
+
};
|
111
|
+
|
112
|
+
const getNextChar = () => [
|
113
|
+
// get char from pointer
|
114
|
+
[ Opcodes.local_get, Pointer ],
|
115
|
+
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(0) ],
|
116
|
+
|
117
|
+
...(exprLastGet ? [] : [
|
118
|
+
// pointer += sizeof i16
|
119
|
+
[ Opcodes.local_get, Pointer ],
|
120
|
+
...number(ValtypeSize.i16, Valtype.i32),
|
121
|
+
[ Opcodes.i32_add ],
|
122
|
+
[ Opcodes.local_set, Pointer ]
|
123
|
+
])
|
124
|
+
];
|
125
|
+
|
126
|
+
const checkFailure = () => [
|
127
|
+
// surely we do not need to do this for every single mismatch, right?
|
128
|
+
/* [ Opcodes.if, Blocktype.void ],
|
129
|
+
...number(0, Valtype.i32),
|
130
|
+
[ Opcodes.return ],
|
131
|
+
[ Opcodes.end ], */
|
132
|
+
|
133
|
+
[ Opcodes.br_if, 0 ]
|
134
|
+
];
|
135
|
+
|
136
|
+
const generateChar = (node, negated, get) => {
|
137
|
+
return [
|
138
|
+
...(get ? getNextChar() : []),
|
139
|
+
...number(node.char.charCodeAt(0), Valtype.i32),
|
140
|
+
negated ? [ Opcodes.i32_eq ] : [ Opcodes.i32_ne ],
|
141
|
+
...(get ? checkFailure(): [])
|
142
|
+
];
|
143
|
+
};
|
144
|
+
|
145
|
+
const generateSet = (node, negated, get) => {
|
146
|
+
// for a single char we do not need a tmp, it is like just
|
147
|
+
const singleChar = node.body.length === 1 && node.body[0].type === 'Character';
|
148
|
+
|
149
|
+
let out = [
|
150
|
+
...(get ? getNextChar() : []),
|
151
|
+
...(singleChar ? [] : [ [ Opcodes.local_set, Tmp ] ]),
|
152
|
+
];
|
153
|
+
|
154
|
+
for (const x of node.body) {
|
155
|
+
out = [
|
156
|
+
...out,
|
157
|
+
...(singleChar ? [] : [ [ Opcodes.local_get, Tmp ] ]),
|
158
|
+
...generate(x, negated, false)
|
159
|
+
];
|
160
|
+
}
|
161
|
+
|
162
|
+
out = out.concat(new Array(node.body.length - 1).fill(negated ? [ Opcodes.i32_or ] : [ Opcodes.i32_and ]));
|
163
|
+
|
164
|
+
return [
|
165
|
+
...out,
|
166
|
+
...checkFailure()
|
167
|
+
];
|
168
|
+
};
|
169
|
+
|
170
|
+
const generateRange = (node, negated, get) => {
|
171
|
+
return [
|
172
|
+
...(get ? getNextChar() : []),
|
173
|
+
...(get ? [ [ Opcodes.local_tee, Tmp ] ] : []),
|
174
|
+
|
175
|
+
...number(node.from.charCodeAt(0), Valtype.i32),
|
176
|
+
// negated ? [ Opcodes.i32_lt_s ] : [ Opcodes.i32_ge_s ],
|
177
|
+
negated ? [ Opcodes.i32_ge_s ] : [ Opcodes.i32_lt_s ],
|
178
|
+
|
179
|
+
[ Opcodes.local_get, Tmp ],
|
180
|
+
...number(node.to.charCodeAt(0), Valtype.i32),
|
181
|
+
// negated ? [ Opcodes.i32_gt_s ] : [ Opcodes.i32_le_s ],
|
182
|
+
negated ? [ Opcodes.i32_le_s ] : [ Opcodes.i32_gt_s ],
|
183
|
+
|
184
|
+
negated ? [ Opcodes.i32_and ] : [ Opcodes.i32_or ],
|
185
|
+
...(get ? checkFailure(): [])
|
186
|
+
];
|
187
|
+
};
|
188
|
+
|
189
|
+
const generateGroup = (node, negated, get) => {
|
190
|
+
|
191
|
+
};
|
192
|
+
|
193
|
+
export const test = (regex, index = 0, name = 'regex_test_' + regex) => outputFunc(generate(parse(regex), false, true, 'test'), name, index);
|
194
|
+
export const search = (regex, index = 0, name = 'regex_search_' + regex) => outputFunc(generate(parse(regex), false, true, 'search'), name, index);
|
195
|
+
|
196
|
+
const outputFunc = (wasm, name, index) => ({
|
197
|
+
name,
|
198
|
+
index,
|
199
|
+
wasm,
|
200
|
+
|
201
|
+
export: true,
|
202
|
+
params: [ Valtype.i32 ],
|
203
|
+
returns: [ Valtype.i32 ],
|
204
|
+
returnType: 0xffffffffffff1, // boolean - todo: do not hardcode this
|
205
|
+
locals: {
|
206
|
+
basePointer: { idx: 0, type: Valtype.i32 },
|
207
|
+
iterPointer: { idx: 1, type: Valtype.i32 },
|
208
|
+
endPointer: { idx: 2, type: Valtype.i32 },
|
209
|
+
counter: { idx: 3, type: Valtype.i32 },
|
210
|
+
pointer: { idx: 4, type: Valtype.i32 },
|
211
|
+
length: { idx: 5, type: Valtype.i32 },
|
212
|
+
tmp: { idx: 6, type: Valtype.i32 },
|
213
|
+
}
|
214
214
|
});
|
package/runner/index.js
CHANGED
@@ -34,14 +34,12 @@ const source = fs.readFileSync(file, 'utf8');
|
|
34
34
|
|
35
35
|
let cache = '';
|
36
36
|
const print = str => {
|
37
|
-
|
37
|
+
cache += str;
|
38
38
|
|
39
39
|
if (str === '\n') {
|
40
40
|
process.stdout.write(cache);
|
41
41
|
cache = '';
|
42
|
-
}
|
43
|
-
|
44
|
-
process.stdout.write(str);
|
42
|
+
}
|
45
43
|
};
|
46
44
|
|
47
45
|
try {
|
@@ -51,5 +49,5 @@ try {
|
|
51
49
|
if (cache) process.stdout.write(cache);
|
52
50
|
} catch (e) {
|
53
51
|
if (cache) process.stdout.write(cache);
|
54
|
-
console.error(
|
52
|
+
console.error(`${e.constructor.name}: ${e.message}`);
|
55
53
|
}
|
package/runner/info.js
CHANGED
@@ -36,7 +36,7 @@ const print = str => {
|
|
36
36
|
};
|
37
37
|
|
38
38
|
const t0 = performance.now();
|
39
|
-
const { wasm, exports
|
39
|
+
const { wasm, exports } = await compile(source, raw ? [ 'module' ] : [ 'module', 'info' ], {}, print);
|
40
40
|
|
41
41
|
if (!raw && typeof Deno === 'undefined') fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
42
42
|
|
@@ -51,39 +51,4 @@ if (!process.argv.includes('-no-run')) {
|
|
51
51
|
}
|
52
52
|
|
53
53
|
if (!raw) console.log(bold(`wasm binary is ${wasm.byteLength} bytes`));
|
54
|
-
if (!raw) console.log(`total: ${(performance.now() - t0).toFixed(2)}ms`);
|
55
|
-
|
56
|
-
if (!raw && process.argv.includes('-mem') && exports.$) {
|
57
|
-
console.log();
|
58
|
-
|
59
|
-
let lastMemory, lastPages;
|
60
|
-
const PageSize = 65536;
|
61
|
-
const memoryToString = mem => {
|
62
|
-
let out = '';
|
63
|
-
const pages = lastPages.length;
|
64
|
-
const wasmPages = mem.buffer.byteLength / PageSize;
|
65
|
-
|
66
|
-
out += `\x1B[1mallocated ${mem.buffer.byteLength / 1024}KiB\x1B[0m for ${pages} things using ${wasmPages} Wasm page${wasmPages === 1 ? '' : 's'}\n`;
|
67
|
-
|
68
|
-
const buf = new Uint8Array(mem.buffer);
|
69
|
-
|
70
|
-
for (let i = 0; i < pages; i++) {
|
71
|
-
out += `\x1B[36m${lastPages[i]}\x1B[2m | \x1B[0m`;
|
72
|
-
|
73
|
-
for (let j = 0; j < 50; j++) {
|
74
|
-
const val = buf[i * pageSize + j];
|
75
|
-
if (val === 0) out += '\x1B[2m';
|
76
|
-
out += val.toString(16).padStart(2, '0');
|
77
|
-
if (val === 0) out += '\x1B[0m';
|
78
|
-
out += ' ';
|
79
|
-
}
|
80
|
-
out += '\n';
|
81
|
-
}
|
82
|
-
|
83
|
-
return out;
|
84
|
-
};
|
85
|
-
|
86
|
-
lastPages = [...pages.keys()];
|
87
|
-
lastMemory = exports.$;
|
88
|
-
console.log(memoryToString(lastMemory));
|
89
|
-
}
|
54
|
+
if (!raw) console.log(`total: ${(performance.now() - t0).toFixed(2)}ms`);
|
package/c
DELETED
Binary file
|
package/c.exe
DELETED
Binary file
|
@@ -1,92 +0,0 @@
|
|
1
|
-
var btoa_a = str => {
|
2
|
-
// todo: throw invalid character for unicode
|
3
|
-
|
4
|
-
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
5
|
-
const mask = (1 << 6) - 1;
|
6
|
-
|
7
|
-
let out = '';
|
8
|
-
let bits = 0, buffer = 0;
|
9
|
-
for (let i = 0; i < str.length; i++) {
|
10
|
-
buffer = (buffer << 8) | (0xff & str.charCodeAt(i));
|
11
|
-
bits += 8;
|
12
|
-
|
13
|
-
while (bits > 6) {
|
14
|
-
bits -= 6;
|
15
|
-
out += chars[mask & (buffer >> bits)];
|
16
|
-
}
|
17
|
-
}
|
18
|
-
|
19
|
-
if (bits) {
|
20
|
-
out += chars[mask & (buffer << (6 - bits))]
|
21
|
-
}
|
22
|
-
|
23
|
-
while ((out.length * 6) & 7) {
|
24
|
-
out += '=';
|
25
|
-
}
|
26
|
-
|
27
|
-
return out;
|
28
|
-
};
|
29
|
-
|
30
|
-
var btoa = function (input) {
|
31
|
-
// todo: throw invalid character for unicode
|
32
|
-
const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
33
|
-
|
34
|
-
let output = "";
|
35
|
-
let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
36
|
-
let i = 0;
|
37
|
-
|
38
|
-
while (i < input.length) {
|
39
|
-
chr1 = input.charCodeAt(i++);
|
40
|
-
chr2 = input.charCodeAt(i++);
|
41
|
-
chr3 = input.charCodeAt(i++);
|
42
|
-
|
43
|
-
enc1 = chr1 >> 2;
|
44
|
-
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
45
|
-
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
46
|
-
enc4 = chr3 & 63;
|
47
|
-
|
48
|
-
if (isNaN(chr2)) {
|
49
|
-
enc3 = enc4 = 64;
|
50
|
-
} else if (isNaN(chr3)) {
|
51
|
-
enc4 = 64;
|
52
|
-
}
|
53
|
-
|
54
|
-
output += keyStr.charAt(enc1);
|
55
|
-
output += keyStr.charAt(enc2);
|
56
|
-
output += keyStr.charAt(enc3);
|
57
|
-
output += keyStr.charAt(enc4);
|
58
|
-
}
|
59
|
-
|
60
|
-
return output;
|
61
|
-
};
|
62
|
-
|
63
|
-
var atob_b = function (input) {
|
64
|
-
const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
65
|
-
|
66
|
-
let output = "";
|
67
|
-
let chr1, chr2, chr3;
|
68
|
-
let enc1, enc2, enc3, enc4;
|
69
|
-
let i = 0;
|
70
|
-
|
71
|
-
while (i < input.length) {
|
72
|
-
enc1 = keyStr.indexOf(input.charAt(i++));
|
73
|
-
enc2 = keyStr.indexOf(input.charAt(i++));
|
74
|
-
enc3 = keyStr.indexOf(input.charAt(i++));
|
75
|
-
enc4 = keyStr.indexOf(input.charAt(i++));
|
76
|
-
|
77
|
-
chr1 = (enc1 << 2) | (enc2 >> 4);
|
78
|
-
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
79
|
-
chr3 = ((enc3 & 3) << 6) | enc4;
|
80
|
-
|
81
|
-
output += String.fromCharCode(chr1);
|
82
|
-
|
83
|
-
if (enc3 != 64) {
|
84
|
-
output += String.fromCharCode(chr2);
|
85
|
-
}
|
86
|
-
if (enc4 != 64) {
|
87
|
-
output += String.fromCharCode(chr3);
|
88
|
-
}
|
89
|
-
}
|
90
|
-
|
91
|
-
return output;
|
92
|
-
};
|
package/cool.exe
DELETED
Binary file
|
package/g
DELETED
Binary file
|
package/g.exe
DELETED
Binary file
|
package/hi.c
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
#include <stdio.h>
|
2
|
-
|
3
|
-
double inline f64_f(double x, double y) {
|
4
|
-
return x - (int)(x / y) * y;
|
5
|
-
}
|
6
|
-
|
7
|
-
double isPrime(double number) {
|
8
|
-
double i;
|
9
|
-
|
10
|
-
if (number < 2e+0) {
|
11
|
-
return 0e+0;
|
12
|
-
}
|
13
|
-
i = 2e+0;
|
14
|
-
while (i < number) {
|
15
|
-
if (f64_f(number, i) == 0e+0) {
|
16
|
-
return 0e+0;
|
17
|
-
}
|
18
|
-
i = i + 1e+0;
|
19
|
-
}
|
20
|
-
return 1e+0;
|
21
|
-
}
|
22
|
-
|
23
|
-
int main() {
|
24
|
-
double sum;
|
25
|
-
double counter;
|
26
|
-
|
27
|
-
sum = 0e+0;
|
28
|
-
counter = 0e+0;
|
29
|
-
while (counter <= 1e+5) {
|
30
|
-
if (isPrime(counter) == 1e+0) {
|
31
|
-
sum = sum + counter;
|
32
|
-
}
|
33
|
-
counter = counter + 1e+0;
|
34
|
-
}
|
35
|
-
printf("%f\n", sum);
|
36
|
-
}
|
37
|
-
|
package/out
DELETED
Binary file
|
package/out.exe
DELETED
Binary file
|
package/porf.cmd
DELETED
package/r.js
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
compareArray.isSameValue = function(a, b) {
|
2
|
-
if (a === 0 && b === 0) return 1 / a === 1 / b;
|
3
|
-
if (a !== a && b !== b) return true;
|
4
|
-
|
5
|
-
return a === b;
|
6
|
-
};
|
7
|
-
|
8
|
-
function compareArray(a, b) {
|
9
|
-
// if either are nullish
|
10
|
-
if (a == null || b == null) return false;
|
11
|
-
|
12
|
-
// megahack: all arrays from now on will be >0 pointer
|
13
|
-
const _hack = '';
|
14
|
-
|
15
|
-
// hack: enforce type inference of being arrays
|
16
|
-
a ??= [];
|
17
|
-
b ??= [];
|
18
|
-
|
19
|
-
if (b.length !== a.length) {
|
20
|
-
return false;
|
21
|
-
}
|
22
|
-
|
23
|
-
for (var i = 0; i < a.length; i++) {
|
24
|
-
if (!compareArray.isSameValue(b[i], a[i])) {
|
25
|
-
return false;
|
26
|
-
}
|
27
|
-
}
|
28
|
-
|
29
|
-
return true;
|
30
|
-
}
|
31
|
-
|
32
|
-
console.log(compareArray(null, []));
|
33
|
-
console.log(compareArray(undefined, []));
|
34
|
-
|
35
|
-
console.log(compareArray([], []));
|
36
|
-
console.log(compareArray([ 1 ], []));
|
37
|
-
console.log(compareArray([ 1 ], [ 1 ]));
|
38
|
-
console.log(compareArray([ 1, 2 ], [ 1 ]));
|
39
|
-
console.log(compareArray([ 1, 2 ], [ 1, 2 ]));
|
package/runner/transform.js
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
import compile from '../compiler/wrap.js';
|
2
|
-
import fs from 'node:fs';
|
3
|
-
|
4
|
-
const file = process.argv.slice(2).find(x => x[0] !== '-');
|
5
|
-
|
6
|
-
const source = fs.readFileSync(file, 'utf8');
|
7
|
-
|
8
|
-
const { wasm } = await compile(source);
|
9
|
-
|
10
|
-
// const out = `(async () => { const print = str => process.stdout.write(str); (await WebAssembly.instantiate(Uint8Array.from([${wasm.toString()}]), {'': { p: i => print(i.toString()), c: i => print(String.fromCharCode(i))}})).instance.exports.m()})()`;
|
11
|
-
// const out = `new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([${wasm.toString()}])),{'':{p:i=>process.stdout.write(i.toString())}}).exports.m()`;
|
12
|
-
const out = `const a=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([${wasm.toString()}])));const b=a.exports.m();console.log(Array.from(new Uint16Array(a.exports.$.buffer,b+4,new Int32Array(a.exports.$.buffer,b,1))).map(x=>String.fromCharCode(x)).join(''))`;
|
13
|
-
|
14
|
-
console.log(out);
|
15
|
-
eval(out);
|
package/sw.js
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
self.addEventListener('install', () => self.skipWaiting());
|
2
|
-
self.addEventListener('activate', e => e.waitUntil(self.clients.claim()));
|
3
|
-
|
4
|
-
const handleFetch = async request => {
|
5
|
-
const r = await fetch(request.mode === 'no-cors' ? new Request(request, { credentials: 'omit' }) : request).catch(e => console.error(e));
|
6
|
-
|
7
|
-
if (r.status === 0) {
|
8
|
-
return r;
|
9
|
-
}
|
10
|
-
|
11
|
-
const headers = new Headers(r.headers);
|
12
|
-
headers.set('Cross-Origin-Embedder-Policy', 'credentialless');
|
13
|
-
headers.set('Cross-Origin-Opener-Policy', 'same-origin');
|
14
|
-
// headers.set('Cross-Origin-Resource-Policy', 'cross-origin');
|
15
|
-
|
16
|
-
return new Response(r.body, { status: r.status, statusText: r.statusText, headers });
|
17
|
-
};
|
18
|
-
|
19
|
-
self.addEventListener('fetch', e => {
|
20
|
-
const { request } = e;
|
21
|
-
if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
|
22
|
-
return;
|
23
|
-
}
|
24
|
-
|
25
|
-
e.respondWith(handleFetch(request));
|
26
|
-
});
|
package/t.js
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
let assert = Object();
|
2
|
-
|
3
|
-
assert._isSameValue = function (a, b) {
|
4
|
-
if (a === b) {
|
5
|
-
// Handle +/-0 vs. -/+0
|
6
|
-
return a !== 0 || 1 / a === 1 / b;
|
7
|
-
}
|
8
|
-
|
9
|
-
// Handle NaN vs. NaN
|
10
|
-
return a !== a && b !== b;
|
11
|
-
|
12
|
-
// return a === b;
|
13
|
-
};
|
14
|
-
|
15
|
-
assert.sameValue = function (actual, expected) {
|
16
|
-
/* try {
|
17
|
-
if (assert._isSameValue(actual, expected)) {
|
18
|
-
return;
|
19
|
-
}
|
20
|
-
} catch (error) {
|
21
|
-
throw new Test262Error('_isSameValue operation threw');
|
22
|
-
} */
|
23
|
-
|
24
|
-
if (assert._isSameValue(actual, expected)) {
|
25
|
-
return;
|
26
|
-
}
|
27
|
-
|
28
|
-
throw new Test262Error('assert.sameValue failed');
|
29
|
-
};
|
30
|
-
|
31
|
-
assert.sameValue("lego".charAt(), "l");
|
package/tmp.c
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
#ifdef _WIN32
|
2
|
-
#include <windows.h>
|
3
|
-
#else
|
4
|
-
#include <time.h>
|
5
|
-
#endif
|
6
|
-
|
7
|
-
#include <stdio.h>
|
8
|
-
|
9
|
-
long long state0 = 1028798103;
|
10
|
-
long long state1 = 477374377;
|
11
|
-
double t = 0;
|
12
|
-
|
13
|
-
double inline __Math_random() {
|
14
|
-
long long s1 = 0;
|
15
|
-
long long s0 = 0;
|
16
|
-
|
17
|
-
s1 = state0;
|
18
|
-
state0 = (s0 = state1);
|
19
|
-
state1 = ((((s1 = (s1 ^ (s1 << 23)))) ^ s0) ^ (s1 >> 17)) ^ (s0 >> 26);
|
20
|
-
return ((double)((state1 + s0) & 2097151) / 2.097152e+6);
|
21
|
-
}
|
22
|
-
|
23
|
-
double randoms(double max) {
|
24
|
-
double sum = 0;
|
25
|
-
double i = 0;
|
26
|
-
|
27
|
-
sum = 0e+0;
|
28
|
-
i = 0e+0;
|
29
|
-
while (i < max) {
|
30
|
-
sum = sum + __Math_random();
|
31
|
-
i = i + 1e+0;
|
32
|
-
}
|
33
|
-
return sum;
|
34
|
-
}
|
35
|
-
|
36
|
-
double inline __performance_now() {
|
37
|
-
double _time_out;
|
38
|
-
#ifdef _WIN32
|
39
|
-
LARGE_INTEGER _time_freq, _time_t;
|
40
|
-
QueryPerformanceFrequency(&_time_freq);
|
41
|
-
QueryPerformanceCounter(&_time_t);
|
42
|
-
_time_out = ((double)_time_t.QuadPart / _time_freq.QuadPart) * 1000.;
|
43
|
-
#else
|
44
|
-
struct timespec _time;
|
45
|
-
clock_gettime(CLOCK_MONOTONIC, &_time);
|
46
|
-
_time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;
|
47
|
-
#endif
|
48
|
-
return _time_out;
|
49
|
-
}
|
50
|
-
|
51
|
-
void inline __console_log(double x) {
|
52
|
-
printf("%f\n", x);
|
53
|
-
printf("%c", (int)(1e+1));
|
54
|
-
}
|
55
|
-
|
56
|
-
int main() {
|
57
|
-
t = __performance_now();
|
58
|
-
randoms(1e+5);
|
59
|
-
__console_log(__performance_now() - t);
|
60
|
-
}
|
61
|
-
|