@@ -23,7 +23,7 @@ const RangeCheckBuiltinRunner = @import("../builtins/builtin_runner/range_check.
23
23
// Function that validates a memory address and returns a list of validated adresses
24
24
pub const validation_rule = * const fn (Allocator , * Memory , Relocatable ) anyerror ! std.ArrayList (Relocatable );
25
25
26
- pub const MemoryCell = struct {
26
+ pub const MemoryCell = extern struct {
27
27
/// Represents a memory cell that holds relocation information and access status.
28
28
const Self = @This ();
29
29
const ACCESS_MASK : u64 = 1 << 62 ;
@@ -103,8 +103,12 @@ pub const MemoryCell = struct {
103
103
/// # Returns
104
104
///
105
105
/// Returns `true` if both MemoryCell instances are equal, otherwise `false`.
106
- pub fn eql (self : Self , other : Self ) bool {
107
- return std .mem .eql (u64 , self .data [0.. ], other .data [0.. ]);
106
+ pub fn eql (self : * const Self , other : * const Self ) bool {
107
+ inline for (0.. 4) | i | {
108
+ if (self .data [i ] != other .data [i ]) return false ;
109
+ }
110
+
111
+ return true ;
108
112
}
109
113
110
114
/// Checks equality between slices of MemoryCell instances.
@@ -124,7 +128,7 @@ pub const MemoryCell = struct {
124
128
if (a .len != b .len ) return false ;
125
129
if (a .ptr == b .ptr ) return true ;
126
130
127
- for (a , b ) | a_elem , b_elem | {
131
+ for (a , b ) | * a_elem , * b_elem | {
128
132
if (! a_elem .eql (b_elem )) return false ;
129
133
}
130
134
@@ -609,20 +613,11 @@ pub const Memory = struct {
609
613
/// # Returns
610
614
///
611
615
/// Returns the segment of MemoryCell items if it exists, or `null` if not found.
612
- fn getSegmentAtIndex (self : * Self , idx : i64 ) ? []MemoryCell {
613
- return switch (idx < 0 ) {
614
- true = > blk : {
615
- const i : usize = @intCast (- (idx + 1 ));
616
- break :blk if (i < self .temp_data .items .len )
617
- self .temp_data .items [i ].items
618
- else
619
- null ;
620
- },
621
- false = > if (idx < self .data .items .len )
622
- self .data .items [@intCast (idx )].items
623
- else
624
- null ,
625
- };
616
+ pub inline fn getSegmentAtIndex (self : * const Self , idx : i64 ) ? []MemoryCell {
617
+ return if (idx < 0 ) {
618
+ const i : usize = @bitCast (- (idx + 1 ));
619
+ return if (i >= self .temp_data .items .len ) null else self .temp_data .items [i ].items ;
620
+ } else if (idx >= self .data .items .len ) null else self .data .items [@intCast (idx )].items ;
626
621
}
627
622
628
623
/// Compares two memory segments within the VM's memory starting from specified addresses
@@ -663,12 +658,6 @@ pub const Memory = struct {
663
658
const l_idx = lhs .offset + i ;
664
659
const r_idx = rhs .offset + i ;
665
660
666
- // std.log.err("lhs: {any}, rhs: {any}, i: {any}, {any}", .{
667
- // if (l_idx < ls.len) ls[l_idx] else MemoryCell.NONE, if (r_idx < rs.len) rs[r_idx] else MemoryCell.NONE, i, MemoryCell.cmp(
668
- // if (l_idx < ls.len) ls[l_idx] else MemoryCell.NONE,
669
- // if (r_idx < rs.len) rs[r_idx] else MemoryCell.NONE,
670
- // ),
671
- // });
672
661
return switch (MemoryCell .cmp (
673
662
if (l_idx < ls .len ) ls [l_idx ] else MemoryCell .NONE ,
674
663
if (r_idx < rs .len ) rs [r_idx ] else MemoryCell .NONE ,
@@ -700,7 +689,7 @@ pub const Memory = struct {
700
689
/// # Returns
701
690
///
702
691
/// Returns `true` if segments are equal up to the specified length, otherwise `false`.
703
- pub fn memEq (self : * Self , lhs : Relocatable , rhs : Relocatable , len : usize ) ! bool {
692
+ pub fn memEq (self : * const Self , lhs : Relocatable , rhs : Relocatable , len : usize ) ! bool {
704
693
// Check if the left and right addresses are the same, in which case the segments are equal.
705
694
if (lhs .eq (rhs )) return true ;
706
695
@@ -714,29 +703,25 @@ pub const Memory = struct {
714
703
// Get the segment starting from the right-hand address.
715
704
const r : ? []MemoryCell = if (self .getSegmentAtIndex (rhs .segment_index )) | s |
716
705
// Check if the offset is within the bounds of the segment.
717
- if (rhs .offset < s .len ) s [rhs .offset .. ] else if (l == null ) return true else return false
718
- else if (l == null ) return true else return false ;
706
+ if (rhs .offset < s .len ) s [rhs .offset .. ] else return l == null
707
+ else
708
+ return l == null ;
719
709
720
710
// If the left segment exists, perform further checks.
721
711
if (l ) | ls | {
722
712
// If the right segment also exists, compare the segments up to the specified length.
723
- if (r ) | rs | {
724
- // Determine the actual lengths to compare.
725
- const lhs_len = @min (ls .len , len );
726
- const rhs_len = @min (rs .len , len );
713
+ // Determine the actual lengths to compare.
714
+ const lhs_len = @min (ls .len , len );
715
+ const rhs_len = @min (r .? .len , len );
727
716
728
- // Compare slices of MemoryCell items up to the specified length.
729
- if (lhs_len != rhs_len ) return false ;
730
-
731
- return MemoryCell .eqlSlice (ls [0.. lhs_len ], rs [0.. rhs_len ]);
732
- }
717
+ // Compare slices of MemoryCell items up to the specified length.
718
+ if (lhs_len != rhs_len ) return false ;
733
719
734
- // If only the left segment exists, return false.
735
- return false ;
720
+ return MemoryCell .eqlSlice (ls [0.. lhs_len ], r .? [0.. rhs_len ]);
736
721
}
737
722
738
- // If the left segment does not exist , return true only if the right segment is also null .
739
- return r == null ;
723
+ // If only the left segment exists , return false .
724
+ return false ;
740
725
}
741
726
742
727
/// Retrieves a range of memory values starting from a specified address.
@@ -769,6 +754,36 @@ pub const Memory = struct {
769
754
return values ;
770
755
}
771
756
757
+ /// Retrieves a range of memory values starting from a specified address.
758
+ ///
759
+ /// # Arguments
760
+ ///
761
+ /// * `allocator`: The allocator used for the memory allocation of the returned list.
762
+ /// * `address`: The starting address in the memory from which the range is retrieved.
763
+ /// * `size`: The size of the range to be retrieved.
764
+ ///
765
+ /// # Returns
766
+ ///
767
+ /// Returns a list containing memory values retrieved from the specified range starting at the given address.
768
+ /// The list may contain `MemoryCell.NONE` elements for inaccessible memory positions.
769
+ ///
770
+ /// # Errors
771
+ ///
772
+ /// Returns an error if there are any issues encountered during the retrieval of the memory range.
773
+ pub fn getRangeRaw (
774
+ self : * Self ,
775
+ allocator : Allocator ,
776
+ address : Relocatable ,
777
+ size : usize ,
778
+ ) ! std. ArrayList (? MaybeRelocatable ) {
779
+ var values = std .ArrayList (? MaybeRelocatable ).init (allocator );
780
+ errdefer values .deinit ();
781
+ for (0.. size ) | i | {
782
+ try values .append (self .get (try address .addUint (i )));
783
+ }
784
+ return values ;
785
+ }
786
+
772
787
/// Counts the number of accessed addresses within a specified segment in the VM memory.
773
788
///
774
789
/// # Arguments
@@ -2426,9 +2441,9 @@ test "MemoryCell: eql function" {
2426
2441
memoryCell4 .markAccessed ();
2427
2442
2428
2443
// Test checks
2429
- try expect (memoryCell1 .eql (memoryCell2 ));
2430
- try expect (! memoryCell1 .eql (memoryCell3 ));
2431
- try expect (! memoryCell1 .eql (memoryCell4 ));
2444
+ try expect (memoryCell1 .eql (& memoryCell2 ));
2445
+ try expect (! memoryCell1 .eql (& memoryCell3 ));
2446
+ try expect (! memoryCell1 .eql (& memoryCell4 ));
2432
2447
}
2433
2448
2434
2449
test "MemoryCell: eqlSlice should return false if slice len are not the same" {
0 commit comments