summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp9
-rw-r--r--src/binaryen-shell.cpp14
-rw-r--r--src/parsing.h27
-rw-r--r--src/shell-interface.h6
-rw-r--r--src/wasm-as.cpp17
-rw-r--r--src/wasm-binary.h18
-rw-r--r--src/wasm-dis.cpp9
-rw-r--r--src/wasm-s-parser.h36
8 files changed, 88 insertions, 48 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 315c11fdb..135ca1504 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -416,10 +416,13 @@ BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) {
std::vector<char> buffer(false);
buffer.resize(inputSize);
std::copy_n(input, inputSize, buffer.begin());
- WasmBinaryBuilder parser(*wasm, buffer, []() {
+ try {
+ WasmBinaryBuilder parser(*wasm, buffer, false);
+ parser.read();
+ } catch (ParseException& p) {
+ p.dump(std::cerr);
Fatal() << "error in parsing wasm binary";
- }, false);
- parser.read();
+ }
return wasm;
}
diff --git a/src/binaryen-shell.cpp b/src/binaryen-shell.cpp
index 8c0390d15..360b576c8 100644
--- a/src/binaryen-shell.cpp
+++ b/src/binaryen-shell.cpp
@@ -113,10 +113,7 @@ static void run_asserts(size_t* i, bool* checked, Module* wasm,
std::unique_ptr<SExpressionWasmBuilder> builder;
try {
builder = std::unique_ptr<SExpressionWasmBuilder>(
- new SExpressionWasmBuilder(wasm, *curr[1], [&]() {
- invalid = true;
- throw ParseException();
- })
+ new SExpressionWasmBuilder(wasm, *curr[1])
);
} catch (const ParseException&) {
invalid = true;
@@ -214,8 +211,13 @@ int main(int argc, const char* argv[]) {
if (id == MODULE) {
if (options.debug) std::cerr << "parsing s-expressions to wasm...\n";
Module wasm;
- std::unique_ptr<SExpressionWasmBuilder> builder(
- new SExpressionWasmBuilder(wasm, *root[i], [&]() { abort(); }));
+ std::unique_ptr<SExpressionWasmBuilder> builder;
+ try {
+ builder = make_unique<SExpressionWasmBuilder>(wasm, *root[i]);
+ } catch (ParseException& p) {
+ p.dump(std::cerr);
+ abort();
+ }
i++;
assert(WasmValidator().validate(wasm));
diff --git a/src/parsing.h b/src/parsing.h
index 2104337a6..6745ad7cd 100644
--- a/src/parsing.h
+++ b/src/parsing.h
@@ -17,12 +17,15 @@
#ifndef wasm_parsing_h
#define wasm_parsing_h
+#include <ostream>
#include <sstream>
+#include <string>
#include "asmjs/shared-constants.h"
#include "mixed_arena.h"
#include "support/utilities.h"
#include "wasm.h"
+#include "wasm-printing.h"
namespace wasm {
@@ -162,6 +165,30 @@ inline Expression* parseConst(cashew::IString s, WasmType type, MixedArena& allo
return ret;
}
+struct ParseException {
+ std::string text;
+ size_t line, col;
+
+ ParseException() : text("unknown parse error"), line(-1), col(-1) {}
+ ParseException(std::string text) : text(text), line(-1), col(-1) {}
+ ParseException(std::string text, size_t line, size_t col) : text(text), line(line), col(col) {}
+
+ void dump(std::ostream& o) {
+ Colors::magenta(o);
+ o << "[";
+ Colors::red(o);
+ o << "parse exception: ";
+ Colors::green(o);
+ o << text;
+ if (line != size_t(-1)) {
+ Colors::normal(o);
+ o << " (at " << line << ":" << col << ")";
+ }
+ Colors::magenta(o);
+ o << "]";
+ Colors::normal(o);
+ }
+};
} // namespace wasm
diff --git a/src/shell-interface.h b/src/shell-interface.h
index 4e56bb8e1..b87460a48 100644
--- a/src/shell-interface.h
+++ b/src/shell-interface.h
@@ -18,6 +18,9 @@
// Implementation of the shell interpreter execution environment
//
+#ifndef wasm_shell_interface_h
+#define wasm_shell_interface_h
+
#include "asmjs/shared-constants.h"
#include "wasm.h"
#include "wasm-interpreter.h"
@@ -26,7 +29,6 @@ namespace wasm {
struct ExitException {};
struct TrapException {};
-struct ParseException {};
struct ShellExternalInterface : ModuleInstance::ExternalInterface {
// The underlying memory can be accessed through unaligned pointers which
@@ -177,3 +179,5 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
};
}
+
+#endif // wasm_shell_interface_h
diff --git a/src/wasm-as.cpp b/src/wasm-as.cpp
index eb03f853a..40839ea55 100644
--- a/src/wasm-as.cpp
+++ b/src/wasm-as.cpp
@@ -43,13 +43,18 @@ int main(int argc, const char *argv[]) {
auto input(read_file<std::string>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release));
- 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;
Module wasm;
- SExpressionWasmBuilder builder(wasm, *root[0], [&]() { abort(); });
+
+ 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 wasm binary";
+ }
if (options.debug) std::cerr << "binarification..." << std::endl;
BufferWithRandomAccess buffer(options.debug);
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 406be3ef7..1fe3ef26a 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -32,6 +32,7 @@
#include "asm_v_wasm.h"
#include "wasm-builder.h"
#include "ast_utils.h"
+#include "parsing.h"
#include "wasm-validator.h"
namespace wasm {
@@ -1164,14 +1165,13 @@ class WasmBinaryBuilder {
Module& wasm;
MixedArena& allocator;
std::vector<char>& input;
- std::function<void ()> onError;
bool debug;
size_t pos = 0;
int32_t startIndex = -1;
public:
- WasmBinaryBuilder(Module& wasm, std::vector<char>& input, std::function<void ()> onError, bool debug) : wasm(wasm), allocator(wasm.allocator), input(input), onError(onError), debug(debug) {}
+ WasmBinaryBuilder(Module& wasm, std::vector<char>& input, bool debug) : wasm(wasm), allocator(wasm.allocator), input(input), debug(debug) {}
void read() {
@@ -1226,7 +1226,7 @@ public:
}
uint8_t getInt8() {
- if (!more()) onError();
+ if (!more()) throw ParseException("unexpected end of input");
if (debug) std::cerr << "getInt8: " << (int)(uint8_t)input[pos] << " (at " << pos << ")" << std::endl;
return input[pos++];
}
@@ -1330,27 +1330,27 @@ public:
void verifyInt8(int8_t x) {
int8_t y = getInt8();
- if (x != y) onError();
+ if (x != y) throw ParseException("surprising value", 0, pos);
}
void verifyInt16(int16_t x) {
int16_t y = getInt16();
- if (x != y) onError();
+ if (x != y) throw ParseException("surprising value", 0, pos);
}
void verifyInt32(int32_t x) {
int32_t y = getInt32();
- if (x != y) onError();
+ if (x != y) throw ParseException("surprising value", 0, pos);
}
void verifyInt64(int64_t x) {
int64_t y = getInt64();
- if (x != y) onError();
+ if (x != y) throw ParseException("surprising value", 0, pos);
}
void verifyFloat32(float x) {
float y = getFloat32();
- if (x != y) onError();
+ if (x != y) throw ParseException("surprising value", 0, pos);
}
void verifyFloat64(double x) {
double y = getFloat64();
- if (x != y) onError();
+ if (x != y) throw ParseException("surprising value", 0, pos);
}
void ungetInt8() {
diff --git a/src/wasm-dis.cpp b/src/wasm-dis.cpp
index 94965518c..93c286913 100644
--- a/src/wasm-dis.cpp
+++ b/src/wasm-dis.cpp
@@ -45,10 +45,13 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "parsing binary..." << std::endl;
Module wasm;
- WasmBinaryBuilder parser(wasm, input, []() {
+ try {
+ WasmBinaryBuilder parser(wasm, input, options.debug);
+ parser.read();
+ } catch (ParseException& p) {
+ p.dump(std::cerr);
Fatal() << "error in parsing wasm binary";
- }, options.debug);
- parser.read();
+ }
if (options.debug) std::cerr << "Printing..." << std::endl;
Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release);
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 4b27918d3..e0f85227d 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -239,7 +239,6 @@ private:
class SExpressionWasmBuilder {
Module& wasm;
MixedArena& allocator;
- std::function<void ()> onError;
std::vector<Name> functionNames;
int functionCounter;
int importCounter;
@@ -247,7 +246,7 @@ class SExpressionWasmBuilder {
public:
// Assumes control of and modifies the input.
- SExpressionWasmBuilder(Module& wasm, Element& module, std::function<void ()> onError) : wasm(wasm), allocator(wasm.allocator), onError(onError), importCounter(0) {
+ SExpressionWasmBuilder(Module& wasm, Element& module) : wasm(wasm), allocator(wasm.allocator), importCounter(0) {
assert(module[0]->str() == MODULE);
if (module.size() > 1 && module[1]->isStr()) {
// these s-expressions contain a binary module, actually
@@ -259,7 +258,7 @@ public:
stringToBinary(str, size, data);
}
}
- WasmBinaryBuilder binaryBuilder(wasm, data, onError, false);
+ WasmBinaryBuilder binaryBuilder(wasm, data, false);
binaryBuilder.read();
return;
}
@@ -274,9 +273,6 @@ public:
}
}
- // constructor without onError
- SExpressionWasmBuilder(Module& wasm, Element& module) : SExpressionWasmBuilder(wasm, module, [&]() { abort(); }) {}
-
private:
// pre-parse types and function definitions, so we know function return types before parsing their contents
@@ -303,7 +299,7 @@ private:
return;
} else if (id == TYPE) {
Name typeName = curr[1]->str();
- if (!wasm.checkFunctionType(typeName)) onError();
+ if (!wasm.checkFunctionType(typeName)) throw ParseException("unknown function");
FunctionType* type = wasm.getFunctionType(typeName);
functionTypes[name] = type->result;
return;
@@ -327,7 +323,7 @@ private:
if (id == TABLE) return parseTable(curr);
if (id == TYPE) return; // already done
std::cerr << "bad module element " << id.str << '\n';
- onError();
+ throw ParseException("unknown module element");
}
// function parsing state
@@ -347,7 +343,7 @@ private:
} else {
// index
size_t offset = atoi(s.str().c_str());
- if (offset >= functionNames.size()) onError();
+ if (offset >= functionNames.size()) throw ParseException("unknown function");
return functionNames[offset];
}
}
@@ -417,7 +413,7 @@ private:
} else if (id == TYPE) {
Name name = curr[1]->str();
type = name;
- if (!wasm.checkFunctionType(name)) onError();
+ if (!wasm.checkFunctionType(name)) throw ParseException("unknown function");
FunctionType* type = wasm.getFunctionType(name);
result = type->result;
for (size_t j = 0; j < type->params.size(); j++) {
@@ -472,7 +468,7 @@ private:
if (str[1] == '6' && str[2] == '4' && (prefix || str[3] == 0)) return f64;
}
if (allowError) return none;
- onError();
+ throw ParseException("unknown type");
abort();
}
@@ -481,7 +477,7 @@ public:
return parseExpression(*s);
}
- #define abort_on(str) { std::cerr << "aborting on " << str << '\n'; onError(); }
+ #define abort_on(str) { throw ParseException(std::string("abort_on ") + str); }
Expression* parseExpression(Element& s) {
IString id = s[0]->str();
@@ -820,7 +816,7 @@ private:
Expression* makeConst(Element& s, WasmType type) {
auto ret = parseConst(s[1]->str(), type, allocator);
- if (!ret) onError();
+ if (!ret) throw ParseException("bad const");
return ret;
}
@@ -854,9 +850,9 @@ private:
ret->align = atoi(eq);
} else if (str[0] == 'o') {
uint64_t offset = atoll(eq);
- if (offset > std::numeric_limits<uint32_t>::max()) onError();
+ if (offset > std::numeric_limits<uint32_t>::max()) throw ParseException("bad offset");
ret->offset = (uint32_t)offset;
- } else onError();
+ } else throw ParseException("bad load attribute");
i++;
}
ret->ptr = parseExpression(s[i]);
@@ -892,7 +888,7 @@ private:
ret->align = atoi(eq);
} else if (str[0] == 'o') {
ret->offset = atoi(eq);
- } else onError();
+ } else throw ParseException("bad store attribute");
i++;
}
ret->ptr = parseExpression(s[i]);
@@ -1140,7 +1136,7 @@ private:
void parseExport(Element& s) {
if (!s[2]->dollared() && !std::isdigit(s[2]->str()[0])) {
assert(s[2]->str() == MEMORY);
- if (!hasMemory) onError();
+ if (!hasMemory) throw ParseException("memory exported but no memory");
wasm.memory.exportName = s[1]->str();
return;
}
@@ -1160,7 +1156,7 @@ private:
}
importCounter++;
im->module = s[i++]->str();
- if (!s[i]->isStr()) onError();
+ if (!s[i]->isStr()) throw ParseException("no name for import");
im->base = s[i++]->str();
std::unique_ptr<FunctionType> type = make_unique<FunctionType>();
if (s.size() > i) {
@@ -1174,10 +1170,10 @@ private:
type->result = stringToWasmType(params[1]->str());
} else if (id == TYPE) {
IString name = params[1]->str();
- if (!wasm.checkFunctionType(name)) onError();
+ if (!wasm.checkFunctionType(name)) throw ParseException("bad function type for import");
*type = *wasm.getFunctionType(name);
} else {
- onError();
+ throw ParseException("bad import element");
}
if (s.size() > i+1) {
Element& result = *s[i+1];