summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xauto_update_tests.py2
-rwxr-xr-xcheck.py30
-rw-r--r--scripts/test/shared.py22
-rw-r--r--src/tools/asm2wasm.cpp21
-rw-r--r--src/tools/wasm-opt.cpp31
-rw-r--r--src/wasm-io.h68
-rw-r--r--src/wasm/CMakeLists.txt1
-rw-r--r--src/wasm/wasm-io.cpp86
8 files changed, 231 insertions, 30 deletions
diff --git a/auto_update_tests.py b/auto_update_tests.py
index 294bad750..7a14f6521 100755
--- a/auto_update_tests.py
+++ b/auto_update_tests.py
@@ -92,7 +92,7 @@ for t in sorted(os.listdir(os.path.join('test', 'passes'))):
print '\n[ checking wasm-opt -o notation... ]\n'
wast = os.path.join('test', 'hello_world.wast')
-cmd = [os.path.join('bin', 'wasm-opt'), wast, '-o', 'a.wast']
+cmd = [os.path.join('bin', 'wasm-opt'), wast, '-o', 'a.wast', '-S']
run_command(cmd)
open(wast, 'w').write(open('a.wast').read())
diff --git a/check.py b/check.py
index ce2ae4f50..7be44e63b 100755
--- a/check.py
+++ b/check.py
@@ -57,10 +57,20 @@ print '\n[ checking wasm-opt -o notation... ]\n'
wast = os.path.join(options.binaryen_test, 'hello_world.wast')
delete_from_orbit('a.wast')
-cmd = WASM_OPT + [wast, '-o', 'a.wast']
+cmd = WASM_OPT + [wast, '-o', 'a.wast', '-S']
run_command(cmd)
fail_if_not_identical(open('a.wast').read(), open(wast).read())
+print '\n[ checking wasm-opt binary reading/writing... ]\n'
+
+shutil.copyfile(os.path.join(options.binaryen_test, 'hello_world.wast'), 'a.wast')
+delete_from_orbit('a.wasm')
+delete_from_orbit('b.wast')
+run_command(WASM_OPT + ['a.wast', '-o', 'a.wasm'])
+assert open('a.wasm', 'rb').read()[0] == '\0', 'we emit binary by default'
+run_command(WASM_OPT + ['a.wasm', '-o', 'b.wast', '-S'])
+assert open('b.wast', 'rb').read()[0] != '\0', 'we emit text with -S'
+
print '\n[ checking wasm-opt passes... ]\n'
for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'passes'))):
@@ -141,6 +151,16 @@ for asm in tests:
fail_with_error('wasm interpreter error: ' + err) # failed to pretty-print
fail_with_error('wasm interpreter error')
+print '\n[ checking asm2wasm binary reading/writing... ]\n'
+
+asmjs = os.path.join(options.binaryen_test, 'hello_world.asm.js')
+delete_from_orbit('a.wasm')
+delete_from_orbit('b.wast')
+run_command(ASM2WASM + [asmjs, '-o', 'a.wasm'])
+assert open('a.wasm', 'rb').read()[0] == '\0', 'we emit binary by default'
+run_command(ASM2WASM + [asmjs, '-o', 'b.wast', '-S'])
+assert open('b.wast', 'rb').read()[0] != '\0', 'we emit text with -S'
+
print '\n[ checking wasm-opt parsing & printing... ]\n'
for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'print'))):
@@ -478,7 +498,7 @@ if EMCC:
asm = asm.replace("'almost asm'", '"use asm"; var not_in_asm = [].length + (true || { x: 5 }.x);')
with open('a.wasm.asm.js', 'w') as o: o.write(asm)
if method.startswith('interpret-asm2wasm'):
- os.unlink('a.wasm.wast') # we should not need the .wast
+ delete_from_orbit('a.wasm.wast') # we should not need the .wast
if not success:
break_cashew() # we need cashew
elif method.startswith('interpret-s-expr'):
@@ -486,12 +506,12 @@ if EMCC:
if not success:
os.unlink('a.wasm.wast')
elif method.startswith('asmjs'):
- os.unlink('a.wasm.wast') # we should not need the .wast
+ delete_from_orbit('a.wasm.wast') # we should not need the .wast
break_cashew() # we don't use cashew, so ok to break it
if not success:
os.unlink('a.wasm.js')
elif method.startswith('interpret-binary'):
- os.unlink('a.wasm.wast') # we should not need the .wast
+ delete_from_orbit('a.wasm.wast') # we should not need the .wast
os.unlink('a.wasm.asm.js') # we should not need the .asm.js
if not success:
os.unlink('a.wasm.wasm')
@@ -551,7 +571,7 @@ if EMCC:
execute()
- if method in ['interpret-asm2wasm', 'interpret-s-expr']:
+ if method in ['interpret-s-expr']:
# binary and back
shutil.copyfile('a.wasm.wast', 'a.wasm.original.wast')
recreated = binary_format_check('a.wasm.wast', verify_final_result=False)
diff --git a/scripts/test/shared.py b/scripts/test/shared.py
index 5aff20091..d899cc1de 100644
--- a/scripts/test/shared.py
+++ b/scripts/test/shared.py
@@ -389,18 +389,18 @@ def minify_check(wast, verify_final_result=True):
print ' ', ' '.join(cmd)
subprocess.check_call(
WASM_OPT + [wast, '--print-minified'],
- stdout=open('a.wasm', 'w'), stderr=subprocess.PIPE)
- assert os.path.exists('a.wasm')
+ stdout=open('a.wast', 'w'), stderr=subprocess.PIPE)
+ assert os.path.exists('a.wast')
subprocess.check_call(
- WASM_OPT + ['a.wasm', '--print-minified'],
- stdout=open('b.wasm', 'w'), stderr=subprocess.PIPE)
- assert os.path.exists('b.wasm')
+ WASM_OPT + ['a.wast', '--print-minified'],
+ stdout=open('b.wast', 'w'), stderr=subprocess.PIPE)
+ assert os.path.exists('b.wast')
if verify_final_result:
- expected = open('a.wasm').read()
- actual = open('b.wasm').read()
+ expected = open('a.wast').read()
+ actual = open('b.wast').read()
if actual != expected:
fail(actual, expected)
- if os.path.exists('a.wasm'):
- os.unlink('a.wasm')
- if os.path.exists('b.wasm'):
- os.unlink('b.wasm')
+ if os.path.exists('a.wast'):
+ os.unlink('a.wast')
+ if os.path.exists('b.wast'):
+ os.unlink('b.wast')
diff --git a/src/tools/asm2wasm.cpp b/src/tools/asm2wasm.cpp
index 9ba6062ea..c880e7459 100644
--- a/src/tools/asm2wasm.cpp
+++ b/src/tools/asm2wasm.cpp
@@ -23,6 +23,7 @@
#include "support/file.h"
#include "wasm-builder.h"
#include "wasm-printing.h"
+#include "wasm-io.h"
#include "asm2wasm.h"
@@ -34,6 +35,9 @@ int main(int argc, const char *argv[]) {
bool runOptimizationPasses = false;
bool imprecise = false;
bool wasmOnly = false;
+ bool debugInfo = false;
+ std::string symbolMap;
+ bool emitBinary = true;
Options options("asm2wasm", "Translate asm.js files to .wast files");
options
@@ -80,6 +84,15 @@ int main(int argc, const char *argv[]) {
[&wasmOnly](Options *o, const std::string &) {
wasmOnly = true;
})
+ .add("--debuginfo", "-g", "Emit names section and debug info",
+ Options::Arguments::Zero,
+ [&](Options *o, const std::string &arguments) { debugInfo = true; })
+ .add("--symbolmap", "-s", "Emit a symbol map (indexes => names)",
+ Options::Arguments::One,
+ [&](Options *o, const std::string &argument) { symbolMap = argument; })
+ .add("--emit-text", "-S", "Emit text instead of binary for the output file",
+ Options::Arguments::Zero,
+ [&](Options *o, const std::string &argument) { emitBinary = false; })
.add_positional("INFILE", Options::Arguments::One,
[](Options *o, const std::string &argument) {
o->extra["infile"] = argument;
@@ -153,8 +166,12 @@ int main(int argc, const char *argv[]) {
}
if (options.debug) std::cerr << "printing..." << std::endl;
- Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release);
- WasmPrinter::printModule(&wasm, output.getStream());
+ ModuleWriter writer;
+ writer.setDebug(options.debug);
+ writer.setDebugInfo(debugInfo);
+ writer.setSymbolMap(symbolMap);
+ writer.setBinary(emitBinary);
+ writer.write(wasm, options.extra["output"]);
if (options.debug) std::cerr << "done." << std::endl;
}
diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp
index 1da038b8e..93d8f5baa 100644
--- a/src/tools/wasm-opt.cpp
+++ b/src/tools/wasm-opt.cpp
@@ -27,6 +27,7 @@
#include "wasm-printing.h"
#include "wasm-s-parser.h"
#include "wasm-validator.h"
+#include "wasm-io.h"
using namespace wasm;
@@ -39,6 +40,7 @@ int main(int argc, const char* argv[]) {
std::vector<std::string> passes;
bool runOptimizationPasses = false;
PassOptions passOptions;
+ bool emitBinary = true;
Options options("wasm-opt", "Optimize .wast files");
options
@@ -49,6 +51,9 @@ int main(int argc, const char* argv[]) {
Colors::disable();
})
#include "optimization-options.h"
+ .add("--emit-text", "-S", "Emit text instead of binary for the output file",
+ Options::Arguments::Zero,
+ [&](Options *o, const std::string &argument) { emitBinary = false; })
.add_positional("INFILE", Options::Arguments::One,
[](Options* o, const std::string& argument) {
o->extra["infile"] = argument;
@@ -71,15 +76,17 @@ int main(int argc, const char* argv[]) {
Module wasm;
- try {
- if (options.debug) std::cerr << "s-parsing..." << std::endl;
- SExpressionParser parser(const_cast<char*>(input.c_str()));
- Element& root = *parser.root;
- if (options.debug) std::cerr << "w-parsing..." << std::endl;
- SExpressionWasmBuilder builder(wasm, *root[0]);
- } catch (ParseException& p) {
- p.dump(std::cerr);
- Fatal() << "error in parsing input";
+ {
+ if (options.debug) std::cerr << "reading...\n";
+ ModuleReader reader;
+ reader.setDebug(options.debug);
+
+ try {
+ reader.read(options.extra["infile"], wasm);
+ } catch (ParseException& p) {
+ p.dump(std::cerr);
+ Fatal() << "error in parsing input";
+ }
}
if (!WasmValidator().validate(wasm)) {
@@ -103,7 +110,9 @@ int main(int argc, const char* argv[]) {
if (options.extra.count("output") > 0) {
if (options.debug) std::cerr << "writing..." << std::endl;
- Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release);
- WasmPrinter::printModule(&wasm, output.getStream());
+ ModuleWriter writer;
+ writer.setDebug(options.debug);
+ writer.setBinary(emitBinary);
+ writer.write(wasm, options.extra["output"]);
}
}
diff --git a/src/wasm-io.h b/src/wasm-io.h
new file mode 100644
index 000000000..7d7358f9c
--- /dev/null
+++ b/src/wasm-io.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 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.
+ */
+
+//
+// Abstracts reading and writing, supporting both text and binary.
+//
+
+#ifndef wasm_wasm_io_h
+#define wasm_wasm_io_h
+
+#include "wasm.h"
+
+namespace wasm {
+
+class ModuleIO {
+protected:
+ bool debug = false;
+
+public:
+ void setDebug(bool debug_) { debug = debug_; }
+};
+
+class ModuleReader : public ModuleIO {
+public:
+ // read text
+ void readText(std::string filename, Module& wasm);
+ // read binary
+ void readBinary(std::string filename, Module& wasm);
+ // read text or binary, checking the contents for what it is
+ void read(std::string filename, Module& wasm);
+};
+
+class ModuleWriter : public ModuleIO {
+ bool binary = true;
+ bool debugInfo = false;
+ std::string symbolMap;
+
+public:
+ void setBinary(bool binary_) { binary = binary_; }
+ void setDebugInfo(bool debugInfo_) { debugInfo = debugInfo_; }
+ void setSymbolMap(std::string symbolMap_) { symbolMap = symbolMap_; }
+
+ // write text
+ void writeText(Module& wasm, std::string filename);
+ // write binary
+ void writeBinary(Module& wasm, std::string filename);
+ // write text or binary, defaulting to binary unless setBinary(false),
+ // and unless there is no output file (in which case we write text
+ // to stdout).
+ void write(Module& wasm, std::string filename);
+};
+
+}
+
+#endif // wasm_wasm_io_h
diff --git a/src/wasm/CMakeLists.txt b/src/wasm/CMakeLists.txt
index 65b626c25..e1b1aac33 100644
--- a/src/wasm/CMakeLists.txt
+++ b/src/wasm/CMakeLists.txt
@@ -1,6 +1,7 @@
SET(wasm_SOURCES
wasm.cpp
wasm-binary.cpp
+ wasm-io.cpp
wasm-s-parser.cpp
)
ADD_LIBRARY(wasm STATIC ${wasm_SOURCES})
diff --git a/src/wasm/wasm-io.cpp b/src/wasm/wasm-io.cpp
new file mode 100644
index 000000000..2380f7447
--- /dev/null
+++ b/src/wasm/wasm-io.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2017 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.
+ */
+
+//
+// Abstracts reading and writing, supporting both text and binary
+// depending on the suffix.
+//
+// When the suffix is unclear, writing defaults to text (this
+// allows odd suffixes, which we use in the test suite), while
+// reading will check the magic number and default to text if not
+// binary.
+//
+
+#include "wasm-io.h"
+#include "wasm-s-parser.h"
+#include "wasm-binary.h"
+#include "support/file.h"
+
+namespace wasm {
+
+void ModuleReader::readText(std::string filename, Module& wasm) {
+ if (debug) std::cerr << "reading text from " << filename << "\n";
+ auto input(read_file<std::string>(filename, Flags::Text, debug ? Flags::Debug : Flags::Release));
+ SExpressionParser parser(const_cast<char*>(input.c_str()));
+ Element& root = *parser.root;
+ SExpressionWasmBuilder builder(wasm, *root[0]);
+}
+
+void ModuleReader::readBinary(std::string filename, Module& wasm) {
+ if (debug) std::cerr << "reading binary from " << filename << "\n";
+ auto input(read_file<std::vector<char>>(filename, Flags::Binary, debug ? Flags::Debug : Flags::Release));
+ WasmBinaryBuilder parser(wasm, input, debug);
+ parser.read();
+}
+
+void ModuleReader::read(std::string filename, Module& wasm) {
+ // see if this is a binary
+ auto contents = read_file<std::vector<char>>(filename, Flags::Binary, debug ? Flags::Debug : Flags::Release);
+ if (contents.size() >= 4 && contents[0] == '\0' && contents[1] == 'a' && contents[2] == 's' && contents[3] == 'm') {
+ readBinary(filename, wasm);
+ } else {
+ // default to text
+ readText(filename, wasm);
+ }
+}
+
+void ModuleWriter::writeText(Module& wasm, std::string filename) {
+ if (debug) std::cerr << "writing text to " << filename << "\n";
+ Output output(filename, Flags::Text, debug ? Flags::Debug : Flags::Release);
+ WasmPrinter::printModule(&wasm, output.getStream());
+}
+
+void ModuleWriter::writeBinary(Module& wasm, std::string filename) {
+ if (debug) std::cerr << "writing binary to " << filename << "\n";
+ BufferWithRandomAccess buffer(debug);
+ WasmBinaryWriter writer(&wasm, buffer, debug);
+ writer.setDebugInfo(debugInfo);
+ if (symbolMap.size() > 0) writer.setSymbolMap(symbolMap);
+ writer.write();
+ Output output(filename, Flags::Binary, debug ? Flags::Debug : Flags::Release);
+ buffer.writeTo(output);
+}
+
+void ModuleWriter::write(Module& wasm, std::string filename) {
+ if (binary && filename.size() > 0) {
+ writeBinary(wasm, filename);
+ } else {
+ writeText(wasm, filename);
+ }
+}
+
+}
+