diff options
Diffstat (limited to 'llvm/lib')
5 files changed, 57 insertions, 37 deletions
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 09628e872dd..2fd7382fbcc 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -492,6 +492,27 @@ public:        CurrentState = EndFunction;        if (pop(Name, Function) || ensureEmptyNestingStack())          return true; +    } else if (Name == "call_indirect" || Name == "return_call_indirect") { +      // This has a special TYPEINDEX operand which in text we +      // represent as a signature, such that we can re-build this signature, +      // attach it to an anonymous symbol, which is what WasmObjectWriter +      // expects to be able to recreate the actual unique-ified type indices. +      auto Loc = Parser.getTok(); +      auto Signature = make_unique<wasm::WasmSignature>(); +      if (parseSignature(Signature.get())) +        return true; +      auto &Ctx = getStreamer().getContext(); +      // The "true" here will cause this to be a nameless symbol. +      MCSymbol *Sym = Ctx.createTempSymbol("typeindex", true); +      auto *WasmSym = cast<MCSymbolWasm>(Sym); +      WasmSym->setSignature(Signature.get()); +      addSignature(std::move(Signature)); +      WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); +      const MCExpr *Expr = MCSymbolRefExpr::create( +          WasmSym, MCSymbolRefExpr::VK_WASM_TYPEINDEX, Ctx); +      Operands.push_back(make_unique<WebAssemblyOperand>( +          WebAssemblyOperand::Symbol, Loc.getLoc(), Loc.getEndLoc(), +          WebAssemblyOperand::SymOp{Expr}));      }      while (Lexer.isNot(AsmToken::EndOfStatement)) { diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp index b5d4d369b72..bc63382aa8f 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp @@ -15,6 +15,7 @@  #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"  #include "WebAssembly.h"  #include "WebAssemblyMachineFunctionInfo.h" +#include "WebAssemblyUtilities.h"  #include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/StringExtras.h"  #include "llvm/CodeGen/TargetRegisterInfo.h" @@ -232,7 +233,16 @@ void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,      }    } else {      assert(Op.isExpr() && "unknown operand kind in printOperand"); -    Op.getExpr()->print(O, &MAI); +    // call_indirect instructions have a TYPEINDEX operand that we print +    // as a signature here, such that the assembler can recover this +    // information. +    auto SRE = static_cast<const MCSymbolRefExpr *>(Op.getExpr()); +    if (SRE->getKind() == MCSymbolRefExpr::VK_WASM_TYPEINDEX) { +      auto &Sym = static_cast<const MCSymbolWasm &>(SRE->getSymbol()); +      O << WebAssembly::signatureToString(Sym.getSignature()); +    } else { +      Op.getExpr()->print(O, &MAI); +    }    }  } @@ -266,7 +276,7 @@ void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI,  // 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) { +const char *WebAssembly::anyTypeToString(unsigned Ty) {    switch (Ty) {    case wasm::WASM_TYPE_I32:      return "i32"; @@ -291,6 +301,24 @@ const char *llvm::WebAssembly::anyTypeToString(unsigned Ty) {    }  } -const char *llvm::WebAssembly::typeToString(wasm::ValType Ty) { +const char *WebAssembly::typeToString(wasm::ValType Ty) {    return anyTypeToString(static_cast<unsigned>(Ty));  } + +std::string WebAssembly::typeListToString(ArrayRef<wasm::ValType> List) { +  std::string S; +  for (auto &Ty : List) { +    if (&Ty != &List[0]) S += ", "; +    S += WebAssembly::typeToString(Ty); +  } +  return S; +} + +std::string WebAssembly::signatureToString(const wasm::WasmSignature *Sig) { +  std::string S("("); +  S += typeListToString(Sig->Params); +  S += ") -> ("; +  S += typeListToString(Sig->Returns); +  S += ")"; +  return S; +} diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h index b979de5028b..cf37778099a 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h @@ -58,6 +58,9 @@ namespace WebAssembly {  const char *typeToString(wasm::ValType Ty);  const char *anyTypeToString(unsigned Ty); +std::string typeListToString(ArrayRef<wasm::ValType> List); +std::string signatureToString(const wasm::WasmSignature *Sig); +  } // end namespace WebAssembly  } // end namespace llvm diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp index e05efef7201..40926201931 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -60,39 +60,10 @@ void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<wasm::ValType> Types) {  void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; } -void WebAssemblyTargetAsmStreamer::emitSignature( -    const wasm::WasmSignature *Sig) { -  OS << "("; -  emitParamList(Sig); -  OS << ") -> ("; -  emitReturnList(Sig); -  OS << ")"; -} - -void WebAssemblyTargetAsmStreamer::emitParamList( -    const wasm::WasmSignature *Sig) { -  auto &Params = Sig->Params; -  for (auto &Ty : Params) { -    if (&Ty != &Params[0]) -      OS << ", "; -    OS << WebAssembly::typeToString(Ty); -  } -} - -void WebAssemblyTargetAsmStreamer::emitReturnList( -    const wasm::WasmSignature *Sig) { -  auto &Returns = Sig->Returns; -  for (auto &Ty : Returns) { -    if (&Ty != &Returns[0]) -      OS << ", "; -    OS << WebAssembly::typeToString(Ty); -  } -} -  void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) {    assert(Sym->isFunction());    OS << "\t.functype\t" << Sym->getName() << " "; -  emitSignature(Sym->getSignature()); +  OS << WebAssembly::signatureToString(Sym->getSignature());    OS << "\n";  } @@ -107,7 +78,7 @@ void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {  void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) {    assert(Sym->isEvent());    OS << "\t.eventtype\t" << Sym->getName() << " "; -  emitParamList(Sym->getSignature()); +  OS << WebAssembly::typeListToString(Sym->getSignature()->Params);    OS << "\n";  } diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h index 5ea62b179d2..0164f8e572e 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h @@ -56,9 +56,6 @@ protected:  /// This part is for ascii assembly output  class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer {    formatted_raw_ostream &OS; -  void emitSignature(const wasm::WasmSignature *Sig); -  void emitParamList(const wasm::WasmSignature *Sig); -  void emitReturnList(const wasm::WasmSignature *Sig);  public:    WebAssemblyTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);  | 

