diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly')
3 files changed, 50 insertions, 10 deletions
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 0a5908f4379..fdba4f55f61 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -298,6 +298,8 @@ public: Type == "i32x4" || Type == "i64x2" || Type == "f32x4" || Type == "f64x2") return wasm::ValType::V128; + if (Type == "except_ref") + return wasm::ValType::EXCEPT_REF; return Optional<wasm::ValType>(); } @@ -317,7 +319,7 @@ public: while (Lexer.is(AsmToken::Identifier)) { auto Type = parseType(Lexer.getTok().getString()); if (!Type) - return true; + return error("unknown type: ", Lexer.getTok()); Types.push_back(Type.getValue()); Parser.Lex(); if (!isNext(AsmToken::Comma)) @@ -561,6 +563,7 @@ public: auto &Out = getStreamer(); auto &TOut = reinterpret_cast<WebAssemblyTargetStreamer &>(*Out.getTargetStreamer()); + auto &Ctx = Out.getContext(); // TODO: any time we return an error, at least one token must have been // consumed, otherwise this will not signal an error to the caller. @@ -578,8 +581,7 @@ public: if (!Type) return error("Unknown type in .globaltype directive: ", TypeTok); // Now set this symbol with the correct type. - auto WasmSym = cast<MCSymbolWasm>( - TOut.getStreamer().getContext().getOrCreateSymbol(SymName)); + auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName)); WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); WasmSym->setGlobalType( wasm::WasmGlobalType{uint8_t(Type.getValue()), true}); @@ -597,8 +599,7 @@ public: auto SymName = expectIdent(); if (SymName.empty()) return true; - auto WasmSym = cast<MCSymbolWasm>( - TOut.getStreamer().getContext().getOrCreateSymbol(SymName)); + auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName)); if (CurrentState == Label && WasmSym == LastLabel) { // This .functype indicates a start of a function. if (ensureEmptyNestingStack()) @@ -621,8 +622,7 @@ public: auto SymName = expectIdent(); if (SymName.empty()) return true; - auto WasmSym = cast<MCSymbolWasm>( - TOut.getStreamer().getContext().getOrCreateSymbol(SymName)); + auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName)); auto Signature = make_unique<wasm::WasmSignature>(); if (parseRegTypeList(Signature->Params)) return true; diff --git a/llvm/lib/Target/WebAssembly/Disassembler/LLVMBuild.txt b/llvm/lib/Target/WebAssembly/Disassembler/LLVMBuild.txt index a452ca1acd0..64fff6f7a27 100644 --- a/llvm/lib/Target/WebAssembly/Disassembler/LLVMBuild.txt +++ b/llvm/lib/Target/WebAssembly/Disassembler/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = WebAssemblyDisassembler parent = WebAssembly -required_libraries = MCDisassembler WebAssemblyInfo Support +required_libraries = MCDisassembler WebAssemblyInfo WebAssemblyAsmPrinter Support add_to_library_groups = WebAssembly diff --git a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp index 6acc9b20eed..ce91a3444fb 100644 --- a/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp +++ b/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp @@ -15,6 +15,7 @@ /// //===----------------------------------------------------------------------===// +#include "InstPrinter/WebAssemblyInstPrinter.h" #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" @@ -45,6 +46,10 @@ class WebAssemblyDisassembler final : public MCDisassembler { ArrayRef<uint8_t> Bytes, uint64_t Address, raw_ostream &VStream, raw_ostream &CStream) const override; + DecodeStatus onSymbolStart(StringRef Name, uint64_t &Size, + ArrayRef<uint8_t> Bytes, uint64_t Address, + raw_ostream &VStream, + raw_ostream &CStream) const override; public: WebAssemblyDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, @@ -77,7 +82,7 @@ static int nextByte(ArrayRef<uint8_t> Bytes, uint64_t &Size) { } static bool nextLEB(int64_t &Val, ArrayRef<uint8_t> Bytes, uint64_t &Size, - bool Signed = false) { + bool Signed) { unsigned N = 0; const char *Error = nullptr; Val = Signed ? decodeSLEB128(Bytes.data() + Size, &N, @@ -116,6 +121,41 @@ bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes) { return true; } +MCDisassembler::DecodeStatus WebAssemblyDisassembler::onSymbolStart( + StringRef Name, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, + raw_ostream &VStream, raw_ostream &CStream) const { + Size = 0; + if (Address == 0) { + // Start of a code section: we're parsing only the function count. + int64_t FunctionCount; + if (!nextLEB(FunctionCount, Bytes, Size, false)) + return MCDisassembler::Fail; + outs() << " # " << FunctionCount << " functions in section."; + } else { + // Parse the start of a single function. + int64_t BodySize, LocalEntryCount; + if (!nextLEB(BodySize, Bytes, Size, false) || + !nextLEB(LocalEntryCount, Bytes, Size, false)) + return MCDisassembler::Fail; + if (LocalEntryCount) { + outs() << " .local "; + for (int64_t I = 0; I < LocalEntryCount; I++) { + int64_t Count, Type; + if (!nextLEB(Count, Bytes, Size, false) || + !nextLEB(Type, Bytes, Size, false)) + return MCDisassembler::Fail; + for (int64_t J = 0; J < Count; J++) { + if (I || J) + outs() << ", "; + outs() << WebAssembly::anyTypeToString(Type); + } + } + } + } + outs() << "\n"; + return MCDisassembler::Success; +} + MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction( MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t /*Address*/, raw_ostream & /*OS*/, raw_ostream &CS) const { @@ -138,7 +178,7 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction( if (!WasmInst) return MCDisassembler::Fail; int64_t PrefixedOpc; - if (!nextLEB(PrefixedOpc, Bytes, Size)) + if (!nextLEB(PrefixedOpc, Bytes, Size, false)) return MCDisassembler::Fail; if (PrefixedOpc < 0 || PrefixedOpc >= WebAssemblyInstructionTableSize) return MCDisassembler::Fail; |