@@ -138,51 +138,50 @@ impl<'a> VM<'a> {
138138
139139 /*
140140 Fast-Path Execution
141- Runs specialized ops from inline cache or adaptive overlay ; returns false to trigger deopt.
141+ Peeks stack without popping ; returns false with stack untouched to trigger deopt.
142142 */
143143
144144 #[ inline]
145145 fn exec_fast ( & mut self , fast : FastOp ) -> Result < bool , VmErr > {
146- let ( a, b) = self . pop2 ( ) ?;
147- let hit = match fast {
146+ let len = self . stack . len ( ) ;
147+ if len < 2 { return Ok ( false ) ; }
148+ let a = self . stack [ len - 2 ] ;
149+ let b = self . stack [ len - 1 ] ;
150+ let result = match fast {
148151 FastOp :: AddInt if a. is_int ( ) && b. is_int ( ) => {
149152 let r = a. as_int ( ) as i128 + b. as_int ( ) as i128 ;
150- self . push ( if r >= Val :: INT_MIN as i128 && r <= Val :: INT_MAX as i128 { Val :: int ( r as i64 ) } else { Val :: float ( r as f64 ) } ) ;
151- true
153+ if r >= Val :: INT_MIN as i128 && r <= Val :: INT_MAX as i128 { Val :: int ( r as i64 ) } else { Val :: float ( r as f64 ) }
152154 }
153- FastOp :: AddFloat if a. is_float ( ) && b. is_float ( ) => { self . push ( Val :: float ( a. as_float ( ) + b. as_float ( ) ) ) ; true }
155+ FastOp :: AddFloat if a. is_float ( ) && b. is_float ( ) => Val :: float ( a. as_float ( ) + b. as_float ( ) ) ,
154156 FastOp :: SubInt if a. is_int ( ) && b. is_int ( ) => {
155157 let r = a. as_int ( ) as i128 - b. as_int ( ) as i128 ;
156- self . push ( if r >= Val :: INT_MIN as i128 && r <= Val :: INT_MAX as i128 { Val :: int ( r as i64 ) } else { Val :: float ( r as f64 ) } ) ;
157- true
158+ if r >= Val :: INT_MIN as i128 && r <= Val :: INT_MAX as i128 { Val :: int ( r as i64 ) } else { Val :: float ( r as f64 ) }
158159 }
159- FastOp :: SubFloat if a. is_float ( ) && b. is_float ( ) => { self . push ( Val :: float ( a. as_float ( ) - b. as_float ( ) ) ) ; true }
160+ FastOp :: SubFloat if a. is_float ( ) && b. is_float ( ) => Val :: float ( a. as_float ( ) - b. as_float ( ) ) ,
160161 FastOp :: MulInt if a. is_int ( ) && b. is_int ( ) => {
161162 let r = a. as_int ( ) as i128 * b. as_int ( ) as i128 ;
162- self . push ( if r >= Val :: INT_MIN as i128 && r <= Val :: INT_MAX as i128 { Val :: int ( r as i64 ) } else { Val :: float ( r as f64 ) } ) ;
163- true
163+ if r >= Val :: INT_MIN as i128 && r <= Val :: INT_MAX as i128 { Val :: int ( r as i64 ) } else { Val :: float ( r as f64 ) }
164164 }
165- FastOp :: MulFloat if a. is_float ( ) && b. is_float ( ) => { self . push ( Val :: float ( a. as_float ( ) * b. as_float ( ) ) ) ; true }
166- FastOp :: LtInt if a. is_int ( ) && b. is_int ( ) => { self . push ( Val :: bool ( a. as_int ( ) < b. as_int ( ) ) ) ; true }
167- FastOp :: LtFloat if a. is_float ( ) && b. is_float ( ) => { self . push ( Val :: bool ( a. as_float ( ) < b. as_float ( ) ) ) ; true }
168- FastOp :: EqInt if a. is_int ( ) && b. is_int ( ) => { self . push ( Val :: bool ( a. as_int ( ) == b. as_int ( ) ) ) ; true }
169- FastOp :: AddStr | FastOp :: EqStr => {
170- if a. is_heap ( ) && b. is_heap ( ) {
171- let ( sa, sb) = match ( self . heap . get ( a) , self . heap . get ( b) ) {
172- ( HeapObj :: Str ( x) , HeapObj :: Str ( y) ) => ( x. clone ( ) , y. clone ( ) ) ,
173- _ => { self . push ( a) ; self . push ( b) ; return Ok ( false ) ; }
174- } ;
175- match fast {
176- FastOp :: AddStr => { let v = self . heap . alloc ( HeapObj :: Str ( format ! ( "{}{}" , sa, sb) ) ) ?; self . push ( v) ; }
177- _ => { self . push ( Val :: bool ( sa == sb) ) ; }
178- }
179- true
180- } else { false }
165+ FastOp :: MulFloat if a. is_float ( ) && b. is_float ( ) => Val :: float ( a. as_float ( ) * b. as_float ( ) ) ,
166+ FastOp :: LtInt if a. is_int ( ) && b. is_int ( ) => Val :: bool ( a. as_int ( ) < b. as_int ( ) ) ,
167+ FastOp :: LtFloat if a. is_float ( ) && b. is_float ( ) => Val :: bool ( a. as_float ( ) < b. as_float ( ) ) ,
168+ FastOp :: EqInt if a. is_int ( ) && b. is_int ( ) => Val :: bool ( a. as_int ( ) == b. as_int ( ) ) ,
169+ FastOp :: AddStr | FastOp :: EqStr if a. is_heap ( ) && b. is_heap ( ) => {
170+ let ( sa, sb) = match ( self . heap . get ( a) , self . heap . get ( b) ) {
171+ ( HeapObj :: Str ( x) , HeapObj :: Str ( y) ) => ( x. clone ( ) , y. clone ( ) ) ,
172+ _ => return Ok ( false ) ,
173+ } ;
174+ match fast {
175+ FastOp :: AddStr => self . heap . alloc ( HeapObj :: Str ( format ! ( "{}{}" , sa, sb) ) ) ?,
176+ _ => Val :: bool ( sa == sb) ,
177+ }
181178 }
182- _ => false ,
179+ _ => return Ok ( false ) ,
183180 } ;
184- if !hit { self . push ( a) ; self . push ( b) ; }
185- Ok ( hit)
181+ // Replace both operands with computed result.
182+ self . stack . truncate ( len - 2 ) ;
183+ self . push ( result) ;
184+ Ok ( true )
186185 }
187186
188187 /*
0 commit comments