From: Sam Clegg Date: Mon, 19 Aug 2019 19:04:54 +0000 (+0000) Subject: [WebAssembly][MC] Allow empty assembly functions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a29e12cb5406fe31251427b838efbe597ed9625c;p=llvm [WebAssembly][MC] Allow empty assembly functions Differential Revision: https://reviews.llvm.org/D66434 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369292 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index da868e59c5f..bfa16a71e11 100644 --- a/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -489,6 +489,7 @@ public: if (pop(Name, Block)) return true; } else if (Name == "end_function") { + ensureLocals(getStreamer()); CurrentState = EndFunction; if (pop(Name, Function) || ensureEmptyNestingStack()) return true; @@ -758,6 +759,19 @@ public: return true; // We didn't process this directive. } + // Called either when the first instruction is parsed of the function ends. + void ensureLocals(MCStreamer &Out) { + if (CurrentState == FunctionStart) { + // We haven't seen a .local directive yet. The streamer requires locals to + // be encoded as a prelude to the instructions, so emit an empty list of + // locals here. + auto &TOut = reinterpret_cast( + *Out.getTargetStreamer()); + TOut.emitLocal(SmallVector()); + CurrentState = FunctionLocals; + } + } + bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned & /*Opcode*/, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, @@ -768,15 +782,7 @@ public: MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); switch (MatchResult) { case Match_Success: { - if (CurrentState == FunctionStart) { - // This is the first instruction in a function, but we haven't seen - // a .local directive yet. The streamer requires locals to be encoded - // as a prelude to the instructions, so emit an empty list of locals - // here. - auto &TOut = reinterpret_cast( - *Out.getTargetStreamer()); - TOut.emitLocal(SmallVector()); - } + ensureLocals(Out); // Fix unknown p2align operands. auto Align = WebAssembly::GetDefaultP2AlignAny(Inst.getOpcode()); if (Align != -1U) { diff --git a/test/MC/WebAssembly/basic-assembly.s b/test/MC/WebAssembly/basic-assembly.s index ac01dca3755..6de4cff8a05 100644 --- a/test/MC/WebAssembly/basic-assembly.s +++ b/test/MC/WebAssembly/basic-assembly.s @@ -2,6 +2,11 @@ # Check that it converts to .o without errors, but don't check any output: # RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+atomics,+unimplemented-simd128,+nontrapping-fptoint,+exception-handling -o %t.o < %s + +empty_func: + .functype empty_func () -> () + end_function + test0: # Test all types: .functype test0 (i32, i64) -> (i32) @@ -111,6 +116,9 @@ test0: .globaltype __stack_pointer, i32 # CHECK: .text +# CHECK-LABEL: empty_func: +# CHECK-NEXT: .functype empty_func () -> () +# CHECK-NEXT: end_function # CHECK-LABEL: test0: # CHECK-NEXT: .functype test0 (i32, i64) -> (i32) # CHECK-NEXT: .eventtype __cpp_exception i32