@@ -57,9 +57,25 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
5757 ( binary try $ty: ty, |$a: ident, $b: ident| $expr: expr) => { self . store. stack. values. binary:: <$ty>( |$a, $b| $expr) ? } ;
5858 ( unary $from: ty => $to: ty, |$v: ident| $expr: expr) => { self . store. stack. values. unary_into:: <$from, $to>( |$v| Ok ( $expr) ) ? } ;
5959 ( binary $from: ty => $to: ty, |$a: ident, $b: ident| $expr: expr) => { self . store. stack. values. binary_into:: <$from, $to>( |$a, $b| Ok ( $expr) ) ? } ;
60+ ( binary_into2 $from: ty => $to: ty, |$a: ident, $b: ident| $expr: expr) => { {
61+ let $b = self . store. stack. values. pop:: <$from>( ) ;
62+ let $a = self . store. stack. values. pop:: <$from>( ) ;
63+ let out = $expr;
64+ self . store. stack. values. push:: <$to>( out. 0 ) ?;
65+ self . store. stack. values. push:: <$to>( out. 1 ) ?;
66+ } } ;
6067 ( binary $a: ty, $b: ty, |$lhs: ident, $rhs: ident| $expr: expr) => { stack_op!( binary $a, $b => $b, |$lhs, $rhs| $expr) } ;
6168 ( binary $a: ty, $b: ty => $res: ty, |$lhs: ident, $rhs: ident| $expr: expr) => { self . store. stack. values. binary_mixed:: <$a, $b, $res>( |$lhs, $rhs| Ok ( $expr) ) ? } ;
6269 ( ternary $ty: ty, |$a: ident, $b: ident, $c: ident| $expr: expr) => { self . store. stack. values. ternary:: <$ty>( |$a, $b, $c| Ok ( $expr) ) ? } ;
70+ ( quaternary_into2 $from: ty => $to: ty, |$a: ident, $b: ident, $c: ident, $d: ident| $expr: expr) => { {
71+ let $d = self . store. stack. values. pop:: <$from>( ) ;
72+ let $c = self . store. stack. values. pop:: <$from>( ) ;
73+ let $b = self . store. stack. values. pop:: <$from>( ) ;
74+ let $a = self . store. stack. values. pop:: <$from>( ) ;
75+ let out = $expr;
76+ self . store. stack. values. push:: <$to>( out. 0 ) ?;
77+ self . store. stack. values. push:: <$to>( out. 1 ) ?;
78+ } } ;
6379 ( local_set_pop $ty: ty, $local_index: expr) => { {
6480 let val = self . store. stack. values. pop:: <$ty>( ) ;
6581 self . store. stack. values. local_set( & self . cf, * $local_index, val) ;
@@ -266,6 +282,26 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
266282 I64Rotl => stack_op ! ( binary i64 , |a, b| a. wasm_rotl( b) ) ,
267283 I32Rotr => stack_op ! ( binary i32 , |a, b| a. wasm_rotr( b) ) ,
268284 I64Rotr => stack_op ! ( binary i64 , |a, b| a. wasm_rotr( b) ) ,
285+ I64Add128 => stack_op ! ( quaternary_into2 i64 => i64 , |a_lo, a_hi, b_lo, b_hi| {
286+ let lo = a_lo. wrapping_add( b_lo) ;
287+ let carry = u64 :: from( ( lo as u64 ) < ( a_lo as u64 ) ) ;
288+ let hi = a_hi. wrapping_add( b_hi) . wrapping_add( carry as i64 ) ;
289+ ( lo, hi)
290+ } ) ,
291+ I64Sub128 => stack_op ! ( quaternary_into2 i64 => i64 , |a_lo, a_hi, b_lo, b_hi| {
292+ let lo = a_lo. wrapping_sub( b_lo) ;
293+ let borrow = u64 :: from( ( a_lo as u64 ) < ( b_lo as u64 ) ) ;
294+ let hi = a_hi. wrapping_sub( b_hi) . wrapping_sub( borrow as i64 ) ;
295+ ( lo, hi)
296+ } ) ,
297+ I64MulWideS => stack_op ! ( binary_into2 i64 => i64 , |a, b| {
298+ let product = ( a as i128 ) . wrapping_mul( b as i128 ) ;
299+ ( product as i64 , ( product >> 64 ) as i64 )
300+ } ) ,
301+ I64MulWideU => stack_op ! ( binary_into2 i64 => i64 , |a, b| {
302+ let product = ( a as u64 as u128 ) . wrapping_mul( b as u64 as u128 ) ;
303+ ( product as u64 as i64 , ( product >> 64 ) as u64 as i64 )
304+ } ) ,
269305 I32Clz => stack_op ! ( unary i32 , |v| v. leading_zeros( ) as i32 ) ,
270306 I64Clz => stack_op ! ( unary i64 , |v| i64 :: from( v. leading_zeros( ) ) ) ,
271307 I32Ctz => stack_op ! ( unary i32 , |v| v. trailing_zeros( ) as i32 ) ,
0 commit comments