Index: lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp =================================================================== --- lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -367,6 +367,27 @@ CurrentState = Label; } + bool ParseSignature(MCSymbolWasm *WasmSym) { + auto Signature = make_unique(); + if (Expect(AsmToken::LParen, "(")) + return true; + if (ParseRegTypeList(Signature->Params)) + return true; + if (Expect(AsmToken::RParen, ")")) + return true; + if (Expect(AsmToken::MinusGreater, "->")) + return true; + if (Expect(AsmToken::LParen, "(")) + return true; + if (ParseRegTypeList(Signature->Returns)) + return true; + if (Expect(AsmToken::RParen, ")")) + return true; + WasmSym->setSignature(Signature.get()); + addSignature(std::move(Signature)); + return false; + } + // This function processes wasm-specific directives streamed to // WebAssemblyTargetStreamer, all others go to the generic parser // (see WasmAsmParser). @@ -422,28 +443,25 @@ // This .functype indicates a start of a function. CurrentState = FunctionStart; } - auto Signature = make_unique(); - if (Expect(AsmToken::LParen, "(")) - return true; - if (ParseRegTypeList(Signature->Params)) - return true; - if (Expect(AsmToken::RParen, ")")) - return true; - if (Expect(AsmToken::MinusGreater, "->")) - return true; - if (Expect(AsmToken::LParen, "(")) - return true; - if (ParseRegTypeList(Signature->Returns)) + if (ParseSignature(WasmSym)) return true; - if (Expect(AsmToken::RParen, ")")) - return true; - WasmSym->setSignature(Signature.get()); - addSignature(std::move(Signature)); WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); TOut.emitFunctionType(WasmSym); // TODO: backend also calls TOut.emitIndIdx, but that is not implemented. return Expect(AsmToken::EndOfStatement, "EOL"); + } else if (DirectiveID.getString() == ".eventtype") { + auto SymName = ExpectIdent(); + if (SymName.empty()) return true; + auto WasmSym = cast( + TOut.getStreamer().getContext().getOrCreateSymbol(SymName)); + if (ParseSignature(WasmSym)) + return true; + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_EVENT); + TOut.emitEventType(WasmSym); + // TODO: backend also calls TOut.emitIndIdx, but that is not implemented. + return Expect(AsmToken::EndOfStatement, "EOL"); + } else if (DirectiveID.getString() == ".local") { if (CurrentState != FunctionStart) return Error(".local directive should follow the start of a function", Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h @@ -54,6 +54,7 @@ /// This part is for ascii assembly output class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer { formatted_raw_ostream &OS; + void emitSignature(const MCSymbolWasm *Sym); public: WebAssemblyTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -61,23 +61,30 @@ void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; } -void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) { - assert(Sym->isFunction()); - OS << "\t.functype\t" << Sym->getName() << " ("; +void WebAssemblyTargetAsmStreamer::emitSignature(const MCSymbolWasm *Sym) { + OS << " ("; auto &Params = Sym->getSignature()->Params; for (auto &Ty : Params) { - if (&Ty != &Params[0]) OS << ", "; + if (&Ty != &Params[0]) + OS << ", "; OS << WebAssembly::TypeToString(Ty); } OS << ") -> ("; auto &Returns = Sym->getSignature()->Returns; for (auto &Ty : Returns) { - if (&Ty != &Returns[0]) OS << ", "; + if (&Ty != &Returns[0]) + OS << ", "; OS << WebAssembly::TypeToString(Ty); } OS << ")\n"; } +void WebAssemblyTargetAsmStreamer::emitFunctionType(const MCSymbolWasm *Sym) { + assert(Sym->isFunction()); + OS << "\t.functype\t" << Sym->getName(); + emitSignature(Sym); +} + void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) { assert(Sym->isGlobal()); OS << "\t.globaltype\t" << Sym->getName() << ", " << @@ -89,16 +96,7 @@ void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) { assert(Sym->isEvent()); OS << "\t.eventtype\t" << Sym->getName(); - if (Sym->getSignature()->Returns.empty()) - OS << ", void"; - else { - assert(Sym->getSignature()->Returns.size() == 1); - OS << ", " - << WebAssembly::TypeToString(Sym->getSignature()->Returns.front()); - } - for (auto Ty : Sym->getSignature()->Params) - OS << ", " << WebAssembly::TypeToString(Ty); - OS << '\n'; + emitSignature(Sym); } void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym, Index: test/CodeGen/WebAssembly/exception.ll =================================================================== --- test/CodeGen/WebAssembly/exception.ll +++ test/CodeGen/WebAssembly/exception.ll @@ -262,4 +262,4 @@ declare %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* returned) ; CHECK: __cpp_exception: -; CHECK: .eventtype __cpp_exception, void, i32 +; CHECK: .eventtype __cpp_exception (i32) -> () Index: test/MC/WebAssembly/basic-assembly.s =================================================================== --- test/MC/WebAssembly/basic-assembly.s +++ test/MC/WebAssembly/basic-assembly.s @@ -8,6 +8,7 @@ test0: # Test all types: .functype test0 (i32, i64) -> (i32) + .eventtype __cpp_exception (i32) -> () .local f32, f64, v128, v128 # Explicit getlocal/setlocal: get_local 2 @@ -66,6 +67,7 @@ # CHECK: .text # CHECK-LABEL: test0: # CHECK-NEXT: .functype test0 (i32, i64) -> (i32) +# CHECK-NEXT: .eventtype __cpp_exception (i32) -> () # CHECK-NEXT: .local f32, f64 # CHECK-NEXT: get_local 2 # CHECK-NEXT: set_local 2