summaryrefslogtreecommitdiff
path: root/src/tools/wasm2js.cpp
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-08-30 16:10:26 -0700
committerAlon Zakai <alonzakai@gmail.com>2018-08-30 16:10:26 -0700
commitf109f3cae1cd81db22ba490a4da17a7a4c495047 (patch)
treefd7307a567505a28f879ccce00a30d2d0d27b848 /src/tools/wasm2js.cpp
parent3976440ccb2c3ab9d67af7239f87ae04ebdeda1e (diff)
downloadbinaryen-f109f3cae1cd81db22ba490a4da17a7a4c495047.tar.gz
binaryen-f109f3cae1cd81db22ba490a4da17a7a4c495047.tar.bz2
binaryen-f109f3cae1cd81db22ba490a4da17a7a4c495047.zip
Rename `wasm2asm` to `wasm2js`, emit ESM by default (#1642)
* Rename the `wasm2asm` tool to `wasm2js` This commit performs a relatively simple rename of the `wasm2asm` tool to `wasm2js`. The functionality of the tool doesn't change just yet but it's intended that we'll start generating an ES module instead of just an `asm.js` function soon. * wasm2js: Support `*.wasm` input files Previously `wasm2js` only supported `*.wast` files but to make it a bit easier to use in tooling pipelines this commit adds support for reading in a `*.wasm` file directly. Determining which parser to use depends on the input filename, where the binary parser is used with `*.wasm` files and the wast parser is used for all other files. * wasm2js: Emit ESM imports/exports by default This commit alters the default behavior of `wasm2js` to emit an ESM by default, either importing items from the environment or exporting. Items like initialization of memory are also handled here.
Diffstat (limited to 'src/tools/wasm2js.cpp')
-rw-r--r--src/tools/wasm2js.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp
new file mode 100644
index 000000000..8a57a5a1a
--- /dev/null
+++ b/src/tools/wasm2js.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2015 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// wasm2js console tool
+//
+
+#include "support/colors.h"
+#include "support/command-line.h"
+#include "support/file.h"
+#include "wasm-s-parser.h"
+#include "wasm2js.h"
+
+using namespace cashew;
+using namespace wasm;
+
+int main(int argc, const char *argv[]) {
+ Wasm2JSBuilder::Flags builderFlags;
+ Options options("wasm2js", "Transform .wasm/.wast files to asm.js");
+ 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("--allow-asserts", "", "Allow compilation of .wast testing asserts",
+ Options::Arguments::Zero,
+ [&](Options* o, const std::string& argument) {
+ builderFlags.allowAsserts = true;
+ o->extra["asserts"] = "1";
+ })
+ .add("--pedantic", "", "Emulate WebAssembly trapping behavior",
+ Options::Arguments::Zero,
+ [&](Options* o, const std::string& argument) {
+ builderFlags.pedantic = true;
+ })
+ .add_positional("INFILE", Options::Arguments::One,
+ [](Options *o, const std::string& argument) {
+ o->extra["infile"] = argument;
+ });
+ options.parse(argc, argv);
+ if (options.debug) builderFlags.debug = true;
+
+ Element* root;
+ Module wasm;
+ Ref asmjs;
+
+ try {
+ // If the input filename ends in `.wasm`, then parse it in binary form,
+ // otherwise assume it's a `*.wast` file and go from there.
+ //
+ // Note that we're not using the built-in `ModuleReader` which will also do
+ // similar logic here because when testing JS files we use the
+ // `--allow-asserts` flag which means we need to parse the extra
+ // s-expressions that come at the end of the `*.wast` file after the module
+ // is defined.
+ auto &input = options.extra["infile"];
+ std::string suffix(".wasm");
+ if (input.size() >= suffix.size() &&
+ input.compare(input.size() - suffix.size(), suffix.size(), suffix) == 0) {
+ ModuleReader reader;
+ reader.setDebug(options.debug);
+ reader.read(input, wasm, "");
+
+ if (options.debug) std::cerr << "asming..." << std::endl;
+ Wasm2JSBuilder wasm2js(builderFlags);
+ asmjs = wasm2js.processWasm(&wasm);
+
+ } else {
+ auto input(
+ read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release));
+ if (options.debug) std::cerr << "s-parsing..." << std::endl;
+ SExpressionParser parser(input.data());
+ root = parser.root;
+
+ if (options.debug) std::cerr << "w-parsing..." << std::endl;
+ SExpressionWasmBuilder builder(wasm, *(*root)[0]);
+
+ if (options.debug) std::cerr << "asming..." << std::endl;
+ Wasm2JSBuilder wasm2js(builderFlags);
+ asmjs = wasm2js.processWasm(&wasm);
+
+ if (options.extra["asserts"] == "1") {
+ if (options.debug) std::cerr << "asserting..." << std::endl;
+ flattenAppend(asmjs, wasm2js.processAsserts(&wasm, *root, builder));
+ }
+ }
+ } catch (ParseException& p) {
+ p.dump(std::cerr);
+ Fatal() << "error in parsing input";
+ } catch (std::bad_alloc&) {
+ Fatal() << "error in building module, std::bad_alloc (possibly invalid request for silly amounts of memory)";
+ }
+
+ if (options.debug) {
+ std::cerr << "a-printing..." << std::endl;
+ asmjs->stringify(std::cout, true);
+ std::cout << '\n';
+ }
+
+ if (options.debug) std::cerr << "j-printing..." << std::endl;
+ JSPrinter jser(true, true, asmjs);
+ jser.printAst();
+ Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release);
+ output << jser.buffer << std::endl;
+
+ if (options.debug) std::cerr << "done." << std::endl;
+}