porffor 0.34.8 → 0.34.9
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/assemble.js +47 -21
- package/package.json +1 -1
- package/runner/index.js +1 -1
package/compiler/assemble.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Valtype, FuncType, ExportDesc, Section, Magic, ModuleVersion, Opcodes, PageSize, Reftype } from './wasmSpec.js';
|
2
|
-
import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64_into } from './encoding.js';
|
2
|
+
import { encodeVector, encodeString, encodeLocal, unsignedLEB128, signedLEB128, unsignedLEB128_into, signedLEB128_into, ieee754_binary64, ieee754_binary64_into } from './encoding.js';
|
3
3
|
import { importedFuncs } from './builtins.js';
|
4
4
|
import { log } from './log.js';
|
5
5
|
import {} from './prefs.js';
|
@@ -72,6 +72,14 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
72
72
|
return typeCache[hash] = idx;
|
73
73
|
};
|
74
74
|
|
75
|
+
let t = performance.now();
|
76
|
+
const time = msg => {
|
77
|
+
if (!Prefs.profileAssemble) return;
|
78
|
+
|
79
|
+
console.log(`${' '.repeat(50)}\r[${(performance.now() - t).toFixed(2)}ms] ${msg}`);
|
80
|
+
t = performance.now();
|
81
|
+
};
|
82
|
+
|
75
83
|
let importFuncs = [], importDelta = 0;
|
76
84
|
if (optLevel < 1 || !Prefs.treeshakeWasmImports || noTreeshake) {
|
77
85
|
importFuncs = importedFuncs;
|
@@ -81,7 +89,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
81
89
|
// tree shake imports
|
82
90
|
for (const f of funcs) {
|
83
91
|
for (const inst of f.wasm) {
|
84
|
-
if ((inst[0] === Opcodes.call || inst[0] === Opcodes.return_call) && inst[1] < importedFuncs.length) {
|
92
|
+
if ((inst[0] === Opcodes.call /* || inst[0] === Opcodes.return_call */) && inst[1] < importedFuncs.length) {
|
85
93
|
const idx = inst[1];
|
86
94
|
const func = importedFuncs[idx];
|
87
95
|
|
@@ -102,17 +110,21 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
102
110
|
f.asmIndex = f.index - importDelta;
|
103
111
|
}
|
104
112
|
|
113
|
+
time('treeshake import funcs');
|
114
|
+
|
105
115
|
if (Prefs.optLog) log('assemble', `treeshake: using ${importFuncs.length}/${importedFuncs.length} imports`);
|
106
116
|
|
107
117
|
const importSection = importFuncs.length === 0 ? [] : createSection(
|
108
118
|
Section.import,
|
109
119
|
encodeVector(importFuncs.map(x => [ 0, ...encodeString(x.import), ExportDesc.func, getType(typeof x.params === 'object' ? x.params : new Array(x.params).fill(valtypeBinary), new Array(x.returns).fill(valtypeBinary)) ]))
|
110
120
|
);
|
121
|
+
time('import section');
|
111
122
|
|
112
123
|
const funcSection = createSection(
|
113
124
|
Section.func,
|
114
125
|
encodeVector(funcs.map(x => getType(x.params, x.returns))) // type indexes
|
115
126
|
);
|
127
|
+
time('func section');
|
116
128
|
|
117
129
|
const nameSection = Prefs.d ? customSection('name', encodeNames(funcs)) : [];
|
118
130
|
|
@@ -120,6 +132,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
120
132
|
Section.table,
|
121
133
|
encodeVector([ [ Reftype.funcref, 0x00, ...unsignedLEB128(funcs.length) ] ])
|
122
134
|
);
|
135
|
+
time('table section');
|
123
136
|
|
124
137
|
const elementSection = !funcs.table ? [] : createSection(
|
125
138
|
Section.element,
|
@@ -129,6 +142,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
129
142
|
...encodeVector(funcs.map(x => unsignedLEB128(x.asmIndex)))
|
130
143
|
] ])
|
131
144
|
);
|
145
|
+
time('element section');
|
132
146
|
|
133
147
|
if (pages.has('func lut')) {
|
134
148
|
const offset = pages.get('func lut').ind * pageSize;
|
@@ -181,8 +195,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
181
195
|
});
|
182
196
|
data.addedFuncArgcLut = true;
|
183
197
|
}
|
184
|
-
|
185
|
-
// const t0 = performance.now();
|
198
|
+
time('func lut');
|
186
199
|
|
187
200
|
// specially optimized assembly for globals as this version is much (>5x) faster than traditional createSection()
|
188
201
|
const globalsValues = Object.values(globals);
|
@@ -224,17 +237,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
224
237
|
unsignedLEB128_into(data.length, globalSection);
|
225
238
|
globalSection = globalSection.concat(data);
|
226
239
|
}
|
227
|
-
|
228
|
-
// if (Prefs.profileCompiler) {
|
229
|
-
// const log = console.log;
|
230
|
-
// console.log = function () {
|
231
|
-
// log.apply(this, arguments);
|
232
|
-
// console.log = log;
|
233
|
-
// console.log(` a. assembled global section in ${(performance.now() - t0).toFixed(2)}ms\n`);
|
234
|
-
// };
|
235
|
-
// }
|
236
|
-
|
237
|
-
const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.asmIndex) ]);
|
240
|
+
time('global section');
|
238
241
|
|
239
242
|
if (Prefs.alwaysMemory && pages.size === 0) pages.set('--always-memory', 0);
|
240
243
|
if (optLevel === 0) pages.set('O0 precaution', 0);
|
@@ -244,9 +247,13 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
244
247
|
Section.memory,
|
245
248
|
encodeVector([ [ 0x00, ...unsignedLEB128(Math.ceil((pages.size * pageSize) / PageSize)) ] ])
|
246
249
|
);
|
250
|
+
time('memory section');
|
251
|
+
|
252
|
+
const exports = funcs.filter(x => x.export).map((x, i) => [ ...encodeString(x.name === 'main' ? 'm' : x.name), ExportDesc.func, ...unsignedLEB128(x.asmIndex) ]);
|
247
253
|
|
248
254
|
// export memory if used
|
249
255
|
if (usesMemory) exports.unshift([ ...encodeString('$'), ExportDesc.mem, 0x00 ]);
|
256
|
+
time('gen exports');
|
250
257
|
|
251
258
|
const tagSection = tags.length === 0 ? [] : createSection(
|
252
259
|
Section.tag,
|
@@ -255,16 +262,20 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
255
262
|
|
256
263
|
// export first tag if used
|
257
264
|
if (tags.length !== 0) exports.unshift([ ...encodeString('0'), ExportDesc.tag, 0x00 ]);
|
265
|
+
time('tag section');
|
258
266
|
|
259
267
|
const exportSection = createSection(
|
260
268
|
Section.export,
|
261
269
|
encodeVector(exports)
|
262
270
|
);
|
271
|
+
time('export section');
|
263
272
|
|
264
273
|
const codeSection = createSection(
|
265
274
|
Section.code,
|
266
275
|
encodeVector(funcs.map(x => {
|
267
|
-
|
276
|
+
// time(x.name);
|
277
|
+
const locals = Object.values(x.locals).sort((a, b) => a.idx - b.idx).slice(x.params.length);
|
278
|
+
// time(' locals gen');
|
268
279
|
|
269
280
|
let localDecl = [], typeCount = 0, lastType;
|
270
281
|
for (let i = 0; i < locals.length; i++) {
|
@@ -279,6 +290,7 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
279
290
|
}
|
280
291
|
|
281
292
|
if (typeCount !== 0) localDecl.push(encodeLocal(typeCount, lastType));
|
293
|
+
// time(' localDecl gen');
|
282
294
|
|
283
295
|
const makeAssembled = Prefs.d;
|
284
296
|
let wasm = [], wasmNonFlat = [];
|
@@ -287,7 +299,8 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
287
299
|
|
288
300
|
// encode local/global ops as unsigned leb128 from raw number
|
289
301
|
if (
|
290
|
-
(o[0] === Opcodes.local_get || o[0] === Opcodes.local_set || o[0] === Opcodes.local_tee || o[0] === Opcodes.global_get || o[0] === Opcodes.global_set) &&
|
302
|
+
// (o[0] === Opcodes.local_get || o[0] === Opcodes.local_set || o[0] === Opcodes.local_tee || o[0] === Opcodes.global_get || o[0] === Opcodes.global_set) &&
|
303
|
+
(o[0] >= Opcodes.local_get && o[0] <= Opcodes.global_set) &&
|
291
304
|
o[1] > 127
|
292
305
|
) {
|
293
306
|
const n = o[1];
|
@@ -298,12 +311,14 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
298
311
|
// encode f64.const ops as ieee754 from raw number
|
299
312
|
if (o[0] === Opcodes.f64_const) {
|
300
313
|
const n = o[1];
|
301
|
-
o = [ o[0] ];
|
302
|
-
ieee754_binary64_into(n, o);
|
314
|
+
// o = [ o[0] ];
|
315
|
+
// ieee754_binary64_into(n, o);
|
316
|
+
o = ieee754_binary64(n);
|
317
|
+
if (o.length === 8) o.unshift(Opcodes.f64_const);
|
303
318
|
}
|
304
319
|
|
305
320
|
// encode call ops as unsigned leb128 from raw number
|
306
|
-
if ((o[0] === Opcodes.call || o[0] === Opcodes.return_call) && o[1] >= importedFuncs.length) {
|
321
|
+
if ((o[0] === Opcodes.call /* || o[0] === Opcodes.return_call */) && o[1] >= importedFuncs.length) {
|
307
322
|
const n = o[1] - importDelta;
|
308
323
|
o = [ o[0] ];
|
309
324
|
unsignedLEB128_into(n, o);
|
@@ -334,19 +349,28 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
334
349
|
|
335
350
|
if (makeAssembled) wasmNonFlat.push(o);
|
336
351
|
}
|
352
|
+
// time(' wasm transform');
|
337
353
|
|
338
354
|
if (makeAssembled) {
|
339
355
|
x.assembled = { localDecl, wasm, wasmNonFlat };
|
340
356
|
}
|
341
357
|
|
342
|
-
|
358
|
+
let out = unsignedLEB128(localDecl.length)
|
359
|
+
.concat(localDecl.flat(), wasm, Opcodes.end);
|
360
|
+
|
361
|
+
out.unshift(...unsignedLEB128(out.length));
|
362
|
+
|
363
|
+
// time(' finish');
|
364
|
+
return out;
|
343
365
|
}))
|
344
366
|
);
|
367
|
+
time('code section');
|
345
368
|
|
346
369
|
const typeSection = createSection(
|
347
370
|
Section.type,
|
348
371
|
encodeVector(types)
|
349
372
|
);
|
373
|
+
time('type section');
|
350
374
|
|
351
375
|
const dataSection = data.length === 0 ? [] : createSection(
|
352
376
|
Section.data,
|
@@ -368,11 +392,13 @@ export default (funcs, globals, tags, pages, data, flags, noTreeshake = false) =
|
|
368
392
|
return bytes;
|
369
393
|
}))
|
370
394
|
);
|
395
|
+
time('data section');
|
371
396
|
|
372
397
|
const dataCountSection = data.length === 0 ? [] : createSection(
|
373
398
|
Section.data_count,
|
374
399
|
unsignedLEB128(data.length)
|
375
400
|
);
|
401
|
+
time('datacount section');
|
376
402
|
|
377
403
|
if (Prefs.sections) console.log({
|
378
404
|
typeSection: typeSection.map(x => x.toString(16)),
|
package/package.json
CHANGED