diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm-main.cpp | 66 | ||||
-rw-r--r-- | src/asm2wasm.h (renamed from src/asm2wasm.cpp) | 64 | ||||
-rw-r--r-- | src/istring.h | 5 | ||||
-rw-r--r-- | src/optimizer-shared.cpp | 4 | ||||
-rw-r--r-- | src/optimizer.h | 62 | ||||
-rw-r--r-- | src/parser.h | 5 | ||||
-rw-r--r-- | src/simple_ast.cpp | 4 | ||||
-rw-r--r-- | src/simple_ast.h | 9 | ||||
-rw-r--r-- | src/wasm-interpreter.cpp | 5 | ||||
-rw-r--r-- | src/wasm.h | 2 |
10 files changed, 135 insertions, 91 deletions
diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp new file mode 100644 index 000000000..c09a2345b --- /dev/null +++ b/src/asm2wasm-main.cpp @@ -0,0 +1,66 @@ +// +// asm2wasm console tool +// + +#include "asm2wasm.h" + +using namespace cashew; +using namespace wasm; + +int main(int argc, char **argv) { + debug = getenv("ASM2WASM_DEBUG") ? getenv("ASM2WASM_DEBUG")[0] - '0' : 0; + + char *infile = argv[1]; + + if (debug) std::cerr << "loading '" << infile << "'...\n"; + FILE *f = fopen(argv[1], "r"); + assert(f); + fseek(f, 0, SEEK_END); + int size = ftell(f); + char *input = new char[size+1]; + rewind(f); + int num = fread(input, 1, size, f); + // On Windows, ftell() gives the byte position (\r\n counts as two bytes), but when + // reading, fread() returns the number of characters read (\r\n is read as one char \n, and counted as one), + // so return value of fread can be less than size reported by ftell, and that is normal. + assert((num > 0 || size == 0) && num <= size); + fclose(f); + input[num] = 0; + + // emcc --separate-asm modules look like + // + // Module["asm"] = (function(global, env, buffer) { + // .. + // }); + // + // we need to clean that up. + if (*input == 'M') { + while (*input != 'f') { + input++; + num--; + } + char *end = input + num - 1; + while (*end != '}') { + *end = 0; + end--; + } + } + + if (debug) std::cerr << "parsing...\n"; + cashew::Parser<Ref, DotZeroValueBuilder> builder; + Ref asmjs = builder.parseToplevel(input); + + if (debug) std::cerr << "wasming...\n"; + Module wasm; + Asm2WasmBuilder asm2wasm(wasm); + asm2wasm.processAsm(asmjs); + + if (debug) std::cerr << "optimizing...\n"; + asm2wasm.optimize(); + + if (debug) std::cerr << "printing...\n"; + std::cout << wasm; + + if (debug) std::cerr << "done.\n"; +} + diff --git a/src/asm2wasm.cpp b/src/asm2wasm.h index a327fb274..6a49559a0 100644 --- a/src/asm2wasm.cpp +++ b/src/asm2wasm.h @@ -2,12 +2,11 @@ #include "wasm.h" #include "optimizer.h" -#include "optimizer-shared.cpp" +namespace wasm { using namespace cashew; -using namespace wasm; -int debug; +int debug = 0; // Utilities @@ -1062,62 +1061,5 @@ void Asm2WasmBuilder::optimize() { } } -// main - -int main(int argc, char **argv) { - debug = getenv("ASM2WASM_DEBUG") ? getenv("ASM2WASM_DEBUG")[0] - '0' : 0; - - char *infile = argv[1]; - - if (debug) std::cerr << "loading '" << infile << "'...\n"; - FILE *f = fopen(argv[1], "r"); - assert(f); - fseek(f, 0, SEEK_END); - int size = ftell(f); - char *input = new char[size+1]; - rewind(f); - int num = fread(input, 1, size, f); - // On Windows, ftell() gives the byte position (\r\n counts as two bytes), but when - // reading, fread() returns the number of characters read (\r\n is read as one char \n, and counted as one), - // so return value of fread can be less than size reported by ftell, and that is normal. - assert((num > 0 || size == 0) && num <= size); - fclose(f); - input[num] = 0; - - // emcc --separate-asm modules look like - // - // Module["asm"] = (function(global, env, buffer) { - // .. - // }); - // - // we need to clean that up. - if (*input == 'M') { - while (*input != 'f') { - input++; - num--; - } - char *end = input + num - 1; - while (*end != '}') { - *end = 0; - end--; - } - } - - if (debug) std::cerr << "parsing...\n"; - cashew::Parser<Ref, DotZeroValueBuilder> builder; - Ref asmjs = builder.parseToplevel(input); - - if (debug) std::cerr << "wasming...\n"; - Module wasm; - Asm2WasmBuilder asm2wasm(wasm); - asm2wasm.processAsm(asmjs); - - if (debug) std::cerr << "optimizing...\n"; - asm2wasm.optimize(); - - if (debug) std::cerr << "printing...\n"; - std::cout << wasm; - - if (debug) std::cerr << "done.\n"; -} +} // namespace wasm diff --git a/src/istring.h b/src/istring.h index 921e04487..b77fec4e5 100644 --- a/src/istring.h +++ b/src/istring.h @@ -1,5 +1,8 @@ // Interned String type, 100% interned on creation. Comparisons are always just a pointer comparison +#ifndef __istring_h__ +#define __istring_h__ + #include <unordered_set> #include <unordered_map> #include <set> @@ -154,3 +157,5 @@ public: } // namespace cashew +#endif // __istring_h__ + diff --git a/src/optimizer-shared.cpp b/src/optimizer-shared.cpp index 9072d6c48..1c36efc62 100644 --- a/src/optimizer-shared.cpp +++ b/src/optimizer-shared.cpp @@ -1,4 +1,8 @@ +#include "optimizer.h" + +using namespace cashew; + IString ASM_FLOAT_ZERO; IString SIMD_INT8X16_CHECK("SIMD_Int8x16_check"), diff --git a/src/optimizer.h b/src/optimizer.h index 04ee7dddf..5edcaad87 100644 --- a/src/optimizer.h +++ b/src/optimizer.h @@ -1,21 +1,27 @@ + +#ifndef __optimizer_h__ +#define __optimizer_h__ + +#include "simple_ast.h" + extern bool preciseF32, receiveJSON, emitJSON, minifyWhitespace, last; -extern Ref extraInfo; +extern cashew::Ref extraInfo; -void eliminateDeadFuncs(Ref ast); -void eliminate(Ref ast, bool memSafe=false); -void eliminateMemSafe(Ref ast); -void simplifyExpressions(Ref ast); -void optimizeFrounds(Ref ast); -void simplifyIfs(Ref ast); -void registerize(Ref ast); -void registerizeHarder(Ref ast); -void minifyLocals(Ref ast); -void asmLastOpts(Ref ast); +void eliminateDeadFuncs(cashew::Ref ast); +void eliminate(cashew::Ref ast, bool memSafe=false); +void eliminateMemSafe(cashew::Ref ast); +void simplifyExpressions(cashew::Ref ast); +void optimizeFrounds(cashew::Ref ast); +void simplifyIfs(cashew::Ref ast); +void registerize(cashew::Ref ast); +void registerizeHarder(cashew::Ref ast); +void minifyLocals(cashew::Ref ast); +void asmLastOpts(cashew::Ref ast); // @@ -33,7 +39,7 @@ enum AsmType { struct AsmData; -AsmType detectType(Ref node, AsmData *asmData=nullptr, bool inVarDef=false); +AsmType detectType(cashew::Ref node, AsmData *asmData=nullptr, bool inVarDef=false); struct AsmData { struct Local { @@ -42,49 +48,49 @@ struct AsmData { AsmType type; bool param; // false if a var }; - typedef std::unordered_map<IString, Local> Locals; + typedef std::unordered_map<cashew::IString, Local> Locals; Locals locals; - std::vector<IString> params; // in order - std::vector<IString> vars; // in order + std::vector<cashew::IString> params; // in order + std::vector<cashew::IString> vars; // in order AsmType ret; - Ref func; + cashew::Ref func; - AsmType getType(const IString& name) { + AsmType getType(const cashew::IString& name) { auto ret = locals.find(name); if (ret != locals.end()) return ret->second.type; return ASM_NONE; } - void setType(const IString& name, AsmType type) { + void setType(const cashew::IString& name, AsmType type) { locals[name].type = type; } - bool isLocal(const IString& name) { + bool isLocal(const cashew::IString& name) { return locals.count(name) > 0; } - bool isParam(const IString& name) { + bool isParam(const cashew::IString& name) { return isLocal(name) && locals[name].param; } - bool isVar(const IString& name) { + bool isVar(const cashew::IString& name) { return isLocal(name) && !locals[name].param; } AsmData() {} // if you want to fill in the data yourself - AsmData(Ref f); // if you want to read data from f, and modify it as you go (parallel to denormalize) + AsmData(cashew::Ref f); // if you want to read data from f, and modify it as you go (parallel to denormalize) void denormalize(); - void addParam(IString name, AsmType type) { + void addParam(cashew::IString name, AsmType type) { locals[name] = Local(type, true); params.push_back(name); } - void addVar(IString name, AsmType type) { + void addVar(cashew::IString name, AsmType type) { locals[name] = Local(type, false); vars.push_back(name); } - void deleteVar(IString name) { + void deleteVar(cashew::IString name) { locals.erase(name); for (size_t i = 0; i < vars.size(); i++) { if (vars[i] == name) { @@ -99,9 +105,9 @@ bool isInteger(double x); bool isInteger32(double x); -extern IString ASM_FLOAT_ZERO; +extern cashew::IString ASM_FLOAT_ZERO; -extern IString SIMD_INT8X16_CHECK, +extern cashew::IString SIMD_INT8X16_CHECK, SIMD_INT16X8_CHECK, SIMD_INT32X4_CHECK, SIMD_FLOAT32X4_CHECK, @@ -117,3 +123,5 @@ struct HeapInfo { HeapInfo parseHeap(const char *name); +#endif // __optimizer_h__ + diff --git a/src/parser.h b/src/parser.h index 9f5b6c3a7..8ca07c6ed 100644 --- a/src/parser.h +++ b/src/parser.h @@ -3,6 +3,9 @@ // XXX All parsing methods assume they take ownership of the input string. This lets them reuse // parts of it. You will segfault if the input string cannot be reused and written to. +#ifndef __parser_h__ +#define __parser_h__ + #include <vector> #include <iostream> #include <algorithm> @@ -898,3 +901,5 @@ public: } // namespace cashew +#endif // __parser_h__ + diff --git a/src/simple_ast.cpp b/src/simple_ast.cpp index 3027010d1..89b8ce8ed 100644 --- a/src/simple_ast.cpp +++ b/src/simple_ast.cpp @@ -1,6 +1,8 @@ #include "simple_ast.h" +namespace cashew { + // Ref methods Ref& Ref::operator[](unsigned x) { @@ -253,3 +255,5 @@ void traverseFunctions(Ref ast, std::function<void (Ref)> visit) { IStringSet ValueBuilder::statable("assign call binary unary-prefix if name num conditional dot new sub seq string object array"); +} // namespace cashew + diff --git a/src/simple_ast.h b/src/simple_ast.h index de894b4bc..4012ff8f6 100644 --- a/src/simple_ast.h +++ b/src/simple_ast.h @@ -1,4 +1,7 @@ +#ifndef __simple_ast_h__ +#define __simple_ast_h__ + #include <assert.h> #include <stdlib.h> #include <stdio.h> @@ -23,7 +26,7 @@ #define errv(str, ...) fprintf(stderr, str "\n", __VA_ARGS__); #define printErr err -using namespace cashew; +namespace cashew { struct Ref; struct Value; @@ -1533,3 +1536,7 @@ public: } }; +} // namespace cashew + +#endif // __simple_ast_h__ + diff --git a/src/wasm-interpreter.cpp b/src/wasm-interpreter.cpp index ec7197203..d4451d55c 100644 --- a/src/wasm-interpreter.cpp +++ b/src/wasm-interpreter.cpp @@ -9,7 +9,10 @@ using namespace wasm; namespace wasm { -// An instance of a WebAssembly module +// +// An instance of a WebAssembly module, which can execute it via AST interpretation +// + class ModuleInstance { public: typedef std::vector<Literal> LiteralList; diff --git a/src/wasm.h b/src/wasm.h index c2816dc19..4ef01395c 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -176,7 +176,7 @@ struct Literal { double getf64() { assert(type == WasmType::f64); return f64; } void printDouble(std::ostream &o, double d) { - const char *text = JSPrinter::numToString(d); + const char *text = cashew::JSPrinter::numToString(d); // spec interpreter hates floats starting with '.' if (text[0] == '.') { o << '0'; |