@@ -825,24 +825,14 @@ impl Compiler<'_, '_> {
825
825
let cur_src_ptr = self . gen_local ( src_opts. ptr ( ) ) ;
826
826
let remaining = self . gen_local ( src_opts. ptr ( ) ) ;
827
827
828
- let iconst = |i : i32 , ty : ValType | match ty {
829
- ValType :: I32 => I32Const ( i32:: try_from ( i) . unwrap ( ) ) ,
830
- ValType :: I64 => I64Const ( i64:: try_from ( i) . unwrap ( ) ) ,
831
- _ => unreachable ! ( ) ,
832
- } ;
833
- let src_add = if src_opts. memory64 { I64Add } else { I32Add } ;
834
- let dst_add = if dst_opts. memory64 { I64Add } else { I32Add } ;
835
- let src_eqz = if src_opts. memory64 { I64Eqz } else { I32Eqz } ;
836
- let src_ne = if src_opts. memory64 { I64Ne } else { I32Ne } ;
837
-
838
828
// This block encompasses the entire loop and is use to exit before even
839
829
// entering the loop if the list size is zero.
840
830
self . instruction ( Block ( BlockType :: Empty ) ) ;
841
831
842
832
// Set the `remaining` local and only continue if it's > 0
843
833
self . instruction ( LocalGet ( src_len) ) ;
844
834
self . instruction ( LocalTee ( remaining) ) ;
845
- self . instruction ( src_eqz . clone ( ) ) ;
835
+ self . ptr_eqz ( src_opts ) ;
846
836
self . instruction ( BrIf ( 0 ) ) ;
847
837
848
838
// Initialize the two destination pointers to their initial values
@@ -868,29 +858,25 @@ impl Compiler<'_, '_> {
868
858
869
859
// Update the two loop pointers
870
860
if src_size > 0 {
871
- let src_size = i32:: try_from ( src_size) . unwrap ( ) ;
872
861
self . instruction ( LocalGet ( cur_src_ptr) ) ;
873
- self . instruction ( iconst ( src_size , src_opts . ptr ( ) ) ) ;
874
- self . instruction ( src_add . clone ( ) ) ;
862
+ self . ptr_uconst ( src_opts , u32 :: try_from ( src_size ) . unwrap ( ) ) ;
863
+ self . ptr_add ( src_opts ) ;
875
864
self . instruction ( LocalSet ( cur_src_ptr) ) ;
876
865
}
877
866
if dst_size > 0 {
878
- let dst_size = i32:: try_from ( dst_size) . unwrap ( ) ;
879
867
self . instruction ( LocalGet ( cur_dst_ptr) ) ;
880
- self . instruction ( iconst ( dst_size , dst_opts . ptr ( ) ) ) ;
881
- self . instruction ( dst_add . clone ( ) ) ;
868
+ self . ptr_uconst ( dst_opts , u32 :: try_from ( dst_size ) . unwrap ( ) ) ;
869
+ self . ptr_add ( dst_opts ) ;
882
870
self . instruction ( LocalSet ( cur_dst_ptr) ) ;
883
871
}
884
872
885
873
// Update the remaining count, falling through to break out if it's zero
886
874
// now.
887
875
self . instruction ( LocalGet ( remaining) ) ;
888
- self . instruction ( iconst ( - 1 , src_opts . ptr ( ) ) ) ;
889
- self . instruction ( src_add . clone ( ) ) ;
876
+ self . ptr_iconst ( src_opts , - 1 ) ;
877
+ self . ptr_add ( src_opts ) ;
890
878
self . instruction ( LocalTee ( remaining) ) ;
891
- self . instruction ( iconst ( 0 , src_opts. ptr ( ) ) ) ;
892
- self . instruction ( src_ne. clone ( ) ) ;
893
- self . instruction ( BrIf ( 0 ) ) ;
879
+ self . ptr_br_if ( src_opts, 0 ) ;
894
880
self . instruction ( End ) ; // end of loop
895
881
self . instruction ( End ) ; // end of block
896
882
}
@@ -1489,18 +1475,9 @@ impl Compiler<'_, '_> {
1489
1475
}
1490
1476
self . instruction ( LocalGet ( memory. addr_local ) ) ;
1491
1477
assert ! ( align. is_power_of_two( ) ) ;
1492
- if memory. opts . memory64 {
1493
- let mask = i64:: try_from ( align - 1 ) . unwrap ( ) ;
1494
- self . instruction ( I64Const ( mask) ) ;
1495
- self . instruction ( I64And ) ;
1496
- self . instruction ( I64Const ( 0 ) ) ;
1497
- self . instruction ( I64Ne ) ;
1498
- } else {
1499
- let mask = i32:: try_from ( align - 1 ) . unwrap ( ) ;
1500
- self . instruction ( I32Const ( mask) ) ;
1501
- self . instruction ( I32And ) ;
1502
- }
1503
- self . instruction ( If ( BlockType :: Empty ) ) ;
1478
+ self . ptr_uconst ( memory. opts , u32:: try_from ( align - 1 ) . unwrap ( ) ) ;
1479
+ self . ptr_and ( memory. opts ) ;
1480
+ self . ptr_if ( memory. opts , BlockType :: Empty ) ;
1504
1481
self . trap ( Trap :: UnalignedPointer ) ;
1505
1482
self . instruction ( End ) ;
1506
1483
}
@@ -1515,45 +1492,24 @@ impl Compiler<'_, '_> {
1515
1492
}
1516
1493
assert ! ( align. is_power_of_two( ) ) ;
1517
1494
self . instruction ( LocalGet ( mem. addr_local ) ) ;
1518
- if mem. opts . memory64 {
1519
- self . instruction ( I64Const ( i64:: from ( mem. offset ) ) ) ;
1520
- self . instruction ( I64Add ) ;
1521
- let mask = i64:: try_from ( align - 1 ) . unwrap ( ) ;
1522
- self . instruction ( I64Const ( mask) ) ;
1523
- self . instruction ( I64And ) ;
1524
- self . instruction ( I64Const ( 0 ) ) ;
1525
- self . instruction ( I64Ne ) ;
1526
- } else {
1527
- self . instruction ( I32Const ( mem. i32_offset ( ) ) ) ;
1528
- self . instruction ( I32Add ) ;
1529
- let mask = i32:: try_from ( align - 1 ) . unwrap ( ) ;
1530
- self . instruction ( I32Const ( mask) ) ;
1531
- self . instruction ( I32And ) ;
1532
- }
1533
- self . instruction ( If ( BlockType :: Empty ) ) ;
1495
+ self . ptr_uconst ( mem. opts , mem. offset ) ;
1496
+ self . ptr_add ( mem. opts ) ;
1497
+ self . ptr_uconst ( mem. opts , u32:: try_from ( align - 1 ) . unwrap ( ) ) ;
1498
+ self . ptr_and ( mem. opts ) ;
1499
+ self . ptr_if ( mem. opts , BlockType :: Empty ) ;
1534
1500
self . trap ( Trap :: AssertFailed ( "pointer not aligned" ) ) ;
1535
1501
self . instruction ( End ) ;
1536
1502
}
1537
1503
1538
1504
fn malloc < ' a > ( & mut self , opts : & ' a Options , size : MallocSize , align : usize ) -> Memory < ' a > {
1539
1505
let addr_local = self . gen_local ( opts. ptr ( ) ) ;
1540
1506
let realloc = opts. realloc . unwrap ( ) ;
1541
- if opts. memory64 {
1542
- self . instruction ( I64Const ( 0 ) ) ;
1543
- self . instruction ( I64Const ( 0 ) ) ;
1544
- self . instruction ( I64Const ( i64:: try_from ( align) . unwrap ( ) ) ) ;
1545
- match size {
1546
- MallocSize :: Const ( size) => self . instruction ( I64Const ( i64:: try_from ( size) . unwrap ( ) ) ) ,
1547
- MallocSize :: Local ( idx) => self . instruction ( LocalGet ( idx) ) ,
1548
- }
1549
- } else {
1550
- self . instruction ( I32Const ( 0 ) ) ;
1551
- self . instruction ( I32Const ( 0 ) ) ;
1552
- self . instruction ( I32Const ( i32:: try_from ( align) . unwrap ( ) ) ) ;
1553
- match size {
1554
- MallocSize :: Const ( size) => self . instruction ( I32Const ( i32:: try_from ( size) . unwrap ( ) ) ) ,
1555
- MallocSize :: Local ( idx) => self . instruction ( LocalGet ( idx) ) ,
1556
- }
1507
+ self . ptr_uconst ( opts, 0 ) ;
1508
+ self . ptr_uconst ( opts, 0 ) ;
1509
+ self . ptr_uconst ( opts, u32:: try_from ( align) . unwrap ( ) ) ;
1510
+ match size {
1511
+ MallocSize :: Const ( size) => self . ptr_uconst ( opts, u32:: try_from ( size) . unwrap ( ) ) ,
1512
+ MallocSize :: Local ( idx) => self . instruction ( LocalGet ( idx) ) ,
1557
1513
}
1558
1514
self . instruction ( Call ( realloc. as_u32 ( ) ) ) ;
1559
1515
self . instruction ( LocalSet ( addr_local) ) ;
@@ -1747,6 +1703,62 @@ impl Compiler<'_, '_> {
1747
1703
}
1748
1704
}
1749
1705
1706
+ fn ptr_add ( & mut self , opts : & Options ) {
1707
+ if opts. memory64 {
1708
+ self . instruction ( I64Add ) ;
1709
+ } else {
1710
+ self . instruction ( I32Add ) ;
1711
+ }
1712
+ }
1713
+
1714
+ fn ptr_eqz ( & mut self , opts : & Options ) {
1715
+ if opts. memory64 {
1716
+ self . instruction ( I64Eqz ) ;
1717
+ } else {
1718
+ self . instruction ( I32Eqz ) ;
1719
+ }
1720
+ }
1721
+
1722
+ fn ptr_uconst ( & mut self , opts : & Options , val : u32 ) {
1723
+ if opts. memory64 {
1724
+ self . instruction ( I64Const ( val. into ( ) ) ) ;
1725
+ } else {
1726
+ self . instruction ( I32Const ( val as i32 ) ) ;
1727
+ }
1728
+ }
1729
+
1730
+ fn ptr_iconst ( & mut self , opts : & Options , val : i32 ) {
1731
+ if opts. memory64 {
1732
+ self . instruction ( I64Const ( val. into ( ) ) ) ;
1733
+ } else {
1734
+ self . instruction ( I32Const ( val) ) ;
1735
+ }
1736
+ }
1737
+
1738
+ fn ptr_and ( & mut self , opts : & Options ) {
1739
+ if opts. memory64 {
1740
+ self . instruction ( I64And ) ;
1741
+ } else {
1742
+ self . instruction ( I32And ) ;
1743
+ }
1744
+ }
1745
+
1746
+ fn ptr_if ( & mut self , opts : & Options , ty : BlockType ) {
1747
+ if opts. memory64 {
1748
+ self . instruction ( I64Const ( 0 ) ) ;
1749
+ self . instruction ( I64Ne ) ;
1750
+ }
1751
+ self . instruction ( If ( ty) ) ;
1752
+ }
1753
+
1754
+ fn ptr_br_if ( & mut self , opts : & Options , depth : u32 ) {
1755
+ if opts. memory64 {
1756
+ self . instruction ( I64Const ( 0 ) ) ;
1757
+ self . instruction ( I64Ne ) ;
1758
+ }
1759
+ self . instruction ( BrIf ( depth) ) ;
1760
+ }
1761
+
1750
1762
fn f32_load ( & mut self , mem : & Memory ) {
1751
1763
self . instruction ( LocalGet ( mem. addr_local ) ) ;
1752
1764
self . instruction ( F32Load ( mem. memarg ( 2 ) ) ) ;
@@ -1925,10 +1937,6 @@ fn payload_offset<'a>(
1925
1937
}
1926
1938
1927
1939
impl < ' a > Memory < ' a > {
1928
- fn i32_offset ( & self ) -> i32 {
1929
- self . offset as i32
1930
- }
1931
-
1932
1940
fn memarg ( & self , align : u32 ) -> MemArg {
1933
1941
MemArg {
1934
1942
offset : u64:: from ( self . offset ) ,
0 commit comments