diff options
author | Wouter van Oortmerssen <aardappel@gmail.com> | 2019-01-03 22:59:59 +0000 |
---|---|---|
committer | Wouter van Oortmerssen <aardappel@gmail.com> | 2019-01-03 22:59:59 +0000 |
commit | 98432956087f564dd39fe8d76aa6bc5fc09e079b (patch) | |
tree | b351c997ff12ff3f06d4ab4ec3a9242c1b86f68a /llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp | |
parent | b8687c21682edf20e6a20df42f0d793901443e78 (diff) | |
download | bcm5719-llvm-98432956087f564dd39fe8d76aa6bc5fc09e079b.tar.gz bcm5719-llvm-98432956087f564dd39fe8d76aa6bc5fc09e079b.zip |
[WebAssembly] Made InstPrinter more robust
Summary:
Instead of asserting on certain kinds of malformed instructions, it
now still print, but instead adds an annotation indicating the
problem, and/or indicates invalid_type etc.
We're using the InstPrinter from many contexts that can't always
guarantee values are within range (e.g. the disassembler), where having
output is more valueable than asserting.
Reviewers: dschuff, aheejin
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D56223
llvm-svn: 350365
Diffstat (limited to 'llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp | 110 |
1 files changed, 59 insertions, 51 deletions
diff --git a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp index a2882673060..2a357238deb 100644 --- a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp @@ -95,23 +95,32 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, case WebAssembly::END_LOOP: case WebAssembly::END_LOOP_S: - assert(!ControlFlowStack.empty() && "End marker mismatch!"); - ControlFlowStack.pop_back(); + if (ControlFlowStack.empty()) { + printAnnotation(OS, "End marker mismatch!"); + } else { + ControlFlowStack.pop_back(); + } break; case WebAssembly::END_BLOCK: case WebAssembly::END_BLOCK_S: - assert(!ControlFlowStack.empty() && "End marker mismatch!"); - printAnnotation( - OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); + if (ControlFlowStack.empty()) { + printAnnotation(OS, "End marker mismatch!"); + } else { + printAnnotation( + OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); + } break; case WebAssembly::END_TRY: case WebAssembly::END_TRY_S: - assert(!ControlFlowStack.empty() && "End marker mismatch!"); - printAnnotation( - OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); - LastSeenEHInst = END_TRY; + if (ControlFlowStack.empty()) { + printAnnotation(OS, "End marker mismatch!"); + } else { + printAnnotation( + OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':'); + LastSeenEHInst = END_TRY; + } break; case WebAssembly::CATCH_I32: @@ -123,8 +132,12 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, // There can be multiple catch instructions for one try instruction, so we // print a label only for the first 'catch' label. if (LastSeenEHInst != CATCH) { - assert(!EHPadStack.empty() && "try-catch mismatch!"); - printAnnotation(OS, "catch" + utostr(EHPadStack.pop_back_val()) + ':'); + if (EHPadStack.empty()) { + printAnnotation(OS, "try-catch mismatch!"); + } else { + printAnnotation(OS, + "catch" + utostr(EHPadStack.pop_back_val()) + ':'); + } } LastSeenEHInst = CATCH; break; @@ -152,8 +165,9 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, continue; if (Opc == WebAssembly::RETHROW || Opc == WebAssembly::RETHROW_S) { - assert(Depth <= EHPadStack.size() && "Invalid depth argument!"); - if (Depth == EHPadStack.size()) { + if (Depth > EHPadStack.size()) { + printAnnotation(OS, "Invalid depth argument!"); + } else if (Depth == EHPadStack.size()) { // This can happen when rethrow instruction breaks out of all nests // and throws up to the current function's caller. printAnnotation(OS, utostr(Depth) + ": " + "to caller"); @@ -164,11 +178,14 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, } } else { - assert(Depth < ControlFlowStack.size() && "Invalid depth argument!"); - const auto &Pair = ControlFlowStack.rbegin()[Depth]; - printAnnotation(OS, utostr(Depth) + ": " + - (Pair.second ? "up" : "down") + " to label" + - utostr(Pair.first)); + if (Depth >= ControlFlowStack.size()) { + printAnnotation(OS, "Invalid depth argument!"); + } else { + const auto &Pair = ControlFlowStack.rbegin()[Depth]; + printAnnotation(OS, utostr(Depth) + ": " + + (Pair.second ? "up" : "down") + " to label" + + utostr(Pair.first)); + } } } } @@ -256,47 +273,38 @@ void WebAssemblyInstPrinter::printWebAssemblyP2AlignOperand(const MCInst *MI, void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { - int64_t Imm = MI->getOperand(OpNo).getImm(); - switch (WebAssembly::ExprType(Imm)) { - case WebAssembly::ExprType::Void: - break; - case WebAssembly::ExprType::I32: - O << "i32"; - break; - case WebAssembly::ExprType::I64: - O << "i64"; - break; - case WebAssembly::ExprType::F32: - O << "f32"; - break; - case WebAssembly::ExprType::F64: - O << "f64"; - break; - case WebAssembly::ExprType::V128: - O << "v128"; - break; - case WebAssembly::ExprType::ExceptRef: - O << "except_ref"; - break; - default: - llvm_unreachable("invalid WebAssembly::ExprType"); - } + auto Imm = static_cast<unsigned>(MI->getOperand(OpNo).getImm()); + if (Imm != wasm::WASM_TYPE_NORESULT) + O << WebAssembly::anyTypeToString(Imm); } -const char *llvm::WebAssembly::TypeToString(wasm::ValType Ty) { +// We have various enums representing a subset of these types, use this +// function to convert any of them to text. +const char *llvm::WebAssembly::anyTypeToString(unsigned Ty) { switch (Ty) { - case wasm::ValType::I32: + case wasm::WASM_TYPE_I32: return "i32"; - case wasm::ValType::I64: + case wasm::WASM_TYPE_I64: return "i64"; - case wasm::ValType::F32: + case wasm::WASM_TYPE_F32: return "f32"; - case wasm::ValType::F64: + case wasm::WASM_TYPE_F64: return "f64"; - case wasm::ValType::V128: + case wasm::WASM_TYPE_V128: return "v128"; - case wasm::ValType::EXCEPT_REF: + case wasm::WASM_TYPE_ANYFUNC: + return "anyfunc"; + case wasm::WASM_TYPE_FUNC: + return "func"; + case wasm::WASM_TYPE_EXCEPT_REF: return "except_ref"; + case wasm::WASM_TYPE_NORESULT: + return "void"; + default: + return "invalid_type"; } - llvm_unreachable("Unknown wasm::ValType"); +} + +const char *llvm::WebAssembly::typeToString(wasm::ValType Ty) { + return anyTypeToString(static_cast<unsigned>(Ty)); } |