@@ -1619,6 +1619,7 @@ impl Parser {
1619
1619
lexer : & mut Lexer < ' a > ,
1620
1620
ctx : & mut ExpressionContext < ' a , ' _ , ' _ > ,
1621
1621
block : & mut ast:: Block < ' a > ,
1622
+ brace_nesting_level : u8 ,
1622
1623
) -> Result < ( ) , Error < ' a > > {
1623
1624
self . push_rule_span ( Rule :: Statement , lexer) ;
1624
1625
match lexer. peek ( ) {
@@ -1627,7 +1628,7 @@ impl Parser {
1627
1628
self . pop_rule_span ( lexer) ;
1628
1629
}
1629
1630
( Token :: Paren ( '{' ) , _) => {
1630
- let ( inner, span) = self . block ( lexer, ctx) ?;
1631
+ let ( inner, span) = self . block ( lexer, ctx, brace_nesting_level ) ?;
1631
1632
block. stmts . push ( ast:: Statement {
1632
1633
kind : ast:: StatementKind :: Block ( inner) ,
1633
1634
span,
@@ -1709,7 +1710,7 @@ impl Parser {
1709
1710
let _ = lexer. next ( ) ;
1710
1711
let condition = self . general_expression ( lexer, ctx) ?;
1711
1712
1712
- let accept = self . block ( lexer, ctx) ?. 0 ;
1713
+ let accept = self . block ( lexer, ctx, brace_nesting_level ) ?. 0 ;
1713
1714
1714
1715
let mut elsif_stack = Vec :: new ( ) ;
1715
1716
let mut elseif_span_start = lexer. start_byte_offset ( ) ;
@@ -1720,12 +1721,12 @@ impl Parser {
1720
1721
1721
1722
if !lexer. skip ( Token :: Word ( "if" ) ) {
1722
1723
// ... else { ... }
1723
- break self . block ( lexer, ctx) ?. 0 ;
1724
+ break self . block ( lexer, ctx, brace_nesting_level ) ?. 0 ;
1724
1725
}
1725
1726
1726
1727
// ... else if (...) { ... }
1727
1728
let other_condition = self . general_expression ( lexer, ctx) ?;
1728
- let other_block = self . block ( lexer, ctx) ?;
1729
+ let other_block = self . block ( lexer, ctx, brace_nesting_level ) ?;
1729
1730
elsif_stack. push ( ( elseif_span_start, other_condition, other_block) ) ;
1730
1731
elseif_span_start = lexer. start_byte_offset ( ) ;
1731
1732
} ;
@@ -1757,7 +1758,9 @@ impl Parser {
1757
1758
"switch" => {
1758
1759
let _ = lexer. next ( ) ;
1759
1760
let selector = self . general_expression ( lexer, ctx) ?;
1760
- lexer. expect ( Token :: Paren ( '{' ) ) ?;
1761
+ let brace_span = lexer. expect_span ( Token :: Paren ( '{' ) ) ?;
1762
+ let brace_nesting_level =
1763
+ Self :: increase_brace_nesting ( brace_nesting_level, brace_span) ?;
1761
1764
let mut cases = Vec :: new ( ) ;
1762
1765
1763
1766
loop {
@@ -1782,7 +1785,7 @@ impl Parser {
1782
1785
} ) ;
1783
1786
} ;
1784
1787
1785
- let body = self . block ( lexer, ctx) ?. 0 ;
1788
+ let body = self . block ( lexer, ctx, brace_nesting_level ) ?. 0 ;
1786
1789
1787
1790
cases. push ( ast:: SwitchCase {
1788
1791
value,
@@ -1792,7 +1795,7 @@ impl Parser {
1792
1795
}
1793
1796
( Token :: Word ( "default" ) , _) => {
1794
1797
lexer. skip ( Token :: Separator ( ':' ) ) ;
1795
- let body = self . block ( lexer, ctx) ?. 0 ;
1798
+ let body = self . block ( lexer, ctx, brace_nesting_level ) ?. 0 ;
1796
1799
cases. push ( ast:: SwitchCase {
1797
1800
value : ast:: SwitchValue :: Default ,
1798
1801
body,
@@ -1808,7 +1811,7 @@ impl Parser {
1808
1811
1809
1812
ast:: StatementKind :: Switch { selector, cases }
1810
1813
}
1811
- "loop" => self . r#loop ( lexer, ctx) ?,
1814
+ "loop" => self . r#loop ( lexer, ctx, brace_nesting_level ) ?,
1812
1815
"while" => {
1813
1816
let _ = lexer. next ( ) ;
1814
1817
let mut body = ast:: Block :: default ( ) ;
@@ -1832,7 +1835,7 @@ impl Parser {
1832
1835
span,
1833
1836
} ) ;
1834
1837
1835
- let ( block, span) = self . block ( lexer, ctx) ?;
1838
+ let ( block, span) = self . block ( lexer, ctx, brace_nesting_level ) ?;
1836
1839
body. stmts . push ( ast:: Statement {
1837
1840
kind : ast:: StatementKind :: Block ( block) ,
1838
1841
span,
@@ -1855,7 +1858,9 @@ impl Parser {
1855
1858
let ( _, span) = {
1856
1859
let ctx = & mut * ctx;
1857
1860
let block = & mut * block;
1858
- lexer. capture_span ( |lexer| self . statement ( lexer, ctx, block) ) ?
1861
+ lexer. capture_span ( |lexer| {
1862
+ self . statement ( lexer, ctx, block, brace_nesting_level)
1863
+ } ) ?
1859
1864
} ;
1860
1865
1861
1866
if block. stmts . len ( ) != num_statements {
@@ -1900,7 +1905,7 @@ impl Parser {
1900
1905
lexer. expect ( Token :: Paren ( ')' ) ) ?;
1901
1906
}
1902
1907
1903
- let ( block, span) = self . block ( lexer, ctx) ?;
1908
+ let ( block, span) = self . block ( lexer, ctx, brace_nesting_level ) ?;
1904
1909
body. stmts . push ( ast:: Statement {
1905
1910
kind : ast:: StatementKind :: Block ( block) ,
1906
1911
span,
@@ -1962,13 +1967,15 @@ impl Parser {
1962
1967
& mut self ,
1963
1968
lexer : & mut Lexer < ' a > ,
1964
1969
ctx : & mut ExpressionContext < ' a , ' _ , ' _ > ,
1970
+ brace_nesting_level : u8 ,
1965
1971
) -> Result < ast:: StatementKind < ' a > , Error < ' a > > {
1966
1972
let _ = lexer. next ( ) ;
1967
1973
let mut body = ast:: Block :: default ( ) ;
1968
1974
let mut continuing = ast:: Block :: default ( ) ;
1969
1975
let mut break_if = None ;
1970
1976
1971
- lexer. expect ( Token :: Paren ( '{' ) ) ?;
1977
+ let brace_span = lexer. expect_span ( Token :: Paren ( '{' ) ) ?;
1978
+ let brace_nesting_level = Self :: increase_brace_nesting ( brace_nesting_level, brace_span) ?;
1972
1979
1973
1980
ctx. local_table . push_scope ( ) ;
1974
1981
@@ -1978,7 +1985,9 @@ impl Parser {
1978
1985
// the last thing in the loop body
1979
1986
1980
1987
// Expect a opening brace to start the continuing block
1981
- lexer. expect ( Token :: Paren ( '{' ) ) ?;
1988
+ let brace_span = lexer. expect_span ( Token :: Paren ( '{' ) ) ?;
1989
+ let brace_nesting_level =
1990
+ Self :: increase_brace_nesting ( brace_nesting_level, brace_span) ?;
1982
1991
loop {
1983
1992
if lexer. skip ( Token :: Word ( "break" ) ) {
1984
1993
// Branch for the `break if` statement, this statement
@@ -2007,7 +2016,7 @@ impl Parser {
2007
2016
break ;
2008
2017
} else {
2009
2018
// Otherwise try to parse a statement
2010
- self . statement ( lexer, ctx, & mut continuing) ?;
2019
+ self . statement ( lexer, ctx, & mut continuing, brace_nesting_level ) ?;
2011
2020
}
2012
2021
}
2013
2022
// Since the continuing block must be the last part of the loop body,
@@ -2021,7 +2030,7 @@ impl Parser {
2021
2030
break ;
2022
2031
}
2023
2032
// Otherwise try to parse a statement
2024
- self . statement ( lexer, ctx, & mut body) ?;
2033
+ self . statement ( lexer, ctx, & mut body, brace_nesting_level ) ?;
2025
2034
}
2026
2035
2027
2036
ctx. local_table . pop_scope ( ) ;
@@ -2038,15 +2047,17 @@ impl Parser {
2038
2047
& mut self ,
2039
2048
lexer : & mut Lexer < ' a > ,
2040
2049
ctx : & mut ExpressionContext < ' a , ' _ , ' _ > ,
2050
+ brace_nesting_level : u8 ,
2041
2051
) -> Result < ( ast:: Block < ' a > , Span ) , Error < ' a > > {
2042
2052
self . push_rule_span ( Rule :: Block , lexer) ;
2043
2053
2044
2054
ctx. local_table . push_scope ( ) ;
2045
2055
2046
- lexer. expect ( Token :: Paren ( '{' ) ) ?;
2056
+ let brace_span = lexer. expect_span ( Token :: Paren ( '{' ) ) ?;
2057
+ let brace_nesting_level = Self :: increase_brace_nesting ( brace_nesting_level, brace_span) ?;
2047
2058
let mut block = ast:: Block :: default ( ) ;
2048
2059
while !lexer. skip ( Token :: Paren ( '}' ) ) {
2049
- self . statement ( lexer, ctx, & mut block) ?;
2060
+ self . statement ( lexer, ctx, & mut block, brace_nesting_level ) ?;
2050
2061
}
2051
2062
2052
2063
ctx. local_table . pop_scope ( ) ;
@@ -2133,9 +2144,10 @@ impl Parser {
2133
2144
2134
2145
// do not use `self.block` here, since we must not push a new scope
2135
2146
lexer. expect ( Token :: Paren ( '{' ) ) ?;
2147
+ let brace_nesting_level = 1 ;
2136
2148
let mut body = ast:: Block :: default ( ) ;
2137
2149
while !lexer. skip ( Token :: Paren ( '}' ) ) {
2138
- self . statement ( lexer, & mut ctx, & mut body) ?;
2150
+ self . statement ( lexer, & mut ctx, & mut body, brace_nesting_level ) ?;
2139
2151
}
2140
2152
2141
2153
ctx. local_table . pop_scope ( ) ;
@@ -2345,4 +2357,30 @@ impl Parser {
2345
2357
2346
2358
Ok ( tu)
2347
2359
}
2360
+
2361
+ const fn increase_brace_nesting (
2362
+ brace_nesting_level : u8 ,
2363
+ brace_span : Span ,
2364
+ ) -> Result < u8 , Error < ' static > > {
2365
+ // From [spec.](https://gpuweb.github.io/gpuweb/wgsl/#limits):
2366
+ //
2367
+ // > § 2.4. Limits
2368
+ // >
2369
+ // > …
2370
+ // >
2371
+ // > Maximum nesting depth of brace-enclosed statements in a function[:] 127
2372
+ //
2373
+ // _However_, we choose 64 instead because (a) it avoids stack overflows in CI and
2374
+ // (b) we expect the limit to be decreased to 63 based on this conversation in
2375
+ // WebGPU CTS upstream:
2376
+ // <https://github.com/gpuweb/cts/pull/3389#discussion_r1543742701>
2377
+ const BRACE_NESTING_MAXIMUM : u8 = 64 ;
2378
+ if brace_nesting_level + 1 > BRACE_NESTING_MAXIMUM {
2379
+ return Err ( Error :: ExceededLimitForNestedBraces {
2380
+ span : brace_span,
2381
+ limit : BRACE_NESTING_MAXIMUM ,
2382
+ } ) ;
2383
+ }
2384
+ Ok ( brace_nesting_level + 1 )
2385
+ }
2348
2386
}
0 commit comments