UNPKG

killawat

Version:

KillaWAT is a WebAssembly Text Macro Assembler

166 lines (131 loc) 5.47 kB
"use strict"; // Object.freeze(obj); const { TokenArray, funcSigTable, ParseTree, main, YELLOW, RED, CYAN, BRIGHT_GREEN, BRIGHT_BLUE, BRIGHT_YELLOW, BRIGHT_MAGENTA, BRIGHT_RED, WasmModule, binaryen, globalSymbolTable, functionTable, funcSymbolMap, BLUE, funcSymbolTable } = require('./shared.js') const fs = require('fs'); const { Tokenizer } = require("./tokenizer.js"); //const { buildTables } = require('./tables.js'); const { Module } = require('./module.js'); const { Global } = require('./global.js'); const { Func } = require('./func.js'); const { Memory, Data } = require('./memory.js'); const { Import } = require('./import.js'); //const { genParseTree, parseTree } = require('./parse.js'); function log_error(error_string) { console.log(RED, ` =================================================================================== ERROR: ${error_string} =================================================================================== `); } function log_support() { console.log( CYAN, ` Need help? Contact Rick Battagline Twitter: @battagline https://wasmbook.com kwc version 0.0.31 `); } /* let flags = { print_function_table: false, print_symbol_table: false, print_tree: false, tokens: false } */ // Don't forget about the misordering that can happen when a function doesn't return a value // you need to add variables to hold the items with values on the stack. function compile(file_name, flags) { console.log(BRIGHT_YELLOW, `compile ${file_name}`) var bytes = fs.readFileSync(file_name); var code = bytes.toString(); //tokenize(code); let tokenizer = new Tokenizer(code, TokenArray); //let processedTokens = new Preprocess(tokenizer).tokens; let module = new Module(tokenizer, file_name); //console.log(module.globalExpressionTokens[0]) module.globalExpressionTokens.forEach(tokenArray => new Global(tokenArray.slice(2))); module.importExpressionTokens.forEach(tokenArray => new Import(tokenArray.slice(2))); module.funcExpressionTokens.forEach(tokenArray => new Func(tokenArray.slice(1))); // data has to be done ahead of memory module.memoryExpressionTokens.forEach(tokenArray => { let mem = new Memory(tokenArray.slice(2)) if (main.fileName !== mem.fileName) { main.mem = mem; } }); module.dataExpressionTokens.forEach(tokenArray => new Data(tokenArray.slice(2))); main.mem.Set(); funcSymbolTable.forEach(func => { if (func.expandMacros) { func.expandMacros() } }); funcSymbolTable.forEach(func => { if (func.addFunction) { func.addFunction() } }); if (module.startExpressionTokens.length > 0) { let startFunc = funcSymbolMap.get(module.startExpressionTokens[1].value); WasmModule.setStart(startFunc.funcRef); } // table // elem // exports //buildTables(parseTree); //console.log(globalSymbolTable); //console.log('=================== FUNCTION SIGNATURES ====================='); //console.log(JSON.stringify(funcSigTable, null, 2)); // NOW THAT YOU HAVE THE TABLES BUILT, LOOK AT THE AST // genBinaryenTree(parseTree); /* if (flags.tokens === true) { console.log(BRIGHT_MAGENTA, '\n================================ TOKENS ================================\n' + JSON.stringify(TokenArray, null, 2) + '\n========================================================================' ); } if (flags.print_function_signatures == true) { console.log(BLUE, '\n========================= FUNCTION SIGNATURES ==========================\n' + JSON.stringify(funcSigTable, null, 2) + '\n========================================================================' ); } genParseTree(); if (flags.print_tree === true) { console.log(BRIGHT_YELLOW, '\n========================= ABSTRACT SYNTAX TREE =========================\n' + JSON.stringify(parseTree, null, 2) + '\n========================================================================' ); } if (flags.print_symbol_table === true) { console.log(BRIGHT_BLUE, '\n========================= SYMBOL TABLE =================================\n' + JSON.stringify(globalSymbolTable, null, 2) + '\n========================================================================'); } if (flags.print_function_table === true) { console.log(BRIGHT_RED, '\n========================= FUNCTION TABLE ===============================\n' + JSON.stringify(functionTable, null, 2) + '\n========================================================================' ); } */ let file_out = file_name.replace('.wat', '.wasm'); console.log(BRIGHT_GREEN, ` Output File: ${file_out}`); if (!WasmModule.validate()) console.log("validation error"); // newModule is a workaround for an issue I had where directly emitting the binary // from WasmModule was screwing up the types for some reason. I'm doing this until // I have more time to look into why that was happening. WasmModule.optimize(); console.log(WasmModule.emitText()); let newModule = binaryen.parseText(WasmModule.emitText()); fs.writeFileSync(file_out, newModule.emitBinary()); //console.log(WasmModule.emitStackIR()) } module.exports = { compile, log_error, log_support };