@@ -367,13 +367,19 @@ impl ExecutingFrame<'_> {
367
367
}
368
368
}
369
369
370
+ #[ inline( always) ]
371
+ fn fetch_next_instr ( & mut self ) -> usize {
372
+ let idx = self . lasti ( ) as usize ;
373
+ self . update_lasti ( |i| * i += 1 ) ;
374
+ idx
375
+ }
376
+
370
377
fn run ( & mut self , vm : & VirtualMachine ) -> PyResult < ExecutionResult > {
371
378
flame_guard ! ( format!( "Frame::run({})" , self . code. obj_name) ) ;
372
379
// Execute until return or exception:
373
380
let instrs = & self . code . instructions ;
374
381
loop {
375
- let idx = self . lasti ( ) as usize ;
376
- self . update_lasti ( |i| * i += 1 ) ;
382
+ let idx = self . fetch_next_instr ( ) ;
377
383
let instr = & instrs[ idx] ;
378
384
let result = self . execute_instruction ( instr, vm) ;
379
385
match result {
@@ -510,35 +516,72 @@ impl ExecutingFrame<'_> {
510
516
trace ! ( "=======" ) ;
511
517
}
512
518
513
- macro_rules! fn_dispatch {
514
- ( args( $dT: ty => $retT: ty , $arg1: ident: $argT1: ty, $arg2: ident: $argT2: ty) , match ( $d: expr) { $( $p: pat => $body: block) * } ) => { {
515
- let f = match $d {
516
- $( $p => {
517
- fn match_arm( x: $dT, #[ allow( unused) ] $arg1: $argT1, #[ allow( unused) ] $arg2: $argT2) -> $retT {
518
- match x {
519
- $p => $body
520
- _ => unsafe { std:: hint:: unreachable_unchecked( ) }
519
+ macro_rules! get_instr_fn_ptr {
520
+ ( fn ( $insT: ty, $arg1: ident: $arg1T: ty, $arg2: ident: $arg2T: ty$( , ) ?) -> $retT: ty, match ( $ins: expr) { $( $p: pat => $body: block) * } ) => { {
521
+ #[ inline( always) ]
522
+ fn get_fn( ins: $insT) -> fn ( $insT, $arg1T, $arg2T) -> $retT {
523
+ #[ allow( unused) ]
524
+ match ins {
525
+ $( $p => {
526
+ fn match_arm( x: $insT, $arg1: $arg1T, $arg2: $arg2T) -> $retT {
527
+ let ret = ( || match x {
528
+ $p => $body
529
+ _ => unsafe { std:: hint:: unreachable_unchecked( ) }
530
+ } ) ( ) ;
531
+ match ret {
532
+ Ok ( None ) => {
533
+ drop( ret) ;
534
+ let idx = $arg1. fetch_next_instr( ) ;
535
+ $arg2. check_signals( ) ?;
536
+ let ins = & $arg1. code. instructions[ idx] ;
537
+ get_fn( ins) ( ins, $arg1, $arg2)
538
+ }
539
+ x => x
540
+ }
521
541
}
522
- }
523
- match_arm as fn ( $dT , $argT1 , $argT2 ) -> $retT
524
- } ) *
525
- } ;
526
- f ( $d , $arg1 , $arg2 )
542
+ match_arm as _
543
+ } ) *
544
+ }
545
+ }
546
+ get_fn ( $ins )
527
547
} }
528
548
}
529
549
530
550
let zelf = self ;
531
- fn_dispatch ! ( args( & bytecode:: Instruction => FrameResult , zelf: & mut ExecutingFrame , vm: & VirtualMachine ) ,
532
- match ( instruction) {
551
+
552
+ macro_rules! fn_dispatch {
553
+ ( match ( $ins: expr, & mut * $z: ident, $v: ident) . 0 { $( $p: pat => $body: block) * } ) => { {
554
+ let f = get_instr_fn_ptr!(
555
+ fn (
556
+ & bytecode:: Instruction ,
557
+ $z: & mut ExecutingFrame ,
558
+ $v: & VirtualMachine ,
559
+ ) -> FrameResult ,
560
+ match ( $ins) { $( $p => $body) * }
561
+ ) ;
562
+ f( $ins, zelf, vm)
563
+ } } ;
564
+ }
565
+ // macro_rules! fn_dispatch {
566
+ // ($e:expr) => {
567
+ // $e
568
+ // };
569
+ // }
570
+
571
+ fn_dispatch ! ( match ( instruction, & mut * zelf, vm) . 0 {
533
572
bytecode:: Instruction :: LoadConst { idx } => {
534
573
zelf. push_value( zelf. code. constants[ * idx as usize ] . 0 . clone( ) ) ;
535
574
Ok ( None )
536
575
}
537
576
bytecode:: Instruction :: ImportName { idx } => {
538
577
zelf. import( vm, Some ( zelf. code. names[ * idx as usize ] . clone( ) ) )
539
578
}
540
- bytecode:: Instruction :: ImportNameless => { zelf. import( vm, None ) }
541
- bytecode:: Instruction :: ImportStar => { zelf. import_star( vm) }
579
+ bytecode:: Instruction :: ImportNameless => {
580
+ zelf. import( vm, None )
581
+ }
582
+ bytecode:: Instruction :: ImportStar => {
583
+ zelf. import_star( vm)
584
+ }
542
585
bytecode:: Instruction :: ImportFrom { idx } => {
543
586
let obj = zelf. import_from( vm, * idx) ?;
544
587
zelf. push_value( obj) ;
@@ -652,9 +695,15 @@ impl ExecutingFrame<'_> {
652
695
zelf. push_value( value. into_object( ) ) ;
653
696
Ok ( None )
654
697
}
655
- bytecode:: Instruction :: Subscript => { zelf. execute_subscript( vm) }
656
- bytecode:: Instruction :: StoreSubscript => { zelf. execute_store_subscript( vm) }
657
- bytecode:: Instruction :: DeleteSubscript => { zelf. execute_delete_subscript( vm) }
698
+ bytecode:: Instruction :: Subscript => {
699
+ zelf. execute_subscript( vm)
700
+ }
701
+ bytecode:: Instruction :: StoreSubscript => {
702
+ zelf. execute_store_subscript( vm)
703
+ }
704
+ bytecode:: Instruction :: DeleteSubscript => {
705
+ zelf. execute_delete_subscript( vm)
706
+ }
658
707
bytecode:: Instruction :: Pop => {
659
708
// Pop value from stack and ignore.
660
709
zelf. pop_value( ) ;
@@ -667,7 +716,9 @@ impl ExecutingFrame<'_> {
667
716
zelf. push_value( value) ;
668
717
Ok ( None )
669
718
}
670
- bytecode:: Instruction :: Rotate { amount } => { zelf. execute_rotate( * amount) }
719
+ bytecode:: Instruction :: Rotate { amount } => {
720
+ zelf. execute_rotate( * amount)
721
+ }
671
722
bytecode:: Instruction :: BuildString { size } => {
672
723
let s = zelf
673
724
. pop_multiple( * size as usize )
@@ -712,8 +763,12 @@ impl ExecutingFrame<'_> {
712
763
size,
713
764
unpack,
714
765
for_call,
715
- } => { zelf. execute_build_map( vm, * size, * unpack, * for_call) }
716
- bytecode:: Instruction :: BuildSlice { step } => { zelf. execute_build_slice( vm, * step) }
766
+ } => {
767
+ zelf. execute_build_map( vm, * size, * unpack, * for_call)
768
+ }
769
+ bytecode:: Instruction :: BuildSlice { step } => {
770
+ zelf. execute_build_slice( vm, * step)
771
+ }
717
772
bytecode:: Instruction :: ListAppend { i } => {
718
773
let list_obj = zelf. nth_value( * i) ;
719
774
let item = zelf. pop_value( ) ;
@@ -741,15 +796,27 @@ impl ExecutingFrame<'_> {
741
796
PyDictRef :: try_from_object( vm, dict_obj) ?. set_item( key, value, vm) ?;
742
797
Ok ( None )
743
798
}
744
- bytecode:: Instruction :: BinaryOperation { op } => { zelf. execute_binop( vm, * op) }
799
+ bytecode:: Instruction :: BinaryOperation { op } => {
800
+ zelf. execute_binop( vm, * op)
801
+ }
745
802
bytecode:: Instruction :: BinaryOperationInplace { op } => {
746
803
zelf. execute_binop_inplace( vm, * op)
747
804
}
748
- bytecode:: Instruction :: LoadAttr { idx } => { zelf. load_attr( vm, * idx) }
749
- bytecode:: Instruction :: StoreAttr { idx } => { zelf. store_attr( vm, * idx) }
750
- bytecode:: Instruction :: DeleteAttr { idx } => { zelf. delete_attr( vm, * idx) }
751
- bytecode:: Instruction :: UnaryOperation { ref op } => { zelf. execute_unop( vm, op) }
752
- bytecode:: Instruction :: CompareOperation { ref op } => { zelf. execute_compare( vm, op) }
805
+ bytecode:: Instruction :: LoadAttr { idx } => {
806
+ zelf. load_attr( vm, * idx)
807
+ }
808
+ bytecode:: Instruction :: StoreAttr { idx } => {
809
+ zelf. store_attr( vm, * idx)
810
+ }
811
+ bytecode:: Instruction :: DeleteAttr { idx } => {
812
+ zelf. delete_attr( vm, * idx)
813
+ }
814
+ bytecode:: Instruction :: UnaryOperation { ref op } => {
815
+ zelf. execute_unop( vm, op)
816
+ }
817
+ bytecode:: Instruction :: CompareOperation { ref op } => {
818
+ zelf. execute_compare( vm, op)
819
+ }
753
820
bytecode:: Instruction :: ReturnValue => {
754
821
let value = zelf. pop_value( ) ;
755
822
zelf. unwind_blocks( vm, UnwindReason :: Returning { value } )
@@ -763,7 +830,9 @@ impl ExecutingFrame<'_> {
763
830
} ;
764
831
Ok ( Some ( ExecutionResult :: Yield ( value) ) )
765
832
}
766
- bytecode:: Instruction :: YieldFrom => { zelf. execute_yield_from( vm) }
833
+ bytecode:: Instruction :: YieldFrom => {
834
+ zelf. execute_yield_from( vm)
835
+ }
767
836
bytecode:: Instruction :: SetupAnnotation => {
768
837
if !zelf. locals. contains_key( "__annotations__" , vm) {
769
838
zelf. locals
@@ -930,8 +999,12 @@ impl ExecutingFrame<'_> {
930
999
Err ( exc. downcast( ) . unwrap( ) )
931
1000
}
932
1001
}
933
- bytecode:: Instruction :: ForIter { target } => { zelf. execute_for_iter( vm, * target) }
934
- bytecode:: Instruction :: MakeFunction ( flags) => { zelf. execute_make_function( vm, * flags) }
1002
+ bytecode:: Instruction :: ForIter { target } => {
1003
+ zelf. execute_for_iter( vm, * target)
1004
+ }
1005
+ bytecode:: Instruction :: MakeFunction ( flags) => {
1006
+ zelf. execute_make_function( vm, * flags)
1007
+ }
935
1008
bytecode:: Instruction :: CallFunctionPositional { nargs } => {
936
1009
let args = zelf. collect_positional_args( * nargs) ;
937
1010
zelf. execute_call( args, vm)
@@ -1015,9 +1088,13 @@ impl ExecutingFrame<'_> {
1015
1088
Ok ( None )
1016
1089
}
1017
1090
1018
- bytecode:: Instruction :: Raise { kind } => { zelf. execute_raise( vm, * kind) }
1091
+ bytecode:: Instruction :: Raise { kind } => {
1092
+ zelf. execute_raise( vm, * kind)
1093
+ }
1019
1094
1020
- bytecode:: Instruction :: Break => { zelf. unwind_blocks( vm, UnwindReason :: Break ) }
1095
+ bytecode:: Instruction :: Break => {
1096
+ zelf. unwind_blocks( vm, UnwindReason :: Break )
1097
+ }
1021
1098
bytecode:: Instruction :: Continue { target } => {
1022
1099
zelf. unwind_blocks( vm, UnwindReason :: Continue { target: * target } )
1023
1100
}
0 commit comments