Skip to content

Commit

Permalink
reduce compilation time, remove flawed wabt dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
menduz committed Jan 24, 2025
1 parent 7d8e27d commit 96b11eb
Show file tree
Hide file tree
Showing 66 changed files with 2,352 additions and 1,639 deletions.
108 changes: 28 additions & 80 deletions src/compiler/phases/codeGenerationPhase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import * as ast from '@webassemblyjs/ast';
import { print } from '@webassemblyjs/wast-printer';
const t = ast as any;

declare var globalThis: any;

import _wabt from 'wabt';
import { annotations } from '../annotations';
import { flatten } from '../helpers';
import { Nodes, findNodesByType, PhaseFlags } from '../nodes';
Expand All @@ -24,8 +21,6 @@ type CompilationModuleResult = {
imports: any[];
};

const wabt = _wabt();

const starterName = t.identifier('%%START%%');

declare var WebAssembly: any;
Expand Down Expand Up @@ -541,97 +536,49 @@ export class CodeGenerationPhaseResult {
}> {
const { default: binaryen } = await import('binaryen');

let text = print(this.programAST);

const theWabt = await wabt;
let wabtModule: ReturnType<typeof theWabt.parseWat>;

try {
wabtModule = theWabt.parseWat(this.document.moduleName, text, {});
} catch (e: any) {
const invalidFile = this.parsingContext.system.resolvePath(
this.parsingContext.system.getCurrentDirectory(),
'failed_debug_wat.wat',
);
this.parsingContext.system.writeFile(invalidFile, text);
console.error('Error while parsing generated code. Writing debug WAT to ' + invalidFile);
console.error(e);
throw e;
}

try {
wabtModule.resolveNames();
wabtModule.validate();
} catch (e: any) {
const invalidFile = this.parsingContext.system.resolvePath(
this.parsingContext.system.getCurrentDirectory(),
'failed_debug_wat.wat',
);
this.parsingContext.system.writeFile(invalidFile, text);

console.error('Error while resolving names and validate code. Writing debug WAT to ' + invalidFile);
console.error(e);

this.parsingContext.messageCollector.error(e, this.document.astNode);
throw e;
}

const binary = wabtModule.toBinary({ log: false, write_debug_names: debug });
wabtModule.destroy();
const parseText = (text: string) => {
try {
return binaryen.parseText(text);
} catch (e: any) {
const invalidFile = this.parsingContext.system.resolvePath(
this.parsingContext.system.getCurrentDirectory(),
'failed_debug_wat.wat',
);
this.parsingContext.system.writeFile(invalidFile, text);
console.error('Error while parsing generated code. Writing debug WAT to ' + invalidFile);
console.error(e);
throw e;
}
};

try {
binaryen.setOptimizeLevel(optimizeLevel);
binaryen.setShrinkLevel(shrinkLevel);
binaryen.setDebugInfo(debug || !optimize);

const module = binaryen.readBinary(binary.buffer);
let text = print(this.programAST);
const module = parseText(text);

// if (!debug) {
// module.runPasses(['duplicate-function-elimination']);
// }

if (!debug) {
module.runPasses(['duplicate-function-elimination']);
}
module.runPasses(['remove-unused-module-elements']);

if (optimize) {
module.optimize();
}

if (module.validate() === 0) {
this.parsingContext.messageCollector.error(new LysCompilerError('binaryen validation failed', this.document));
}

if (debug) {
let last = module.emitBinary('sourceMap.map');

if (optimize) {
do {
module.optimize();
let next = module.emitBinary('sourceMap.map');
if (next.binary.length >= last.binary.length) {
// a if (next.length > last.length) {
// a this.parsingContext.system.write('Last converge was suboptimial.\n');
// a }
break;
}
last = next;
} while (true);
}

this.buffer = last.binary;
this.sourceMap = last.sourceMap;
} else {
let last = module.emitBinary();

if (optimize) {
do {
module.optimize();
let next = module.emitBinary();
if (next.length >= last.length) {
// a if (next.length > last.length) {
// a this.parsingContext.system.write('Last converge was suboptimial.\n');
// a }
break;
}
last = next;
} while (true);
}

this.buffer = last;
this.buffer = module.emitBinary();
}

module.dispose();
Expand Down Expand Up @@ -719,7 +666,8 @@ export class CodeGenerationPhaseResult {
const numberLiteral = t.numberLiteralFromRaw(offset, 'i32');
const offsetToken = t.objectInstruction('const', 'i32', [numberLiteral]);

dataSection.push(t.data(t.memIndexLiteral(0), offsetToken, t.byteArray(bytes)));
// dataSection.push(t.data(t.memIndexLiteral(dataCount++), offsetToken, t.byteArray(bytes)));
dataSection.push(t.data(t.identifier(`mem_${offset}`), offsetToken, t.byteArray(bytes)));

return offset + size;
}
Expand Down Expand Up @@ -820,7 +768,7 @@ export class CodeGenerationPhaseResult {
const table = t.table('funcref', t.limit(tableElems.length), t.identifier('lys::internal-functions'));
const elem = t.elem(
// table
t.indexLiteral(0),
t.identifier('elem_table_0'),
// offset
[t.objectInstruction('const', 'i32', [t.numberLiteralFromRaw(0)])],
// elems
Expand Down
2 changes: 1 addition & 1 deletion src/index-bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ async function emit(parsingContext: ReturnType<typeof getParsingContext>): Promi

writeFileSync(parsingContext.outFileFullWithoutExtension + '.wasm', codeGen.buffer);

let src = [];
let src: string[] = [];

src.push('Object.defineProperty(exports, "__esModule", { value: true });');
src.push('const modules = [];');
Expand Down
3 changes: 3 additions & 0 deletions src/utils/libs/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ function printHexByte(x: number) {
export default function(getInstance: () => any) {
return {
env: {
putchar: function() {
throw new Error('putchar not implemented')
},
printf: function(offset: number, ...args: number[]) {
try {
let str = readString(getInstance().exports.memory.buffer, offset);
Expand Down
Loading

0 comments on commit 96b11eb

Please sign in to comment.