Parse an exception-table decl. exception-table ::= * SigRef(sig) "," BlockCall "," "[" (exception-table-entry ( "," exception-table-entry )*)? "]" exception-table-entry ::= ExceptionTag(tag) ":" BlockCall | "default" ":" BlockCall | "context" value
(&mut self, ctx: &mut Context)
| 1854 | // | "default" ":" BlockCall |
| 1855 | // | "context" value |
| 1856 | fn parse_exception_table(&mut self, ctx: &mut Context) -> ParseResult<ir::ExceptionTable> { |
| 1857 | let sig = self.match_sig("expected signature of called function")?; |
| 1858 | self.match_token(Token::Comma, "expected comma after signature argument")?; |
| 1859 | |
| 1860 | let mut handlers = vec![]; |
| 1861 | |
| 1862 | let block_num = self.match_block("expected branch destination block")?; |
| 1863 | let args = self.parse_opt_block_call_args()?; |
| 1864 | let normal_return = ctx.function.dfg.block_call(block_num, &args); |
| 1865 | |
| 1866 | self.match_token( |
| 1867 | Token::Comma, |
| 1868 | "expected comma after normal-return destination", |
| 1869 | )?; |
| 1870 | |
| 1871 | self.match_token( |
| 1872 | Token::LBracket, |
| 1873 | "expected an open-bracket for exception table list", |
| 1874 | )?; |
| 1875 | loop { |
| 1876 | match self.token() { |
| 1877 | Some(Token::RBracket) => { |
| 1878 | break; |
| 1879 | } |
| 1880 | Some(Token::ExceptionTag(tag)) => { |
| 1881 | self.consume(); |
| 1882 | self.match_token(Token::Colon, "expected ':' after exception tag")?; |
| 1883 | let tag = ir::ExceptionTag::from_u32(tag); |
| 1884 | let block_num = self.match_block("expected branch destination block")?; |
| 1885 | let args = self.parse_opt_block_call_args()?; |
| 1886 | let block_call = ctx.function.dfg.block_call(block_num, &args); |
| 1887 | handlers.push(ir::ExceptionTableItem::Tag(tag, block_call)); |
| 1888 | } |
| 1889 | Some(Token::Identifier("default")) => { |
| 1890 | self.consume(); |
| 1891 | self.match_token(Token::Colon, "expected ':' after 'default'")?; |
| 1892 | let block_num = self.match_block("expected branch destination block")?; |
| 1893 | let args = self.parse_opt_block_call_args()?; |
| 1894 | let block_call = ctx.function.dfg.block_call(block_num, &args); |
| 1895 | handlers.push(ir::ExceptionTableItem::Default(block_call)); |
| 1896 | } |
| 1897 | Some(Token::Identifier("context")) => { |
| 1898 | self.consume(); |
| 1899 | let val = self.match_value("expected value for exception-handler context")?; |
| 1900 | handlers.push(ir::ExceptionTableItem::Context(val)); |
| 1901 | } |
| 1902 | _ => return err!(self.loc, "invalid token"), |
| 1903 | } |
| 1904 | |
| 1905 | if let Some(Token::Comma) = self.token() { |
| 1906 | self.consume(); |
| 1907 | } else { |
| 1908 | break; |
| 1909 | } |
| 1910 | } |
| 1911 | self.match_token(Token::RBracket, "expected closing bracket")?; |
| 1912 | |
| 1913 | Ok(ctx |
no test coverage detected