@@ -105,6 +105,10 @@ instructions! {
105105 ( Some ( i64_store_valid) , i64_store_32) ,
106106 ( Some ( have_memory) , memory_size) ,
107107 ( Some ( memory_grow_valid) , memory_grow) ,
108+ ( Some ( memory_init_valid) , memory_init) ,
109+ ( Some ( data_drop_valid) , data_drop) ,
110+ ( Some ( memory_copy_valid) , memory_copy) ,
111+ ( Some ( memory_fill_valid) , memory_fill) ,
108112 // Numeric instructions.
109113 ( None , i32_const) ,
110114 ( None , i64_const) ,
@@ -1053,6 +1057,11 @@ fn have_memory_and_offset<C: Config>(
10531057 have_memory ( module, builder) && builder. type_on_stack ( ValType :: I32 )
10541058}
10551059
1060+ #[ inline]
1061+ fn have_data < C : Config > ( module : & ConfiguredModule < C > , _: & mut CodeBuilder < C > ) -> bool {
1062+ module. data . len ( ) > 0
1063+ }
1064+
10561065fn i32_load < C : Config > (
10571066 u : & mut Unstructured ,
10581067 module : & ConfiguredModule < C > ,
@@ -1395,6 +1404,80 @@ fn memory_grow<C: Config>(
13951404 Ok ( Instruction :: MemoryGrow ( memory_index ( u, builder) ?) )
13961405}
13971406
1407+ #[ inline]
1408+ fn memory_init_valid < C : Config > (
1409+ module : & ConfiguredModule < C > ,
1410+ builder : & mut CodeBuilder < C > ,
1411+ ) -> bool {
1412+ have_memory ( module, builder)
1413+ && have_data ( module, builder)
1414+ && module. config . bulk_memory_enabled ( )
1415+ && builder. types_on_stack ( & [ ValType :: I32 , ValType :: I32 , ValType :: I32 ] )
1416+ }
1417+
1418+ fn memory_init < C : Config > (
1419+ u : & mut Unstructured ,
1420+ module : & ConfiguredModule < C > ,
1421+ builder : & mut CodeBuilder < C > ,
1422+ ) -> Result < Instruction > {
1423+ let mem = memory_index ( u, builder) ?;
1424+ let data = data_index ( u, module) ?;
1425+ builder. pop_operands ( & [ ValType :: I32 , ValType :: I32 , ValType :: I32 ] ) ;
1426+ Ok ( Instruction :: MemoryInit { mem, data } )
1427+ }
1428+
1429+ #[ inline]
1430+ fn memory_fill_valid < C : Config > (
1431+ module : & ConfiguredModule < C > ,
1432+ builder : & mut CodeBuilder < C > ,
1433+ ) -> bool {
1434+ have_memory ( module, builder)
1435+ && module. config . bulk_memory_enabled ( )
1436+ && builder. types_on_stack ( & [ ValType :: I32 , ValType :: I32 , ValType :: I32 ] )
1437+ }
1438+
1439+ fn memory_fill < C : Config > (
1440+ u : & mut Unstructured ,
1441+ _module : & ConfiguredModule < C > ,
1442+ builder : & mut CodeBuilder < C > ,
1443+ ) -> Result < Instruction > {
1444+ let mem = memory_index ( u, builder) ?;
1445+ builder. pop_operands ( & [ ValType :: I32 , ValType :: I32 , ValType :: I32 ] ) ;
1446+ Ok ( Instruction :: MemoryFill ( mem) )
1447+ }
1448+
1449+ #[ inline]
1450+ fn memory_copy_valid < C : Config > (
1451+ module : & ConfiguredModule < C > ,
1452+ builder : & mut CodeBuilder < C > ,
1453+ ) -> bool {
1454+ memory_fill_valid ( module, builder)
1455+ }
1456+
1457+ fn memory_copy < C : Config > (
1458+ u : & mut Unstructured ,
1459+ _module : & ConfiguredModule < C > ,
1460+ builder : & mut CodeBuilder < C > ,
1461+ ) -> Result < Instruction > {
1462+ let src = memory_index ( u, builder) ?;
1463+ let dst = memory_index ( u, builder) ?;
1464+ builder. pop_operands ( & [ ValType :: I32 , ValType :: I32 , ValType :: I32 ] ) ;
1465+ Ok ( Instruction :: MemoryCopy { dst, src } )
1466+ }
1467+
1468+ #[ inline]
1469+ fn data_drop_valid < C : Config > ( module : & ConfiguredModule < C > , builder : & mut CodeBuilder < C > ) -> bool {
1470+ have_data ( module, builder) && module. config . bulk_memory_enabled ( )
1471+ }
1472+
1473+ fn data_drop < C : Config > (
1474+ u : & mut Unstructured ,
1475+ module : & ConfiguredModule < C > ,
1476+ _builder : & mut CodeBuilder < C > ,
1477+ ) -> Result < Instruction > {
1478+ Ok ( Instruction :: DataDrop ( data_index ( u, module) ?) )
1479+ }
1480+
13981481fn i32_const < C : Config > (
13991482 u : & mut Unstructured ,
14001483 _: & ConfiguredModule < C > ,
@@ -2885,3 +2968,13 @@ fn memory_index<C: Config>(u: &mut Unstructured, builder: &mut CodeBuilder<C>) -
28852968 u. int_in_range ( 0 ..=builder. allocs . num_memories - 1 )
28862969 }
28872970}
2971+
2972+ fn data_index < C : Config > ( u : & mut Unstructured , module : & ConfiguredModule < C > ) -> Result < u32 > {
2973+ let data = module. data . len ( ) as u32 ;
2974+ assert ! ( data > 0 ) ;
2975+ if data == 1 {
2976+ Ok ( 0 )
2977+ } else {
2978+ u. int_in_range ( 0 ..=data - 1 )
2979+ }
2980+ }
0 commit comments