Remove the concept of non-dense jump tables.
WebAssembly doesn't have non-dense jump tables, and higher-level users are better served by the facilities in lib/frontend/src/switch.rs for working with non-dense switches. This eliminates the concept of "absent" jump table entries, which were represented as "0" in the text format. Also, jump table contents are now enclosed in `[` and `]`, so that we can unambiguously display empty jump tables. Previously, empty jump tables were displayed as if they had a single absent entry.
This commit is contained in:
@@ -1494,48 +1494,48 @@ impl<'a> Parser<'a> {
|
||||
|
||||
// Parse a jump table decl.
|
||||
//
|
||||
// jump-table-decl ::= * JumpTable(jt) "=" "jump_table" jt-entry {"," jt-entry}
|
||||
// jump-table-decl ::= * JumpTable(jt) "=" "jump_table" "[" jt-entry {"," jt-entry} "]"
|
||||
fn parse_jump_table_decl(&mut self) -> ParseResult<(JumpTable, JumpTableData)> {
|
||||
let jt = self.match_jt()?;
|
||||
self.match_token(Token::Equal, "expected '=' in jump_table decl")?;
|
||||
self.match_identifier("jump_table", "expected 'jump_table'")?;
|
||||
self.match_token(Token::LBracket, "expected '[' before jump table contents")?;
|
||||
|
||||
let mut data = JumpTableData::new();
|
||||
|
||||
// jump-table-decl ::= JumpTable(jt) "=" "jump_table" * jt-entry {"," jt-entry}
|
||||
for idx in 0_usize.. {
|
||||
if let Some(dest) = self.parse_jump_table_entry()? {
|
||||
data.set_entry(idx, dest);
|
||||
}
|
||||
if !self.optional(Token::Comma) {
|
||||
// Collect any trailing comments.
|
||||
self.token();
|
||||
self.claim_gathered_comments(jt);
|
||||
|
||||
return Ok((jt, data));
|
||||
}
|
||||
}
|
||||
|
||||
err!(self.loc, "jump_table too long")
|
||||
}
|
||||
|
||||
// jt-entry ::= * Ebb(dest) | "0"
|
||||
fn parse_jump_table_entry(&mut self) -> ParseResult<Option<Ebb>> {
|
||||
// jump-table-decl ::= JumpTable(jt) "=" "jump_table" "[" * Ebb(dest) {"," Ebb(dest)} "]"
|
||||
match self.token() {
|
||||
Some(Token::Integer(s)) => {
|
||||
if s == "0" {
|
||||
self.consume();
|
||||
Ok(None)
|
||||
} else {
|
||||
err!(self.loc, "invalid jump_table entry '{}'", s)
|
||||
}
|
||||
}
|
||||
Some(Token::Ebb(dest)) => {
|
||||
self.consume();
|
||||
Ok(Some(dest))
|
||||
data.push_entry(dest);
|
||||
|
||||
loop {
|
||||
match self.token() {
|
||||
Some(Token::Comma) => {
|
||||
self.consume();
|
||||
if let Some(Token::Ebb(dest)) = self.token() {
|
||||
self.consume();
|
||||
data.push_entry(dest);
|
||||
} else {
|
||||
return err!(self.loc, "expected jump_table entry");
|
||||
}
|
||||
}
|
||||
Some(Token::RBracket) => break,
|
||||
_ => return err!(self.loc, "expected ']' after jump table contents"),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => err!(self.loc, "expected jump_table entry"),
|
||||
Some(Token::RBracket) => (),
|
||||
_ => return err!(self.loc, "expected jump_table entry"),
|
||||
}
|
||||
|
||||
self.consume();
|
||||
|
||||
// Collect any trailing comments.
|
||||
self.token();
|
||||
self.claim_gathered_comments(jt);
|
||||
|
||||
Ok((jt, data))
|
||||
}
|
||||
|
||||
// Parse a function body, add contents to `ctx`.
|
||||
@@ -2738,8 +2738,8 @@ mod tests {
|
||||
fn duplicate_jt() {
|
||||
let ParseError { location, message } = Parser::new(
|
||||
"function %ebbs() system_v {
|
||||
jt0 = jump_table 0, 0
|
||||
jt0 = jump_table 0, 0",
|
||||
jt0 = jump_table []
|
||||
jt0 = jump_table []",
|
||||
).parse_function(None)
|
||||
.unwrap_err();
|
||||
|
||||
@@ -2820,7 +2820,7 @@ mod tests {
|
||||
function %comment() system_v { ; decl
|
||||
ss10 = outgoing_arg 13 ; stackslot.
|
||||
; Still stackslot.
|
||||
jt10 = jump_table ebb0
|
||||
jt10 = jump_table [ebb0]
|
||||
; Jumptable
|
||||
ebb0: ; Basic block
|
||||
trap user42; Instruction
|
||||
|
||||
@@ -218,7 +218,7 @@ mod tests {
|
||||
let tf = parse_test(
|
||||
"function %detail() {
|
||||
ss10 = incoming_arg 13
|
||||
jt10 = jump_table ebb0
|
||||
jt10 = jump_table [ebb0]
|
||||
ebb0(v4: i32, v7: i32):
|
||||
v10 = iadd v4, v7
|
||||
}",
|
||||
|
||||
Reference in New Issue
Block a user