@@ -1887,45 +1887,60 @@ impl Module {
18871887
18881888 fn arbitrary_elems ( & mut self , u : & mut Unstructured ) -> Result < ( ) > {
18891889 // Create a helper closure to choose an arbitrary offset.
1890- let mut offset_global_choices = vec ! [ ] ;
1890+ let mut global_i32 = vec ! [ ] ;
1891+ let mut global_i64 = vec ! [ ] ;
18911892 if !self . config . disallow_traps {
18921893 for i in self . globals_for_const_expr ( ValType :: I32 ) {
1893- offset_global_choices. push ( i) ;
1894+ global_i32. push ( i) ;
1895+ }
1896+ for i in self . globals_for_const_expr ( ValType :: I64 ) {
1897+ global_i64. push ( i) ;
18941898 }
18951899 }
18961900 let disallow_traps = self . config . disallow_traps ;
1897- let arbitrary_active_elem = |u : & mut Unstructured ,
1898- min_mem_size : u32 ,
1899- table : Option < u32 > ,
1900- table_ty : & TableType | {
1901- let ( offset, max_size_hint) = if !offset_global_choices. is_empty ( ) && u. arbitrary ( ) ? {
1902- let g = u. choose ( & offset_global_choices) ?;
1903- ( Offset :: Global ( * g) , None )
1904- } else {
1905- let max_mem_size = if disallow_traps {
1906- table_ty. minimum
1901+ let arbitrary_active_elem =
1902+ |u : & mut Unstructured , min_mem_size : u64 , table : Option < u32 > , table_ty : & TableType | {
1903+ let global_choices = if table_ty. table64 {
1904+ & global_i64
19071905 } else {
1908- u32 :: MAX
1906+ & global_i32
19091907 } ;
1910- let offset =
1911- arbitrary_offset ( u, min_mem_size. into ( ) , max_mem_size. into ( ) , 0 ) ? as u32 ;
1912- let max_size_hint = if disallow_traps
1913- || ( offset <= min_mem_size && u. int_in_range ( 0 ..=CHANCE_OFFSET_INBOUNDS ) ? != 0 )
1914- {
1915- Some ( min_mem_size - offset)
1908+ let ( offset, max_size_hint) = if !global_choices. is_empty ( ) && u. arbitrary ( ) ? {
1909+ let g = u. choose ( & global_choices) ?;
1910+ ( Offset :: Global ( * g) , None )
19161911 } else {
1917- None
1912+ let max_mem_size = if disallow_traps {
1913+ table_ty. minimum
1914+ } else if table_ty. table64 {
1915+ u64:: MAX
1916+ } else {
1917+ u64:: from ( u32:: MAX )
1918+ } ;
1919+ let offset = arbitrary_offset ( u, min_mem_size, max_mem_size, 0 ) ?;
1920+ let max_size_hint = if disallow_traps
1921+ || ( offset <= min_mem_size
1922+ && u. int_in_range ( 0 ..=CHANCE_OFFSET_INBOUNDS ) ? != 0 )
1923+ {
1924+ Some ( min_mem_size - offset)
1925+ } else {
1926+ None
1927+ } ;
1928+
1929+ let offset = if table_ty. table64 {
1930+ Offset :: Const64 ( offset as i64 )
1931+ } else {
1932+ Offset :: Const32 ( offset as i32 )
1933+ } ;
1934+ ( offset, max_size_hint)
19181935 } ;
1919- ( Offset :: Const32 ( offset as i32 ) , max_size_hint)
1936+ Ok ( ( ElementKind :: Active { table , offset } , max_size_hint) )
19201937 } ;
1921- Ok ( ( ElementKind :: Active { table, offset } , max_size_hint) )
1922- } ;
19231938
19241939 // Generate a list of candidates for "kinds" of elements segments. For
19251940 // example we can have an active segment for any existing table or
19261941 // passive/declared segments if the right wasm features are enabled.
19271942 type GenElemSegment < ' a > =
1928- dyn Fn ( & mut Unstructured ) -> Result < ( ElementKind , Option < u32 > ) > + ' a ;
1943+ dyn Fn ( & mut Unstructured ) -> Result < ( ElementKind , Option < u64 > ) > + ' a ;
19291944 let mut choices: Vec < Box < GenElemSegment > > = Vec :: new ( ) ;
19301945
19311946 // Bulk memory enables passive/declared segments, and note that the
@@ -2400,26 +2415,6 @@ impl Module {
24002415 }
24012416}
24022417
2403- pub ( crate ) fn arbitrary_limits32 (
2404- u : & mut Unstructured ,
2405- min_minimum : Option < u32 > ,
2406- max_minimum : u32 ,
2407- max_required : bool ,
2408- max_inbounds : u32 ,
2409- ) -> Result < ( u32 , Option < u32 > ) > {
2410- let ( min, max) = arbitrary_limits64 (
2411- u,
2412- min_minimum. map ( Into :: into) ,
2413- max_minimum. into ( ) ,
2414- max_required,
2415- max_inbounds. into ( ) ,
2416- ) ?;
2417- Ok ( (
2418- u32:: try_from ( min) . unwrap ( ) ,
2419- max. map ( |i| u32:: try_from ( i) . unwrap ( ) ) ,
2420- ) )
2421- }
2422-
24232418pub ( crate ) fn arbitrary_limits64 (
24242419 u : & mut Unstructured ,
24252420 min_minimum : Option < u64 > ,
@@ -2485,12 +2480,13 @@ pub(crate) fn arbitrary_table_type(
24852480 config : & Config ,
24862481 module : Option < & Module > ,
24872482) -> Result < TableType > {
2483+ let table64 = config. memory64_enabled && u. arbitrary ( ) ?;
24882484 // We don't want to generate tables that are too large on average, so
24892485 // keep the "inbounds" limit here a bit smaller.
24902486 let max_inbounds = 10_000 ;
24912487 let min_elements = if config. disallow_traps { Some ( 1 ) } else { None } ;
24922488 let max_elements = min_elements. unwrap_or ( 0 ) . max ( config. max_table_elements ) ;
2493- let ( minimum, maximum) = arbitrary_limits32 (
2489+ let ( minimum, maximum) = arbitrary_limits64 (
24942490 u,
24952491 min_elements,
24962492 max_elements,
@@ -2508,6 +2504,7 @@ pub(crate) fn arbitrary_table_type(
25082504 element_type,
25092505 minimum,
25102506 maximum,
2507+ table64,
25112508 } )
25122509}
25132510
0 commit comments