@@ -31,7 +31,7 @@ pub enum NativeType{
31
31
Function ( Function ) ,
32
32
Slice ( Option < i32 > , Option < i32 > , Option < i32 > ) , // start, stop, step
33
33
#[ serde( skip_serializing, skip_deserializing) ]
34
- NativeFunction ( fn ( Vec < NativeType > ) -> NativeType ) ,
34
+ NativeFunction ( fn ( Vec < Rc < NativeType > > ) -> NativeType ) ,
35
35
}
36
36
37
37
const CMP_OP : & ' static [ & ' static str ] = & [ ">" ,
@@ -572,15 +572,14 @@ impl VirtualMachine {
572
572
None
573
573
} ,
574
574
575
- /*
576
575
( "BINARY_SUBSCR" , None ) => {
577
576
let curr_frame = self . curr_frame ( ) ;
578
577
let tos = curr_frame. stack . pop ( ) . unwrap ( ) ;
579
578
let tos1 = curr_frame. stack . pop ( ) . unwrap ( ) ;
580
- match (& tos1, & tos) {
579
+ match ( tos1. deref ( ) , tos. deref ( ) ) {
581
580
( & NativeType :: List ( ref l) , & NativeType :: Int ( ref index) ) => {
582
581
let pos_index = ( index + l. len ( ) as i32 ) % l. len ( ) as i32 ;
583
- curr_frame.stack.push(l[pos_index as usize].clone())
582
+ curr_frame. stack . push ( Rc :: new ( l[ pos_index as usize ] . clone ( ) ) )
584
583
} ,
585
584
( & NativeType :: List ( ref l) , & NativeType :: Slice ( ref opt_start, ref opt_stop, ref opt_step) ) => {
586
585
let start = match opt_start {
@@ -597,12 +596,12 @@ impl VirtualMachine {
597
596
_ => unimplemented ! ( ) ,
598
597
} ;
599
598
// TODO: we could potentially avoid this copy and use slice
600
- curr_frame.stack.push(NativeType::List(l[start..stop].to_vec()));
599
+ curr_frame. stack . push ( Rc :: new ( NativeType :: List ( l[ start..stop] . to_vec ( ) ) ) ) ;
601
600
} ,
602
- (&NativeType::Tuple(ref t), &NativeType::Int(ref index)) => curr_frame.stack.push(t[*index as usize].clone()),
601
+ ( & NativeType :: Tuple ( ref t) , & NativeType :: Int ( ref index) ) => curr_frame. stack . push ( Rc :: new ( t[ * index as usize ] . clone ( ) ) ) ,
603
602
( & NativeType :: Str ( ref s) , & NativeType :: Int ( ref index) ) => {
604
603
let idx = ( index + s. len ( ) as i32 ) % s. len ( ) as i32 ;
605
- curr_frame.stack.push(NativeType::Str(s.chars().nth(idx as usize).unwrap().to_string()));
604
+ curr_frame. stack . push ( Rc :: new ( NativeType :: Str ( s. chars ( ) . nth ( idx as usize ) . unwrap ( ) . to_string ( ) ) ) ) ;
606
605
} ,
607
606
( & NativeType :: Str ( ref s) , & NativeType :: Slice ( ref opt_start, ref opt_stop, ref opt_step) ) => {
608
607
let start = match opt_start {
@@ -618,7 +617,7 @@ impl VirtualMachine {
618
617
& None => 1 as usize ,
619
618
_ => unimplemented ! ( ) ,
620
619
} ;
621
- curr_frame.stack.push(NativeType::Str(s[start..stop].to_string()));
620
+ curr_frame. stack . push ( Rc :: new ( NativeType :: Str ( s[ start..stop] . to_string ( ) ) ) ) ;
622
621
} ,
623
622
// TODO: implement other Slice possibilities
624
623
_ => panic ! ( "TypeError: indexing type {:?} with index {:?} is not supported (yet?)" , tos1, tos)
@@ -636,9 +635,9 @@ impl VirtualMachine {
636
635
( "UNARY_NEGATIVE" , None ) => {
637
636
let curr_frame = self . curr_frame ( ) ;
638
637
let v = curr_frame. stack . pop ( ) . unwrap ( ) ;
639
- match v {
640
- NativeType::Int(v1i) => {
641
- curr_frame.stack.push(NativeType::Int(-v1i));
638
+ match v. deref ( ) {
639
+ & NativeType :: Int ( v1i) => {
640
+ curr_frame. stack . push ( Rc :: new ( NativeType :: Int ( -v1i) ) ) ;
642
641
} ,
643
642
_ => panic ! ( "TypeError in UINARY_NEGATIVE" )
644
643
}
@@ -665,14 +664,14 @@ impl VirtualMachine {
665
664
// https://docs.python.org/3.4/library/dis.html#opcode-MAKE_FUNCTION
666
665
let curr_frame = self . curr_frame ( ) ;
667
666
let qualified_name = curr_frame. stack . pop ( ) . unwrap ( ) ;
668
- let code_obj = match curr_frame.stack.pop().unwrap() {
669
- NativeType::Code(code) => code,
667
+ let code_obj = match curr_frame. stack . pop ( ) . unwrap ( ) . deref ( ) {
668
+ & NativeType :: Code ( ref code) => code. clone ( ) ,
670
669
_ => panic ! ( "Second item on the stack should be a code object" )
671
670
} ;
672
671
// pop argc arguments
673
672
// argument: name, args, globals
674
673
let func = Function :: new ( code_obj) ;
675
- curr_frame.stack.push(NativeType::Function(func));
674
+ curr_frame. stack . push ( Rc :: new ( NativeType :: Function ( func) ) ) ;
676
675
None
677
676
} ,
678
677
( "CALL_FUNCTION" , Some ( argc) ) => {
@@ -686,9 +685,9 @@ impl VirtualMachine {
686
685
for _ in 0 ..kw_count {
687
686
let native_val = curr_frame. stack . pop ( ) . unwrap ( ) ;
688
687
let native_key = curr_frame. stack . pop ( ) . unwrap ( ) ;
689
- if let (val, NativeType::Str(key)) = (native_val, native_key) {
688
+ if let ( ref val, & NativeType :: Str ( ref key) ) = ( native_val, native_key. deref ( ) ) {
690
689
691
- kw_args.insert(key, val);
690
+ kw_args. insert ( key. clone ( ) , val. clone ( ) ) ;
692
691
}
693
692
else {
694
693
panic ! ( "Incorrect type found while building keyword argument list" )
@@ -704,8 +703,8 @@ impl VirtualMachine {
704
703
} ;
705
704
706
705
let func = {
707
- match self.curr_frame().stack.pop().unwrap() {
708
- NativeType::Function(func) => {
706
+ match self . curr_frame ( ) . stack . pop ( ) . unwrap ( ) . deref ( ) {
707
+ & NativeType :: Function ( ref func) => {
709
708
// pop argc arguments
710
709
// argument: name, args, globals
711
710
// build the callargs hashmap
@@ -716,29 +715,27 @@ impl VirtualMachine {
716
715
}
717
716
// merge callargs with kw_args
718
717
let return_value = {
719
- let frame = self.make_frame(func.code, callargs, Some(locals));
718
+ let frame = self . make_frame ( func. code . clone ( ) , callargs, Some ( locals) ) ;
720
719
self . run_frame ( frame)
721
720
} ;
722
- self.curr_frame().stack.push(return_value);
721
+ self . curr_frame ( ) . stack . push ( Rc :: new ( return_value) ) ;
723
722
} ,
724
- NativeType::NativeFunction(func) => {
723
+ & NativeType :: NativeFunction ( func) => {
725
724
pos_args. reverse ( ) ;
726
725
let return_value = func ( pos_args) ;
727
- self.curr_frame().stack.push(return_value);
726
+ self . curr_frame ( ) . stack . push ( Rc :: new ( return_value) ) ;
728
727
} ,
729
728
_ => panic ! ( "The item on the stack should be a code object" )
730
729
}
731
730
} ;
732
731
None
733
732
} ,
734
- */
735
733
( "RETURN_VALUE" , None ) => {
736
734
// Hmmm... what is this used?
737
735
// I believe we need to push this to the next frame
738
736
self . curr_frame ( ) . return_value = ( * self . curr_frame ( ) . stack . pop ( ) . unwrap ( ) ) . clone ( ) ;
739
737
Some ( "return" . to_string ( ) )
740
738
} ,
741
- /*
742
739
( "SETUP_LOOP" , Some ( delta) ) => {
743
740
let curr_frame = self . curr_frame ( ) ;
744
741
let curr_offset = curr_frame. get_bytecode_offset ( ) . unwrap ( ) ;
@@ -756,7 +753,6 @@ impl VirtualMachine {
756
753
// Skip
757
754
None
758
755
} ,
759
- */
760
756
( name, _) => {
761
757
panic ! ( "Unrecongnizable op code: {}" , name) ;
762
758
}
0 commit comments