@@ -2044,8 +2044,6 @@ impl Module {
20442044 u : & mut Unstructured ,
20452045 allow_defined_globals : bool ,
20462046 ) -> Result < ConstExpr > {
2047- const MAX_CONST_EXPR_RECURSION_DEPTH : usize = 8 ;
2048-
20492047 #[ derive( Clone , Copy ) ]
20502048 enum Choice {
20512049 GlobalGet ( u32 ) ,
@@ -2163,12 +2161,27 @@ impl Module {
21632161 . all ( |f| type_is_defaultable ( f. element_type ) )
21642162 }
21652163
2164+ fn const_expr_bytes_for_array_length (
2165+ module : & mut Module ,
2166+ u : & mut Unstructured < ' _ > ,
2167+ allow_defined_globals : bool ,
2168+ fuel : & mut u32 ,
2169+ ) -> Result < Vec < u8 > > {
2170+ if module. config . limit_arrays_in_const_exprs {
2171+ let size = u. int_in_range ( 0 ..=* fuel) ?;
2172+ * fuel -= size;
2173+ return Ok ( encode_instrs ( [ Instruction :: I32Const ( size as i32 ) ] ) ) ;
2174+ }
2175+
2176+ const_expr_bytes ( module, ValType :: I32 , u, allow_defined_globals, fuel)
2177+ }
2178+
21662179 fn const_expr_bytes (
21672180 module : & mut Module ,
21682181 ty : ValType ,
21692182 u : & mut Unstructured < ' _ > ,
21702183 allow_defined_globals : bool ,
2171- fuel : usize ,
2184+ fuel : & mut u32 ,
21722185 ) -> Result < Vec < u8 > > {
21732186 let mut choices = Vec :: new ( ) ;
21742187
@@ -2215,7 +2228,7 @@ impl Module {
22152228 continue ;
22162229 }
22172230 if can_use_struct_new ( module. ty ( type_idx) )
2218- && ( fuel > 0
2231+ && ( * fuel > 0
22192232 || module. ty ( type_idx) . unwrap_struct ( ) . fields . is_empty ( ) )
22202233 {
22212234 choices. push ( Choice :: StructNew ( type_idx) ) ;
@@ -2230,7 +2243,7 @@ impl Module {
22302243 if !module. ref_type_is_sub_type ( produced, ref_ty) {
22312244 continue ;
22322245 }
2233- if fuel > 0 {
2246+ if * fuel > 0 {
22342247 choices. push ( Choice :: ArrayNew ( type_idx) ) ;
22352248 choices. push ( Choice :: ArrayNewFixed ( type_idx) ) ;
22362249 if type_is_defaultable (
@@ -2242,13 +2255,13 @@ impl Module {
22422255 }
22432256
22442257 let produced_i31 = abstract_ref ( false , false , AbstractHeapType :: I31 ) ;
2245- if fuel > 0 && module. ref_type_is_sub_type ( produced_i31, ref_ty) {
2258+ if * fuel > 0 && module. ref_type_is_sub_type ( produced_i31, ref_ty) {
22462259 choices. push ( Choice :: RefI31 { shared : false } ) ;
22472260 }
22482261
22492262 if module. config . shared_everything_threads_enabled {
22502263 let produced_i31 = abstract_ref ( false , true , AbstractHeapType :: I31 ) ;
2251- if fuel > 0 && module. ref_type_is_sub_type ( produced_i31, ref_ty) {
2264+ if * fuel > 0 && module. ref_type_is_sub_type ( produced_i31, ref_ty) {
22522265 choices. push ( Choice :: RefI31 { shared : true } ) ;
22532266 }
22542267 }
@@ -2257,7 +2270,7 @@ impl Module {
22572270 HeapType :: Abstract {
22582271 shared,
22592272 ty : AbstractHeapType :: Any ,
2260- } if fuel > 0 => {
2273+ } if * fuel > 0 => {
22612274 choices. push ( Choice :: AnyConvertExtern {
22622275 nullable : ref_ty. nullable ,
22632276 shared,
@@ -2266,7 +2279,7 @@ impl Module {
22662279 HeapType :: Abstract {
22672280 shared,
22682281 ty : AbstractHeapType :: Extern ,
2269- } if fuel > 0 => {
2282+ } if * fuel > 0 => {
22702283 choices. push ( Choice :: ExternConvertAny {
22712284 nullable : ref_ty. nullable ,
22722285 shared,
@@ -2279,6 +2292,7 @@ impl Module {
22792292 }
22802293
22812294 let choice = * u. choose ( & choices) ?;
2295+ * fuel = fuel. saturating_sub ( 1 ) ;
22822296 Ok ( match choice {
22832297 Choice :: GlobalGet ( i) => encode_instrs ( [ Instruction :: GlobalGet ( i) ] ) ,
22842298 Choice :: I32Const => encode_instrs ( [ Instruction :: I32Const ( u. arbitrary ( ) ?) ] ) ,
@@ -2308,7 +2322,7 @@ impl Module {
23082322 field_ty,
23092323 u,
23102324 allow_defined_globals,
2311- fuel. saturating_sub ( 1 ) ,
2325+ fuel,
23122326 ) ?) ;
23132327 }
23142328 bytes. extend ( encode_instrs ( [ Instruction :: StructNew ( type_idx) ] ) ) ;
@@ -2325,26 +2339,20 @@ impl Module {
23252339 elem_ty,
23262340 u,
23272341 allow_defined_globals,
2328- fuel. saturating_sub ( 1 ) ,
2342+ fuel,
23292343 ) ?) ;
2330- bytes. extend ( const_expr_bytes (
2344+ bytes. extend ( const_expr_bytes_for_array_length (
23312345 module,
2332- ValType :: I32 ,
23332346 u,
23342347 allow_defined_globals,
2335- fuel. saturating_sub ( 1 ) ,
2348+ fuel,
23362349 ) ?) ;
23372350 bytes. extend ( encode_instrs ( [ Instruction :: ArrayNew ( type_idx) ] ) ) ;
23382351 bytes
23392352 }
23402353 Choice :: ArrayNewDefault ( type_idx) => {
2341- let mut bytes = const_expr_bytes (
2342- module,
2343- ValType :: I32 ,
2344- u,
2345- allow_defined_globals,
2346- fuel. saturating_sub ( 1 ) ,
2347- ) ?;
2354+ let mut bytes =
2355+ const_expr_bytes_for_array_length ( module, u, allow_defined_globals, fuel) ?;
23482356 bytes. extend ( encode_instrs ( [ Instruction :: ArrayNewDefault ( type_idx) ] ) ) ;
23492357 bytes
23502358 }
@@ -2359,7 +2367,7 @@ impl Module {
23592367 elem_ty,
23602368 u,
23612369 allow_defined_globals,
2362- fuel. saturating_sub ( 1 ) ,
2370+ fuel,
23632371 ) ?) ;
23642372 }
23652373 bytes. extend ( encode_instrs ( [ Instruction :: ArrayNewFixed {
@@ -2369,13 +2377,8 @@ impl Module {
23692377 bytes
23702378 }
23712379 Choice :: RefI31 { shared } => {
2372- let mut bytes = const_expr_bytes (
2373- module,
2374- ValType :: I32 ,
2375- u,
2376- allow_defined_globals,
2377- fuel. saturating_sub ( 1 ) ,
2378- ) ?;
2380+ let mut bytes =
2381+ const_expr_bytes ( module, ValType :: I32 , u, allow_defined_globals, fuel) ?;
23792382 bytes. extend ( encode_instrs ( [ if shared {
23802383 Instruction :: RefI31Shared
23812384 } else {
@@ -2389,7 +2392,7 @@ impl Module {
23892392 ValType :: Ref ( abstract_ref ( nullable, shared, AbstractHeapType :: Extern ) ) ,
23902393 u,
23912394 allow_defined_globals,
2392- fuel. saturating_sub ( 1 ) ,
2395+ fuel,
23932396 ) ?;
23942397 bytes. extend ( encode_instrs ( [ Instruction :: AnyConvertExtern ] ) ) ;
23952398 bytes
@@ -2400,20 +2403,21 @@ impl Module {
24002403 ValType :: Ref ( abstract_ref ( nullable, shared, AbstractHeapType :: Any ) ) ,
24012404 u,
24022405 allow_defined_globals,
2403- fuel. saturating_sub ( 1 ) ,
2406+ fuel,
24042407 ) ?;
24052408 bytes. extend ( encode_instrs ( [ Instruction :: ExternConvertAny ] ) ) ;
24062409 bytes
24072410 }
24082411 } )
24092412 }
24102413
2414+ let mut fuel = self . config . const_expr_fuel ;
24112415 Ok ( ConstExpr :: raw ( const_expr_bytes (
24122416 self ,
24132417 ty,
24142418 u,
24152419 allow_defined_globals,
2416- MAX_CONST_EXPR_RECURSION_DEPTH ,
2420+ & mut fuel ,
24172421 ) ?) )
24182422 }
24192423
0 commit comments