[llvm] [WebAssembly] Support assembly parsing for new EH (PR #108668)
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 16 20:12:16 PDT 2024
https://github.com/aheejin updated https://github.com/llvm/llvm-project/pull/108668
>From 04640a300dd5ef5587f593ff82feebc0d5c0fa4e Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Tue, 10 Sep 2024 04:22:35 +0000
Subject: [PATCH 01/10] [WebAssembly] Support assembly parsing for new EH
This adds assembly parsing support for the new EH (exnref) proposal.
`try_table` parsing is a little tricky because catch clause lists use
`()` and the multivalue block return types also use `()`. This handles
all combinations below:
- No return type (void) + no catch list
- No return type (void) + catch list
- Single return type + no catch list
- Single return type + catch list
- Multivalue return type + no catch list
- Multivalue return type + catch list
This does not include AsmTypeCheck support yet. That's the reason why
this adds a new test file and use `--no-type-check` in the command line.
After the type checker is added as a follow-up, I plan to merge this
file with the existing
https://github.com/llvm/llvm-project/blob/main/llvm/test/MC/WebAssembly/eh-assembly.s.
(Turning on `-mattr=+exception-handling` adds support for all
legacy and new EH instructions in the assembly. `-wasm-enable-exnref`
in `llc` only controls which instructions to generate and it doesn't
affect `llvm-mc` and assembly parsing.)
---
.../AsmParser/WebAssemblyAsmParser.cpp | 147 ++++++++++++++++--
llvm/test/MC/WebAssembly/eh-assembly-new.s | 146 +++++++++++++++++
2 files changed, 283 insertions(+), 10 deletions(-)
create mode 100644 llvm/test/MC/WebAssembly/eh-assembly-new.s
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index 5299e6ea06f0bd..03ea5b09c4fd4a 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -69,12 +69,23 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
std::vector<unsigned> List;
};
+ struct CaLOpElem {
+ int64_t Opcode;
+ const MCExpr *Tag;
+ int64_t Dest;
+ };
+
+ struct CaLOp {
+ std::vector<CaLOpElem> List;
+ };
+
union {
struct TokOp Tok;
struct IntOp Int;
struct FltOp Flt;
struct SymOp Sym;
struct BrLOp BrL;
+ struct CaLOp CaL;
};
WebAssemblyOperand(SMLoc Start, SMLoc End, TokOp T)
@@ -85,12 +96,16 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
: Kind(Float), StartLoc(Start), EndLoc(End), Flt(F) {}
WebAssemblyOperand(SMLoc Start, SMLoc End, SymOp S)
: Kind(Symbol), StartLoc(Start), EndLoc(End), Sym(S) {}
- WebAssemblyOperand(SMLoc Start, SMLoc End)
- : Kind(BrList), StartLoc(Start), EndLoc(End), BrL() {}
+ WebAssemblyOperand(SMLoc Start, SMLoc End, BrLOp B)
+ : Kind(BrList), StartLoc(Start), EndLoc(End), BrL(B) {}
+ WebAssemblyOperand(SMLoc Start, SMLoc End, CaLOp C)
+ : Kind(CatchList), StartLoc(Start), EndLoc(End), CaL(C) {}
~WebAssemblyOperand() {
if (isBrList())
BrL.~BrLOp();
+ if (isCatchList())
+ CaL.~CaLOp();
}
bool isToken() const override { return Kind == Token; }
@@ -153,7 +168,15 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
}
void addCatchListOperands(MCInst &Inst, unsigned N) const {
- // TODO
+ assert(N == 1 && isCatchList() && "Invalid CatchList!");
+ Inst.addOperand(MCOperand::createImm(CaL.List.size()));
+ for (auto Ca : CaL.List) {
+ Inst.addOperand(MCOperand::createImm(Ca.Opcode));
+ if (Ca.Opcode == wasm::WASM_OPCODE_CATCH ||
+ Ca.Opcode == wasm::WASM_OPCODE_CATCH_REF)
+ Inst.addOperand(MCOperand::createExpr(Ca.Tag));
+ Inst.addOperand(MCOperand::createImm(Ca.Dest));
+ }
}
void print(raw_ostream &OS) const override {
@@ -174,7 +197,7 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
OS << "BrList:" << BrL.List.size();
break;
case CatchList:
- // TODO
+ OS << "CaList:" << CaL.List.size();
break;
}
}
@@ -228,6 +251,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
Loop,
Try,
CatchAll,
+ TryTable,
If,
Else,
Undefined,
@@ -304,6 +328,8 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
return {"try", "end_try/delegate"};
case CatchAll:
return {"catch_all", "end_try"};
+ case TryTable:
+ return {"try_table", "end_try_table"};
case If:
return {"if", "end_if"};
case Else:
@@ -571,6 +597,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
// proper nesting.
bool ExpectBlockType = false;
bool ExpectFuncType = false;
+ bool ExpectCatchList = false;
std::unique_ptr<WebAssemblyOperand> FunctionTable;
if (Name == "block") {
push(Block);
@@ -593,12 +620,19 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
} else if (Name == "catch_all") {
if (popAndPushWithSameSignature(Name, Try, CatchAll))
return true;
+ } else if (Name == "try_table") {
+ push(TryTable);
+ ExpectBlockType = true;
+ ExpectCatchList = true;
} else if (Name == "end_if") {
if (pop(Name, If, Else))
return true;
} else if (Name == "end_try") {
if (pop(Name, Try, CatchAll))
return true;
+ } else if (Name == "end_try_table") {
+ if (pop(Name, TryTable))
+ return true;
} else if (Name == "delegate") {
if (pop(Name, Try))
return true;
@@ -622,7 +656,18 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
ExpectFuncType = true;
}
- if (ExpectFuncType || (ExpectBlockType && Lexer.is(AsmToken::LParen))) {
+ // Returns true if the next tokens are a catch clause
+ auto PeekCatchList = [&]() {
+ if (Lexer.isNot(AsmToken::LParen))
+ return false;
+ AsmToken NextTok = Lexer.peekTok();
+ return NextTok.getKind() == AsmToken::Identifier &&
+ NextTok.getIdentifier().starts_with("catch");
+ };
+
+ // Parse a multivalue block type
+ if (ExpectFuncType ||
+ (Lexer.is(AsmToken::LParen) && ExpectBlockType && !PeekCatchList())) {
// 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
@@ -648,6 +693,23 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
Loc.getLoc(), Loc.getEndLoc(), WebAssemblyOperand::SymOp{Expr}));
}
+ // If we are expecting a catch clause list, try to parse it here.
+ //
+ // If there is a multivalue block return type before this catch list, it
+ // should have been parsed above. If there is no return type before
+ // encountering this catch list, this means the type is void.
+ // The case when there is a single block return value and then a catch list
+ // will be handled below in the 'while' loop.
+ if (ExpectCatchList && PeekCatchList()) {
+ if (ExpectBlockType) {
+ ExpectBlockType = false;
+ addBlockTypeOperand(Operands, NameLoc, WebAssembly::BlockType::Void);
+ }
+ if (parseCatchList(Operands))
+ return true;
+ ExpectCatchList = false;
+ }
+
while (Lexer.isNot(AsmToken::EndOfStatement)) {
auto &Tok = Lexer.getTok();
switch (Tok.getKind()) {
@@ -661,7 +723,15 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
if (BT == WebAssembly::BlockType::Invalid)
return error("Unknown block type: ", Id);
addBlockTypeOperand(Operands, NameLoc, BT);
+ ExpectBlockType = false;
Parser.Lex();
+ // Now that we've parsed a single block return type, if we are
+ // expecting a catch clause list, try to parse it.
+ if (ExpectCatchList && PeekCatchList()) {
+ if (parseCatchList(Operands))
+ return true;
+ ExpectCatchList = false;
+ }
} else {
// Assume this identifier is a label.
const MCExpr *Val;
@@ -703,8 +773,8 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
}
case AsmToken::LCurly: {
Parser.Lex();
- auto Op =
- std::make_unique<WebAssemblyOperand>(Tok.getLoc(), Tok.getEndLoc());
+ auto Op = std::make_unique<WebAssemblyOperand>(
+ Tok.getLoc(), Tok.getEndLoc(), WebAssemblyOperand::BrLOp{});
if (!Lexer.is(AsmToken::RCurly))
for (;;) {
Op->BrL.List.push_back(Lexer.getTok().getIntVal());
@@ -724,10 +794,18 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
return true;
}
}
- if (ExpectBlockType && Operands.size() == 1) {
- // Support blocks with no operands as default to void.
+
+ // If we are still expecting to parse a block type or a catch list at this
+ // point, we set them to the default/empty state.
+
+ // Support blocks with no operands as default to void.
+ if (ExpectBlockType)
addBlockTypeOperand(Operands, NameLoc, WebAssembly::BlockType::Void);
- }
+ // If no catch list has been parsed, add an empty catch list operand.
+ if (ExpectCatchList)
+ Operands.push_back(std::make_unique<WebAssemblyOperand>(
+ NameLoc, NameLoc, WebAssemblyOperand::CaLOp{}));
+
if (FunctionTable)
Operands.push_back(std::move(FunctionTable));
Parser.Lex();
@@ -752,6 +830,55 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
return false;
}
+ bool parseCatchList(OperandVector &Operands) {
+ auto Op = std::make_unique<WebAssemblyOperand>(
+ Lexer.getTok().getLoc(), SMLoc(), WebAssemblyOperand::CaLOp{});
+ SMLoc EndLoc;
+
+ while (Lexer.is(AsmToken::LParen)) {
+ if (expect(AsmToken::LParen, "("))
+ return true;
+
+ auto CatchStr = expectIdent();
+ if (CatchStr.empty())
+ return true;
+ int64_t CatchOpcode =
+ StringSwitch<int64_t>(CatchStr)
+ .Case("catch", wasm::WASM_OPCODE_CATCH)
+ .Case("catch_ref", wasm::WASM_OPCODE_CATCH_REF)
+ .Case("catch_all", wasm::WASM_OPCODE_CATCH_ALL)
+ .Case("catch_all_ref", wasm::WASM_OPCODE_CATCH_ALL_REF)
+ .Default(-1);
+ if (CatchOpcode == -1)
+ return error(
+ "Expected catch/catch_ref/catch_all/catch_all_ref, instead got: " +
+ CatchStr);
+
+ const MCExpr *Tag = nullptr;
+ if (CatchOpcode == wasm::WASM_OPCODE_CATCH ||
+ CatchOpcode == wasm::WASM_OPCODE_CATCH_REF) {
+ if (Parser.parseExpression(Tag))
+ return error("Cannot parse symbol: ", Lexer.getTok());
+ }
+
+ auto &DestTok = Lexer.getTok();
+ if (DestTok.isNot(AsmToken::Integer))
+ return error("Expected integer constant, instead got: ", DestTok);
+ int64_t Dest = DestTok.getIntVal();
+ Parser.Lex();
+
+ EndLoc = Lexer.getTok().getEndLoc();
+ if (expect(AsmToken::RParen, ")"))
+ return true;
+
+ Op->CaL.List.push_back({CatchOpcode, Tag, Dest});
+ }
+
+ Op->EndLoc = EndLoc;
+ Operands.push_back(std::move(Op));
+ return false;
+ }
+
bool CheckDataSection() {
if (CurrentState != DataSection) {
auto WS = cast<MCSectionWasm>(getStreamer().getCurrentSectionOnly());
diff --git a/llvm/test/MC/WebAssembly/eh-assembly-new.s b/llvm/test/MC/WebAssembly/eh-assembly-new.s
new file mode 100644
index 00000000000000..8069b666d73e53
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/eh-assembly-new.s
@@ -0,0 +1,146 @@
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+exception-handling --no-type-check < %s | FileCheck %s
+
+ .tagtype __cpp_exception i32
+ .tagtype __c_longjmp i32
+ .functype eh_test () -> ()
+ .functype foo () -> ()
+
+eh_test:
+ # try_table with all four kinds of catch clauses
+ block exnref
+ block
+ block () -> (i32, exnref)
+ block i32
+ try_table (catch __cpp_exception 0) (catch_ref __c_longjmp 1) (catch_all 2) (catch_all_ref 3)
+ i32.const 0
+ throw __cpp_exception
+ end_try_table
+ end_block
+ drop
+ end_block
+ drop
+ drop
+ end_block
+ end_block
+ drop
+
+ # You can use the same kind of catch clause more than once
+ block
+ block exnref
+ block
+ try_table (catch_all 0) (catch_all_ref 1) (catch_all 2)
+ call foo
+ end_try_table
+ end_block
+ end_block
+ drop
+ end_block
+
+ # Two catch clauses targeting the same block
+ block
+ try_table (catch_all 0) (catch_all 0)
+ end_try_table
+ end_block
+
+ # try_table with a return type
+ block
+ try_table f32 (catch_all 0)
+ f32.const 0.0
+ end_try_table
+ drop
+ end_block
+
+ # try_table with a multivalue type return
+ block
+ try_table () -> (i32, f32) (catch_all 0)
+ i32.const 0
+ f32.const 0.0
+ end_try_table
+ drop
+ drop
+ end_block
+
+ # catch-less try_tables
+ try_table
+ call foo
+ end_try_table
+
+ try_table i32
+ i32.const 0
+ end_try_table
+ drop
+
+ try_table () -> (i32, f32)
+ i32.const 0
+ f32.const 0.0
+ end_try_table
+ drop
+ drop
+
+ end_function
+
+# CHECK-LABEL: eh_test:
+# CHECK-NEXT: block exnref
+# CHECK-NEXT: block
+# CHECK-NEXT: block () -> (i32, exnref)
+# CHECK-NEXT: block i32
+# CHECK-NEXT: try_table (catch __cpp_exception 0) (catch_ref __c_longjmp 1) (catch_all 2) (catch_all_ref 3)
+# CHECK: i32.const 0
+# CHECK-NEXT: throw __cpp_exception
+# CHECK-NEXT: end_try_table
+# CHECK-NEXT: end_block
+# CHECK-NEXT: drop
+# CHECK-NEXT: end_block
+# CHECK-NEXT: drop
+# CHECK-NEXT: drop
+# CHECK-NEXT: end_block
+# CHECK-NEXT: end_block
+# CHECK-NEXT: drop
+
+# CHECK: block
+# CHECK-NEXT: block exnref
+# CHECK-NEXT: block
+# CHECK-NEXT: try_table (catch_all 0) (catch_all_ref 1) (catch_all 2)
+# CHECK: call foo
+# CHECK-NEXT: end_try_table
+# CHECK-NEXT: end_block
+# CHECK-NEXT: end_block
+# CHECK-NEXT: drop
+# CHECK-NEXT: end_block
+
+# CHECK: block
+# CHECK-NEXT: try_table (catch_all 0) (catch_all 0)
+# CHECK: end_try_table
+# CHECK-NEXT: end_block
+
+# CHECK: block
+# CHECK-NEXT: try_table f32 (catch_all 0)
+# CHECK: f32.const 0x0p0
+# CHECK-NEXT: end_try_table
+# CHECK-NEXT: drop
+# CHECK-NEXT: end_block
+
+# CHECK: block
+# CHECK-NEXT: try_table () -> (i32, f32) (catch_all 0)
+# CHECK: i32.const 0
+# CHECK-NEXT: f32.const 0x0p0
+# CHECK-NEXT: end_try_table
+# CHECK-NEXT: drop
+# CHECK-NEXT: drop
+# CHECK-NEXT: end_block
+
+# CHECK: try_table
+# CHECK-NEXT: call foo
+# CHECK-NEXT: end_try_table
+
+# CHECK: try_table i32
+# CHECK-NEXT: i32.const 0
+# CHECK-NEXT: end_try_table
+# CHECK-NEXT: drop
+
+# CHECK: try_table () -> (i32, f32)
+# CHECK-NEXT: i32.const 0
+# CHECK-NEXT: f32.const 0x0p0
+# CHECK-NEXT: end_try_table
+# CHECK-NEXT: drop
+# CHECK-NEXT: drop
>From cbcf191ed3f34a61211f1a1563966dc4bd695f3a Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Sat, 14 Sep 2024 02:09:11 +0000
Subject: [PATCH 02/10] Add throw_ref to tests
---
llvm/test/MC/WebAssembly/eh-assembly-new.s | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/test/MC/WebAssembly/eh-assembly-new.s b/llvm/test/MC/WebAssembly/eh-assembly-new.s
index 8069b666d73e53..c13ee8ecb30d91 100644
--- a/llvm/test/MC/WebAssembly/eh-assembly-new.s
+++ b/llvm/test/MC/WebAssembly/eh-assembly-new.s
@@ -19,9 +19,10 @@ eh_test:
drop
end_block
drop
- drop
+ throw_ref
end_block
end_block
+ throw_ref
drop
# You can use the same kind of catch clause more than once
@@ -92,10 +93,10 @@ eh_test:
# CHECK-NEXT: drop
# CHECK-NEXT: end_block
# CHECK-NEXT: drop
-# CHECK-NEXT: drop
+# CHECK-NEXT: throw_ref
# CHECK-NEXT: end_block
# CHECK-NEXT: end_block
-# CHECK-NEXT: drop
+# CHECK-NEXT: throw_ref
# CHECK: block
# CHECK-NEXT: block exnref
>From dc379e7c2f6f6bb96c245375ed390404e399291e Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Sun, 15 Sep 2024 07:09:15 +0000
Subject: [PATCH 03/10] test fix
---
llvm/test/MC/WebAssembly/eh-assembly-new.s | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/llvm/test/MC/WebAssembly/eh-assembly-new.s b/llvm/test/MC/WebAssembly/eh-assembly-new.s
index c13ee8ecb30d91..4ecb8c3b0dd875 100644
--- a/llvm/test/MC/WebAssembly/eh-assembly-new.s
+++ b/llvm/test/MC/WebAssembly/eh-assembly-new.s
@@ -15,14 +15,15 @@ eh_test:
i32.const 0
throw __cpp_exception
end_try_table
+ return
end_block
drop
+ return
end_block
- drop
throw_ref
+ drop
end_block
end_block
- throw_ref
drop
# You can use the same kind of catch clause more than once
@@ -33,6 +34,7 @@ eh_test:
call foo
end_try_table
end_block
+ return
end_block
drop
end_block
@@ -89,14 +91,16 @@ eh_test:
# CHECK: i32.const 0
# CHECK-NEXT: throw __cpp_exception
# CHECK-NEXT: end_try_table
+# CHECK-NEXT: return
# CHECK-NEXT: end_block
# CHECK-NEXT: drop
+# CHECK-NEXT: return
# CHECK-NEXT: end_block
-# CHECK-NEXT: drop
# CHECK-NEXT: throw_ref
+# CHECK-NEXT: drop
# CHECK-NEXT: end_block
# CHECK-NEXT: end_block
-# CHECK-NEXT: throw_ref
+# CHECK-NEXT: drop
# CHECK: block
# CHECK-NEXT: block exnref
@@ -105,6 +109,7 @@ eh_test:
# CHECK: call foo
# CHECK-NEXT: end_try_table
# CHECK-NEXT: end_block
+# CHECK-NEXT: return
# CHECK-NEXT: end_block
# CHECK-NEXT: drop
# CHECK-NEXT: end_block
>From 558f3a5380d5e4b6a4d661d7717a9347e5f28b02 Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Sun, 15 Sep 2024 09:34:43 +0000
Subject: [PATCH 04/10] functype location
---
llvm/test/MC/WebAssembly/eh-assembly-new.s | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/test/MC/WebAssembly/eh-assembly-new.s b/llvm/test/MC/WebAssembly/eh-assembly-new.s
index 4ecb8c3b0dd875..0bae4a3512235f 100644
--- a/llvm/test/MC/WebAssembly/eh-assembly-new.s
+++ b/llvm/test/MC/WebAssembly/eh-assembly-new.s
@@ -2,10 +2,11 @@
.tagtype __cpp_exception i32
.tagtype __c_longjmp i32
- .functype eh_test () -> ()
.functype foo () -> ()
eh_test:
+ .functype eh_test () -> ()
+
# try_table with all four kinds of catch clauses
block exnref
block
>From 9a0aaeab8a0eeea594874b2291bdd2b490480b41 Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Sun, 15 Sep 2024 09:44:33 +0000
Subject: [PATCH 05/10] fix
---
llvm/test/MC/WebAssembly/eh-assembly-new.s | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/MC/WebAssembly/eh-assembly-new.s b/llvm/test/MC/WebAssembly/eh-assembly-new.s
index 0bae4a3512235f..d5298f1a6b763d 100644
--- a/llvm/test/MC/WebAssembly/eh-assembly-new.s
+++ b/llvm/test/MC/WebAssembly/eh-assembly-new.s
@@ -84,7 +84,7 @@ eh_test:
end_function
# CHECK-LABEL: eh_test:
-# CHECK-NEXT: block exnref
+# CHECK: block exnref
# CHECK-NEXT: block
# CHECK-NEXT: block () -> (i32, exnref)
# CHECK-NEXT: block i32
>From 9b2f371a6f6281d3c7ad0994842a48ae6d8b834b Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Sun, 15 Sep 2024 09:46:08 +0000
Subject: [PATCH 06/10] fix
---
llvm/test/MC/WebAssembly/eh-assembly-new.s | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/test/MC/WebAssembly/eh-assembly-new.s b/llvm/test/MC/WebAssembly/eh-assembly-new.s
index d5298f1a6b763d..a769bc447d0ba9 100644
--- a/llvm/test/MC/WebAssembly/eh-assembly-new.s
+++ b/llvm/test/MC/WebAssembly/eh-assembly-new.s
@@ -24,6 +24,7 @@ eh_test:
throw_ref
drop
end_block
+ return
end_block
drop
@@ -100,6 +101,7 @@ eh_test:
# CHECK-NEXT: throw_ref
# CHECK-NEXT: drop
# CHECK-NEXT: end_block
+# CHECK-NEXT: return
# CHECK-NEXT: end_block
# CHECK-NEXT: drop
>From d578e2c254bced2e4ac946ddbeb6ef1fe1561f5a Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Mon, 16 Sep 2024 18:38:05 +0000
Subject: [PATCH 07/10] eh-assembly-new.s -> eh-assembly.s
---
llvm/test/MC/WebAssembly/{eh-assembly-new.s => eh-assembly.s} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename llvm/test/MC/WebAssembly/{eh-assembly-new.s => eh-assembly.s} (100%)
diff --git a/llvm/test/MC/WebAssembly/eh-assembly-new.s b/llvm/test/MC/WebAssembly/eh-assembly.s
similarity index 100%
rename from llvm/test/MC/WebAssembly/eh-assembly-new.s
rename to llvm/test/MC/WebAssembly/eh-assembly.s
>From 17f3e92f7baed2d36c861a6ee7787e2f2fc178fc Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Tue, 17 Sep 2024 02:58:59 +0000
Subject: [PATCH 08/10] Fix CalOpElem type
---
.../WebAssembly/AsmParser/WebAssemblyAsmParser.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index 03ea5b09c4fd4a..4fef5fa0ef2208 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -70,9 +70,9 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
};
struct CaLOpElem {
- int64_t Opcode;
+ uint8_t Opcode;
const MCExpr *Tag;
- int64_t Dest;
+ unsigned Dest;
};
struct CaLOp {
@@ -842,14 +842,14 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
auto CatchStr = expectIdent();
if (CatchStr.empty())
return true;
- int64_t CatchOpcode =
- StringSwitch<int64_t>(CatchStr)
+ uint8_t CatchOpcode =
+ StringSwitch<uint8_t>(CatchStr)
.Case("catch", wasm::WASM_OPCODE_CATCH)
.Case("catch_ref", wasm::WASM_OPCODE_CATCH_REF)
.Case("catch_all", wasm::WASM_OPCODE_CATCH_ALL)
.Case("catch_all_ref", wasm::WASM_OPCODE_CATCH_ALL_REF)
- .Default(-1);
- if (CatchOpcode == -1)
+ .Default(0xff);
+ if (CatchOpcode == 0xff)
return error(
"Expected catch/catch_ref/catch_all/catch_all_ref, instead got: " +
CatchStr);
@@ -864,7 +864,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
auto &DestTok = Lexer.getTok();
if (DestTok.isNot(AsmToken::Integer))
return error("Expected integer constant, instead got: ", DestTok);
- int64_t Dest = DestTok.getIntVal();
+ unsigned Dest = DestTok.getIntVal();
Parser.Lex();
EndLoc = Lexer.getTok().getEndLoc();
>From 29f7e2f2febeb73702b6aff4e26dde031b722690 Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Tue, 17 Sep 2024 03:03:08 +0000
Subject: [PATCH 09/10] drive-by vix
---
.../Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 903dbcd21ea967..37dc19c02c6e48 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -378,7 +378,7 @@ void WebAssemblyInstPrinter::printCatchList(const MCInst *MI, unsigned OpNo,
const MCSymbolRefExpr *TagExpr = nullptr;
const MCSymbolWasm *TagSym = nullptr;
assert(Op.isExpr());
- TagExpr = dyn_cast<MCSymbolRefExpr>(Op.getExpr());
+ TagExpr = cast<MCSymbolRefExpr>(Op.getExpr());
TagSym = cast<MCSymbolWasm>(&TagExpr->getSymbol());
O << TagSym->getName() << " ";
};
>From a5cec4ba0453a8f681ca1aad367dac4b8e591070 Mon Sep 17 00:00:00 2001
From: Heejin Ahn <aheejin at gmail.com>
Date: Tue, 17 Sep 2024 03:03:21 +0000
Subject: [PATCH 10/10] Error test cases
---
.../MC/WebAssembly/basic-assembly-errors.s | 32 +++++++++++++++++--
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/llvm/test/MC/WebAssembly/basic-assembly-errors.s b/llvm/test/MC/WebAssembly/basic-assembly-errors.s
index aab3b5b1a9028e..6699b66d04a150 100644
--- a/llvm/test/MC/WebAssembly/basic-assembly-errors.s
+++ b/llvm/test/MC/WebAssembly/basic-assembly-errors.s
@@ -26,11 +26,37 @@ test0:
catch_all
# CHECK: error: Block construct type mismatch, expected: end_try, instead got: catch_all
end
-# CHECK: Block construct type mismatch, expected: end_try, instead got: end_function
+
+# CHECK: error: Expected integer constant, instead got: )
+ try_table (catch __cpp_exception)
+ end_try_table
+
+ block
+# CHECK: error: invalid operand for instruction
+ try_table (catch_all 0) i32
+ i32.const 0
+ end_try_table
+ drop
+ end_block
+
+ block
+# CHECK: error: Expected identifier, got: )
+ try_table (catch_all 0) () -> (i32, i32)
+ i32.const 0
+ i32.const 0
+ end_try_table
+ drop
+ drop
+ end_block
+
+# CHECK: error: unknown type: not_catch
+ try_table (not_catch 0)
+
+# CHECK: Block construct type mismatch, expected: end_try_table, instead got: end_function
+ end_function
+# CHECK: error: Unmatched block construct(s) at function end: try_table
# CHECK: error: Unmatched block construct(s) at function end: catch_all
# CHECK: error: Unmatched block construct(s) at function end: loop
# CHECK: error: Unmatched block construct(s) at function end: try
# CHECK: error: Unmatched block construct(s) at function end: block
# CHECK: error: Unmatched block construct(s) at function end: function
- end_function
-
More information about the llvm-commits
mailing list