1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[WebAssembly] Add '.eventtype' directive support

Summary:
This patch supports `.eventtype` directive printing and parsing in the
same syntax with `.functype`.

Reviewers: aardappel, sbc100

Subscribers: dschuff, sbc100, jgravelle-google, sunfish, llvm-commits

Differential Revision: https://reviews.llvm.org/D55353

llvm-svn: 348818
This commit is contained in:
Heejin Ahn 2018-12-11 01:11:04 +00:00
parent 08f3004e2a
commit 73b2f90c13
5 changed files with 77 additions and 38 deletions

View File

@ -367,6 +367,24 @@ public:
CurrentState = Label;
}
bool parseSignature(wasm::WasmSignature *Signature) {
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;
return false;
}
// This function processes wasm-specific directives streamed to
// WebAssemblyTargetStreamer, all others go to the generic parser
// (see WasmAsmParser).
@ -424,19 +442,7 @@ public:
CurrentState = FunctionStart;
}
auto Signature = make_unique<wasm::WasmSignature>();
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, ")"))
if (parseSignature(Signature.get()))
return true;
WasmSym->setSignature(Signature.get());
addSignature(std::move(Signature));
@ -446,6 +452,23 @@ public:
return expect(AsmToken::EndOfStatement, "EOL");
}
if (DirectiveID.getString() == ".eventtype") {
auto SymName = expectIdent();
if (SymName.empty())
return true;
auto WasmSym = cast<MCSymbolWasm>(
TOut.getStreamer().getContext().getOrCreateSymbol(SymName));
auto Signature = make_unique<wasm::WasmSignature>();
if (parseRegTypeList(Signature->Params))
return true;
WasmSym->setSignature(Signature.get());
addSignature(std::move(Signature));
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");
}
if (DirectiveID.getString() == ".local") {
if (CurrentState != FunctionStart)
return error(".local directive should follow the start of a function",

View File

@ -61,21 +61,40 @@ 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() << " (";
auto &Params = Sym->getSignature()->Params;
for (auto &Ty : Params) {
if (&Ty != &Params[0]) OS << ", ";
OS << WebAssembly::TypeToString(Ty);
}
OS << ") -> (";
auto &Returns = Sym->getSignature()->Returns;
for (auto &Ty : Returns) {
if (&Ty != &Returns[0]) OS << ", ";
OS << WebAssembly::TypeToString(Ty);
}
OS << ")\n";
OS << "\t.functype\t" << Sym->getName() << " ";
emitSignature(Sym->getSignature());
OS << "\n";
}
void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
@ -88,17 +107,9 @@ void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
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';
OS << "\t.eventtype\t" << Sym->getName() << " ";
emitParamList(Sym->getSignature());
OS << "\n";
}
void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,

View File

@ -54,6 +54,9 @@ 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);

View File

@ -262,4 +262,4 @@ declare void @_ZSt9terminatev()
declare %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* returned)
; CHECK: __cpp_exception:
; CHECK: .eventtype __cpp_exception, void, i32
; CHECK: .eventtype __cpp_exception i32

View File

@ -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 @@ test0:
# 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