diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binaryen-c.cpp | 9 | ||||
-rw-r--r-- | src/binaryen-shell.cpp | 14 | ||||
-rw-r--r-- | src/parsing.h | 27 | ||||
-rw-r--r-- | src/shell-interface.h | 6 | ||||
-rw-r--r-- | src/wasm-as.cpp | 17 | ||||
-rw-r--r-- | src/wasm-binary.h | 18 | ||||
-rw-r--r-- | src/wasm-dis.cpp | 9 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 36 |
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]; |