@@ -84,21 +84,14 @@ impl<'a> VM<'a> {
8484 accounts : & ' a [ AccountInfo < ' a > ] ,
8585 _instruction_data : & ' a [ u8 ] ,
8686 ) -> Self {
87- let data_structures = DataStructureStore {
88- btrees : vec ! [ None ; 8 ] ,
89- tries : vec ! [ None ; 8 ] ,
90- graphs : vec ! [ None ; 8 ] ,
91- ohlcvs : vec ! [ None ; 8 ] ,
92- hypergraphs : vec ! [ None ; 8 ] ,
93- } ;
9487 Self {
9588 pc : 0 ,
9689 gas : Gas :: new ( 200_000 ) ,
9790 stack : Stack :: new ( ) ,
9891 memory : Memory :: new ( ) ,
9992 accounts : AccountsView { accounts, current : 0 } ,
10093 program_id,
101- data_structures,
94+ data_structures : DataStructureStore :: new ( ) ,
10295 reentrancy_guard : ReentrancyGuard :: new ( ) ,
10396 tracer : Box :: new ( DefaultTracer ) ,
10497 }
@@ -146,8 +139,21 @@ impl<'a> VM<'a> {
146139 return Err ( VMError :: StackUnderflow ) ;
147140 }
148141
149- let values = _mm256_loadu_si256 ( self . stack . as_simd_ptr ( ) ? as * const __m256i ) ;
150- let result = _mm256_add_epi64 ( values, values) ;
142+ // Get two vectors from the stack (4 values each)
143+ let values1 = _mm256_loadu_si256 ( self . stack . as_simd_ptr ( ) ? as * const __m256i ) ;
144+
145+ // Pop the first 4 values and get the next 4 values
146+ self . stack . pop ( ) ?;
147+ self . stack . pop ( ) ?;
148+ self . stack . pop ( ) ?;
149+ self . stack . pop ( ) ?;
150+
151+ let values2 = _mm256_loadu_si256 ( self . stack . as_simd_ptr ( ) ? as * const __m256i ) ;
152+
153+ // Add the two vectors
154+ let result = _mm256_add_epi64 ( values1, values2) ;
155+
156+ // Store the result back to the stack
151157 _mm256_storeu_si256 ( self . stack . as_simd_mut_ptr ( ) ? as * mut __m256i , result) ;
152158 Ok ( ( ) )
153159 }
@@ -236,6 +242,67 @@ impl<'a> VM<'a> {
236242 }
237243 self . stack . push ( Value ( div as u64 ) ) ?;
238244 } ,
245+ OpCode :: Mod => {
246+ let b = self . stack . pop ( ) ?;
247+ let a = self . stack . pop ( ) ?;
248+ if b. 0 == 0 {
249+ return Err ( VMError :: DivisionByZero . into ( ) ) ;
250+ }
251+ let result = Value ( a. 0 % b. 0 ) ;
252+ self . stack . push ( result) ?;
253+ } ,
254+ OpCode :: Exp => {
255+ let exponent = self . stack . pop ( ) ?. 0 ;
256+ let base = self . stack . pop ( ) ?. 0 ;
257+
258+ // Handle potential overflow
259+ if exponent > 64 && base > 1 {
260+ return Err ( VMError :: ArithmeticOverflow . into ( ) ) ;
261+ }
262+
263+ let mut result = 1u64 ;
264+ let mut base_power = base;
265+ let mut exp = exponent;
266+
267+ // Fast exponentiation algorithm
268+ while exp > 0 {
269+ if exp & 1 == 1 {
270+ result = result. checked_mul ( base_power)
271+ . ok_or ( VMError :: ArithmeticOverflow ) ?;
272+ }
273+ base_power = base_power. checked_mul ( base_power)
274+ . ok_or ( VMError :: ArithmeticOverflow ) ?;
275+ exp >>= 1 ;
276+ }
277+
278+ self . stack . push ( Value ( result) ) ?;
279+ } ,
280+ OpCode :: SignExtend => {
281+ let byte_num = self . stack . pop ( ) ?. 0 as usize ;
282+ let value = self . stack . pop ( ) ?. 0 ;
283+
284+ if byte_num >= 8 {
285+ // No change if byte_num is out of range
286+ self . stack . push ( Value ( value) ) ?;
287+ return Ok ( ( ) ) ;
288+ }
289+
290+ let bit_position = ( byte_num + 1 ) * 8 - 1 ;
291+ let mask = 1u64 << bit_position;
292+ let sign_bit = value & mask;
293+
294+ let result = if sign_bit != 0 {
295+ // If sign bit is 1, set all higher bits to 1
296+ let higher_bits_mask = !( ( 1u64 << ( bit_position + 1 ) ) - 1 ) ;
297+ value | higher_bits_mask
298+ } else {
299+ // If sign bit is 0, clear all higher bits
300+ let lower_bits_mask = ( 1u64 << ( bit_position + 1 ) ) - 1 ;
301+ value & lower_bits_mask
302+ } ;
303+
304+ self . stack . push ( Value ( result) ) ?;
305+ } ,
239306
240307 // Memory Operations
241308 OpCode :: Load => {
@@ -266,6 +333,16 @@ impl<'a> VM<'a> {
266333 OpCode :: Msize => {
267334 self . stack . push ( Value ( self . memory . size ( ) as u64 ) ) ?;
268335 } ,
336+ OpCode :: Mload8 => {
337+ let offset = self . stack . pop ( ) ?. 0 as usize ;
338+ let value = self . memory . load8 ( offset) ? as u64 ;
339+ self . stack . push ( Value ( value) ) ?;
340+ } ,
341+ OpCode :: Mstore8 => {
342+ let offset = self . stack . pop ( ) ?. 0 as usize ;
343+ let value = self . stack . pop ( ) ?. 0 as u8 ;
344+ self . memory . store8 ( offset, value) ?;
345+ } ,
269346
270347 // Control Flow
271348 OpCode :: Jump => {
@@ -454,9 +531,7 @@ impl<'a> VM<'a> {
454531 OpCode :: BTreeClear => {
455532 let id = self . stack . pop ( ) ?. 0 as usize ;
456533
457- if id >= self . data_structures . btrees . len ( ) {
458- return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
459- }
534+ self . data_structures . ensure_capacity ( DataStructureType :: BTreeMap , id) ;
460535
461536 if let Some ( btree) = & mut self . data_structures . btrees [ id] {
462537 btree. clear ( ) ;
@@ -468,9 +543,7 @@ impl<'a> VM<'a> {
468543 // Trie operations
469544 OpCode :: TrieCreate => {
470545 let id = self . stack . pop ( ) ?. 0 as usize ;
471- if id >= self . data_structures . tries . len ( ) {
472- return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
473- }
546+ self . data_structures . ensure_capacity ( DataStructureType :: Trie , id) ;
474547 self . data_structures . tries [ id] = Some ( TrieDS :: new ( ) ) ;
475548 } ,
476549 OpCode :: TrieInsert => {
@@ -480,9 +553,7 @@ impl<'a> VM<'a> {
480553 let key_ptr = self . stack . pop ( ) ?. 0 as usize ;
481554 let id = self . stack . pop ( ) ?. 0 as usize ;
482555
483- if id >= self . data_structures . tries . len ( ) {
484- return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
485- }
556+ self . data_structures . ensure_capacity ( DataStructureType :: Trie , id) ;
486557
487558 // Read key from memory
488559 let key = self . memory . load ( key_ptr, key_len) ?;
@@ -504,9 +575,7 @@ impl<'a> VM<'a> {
504575 return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
505576 }
506577
507- if id >= self . data_structures . tries . len ( ) {
508- return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
509- }
578+ self . data_structures . ensure_capacity ( DataStructureType :: Trie , id) ;
510579
511580 // Read key from memory with bounds check
512581 let key = match self . memory . load ( key_ptr, key_len) {
@@ -534,9 +603,7 @@ impl<'a> VM<'a> {
534603 return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
535604 }
536605
537- if id >= self . data_structures . tries . len ( ) {
538- return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
539- }
606+ self . data_structures . ensure_capacity ( DataStructureType :: Trie , id) ;
540607
541608 // Read key from memory with bounds check
542609 let key = match self . memory . load ( key_ptr, key_len) {
@@ -554,9 +621,7 @@ impl<'a> VM<'a> {
554621 OpCode :: TrieClear => {
555622 let id = self . stack . pop ( ) ?. 0 as usize ;
556623
557- if id >= self . data_structures . tries . len ( ) {
558- return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
559- }
624+ self . data_structures . ensure_capacity ( DataStructureType :: Trie , id) ;
560625
561626 if let Some ( trie) = & mut self . data_structures . tries [ id] {
562627 trie. clear ( ) ;
@@ -595,21 +660,97 @@ impl<'a> VM<'a> {
595660 // OHLCV operations
596661 OpCode :: OhlcvCreate => {
597662 let id = self . stack . pop ( ) ?. 0 as usize ;
598- if id >= self . data_structures . ohlcvs . len ( ) {
599- return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
600- }
663+ self . data_structures . ensure_capacity ( DataStructureType :: OHLCV , id) ;
601664 self . data_structures . ohlcvs [ id] = Some ( OHLCVDS :: new ( ) ) ;
602665 } ,
603666
604667 // Hypergraph operations
605668 OpCode :: HyperCreate => {
606669 let id = self . stack . pop ( ) ?. 0 as usize ;
607- if id >= self . data_structures . hypergraphs . len ( ) {
608- return Err ( VMError :: InvalidDataStructureOperation . into ( ) ) ;
609- }
670+ self . data_structures . ensure_capacity ( DataStructureType :: Hypergraph , id) ;
610671 self . data_structures . hypergraphs [ id] = Some ( HypergraphDS :: new ( ) ) ;
611672 } ,
612673
674+ // Bitwise Operations
675+ OpCode :: And => {
676+ let b = self . stack . pop ( ) ?. 0 ;
677+ let a = self . stack . pop ( ) ?. 0 ;
678+ self . stack . push ( Value ( a & b) ) ?;
679+ } ,
680+ OpCode :: Or => {
681+ let b = self . stack . pop ( ) ?. 0 ;
682+ let a = self . stack . pop ( ) ?. 0 ;
683+ self . stack . push ( Value ( a | b) ) ?;
684+ } ,
685+ OpCode :: Xor => {
686+ let b = self . stack . pop ( ) ?. 0 ;
687+ let a = self . stack . pop ( ) ?. 0 ;
688+ self . stack . push ( Value ( a ^ b) ) ?;
689+ } ,
690+ OpCode :: Not => {
691+ let a = self . stack . pop ( ) ?. 0 ;
692+ self . stack . push ( Value ( !a) ) ?;
693+ } ,
694+ OpCode :: Byte => {
695+ let byte_index = self . stack . pop ( ) ?. 0 as usize ;
696+ let value = self . stack . pop ( ) ?. 0 ;
697+
698+ let result = if byte_index >= 32 {
699+ 0
700+ } else {
701+ // Extract the specified byte
702+ let shift = ( 31 - byte_index) * 8 ;
703+ ( value >> shift) & 0xFF
704+ } ;
705+
706+ self . stack . push ( Value ( result) ) ?;
707+ } ,
708+ OpCode :: Shl => {
709+ let shift = self . stack . pop ( ) ?. 0 ;
710+ let value = self . stack . pop ( ) ?. 0 ;
711+
712+ // Avoid undefined behavior with large shifts
713+ let result = if shift >= 64 {
714+ 0
715+ } else {
716+ value << shift
717+ } ;
718+
719+ self . stack . push ( Value ( result) ) ?;
720+ } ,
721+ OpCode :: Shr => {
722+ let shift = self . stack . pop ( ) ?. 0 ;
723+ let value = self . stack . pop ( ) ?. 0 ;
724+
725+ // Avoid undefined behavior with large shifts
726+ let result = if shift >= 64 {
727+ 0
728+ } else {
729+ value >> shift
730+ } ;
731+
732+ self . stack . push ( Value ( result) ) ?;
733+ } ,
734+ OpCode :: Sar => {
735+ let shift = self . stack . pop ( ) ?. 0 ;
736+ let value = self . stack . pop ( ) ?. 0 ;
737+
738+ // Arithmetic right shift (sign-extending)
739+ let result = if shift >= 64 {
740+ if ( value as i64 ) < 0 {
741+ u64:: MAX // All 1s for negative numbers
742+ } else {
743+ 0 // All 0s for positive numbers
744+ }
745+ } else {
746+ // Rust doesn't have arithmetic right shift for unsigned types
747+ // Convert to signed, shift, then back to unsigned
748+ ( ( value as i64 ) >> shift) as u64
749+ } ;
750+
751+ self . stack . push ( Value ( result) ) ?;
752+ } ,
753+
613754 OpCode :: Halt => {
614755 break ;
615756 } ,
0 commit comments