From 0b8c4dbf2a5c8841a0ed4d69da01aabdc2e2b360 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sun, 21 Feb 2021 23:52:21 -0800 Subject: [PATCH] Make the compiler async so it can avoid blocking animation --- .../src/__tests__/errorsUtils.test.ts | 4 +-- packages/compiler/src/compiler.ts | 11 ++++---- packages/compiler/src/loader.ts | 2 +- .../compiler/tools/__tests__/binary.test.ts | 2 +- packages/compiler/tools/parseMilk.js | 14 +++++------ packages/playground/src/hooks.js | 25 ++++++++++--------- 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/packages/compiler/src/__tests__/errorsUtils.test.ts b/packages/compiler/src/__tests__/errorsUtils.test.ts index aa1adb2..f07f6a3 100644 --- a/packages/compiler/src/__tests__/errorsUtils.test.ts +++ b/packages/compiler/src/__tests__/errorsUtils.test.ts @@ -10,11 +10,11 @@ const testCases = fs.readdirSync(DIR); testCases.forEach((filename: string) => { const testFunc = filename.startsWith("only.") ? test.only : test; const testName = filename.replace(/^only\./, ""); - testFunc(`${testName}`, () => { + testFunc(`${testName}`, async () => { const eel = fs.readFileSync(path.join(DIR, filename), { encoding: "utf8" }); let compilerError = null; try { - compileModule({ + await compileModule({ pools: { main: new Set() }, functions: { run: { pool: "main", code: eel } }, }); diff --git a/packages/compiler/src/compiler.ts b/packages/compiler/src/compiler.ts index 0653e57..cace540 100644 --- a/packages/compiler/src/compiler.ts +++ b/packages/compiler/src/compiler.ts @@ -36,12 +36,12 @@ type CompilerOptions = { preParsed?: boolean; }; -export function compileModule({ +export async function compileModule({ pools, functions: funcs, eelVersion = 2, preParsed = false, -}: CompilerOptions) { +}: CompilerOptions): Promise { if (Object.keys(pools).includes("shims")) { throw new Error( 'You may not name a pool "shims". "shims" is reserved for injected JavaScript functions.' @@ -81,7 +81,7 @@ export function compileModule({ localVariables: number[]; }[] = []; - Object.entries(funcs).forEach(([name, { pool, code }]) => { + for (const [name, { pool, code }] of Object.entries(funcs)) { if (pools[pool] == null) { const poolsList = Object.keys(pools); if (poolsList.length === 0) { @@ -108,7 +108,7 @@ export function compileModule({ throw new Error("Invalid AST"); } if (ast.body.length === 0) { - return; + continue; } const localVariables: number[] = []; const context: CompilerContext = { @@ -160,7 +160,8 @@ export function compileModule({ returns: [], localVariables, }); - }); + await Promise.resolve(); + } const localFuncs = localFuncOrder.map(name => { const func = localFuncMap[name]; diff --git a/packages/compiler/src/loader.ts b/packages/compiler/src/loader.ts index 27a980b..3aaef27 100644 --- a/packages/compiler/src/loader.ts +++ b/packages/compiler/src/loader.ts @@ -26,7 +26,7 @@ export async function loadModule({ Object.entries(pools).forEach(([key, globals]) => { compilerPools[key] = new Set(Object.keys(globals)); }); - const buffer = compileModule({ + const buffer = await compileModule({ pools: compilerPools, functions, eelVersion, diff --git a/packages/compiler/tools/__tests__/binary.test.ts b/packages/compiler/tools/__tests__/binary.test.ts index 46cf286..da4a25f 100644 --- a/packages/compiler/tools/__tests__/binary.test.ts +++ b/packages/compiler/tools/__tests__/binary.test.ts @@ -12,7 +12,7 @@ test("Can execute hand crafted binary Wasm", async () => { shims, }; - const buffer = compileModule({ + const buffer = await compileModule({ pools: { main: new Set(Object.keys(importObject.main)), }, diff --git a/packages/compiler/tools/parseMilk.js b/packages/compiler/tools/parseMilk.js index 0febbc4..7b896ac 100644 --- a/packages/compiler/tools/parseMilk.js +++ b/packages/compiler/tools/parseMilk.js @@ -128,17 +128,17 @@ const BAD = new Set([ "fixtures/mega/Telek & EMPR - Hell Cave (Fiddle A Bit (Flicker @xis) Mix).milk", // vnum_increment = ; ]); -function validate(milkPath, context) { +async function validate(milkPath, context) { if (BAD.has(milkPath)) { return; } const presetIni = fs.readFileSync(milkPath, { encoding: "utf8" }); const eels = getEels(presetIni); - Object.entries(eels).forEach(([name, eel]) => { + for (const [name, eel] of Object.entries(eels)) { try { const root = parse(eel); - compileModule({ + await compileModule({ globals: new Set(), functions: { run: root }, shims, @@ -155,7 +155,7 @@ function validate(milkPath, context) { } throw e; } - }); + } } let milkFiles; @@ -184,10 +184,10 @@ const context = { const errors = {}; let good = 0; let bad = 0; -milkFiles.forEach(milk => { +for (const milk of milkFiles) { // console.log(`Validating eel in "${milk}"...`); try { - validate(milk, context); + await validate(milk, context); good++; } catch (e) { const messageLines = e.message.split("\n"); @@ -209,7 +209,7 @@ milkFiles.forEach(milk => { } bad++; } -}); +} if (bad === 0) { console.log("No errors found!"); diff --git a/packages/playground/src/hooks.js b/packages/playground/src/hooks.js index 53604fd..fe24cad 100644 --- a/packages/playground/src/hooks.js +++ b/packages/playground/src/hooks.js @@ -74,19 +74,20 @@ export function useWasm(code, globals, eelVersion) { if (code == null) { return; } - try { - const wasm = compileModule({ - functions: { - main: { pool: "main", code } - }, - pools: { main: new Set(Object.keys(globals)) }, - eelVersion + compileModule({ + functions: { + main: { pool: "main", code } + }, + pools: { main: new Set(Object.keys(globals)) }, + eelVersion + }) + .then(wasm => { + setWasm(wasm); + setWasmError(null); + }) + .catch(e => { + setWasmError(e); }); - setWasm(wasm); - setWasmError(null); - } catch (e) { - setWasmError(e); - } }, [code, eelVersion, globals]); return [wasm, wasmError, eelVersion];