summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJF Bastien <jfb@chromium.org>2016-01-11 17:23:27 -0800
committerJF Bastien <jfb@chromium.org>2016-01-11 17:23:27 -0800
commit1b3600b0aca6a8f23b6d9e8ae33dcd75c9493810 (patch)
tree606226cd0b851f09999647643476c492a80a93a3 /src
parent75a562190a9f4588c8ffb19b8304f76c15a850c6 (diff)
downloadbinaryen-1b3600b0aca6a8f23b6d9e8ae33dcd75c9493810.tar.gz
binaryen-1b3600b0aca6a8f23b6d9e8ae33dcd75c9493810.tar.bz2
binaryen-1b3600b0aca6a8f23b6d9e8ae33dcd75c9493810.zip
asm2wasm: use support's command-line
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm-main.cpp81
-rw-r--r--src/asm2wasm.h17
-rw-r--r--src/s2wasm-main.cpp2
-rw-r--r--src/support/command-line.cpp25
-rw-r--r--src/support/command-line.h4
-rw-r--r--src/support/file.cpp9
-rw-r--r--src/support/file.h9
-rw-r--r--src/wasm-js.cpp2
8 files changed, 91 insertions, 58 deletions
diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp
index 6a784bd76..1fd1273c0 100644
--- a/src/asm2wasm-main.cpp
+++ b/src/asm2wasm-main.cpp
@@ -18,64 +18,71 @@
// asm2wasm console tool
//
+#include "support/colors.h"
+#include "support/command-line.h"
+#include "support/file.h"
+
#include "asm2wasm.h"
using namespace cashew;
using namespace wasm;
-namespace wasm {
-int debug = 0;
-}
-
-int main(int argc, char **argv) {
- debug = getenv("ASM2WASM_DEBUG") ? getenv("ASM2WASM_DEBUG")[0] - '0' : 0;
-
- char *infile = argv[1];
- char *mappedGlobals = argc < 3 ? nullptr : argv[2];
+int main(int argc, const char *argv[]) {
+ Options options("asm2wasm", "Translate asm.js files to .wast files");
+ options
+ .add("--output", "-o", "Output file (stdout if not specified)",
+ Options::Arguments::One,
+ [](Options *o, const std::string &argument) {
+ o->extra["output"] = argument;
+ Colors::disable();
+ })
+ .add("--mapped-globals", "-m", "Mapped globals", Options::Arguments::One,
+ [](Options *o, const std::string &argument) {
+ o->extra["mapped globals"] = argument;
+ })
+ .add_positional("INFILE", Options::Arguments::One,
+ [](Options *o, const std::string &argument) {
+ o->extra["infile"] = argument;
+ });
+ options.parse(argc, argv);
- 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;
+ const auto &mg_it = options.extra.find("mapped globals");
+ const char *mappedGlobals =
+ mg_it == options.extra.end() ? nullptr : mg_it->second.c_str();
Asm2WasmPreProcessor pre;
- input = pre.process(input);
+ auto input(
+ read_file<std::vector<char>>(options.extra["infile"], options.debug));
+ char *start = pre.process(input.data());
- if (debug) std::cerr << "parsing...\n";
+ if (options.debug) std::cerr << "parsing..." << std::endl;
cashew::Parser<Ref, DotZeroValueBuilder> builder;
- Ref asmjs = builder.parseToplevel(input);
- if (debug) {
- std::cerr << "parsed:\n";
+ Ref asmjs = builder.parseToplevel(start);
+ if (options.debug) {
+ std::cerr << "parsed:" << std::endl;
asmjs->stringify(std::cerr, true);
- std::cerr << '\n';
+ std::cerr << std::endl;
}
- if (debug) std::cerr << "wasming...\n";
+ if (options.debug) std::cerr << "wasming..." << std::endl;
AllocatingModule wasm;
- wasm.memory.initial = wasm.memory.max = 16*1024*1024; // we would normally receive this from the compiler
- Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth);
+ wasm.memory.initial = wasm.memory.max =
+ 16 * 1024 * 1024; // we would normally receive this from the compiler
+ Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth, options.debug);
asm2wasm.processAsm(asmjs);
- if (debug) std::cerr << "optimizing...\n";
+ if (options.debug) std::cerr << "optimizing..." << std::endl;
asm2wasm.optimize();
- if (debug) std::cerr << "printing...\n";
- std::cout << wasm;
+ if (options.debug) std::cerr << "printing..." << std::endl;
+ Output output(options.extra["output"], options.debug);
+ output << wasm;
if (mappedGlobals) {
- if (debug) std::cerr << "serializing mapped globals...\n";
+ if (options.debug)
+ std::cerr << "serializing mapped globals..." << std::endl;
asm2wasm.serializeMappedGlobals(mappedGlobals);
}
- if (debug) std::cerr << "done.\n";
+ if (options.debug) std::cerr << "done." << std::endl;
}
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index db7cc1ae0..11cb75b30 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -33,8 +33,6 @@ namespace wasm {
using namespace cashew;
-extern int debug; // wasm::debug is set in main(), typically from an env var
-
// Utilities
static void abort_on(std::string why, Ref element) {
@@ -151,6 +149,7 @@ class Asm2WasmBuilder {
std::map<CallIndirect*, IString> callIndirects; // track these, as we need to fix them after we know the functionTableStarts. this maps call => its function table
bool memoryGrowth;
+ int debug;
public:
std::map<IString, MappedGlobal> mappedGlobals;
@@ -267,10 +266,16 @@ private:
}
public:
- Asm2WasmBuilder(AllocatingModule& wasm, bool memoryGrowth) : wasm(wasm), allocator(wasm.allocator), nextGlobal(8), maxGlobal(1000), memoryGrowth(memoryGrowth) {}
-
- void processAsm(Ref ast);
- void optimize();
+ Asm2WasmBuilder(AllocatingModule& wasm, bool memoryGrowth, int debug)
+ : wasm(wasm),
+ allocator(wasm.allocator),
+ nextGlobal(8),
+ maxGlobal(1000),
+ memoryGrowth(memoryGrowth),
+ debug(debug) {}
+
+ void processAsm(Ref ast);
+ void optimize();
private:
AsmType detectAsmType(Ref ast, AsmData *data) {
diff --git a/src/s2wasm-main.cpp b/src/s2wasm-main.cpp
index 277cee365..d0dd60bbf 100644
--- a/src/s2wasm-main.cpp
+++ b/src/s2wasm-main.cpp
@@ -45,7 +45,7 @@ int main(int argc, const char *argv[]) {
});
options.parse(argc, argv);
- std::string input(read_file(options.extra["infile"], options.debug));
+ auto input(read_file<std::string>(options.extra["infile"], options.debug));
if (options.debug) std::cerr << "Parsing and wasming..." << std::endl;
AllocatingModule wasm;
diff --git a/src/support/command-line.cpp b/src/support/command-line.cpp
index 659c055c9..c078ef45f 100644
--- a/src/support/command-line.cpp
+++ b/src/support/command-line.cpp
@@ -19,7 +19,7 @@
using namespace wasm;
Options::Options(const std::string &command, const std::string &description)
- : debug(false), positional(Arguments::Zero) {
+ : debug(0), positional(Arguments::Zero) {
add("--help", "-h", "Show this help message and exit", Arguments::Zero,
[this, command, description](Options *o, const std::string &) {
std::cerr << command;
@@ -39,8 +39,10 @@ Options::Options(const std::string &command, const std::string &description)
std::cerr << '\n';
exit(EXIT_SUCCESS);
});
- add("--debug", "-d", "Print debug information to stderr", Arguments::Zero,
- [](Options *o, const std::string &) { o->debug = true; });
+ add("--debug", "-d", "Print debug information to stderr", Arguments::Optional,
+ [](Options *o, const std::string &arguments) {
+ o->debug = arguments.size() ? std::stoi(arguments) : 1;
+ });
}
Options::~Options() {}
@@ -79,6 +81,7 @@ void Options::parse(int argc, const char *argv[]) {
<< "'\n";
exit(EXIT_FAILURE);
case Arguments::One:
+ case Arguments::Optional:
if (positionalsSeen) {
std::cerr << "Unexpected second positional argument '"
<< currentOption << "' for " << positionalName << '\n';
@@ -88,6 +91,7 @@ void Options::parse(int argc, const char *argv[]) {
case Arguments::N:
positionalAction(this, currentOption);
++positionalsSeen;
+ break;
}
continue;
}
@@ -110,8 +114,8 @@ void Options::parse(int argc, const char *argv[]) {
switch (option->arguments) {
case Arguments::Zero:
if (argument.size()) {
- std::cerr << "Unexpected argument '" << argument
- << "' for option '" << currentOption << "'\n";
+ std::cerr << "Unexpected argument '" << argument << "' for option '"
+ << currentOption << "'\n";
exit(EXIT_FAILURE);
}
break;
@@ -121,15 +125,22 @@ void Options::parse(int argc, const char *argv[]) {
<< currentOption << "'\n";
exit(EXIT_FAILURE);
}
- // Fallthrough.
+ // Fallthrough.
case Arguments::N:
if (!argument.size()) {
if (i + 1 == e) {
- std::cerr << "Couldn't find expected argument for '" << currentOption << "'\n";
+ std::cerr << "Couldn't find expected argument for '"
+ << currentOption << "'\n";
exit(EXIT_FAILURE);
}
argument = argv[++i];
}
+ break;
+ case Arguments::Optional:
+ if (!argument.size()) {
+ if (i + 1 != e) argument = argv[++i];
+ }
+ break;
}
option->action(this, argument);
++option->seen;
diff --git a/src/support/command-line.h b/src/support/command-line.h
index 14dbce57f..6e0af846e 100644
--- a/src/support/command-line.h
+++ b/src/support/command-line.h
@@ -35,9 +35,9 @@ namespace wasm {
class Options {
public:
typedef std::function<void(Options *, const std::string &)> Action;
- enum class Arguments { Zero, One, N };
+ enum class Arguments { Zero, One, N, Optional };
- bool debug;
+ int debug;
std::map<std::string, std::string> extra;
Options(const std::string &command, const std::string &description);
diff --git a/src/support/file.cpp b/src/support/file.cpp
index 470d07737..8813750d4 100644
--- a/src/support/file.cpp
+++ b/src/support/file.cpp
@@ -18,7 +18,8 @@
#include <cstdlib>
-std::string wasm::read_file(const std::string &filename, bool debug) {
+template <typename T>
+T wasm::read_file(const std::string &filename, bool debug) {
if (debug) std::cerr << "Loading '" << filename << "'..." << std::endl;
std::ifstream infile(filename);
if (!infile.is_open()) {
@@ -27,12 +28,16 @@ std::string wasm::read_file(const std::string &filename, bool debug) {
}
infile.seekg(0, std::ios::end);
size_t insize = infile.tellg();
- std::string input(insize + 1, '\0');
+ T input(insize + 1, '\0');
infile.seekg(0);
infile.read(&input[0], insize);
return input;
}
+// Explicit instantiations for the explicit specializations.
+template std::string wasm::read_file<>(const std::string &, bool);
+template std::vector<char> wasm::read_file<>(const std::string &, bool);
+
wasm::Output::Output(const std::string &filename, bool debug)
: outfile(), out([this, filename, debug]() {
std::streambuf *buffer;
diff --git a/src/support/file.h b/src/support/file.h
index e9c35f5f3..5e464d6c1 100644
--- a/src/support/file.h
+++ b/src/support/file.h
@@ -25,9 +25,14 @@
#include <iostream>
#include <string>
#include <utility>
+#include <vector>
namespace wasm {
-std::string read_file(const std::string &filename, bool debug);
+template <typename T>
+T read_file(const std::string &filename, bool debug);
+// Declare the valid explicit specializations.
+extern template std::string read_file<>(const std::string &, bool);
+extern template std::vector<char> read_file<>(const std::string &, bool);
class Output {
public:
@@ -48,4 +53,4 @@ class Output {
};
}
-#endif // wasm_support_file_h
+#endif // wasm_support_file_h
diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp
index 760f00c46..fdb157319 100644
--- a/src/wasm-js.cpp
+++ b/src/wasm-js.cpp
@@ -72,7 +72,7 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm2wasm(char *input) {
module->memory.max = pre.memoryGrowth ? -1 : module->memory.initial;
if (wasmJSDebug) std::cerr << "wasming...\n";
- asm2wasm = new Asm2WasmBuilder(*module, pre.memoryGrowth);
+ asm2wasm = new Asm2WasmBuilder(*module, pre.memoryGrowth, debug);
asm2wasm->processAsm(asmjs);
if (wasmJSDebug) std::cerr << "optimizing...\n";