porffor 0.0.0-ba812f2 → 0.0.0-beff13f
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 +5 -5
- package/c.exe +0 -0
- package/compiler/2c.js +112 -19
- package/compiler/builtins.js +6 -0
- package/compiler/codeGen.js +295 -81
- package/compiler/embedding.js +9 -5
- package/compiler/index.js +5 -5
- package/compiler/opt.js +14 -18
- package/compiler/parse.js +2 -2
- package/compiler/prototype.js +90 -28
- package/compiler/sections.js +17 -4
- package/compiler/wrap.js +9 -2
- package/g.exe +0 -0
- package/out.exe +0 -0
- package/package.json +1 -1
- package/r.js +39 -1
- package/rhemyn/README.md +1 -1
- package/rhemyn/compile.js +1 -1
- package/rhemyn/parse.js +12 -10
- package/runner/index.js +5 -3
- package/runner/info.js +37 -2
- package/tmp.c +46 -25
package/compiler/prototype.js
CHANGED
@@ -23,6 +23,9 @@ const TYPES = {
|
|
23
23
|
|
24
24
|
export const PrototypeFuncs = function() {
|
25
25
|
const noUnlikelyChecks = process.argv.includes('-funsafe-no-unlikely-proto-checks');
|
26
|
+
let zeroChecks = process.argv.find(x => x.startsWith('-funsafe-zero-proto-checks='));
|
27
|
+
if (zeroChecks) zeroChecks = zeroChecks.split('=')[1].split(',').reduce((acc, x) => { acc[x.toLowerCase()] = true; return acc; }, {});
|
28
|
+
else zeroChecks = {};
|
26
29
|
|
27
30
|
this[TYPES._array] = {
|
28
31
|
// lX = local accessor of X ({ get, set }), iX = local index of X, wX = wasm ops of X
|
@@ -36,7 +39,7 @@ export const PrototypeFuncs = function() {
|
|
36
39
|
[ Opcodes.i32_lt_s ],
|
37
40
|
[ Opcodes.if, Blocktype.void ],
|
38
41
|
[ Opcodes.local_get, iTmp ],
|
39
|
-
...length.
|
42
|
+
...length.getCachedI32(),
|
40
43
|
[ Opcodes.i32_add ],
|
41
44
|
[ Opcodes.local_set, iTmp ],
|
42
45
|
[ Opcodes.end ],
|
@@ -47,7 +50,7 @@ export const PrototypeFuncs = function() {
|
|
47
50
|
[ Opcodes.i32_lt_s ],
|
48
51
|
|
49
52
|
[ Opcodes.local_get, iTmp ],
|
50
|
-
...length.
|
53
|
+
...length.getCachedI32(),
|
51
54
|
[ Opcodes.i32_ge_s ],
|
52
55
|
[ Opcodes.i32_or ],
|
53
56
|
|
@@ -67,7 +70,7 @@ export const PrototypeFuncs = function() {
|
|
67
70
|
// todo: only for 1 argument
|
68
71
|
push: (pointer, length, wNewMember) => [
|
69
72
|
// get memory offset of array at last index (length)
|
70
|
-
...length.
|
73
|
+
...length.getCachedI32(),
|
71
74
|
...number(ValtypeSize[valtype], Valtype.i32),
|
72
75
|
[ Opcodes.i32_mul ],
|
73
76
|
|
@@ -79,17 +82,17 @@ export const PrototypeFuncs = function() {
|
|
79
82
|
|
80
83
|
// bump array length by 1 and return it
|
81
84
|
...length.setI32([
|
82
|
-
...length.
|
85
|
+
...length.getCachedI32(),
|
83
86
|
...number(1, Valtype.i32),
|
84
87
|
[ Opcodes.i32_add ]
|
85
88
|
]),
|
86
89
|
|
87
|
-
...length.get
|
90
|
+
...length.get()
|
88
91
|
],
|
89
92
|
|
90
93
|
pop: (pointer, length) => [
|
91
94
|
// if length == 0, noop
|
92
|
-
...length.
|
95
|
+
...length.getCachedI32(),
|
93
96
|
[ Opcodes.i32_eqz ],
|
94
97
|
[ Opcodes.if, Blocktype.void ],
|
95
98
|
...number(UNDEFINED),
|
@@ -100,13 +103,13 @@ export const PrototypeFuncs = function() {
|
|
100
103
|
|
101
104
|
// decrement length by 1
|
102
105
|
...length.setI32([
|
103
|
-
...length.
|
106
|
+
...length.getCachedI32(),
|
104
107
|
...number(1, Valtype.i32),
|
105
108
|
[ Opcodes.i32_sub ]
|
106
109
|
]),
|
107
110
|
|
108
111
|
// load last element
|
109
|
-
...length.
|
112
|
+
...length.getCachedI32(),
|
110
113
|
...number(ValtypeSize[valtype], Valtype.i32),
|
111
114
|
[ Opcodes.i32_mul ],
|
112
115
|
|
@@ -115,7 +118,7 @@ export const PrototypeFuncs = function() {
|
|
115
118
|
|
116
119
|
shift: (pointer, length) => [
|
117
120
|
// if length == 0, noop
|
118
|
-
...length.
|
121
|
+
...length.getCachedI32(),
|
119
122
|
Opcodes.i32_eqz,
|
120
123
|
[ Opcodes.if, Blocktype.void ],
|
121
124
|
...number(UNDEFINED),
|
@@ -126,7 +129,7 @@ export const PrototypeFuncs = function() {
|
|
126
129
|
|
127
130
|
// decrement length by 1
|
128
131
|
...length.setI32([
|
129
|
-
...length.
|
132
|
+
...length.getCachedI32(),
|
130
133
|
...number(1, Valtype.i32),
|
131
134
|
[ Opcodes.i32_sub ]
|
132
135
|
]),
|
@@ -140,11 +143,66 @@ export const PrototypeFuncs = function() {
|
|
140
143
|
...number(pointer + ValtypeSize.i32 + ValtypeSize[valtype], Valtype.i32), // src = base array index + length size + an index
|
141
144
|
...number(pageSize - ValtypeSize.i32 - ValtypeSize[valtype], Valtype.i32), // size = PageSize - length size - an index
|
142
145
|
[ ...Opcodes.memory_copy, 0x00, 0x00 ]
|
146
|
+
],
|
147
|
+
|
148
|
+
fill: (pointer, length, wElement, iTmp) => [
|
149
|
+
...wElement,
|
150
|
+
[ Opcodes.local_set, iTmp ],
|
151
|
+
|
152
|
+
// use cached length i32 as pointer
|
153
|
+
...length.getCachedI32(),
|
154
|
+
|
155
|
+
// length - 1 for indexes
|
156
|
+
...number(1, Valtype.i32),
|
157
|
+
[ Opcodes.i32_sub ],
|
158
|
+
|
159
|
+
// * sizeof value
|
160
|
+
...number(ValtypeSize[valtype], Valtype.i32),
|
161
|
+
[ Opcodes.i32_mul ],
|
162
|
+
|
163
|
+
...length.setCachedI32(),
|
164
|
+
|
165
|
+
...(noUnlikelyChecks ? [] : [
|
166
|
+
...length.getCachedI32(),
|
167
|
+
...number(0, Valtype.i32),
|
168
|
+
[ Opcodes.i32_lt_s ],
|
169
|
+
[ Opcodes.if, Blocktype.void ],
|
170
|
+
...number(pointer),
|
171
|
+
[ Opcodes.br, 1 ],
|
172
|
+
[ Opcodes.end ]
|
173
|
+
]),
|
174
|
+
|
175
|
+
[ Opcodes.loop, Blocktype.void ],
|
176
|
+
|
177
|
+
// set element using pointer
|
178
|
+
...length.getCachedI32(),
|
179
|
+
[ Opcodes.local_get, iTmp ],
|
180
|
+
[ Opcodes.store, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(pointer + ValtypeSize.i32) ],
|
181
|
+
|
182
|
+
// pointer - sizeof value
|
183
|
+
...length.getCachedI32(),
|
184
|
+
...number(ValtypeSize[valtype], Valtype.i32),
|
185
|
+
[ Opcodes.i32_sub ],
|
186
|
+
|
187
|
+
...length.setCachedI32(),
|
188
|
+
|
189
|
+
// if pointer >= 0, loop
|
190
|
+
...length.getCachedI32(),
|
191
|
+
...number(0, Valtype.i32),
|
192
|
+
[ Opcodes.i32_ge_s ],
|
193
|
+
[ Opcodes.br_if, 0 ],
|
194
|
+
|
195
|
+
[ Opcodes.end ],
|
196
|
+
|
197
|
+
// return this array
|
198
|
+
...number(pointer)
|
143
199
|
]
|
144
200
|
};
|
145
201
|
|
146
202
|
this[TYPES._array].at.local = Valtype.i32;
|
147
203
|
this[TYPES._array].push.noArgRetLength = true;
|
204
|
+
this[TYPES._array].fill.local = valtypeBinary;
|
205
|
+
this[TYPES._array].fill.returnType = TYPES._array;
|
148
206
|
|
149
207
|
this[TYPES.string] = {
|
150
208
|
at: (pointer, length, wIndex, iTmp, arrayShell) => {
|
@@ -166,7 +224,7 @@ export const PrototypeFuncs = function() {
|
|
166
224
|
[ Opcodes.i32_lt_s ],
|
167
225
|
[ Opcodes.if, Blocktype.void ],
|
168
226
|
[ Opcodes.local_get, iTmp ],
|
169
|
-
...length.
|
227
|
+
...length.getCachedI32(),
|
170
228
|
[ Opcodes.i32_add ],
|
171
229
|
[ Opcodes.local_set, iTmp ],
|
172
230
|
[ Opcodes.end ],
|
@@ -177,7 +235,7 @@ export const PrototypeFuncs = function() {
|
|
177
235
|
[ Opcodes.i32_lt_s ],
|
178
236
|
|
179
237
|
[ Opcodes.local_get, iTmp ],
|
180
|
-
...length.
|
238
|
+
...length.getCachedI32(),
|
181
239
|
[ Opcodes.i32_ge_s ],
|
182
240
|
[ Opcodes.i32_or ],
|
183
241
|
|
@@ -233,27 +291,31 @@ export const PrototypeFuncs = function() {
|
|
233
291
|
return [
|
234
292
|
...wIndex,
|
235
293
|
Opcodes.i32_to,
|
236
|
-
[ Opcodes.local_set, iTmp ],
|
237
294
|
|
238
|
-
|
239
|
-
|
295
|
+
...(zeroChecks.charcodeat ? [] : [
|
296
|
+
[ Opcodes.local_set, iTmp ],
|
297
|
+
|
298
|
+
// index < 0
|
299
|
+
...(noUnlikelyChecks ? [] : [
|
300
|
+
[ Opcodes.local_get, iTmp ],
|
301
|
+
...number(0, Valtype.i32),
|
302
|
+
[ Opcodes.i32_lt_s ],
|
303
|
+
]),
|
304
|
+
|
305
|
+
// index >= length
|
240
306
|
[ Opcodes.local_get, iTmp ],
|
241
|
-
...
|
242
|
-
[ Opcodes.
|
243
|
-
]),
|
307
|
+
...length.getCachedI32(),
|
308
|
+
[ Opcodes.i32_ge_s ],
|
244
309
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
310
|
+
...(noUnlikelyChecks ? [] : [ [ Opcodes.i32_or ] ]),
|
311
|
+
[ Opcodes.if, Blocktype.void ],
|
312
|
+
...number(NaN),
|
313
|
+
[ Opcodes.br, 1 ],
|
314
|
+
[ Opcodes.end ],
|
249
315
|
|
250
|
-
|
251
|
-
|
252
|
-
...number(NaN),
|
253
|
-
[ Opcodes.br, 1 ],
|
254
|
-
[ Opcodes.end ],
|
316
|
+
[ Opcodes.local_get, iTmp ],
|
317
|
+
]),
|
255
318
|
|
256
|
-
[ Opcodes.local_get, iTmp ],
|
257
319
|
...number(ValtypeSize.i16, Valtype.i32),
|
258
320
|
[ Opcodes.i32_mul ],
|
259
321
|
|
package/compiler/sections.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Valtype, FuncType, Empty, ExportDesc, Section, Magic, ModuleVersion, Opcodes, PageSize } from './wasmSpec.js';
|
2
|
-
import { encodeVector, encodeString, encodeLocal } from './encoding.js';
|
2
|
+
import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128 } from './encoding.js';
|
3
3
|
import { number } from './embedding.js';
|
4
4
|
import { importedFuncs } from './builtins.js';
|
5
5
|
|
@@ -20,7 +20,7 @@ const chHint = (topTier, baselineTier, strategy) => {
|
|
20
20
|
return (strategy | (baselineTier << 2) | (topTier << 4));
|
21
21
|
};
|
22
22
|
|
23
|
-
export default (funcs, globals, tags, pages, flags) => {
|
23
|
+
export default (funcs, globals, tags, pages, data, flags) => {
|
24
24
|
const types = [], typeCache = {};
|
25
25
|
|
26
26
|
const optLevel = parseInt(process.argv.find(x => x.startsWith('-O'))?.[2] ?? 1);
|
@@ -155,13 +155,24 @@ export default (funcs, globals, tags, pages, flags) => {
|
|
155
155
|
encodeVector(types)
|
156
156
|
);
|
157
157
|
|
158
|
+
const dataSection = data.length === 0 ? [] : createSection(
|
159
|
+
Section.data,
|
160
|
+
encodeVector(data.map(x => [ 0x00, Opcodes.i32_const, ...signedLEB128(x.offset), Opcodes.end, ...encodeVector(x.bytes) ]))
|
161
|
+
);
|
162
|
+
|
163
|
+
const dataCountSection = data.length === 0 ? [] : createSection(
|
164
|
+
Section.data_count,
|
165
|
+
unsignedLEB128(data.length)
|
166
|
+
);
|
167
|
+
|
158
168
|
if (process.argv.includes('-sections')) console.log({
|
159
169
|
typeSection: typeSection.map(x => x.toString(16)),
|
160
170
|
importSection: importSection.map(x => x.toString(16)),
|
161
171
|
funcSection: funcSection.map(x => x.toString(16)),
|
162
172
|
globalSection: globalSection.map(x => x.toString(16)),
|
163
173
|
exportSection: exportSection.map(x => x.toString(16)),
|
164
|
-
codeSection: codeSection.map(x => x.toString(16))
|
174
|
+
codeSection: codeSection.map(x => x.toString(16)),
|
175
|
+
dataSection: dataSection.map(x => x.toString(16)),
|
165
176
|
});
|
166
177
|
|
167
178
|
return Uint8Array.from([
|
@@ -175,6 +186,8 @@ export default (funcs, globals, tags, pages, flags) => {
|
|
175
186
|
...tagSection,
|
176
187
|
...globalSection,
|
177
188
|
...exportSection,
|
178
|
-
...
|
189
|
+
...dataCountSection,
|
190
|
+
...codeSection,
|
191
|
+
...dataSection
|
179
192
|
]);
|
180
193
|
};
|
package/compiler/wrap.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import compile from './index.js';
|
2
2
|
import decompile from './decompile.js';
|
3
|
-
import fs from 'node:fs';
|
3
|
+
// import fs from 'node:fs';
|
4
4
|
|
5
5
|
const bold = x => `\u001b[1m${x}\u001b[0m`;
|
6
6
|
|
@@ -29,16 +29,23 @@ export default async (source, flags = [ 'module' ], customImports = {}, print =
|
|
29
29
|
|
30
30
|
if (source.includes('export function')) flags.push('module');
|
31
31
|
|
32
|
-
fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
32
|
+
// fs.writeFileSync('out.wasm', Buffer.from(wasm));
|
33
33
|
|
34
34
|
times.push(performance.now() - t1);
|
35
35
|
if (flags.includes('info')) console.log(bold(`compiled in ${times[0].toFixed(2)}ms`));
|
36
36
|
|
37
|
+
const getString = pointer => {
|
38
|
+
const length = new Int32Array(memory.buffer, pointer, 1);
|
39
|
+
|
40
|
+
return Array.from(new Uint16Array(memory.buffer, pointer + 4, length)).map(x => String.fromCharCode(x)).join('');
|
41
|
+
};
|
42
|
+
|
37
43
|
const t2 = performance.now();
|
38
44
|
const { instance } = await WebAssembly.instantiate(wasm, {
|
39
45
|
'': {
|
40
46
|
p: valtype === 'i64' ? i => print(Number(i).toString()) : i => print(i.toString()),
|
41
47
|
c: valtype === 'i64' ? i => print(String.fromCharCode(Number(i))) : i => print(String.fromCharCode(i)),
|
48
|
+
s: valtype === 'i64' ? i => print(getString(Number(i))) : i => print(getString(i)),
|
42
49
|
a: c => { if (!Number(c)) throw new Error(`assert failed`); },
|
43
50
|
t: _ => performance.now(),
|
44
51
|
...customImports
|
package/g.exe
CHANGED
Binary file
|
package/out.exe
ADDED
Binary file
|
package/package.json
CHANGED
package/r.js
CHANGED
@@ -1 +1,39 @@
|
|
1
|
-
|
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/rhemyn/README.md
CHANGED
@@ -31,7 +31,7 @@ made for use with porffor but could possibly be adapted, implementation/library
|
|
31
31
|
- 🟠 lazy modifier (eg `a*?`)
|
32
32
|
- 🔴 n repetitions (eg `a{4}`)
|
33
33
|
- 🔴 n-m repetitions (eg `a{2,4}`)
|
34
|
-
- 🔴
|
34
|
+
- 🔴 assertions
|
35
35
|
- 🔴 beginning (eg `^a`)
|
36
36
|
- 🔴 end (eg `a$`)
|
37
37
|
- 🔴 word boundary assertion (eg `\b\B`)
|
package/rhemyn/compile.js
CHANGED
@@ -21,7 +21,7 @@ const generate = (node, negated = false, get = true, func = 'test') => {
|
|
21
21
|
out = [
|
22
22
|
// set length local
|
23
23
|
[ Opcodes.local_get, BasePointer ],
|
24
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1,
|
24
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
25
25
|
[ Opcodes.local_set, Length ],
|
26
26
|
|
27
27
|
// set iter pointer local as base + sizeof i32 initially
|
package/rhemyn/parse.js
CHANGED
@@ -18,35 +18,35 @@ const getArg = (name, def) => {
|
|
18
18
|
};
|
19
19
|
|
20
20
|
// full is spec-compliant but slower. not needed most of the time. (evil)
|
21
|
-
const DotChars = ({
|
21
|
+
const DotChars = () => ({
|
22
22
|
full: [ '\n', '\r', '\u2028', '\u2029' ],
|
23
23
|
simple: [ '\n', '\r' ],
|
24
24
|
fast: [ '\n' ]
|
25
25
|
})[getArg('regex-dot', 'fast')];
|
26
26
|
|
27
|
-
const WordChars = ({
|
27
|
+
const WordChars = () => ({
|
28
28
|
full: [ [ 'a', 'z' ], [ 'A', 'Z' ], [ '0', '9' ], '_' ],
|
29
29
|
fast: [ [ '_', 'z' ], [ 'A', 'Z' ], [ '0', '9' ] ] // skip individual _ with _-z BUT it also matches '`'
|
30
30
|
})[getArg('regex-word', 'full')];
|
31
31
|
|
32
|
-
const WhitespaceChars = ({
|
32
|
+
const WhitespaceChars = () => ({
|
33
33
|
full: [ ' ', '\t', '\n', '\r', '\u2028', '\u2029' ],
|
34
34
|
simple: [ ' ', '\t', '\n', '\r' ]
|
35
35
|
})[getArg('regex-ws', 'simple')];
|
36
36
|
|
37
|
-
const
|
37
|
+
const _Metachars = () => ({
|
38
38
|
unescaped: {
|
39
|
-
'.': [ DotChars, true ], // dot
|
39
|
+
'.': [ DotChars(), true ], // dot
|
40
40
|
},
|
41
41
|
escaped: {
|
42
42
|
d: [ [ [ '0', '9' ] ], false ], // digit
|
43
43
|
D: [ [ [ '0', '9' ] ], true ], // not digit
|
44
|
-
w: [ WordChars, false ], // word
|
45
|
-
W: [ WordChars, true ], // not word
|
46
|
-
s: [ WhitespaceChars, false ], // whitespace
|
47
|
-
S: [ WhitespaceChars, true ], // not whitespace
|
44
|
+
w: [ WordChars(), false ], // word
|
45
|
+
W: [ WordChars(), true ], // not word
|
46
|
+
s: [ WhitespaceChars(), false ], // whitespace
|
47
|
+
S: [ WhitespaceChars(), true ], // not whitespace
|
48
48
|
}
|
49
|
-
};
|
49
|
+
});
|
50
50
|
|
51
51
|
const EscapeSequences = {
|
52
52
|
f: '\f',
|
@@ -60,6 +60,8 @@ const EscapeSequences = {
|
|
60
60
|
const HexDigit = /[0-9a-fA-F]/;
|
61
61
|
|
62
62
|
export default str => {
|
63
|
+
const Metachars = _Metachars();
|
64
|
+
|
63
65
|
const out = {
|
64
66
|
type: 'Expression',
|
65
67
|
body: []
|
package/runner/index.js
CHANGED
@@ -34,12 +34,14 @@ const source = fs.readFileSync(file, 'utf8');
|
|
34
34
|
|
35
35
|
let cache = '';
|
36
36
|
const print = str => {
|
37
|
-
cache += str;
|
37
|
+
/* cache += str;
|
38
38
|
|
39
39
|
if (str === '\n') {
|
40
40
|
process.stdout.write(cache);
|
41
41
|
cache = '';
|
42
|
-
}
|
42
|
+
} */
|
43
|
+
|
44
|
+
process.stdout.write(str);
|
43
45
|
};
|
44
46
|
|
45
47
|
try {
|
@@ -49,5 +51,5 @@ try {
|
|
49
51
|
if (cache) process.stdout.write(cache);
|
50
52
|
} catch (e) {
|
51
53
|
if (cache) process.stdout.write(cache);
|
52
|
-
console.error(`${e.constructor.name}: ${e.message}`);
|
54
|
+
console.error(process.argv.includes('-i') ? e : `${e.constructor.name}: ${e.message}`);
|
53
55
|
}
|
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 } = await compile(source, raw ? [ 'module' ] : [ 'module', 'info' ], {}, print);
|
39
|
+
const { wasm, exports, pages } = 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,4 +51,39 @@ 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`);
|
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
|
+
}
|
package/tmp.c
CHANGED
@@ -1,37 +1,58 @@
|
|
1
|
+
#ifdef _WIN32
|
2
|
+
#include <windows.h>
|
3
|
+
#else
|
4
|
+
#include <time.h>
|
5
|
+
#endif
|
6
|
+
|
1
7
|
#include <stdio.h>
|
2
8
|
|
3
|
-
double
|
4
|
-
|
9
|
+
double aux(double n, double acc1, double acc2) {
|
10
|
+
if (n == 0e+0) {
|
11
|
+
return acc1;
|
12
|
+
}
|
13
|
+
if (n == 1e+0) {
|
14
|
+
return acc2;
|
15
|
+
}
|
16
|
+
return aux(n - 1e+0, acc2, acc1 + acc2);
|
5
17
|
}
|
6
18
|
|
7
|
-
double
|
8
|
-
|
19
|
+
double fib(double n) {
|
20
|
+
return aux(n, 0e+0, 1e+0);
|
21
|
+
}
|
9
22
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
}
|
23
|
+
double test(double n, double count) {
|
24
|
+
double res = 0;
|
25
|
+
double i = 0;
|
26
|
+
|
27
|
+
i = 0e+0;
|
28
|
+
while (i < count) {
|
29
|
+
res = fib(n);
|
18
30
|
i = i + 1e+0;
|
19
31
|
}
|
20
|
-
return
|
32
|
+
return res;
|
33
|
+
}
|
34
|
+
|
35
|
+
double inline __performance_now() {
|
36
|
+
double _time_out;
|
37
|
+
#ifdef _WIN32
|
38
|
+
LARGE_INTEGER _time_freq, _time_t;
|
39
|
+
QueryPerformanceFrequency(&_time_freq);
|
40
|
+
QueryPerformanceCounter(&_time_t);
|
41
|
+
_time_out = ((double)_time_t.QuadPart / _time_freq.QuadPart) * 1000.;
|
42
|
+
#else
|
43
|
+
struct timespec _time;
|
44
|
+
clock_gettime(CLOCK_MONOTONIC, &_time);
|
45
|
+
_time_out = _time.tv_nsec / 1000000.;
|
46
|
+
#endif
|
47
|
+
return _time_out;
|
21
48
|
}
|
22
49
|
|
23
50
|
int main() {
|
24
|
-
double
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
if (isPrime(counter) == 1e+0) {
|
31
|
-
sum = sum + counter;
|
32
|
-
}
|
33
|
-
counter = counter + 1e+0;
|
34
|
-
}
|
35
|
-
printf("%f\n", sum);
|
51
|
+
double t = 0;
|
52
|
+
|
53
|
+
t = __performance_now();
|
54
|
+
// Sleep(1000);
|
55
|
+
printf("%f\n", test(4.6e+1, 1e+7));
|
56
|
+
printf("%f\n", (__performance_now() - t));
|
36
57
|
}
|
37
58
|
|