summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm-main.cpp66
-rw-r--r--src/asm2wasm.h (renamed from src/asm2wasm.cpp)64
-rw-r--r--src/istring.h5
-rw-r--r--src/optimizer-shared.cpp4
-rw-r--r--src/optimizer.h62
-rw-r--r--src/parser.h5
-rw-r--r--src/simple_ast.cpp4
-rw-r--r--src/simple_ast.h9
-rw-r--r--src/wasm-interpreter.cpp5
-rw-r--r--src/wasm.h2
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';