@@ -113,6 +113,7 @@ pub struct CodeObject<C: Constant = ConstantData> {
113113 pub kwonlyarg_count : usize ,
114114 pub source_path : C :: Name ,
115115 pub first_line_number : usize ,
116+ pub max_stacksize : u32 ,
116117 pub obj_name : C :: Name , // Name of the object that created this code object
117118 pub cell2arg : Option < Box < [ isize ] > > ,
118119 pub constants : Box < [ C ] > ,
@@ -246,7 +247,9 @@ pub enum Instruction {
246247 Continue {
247248 target : Label ,
248249 } ,
249- Break ,
250+ Break {
251+ target : Label ,
252+ } ,
250253 Jump {
251254 target : Label ,
252255 } ,
@@ -285,9 +288,7 @@ pub enum Instruction {
285288 YieldValue ,
286289 YieldFrom ,
287290 SetupAnnotation ,
288- SetupLoop {
289- end : Label ,
290- } ,
291+ SetupLoop ,
291292
292293 /// Setup a finally handler, which will be called whenever one of this events occurs:
293294 /// - the block is popped
@@ -556,34 +557,6 @@ impl<N: AsRef<str>> fmt::Debug for Arguments<'_, N> {
556557}
557558
558559impl < C : Constant > CodeObject < C > {
559- pub fn new (
560- flags : CodeFlags ,
561- posonlyarg_count : usize ,
562- arg_count : usize ,
563- kwonlyarg_count : usize ,
564- source_path : C :: Name ,
565- first_line_number : usize ,
566- obj_name : C :: Name ,
567- ) -> Self {
568- CodeObject {
569- instructions : Box :: new ( [ ] ) ,
570- locations : Box :: new ( [ ] ) ,
571- flags,
572- posonlyarg_count,
573- arg_count,
574- kwonlyarg_count,
575- source_path,
576- first_line_number,
577- obj_name,
578- cell2arg : None ,
579- constants : Box :: new ( [ ] ) ,
580- names : Box :: new ( [ ] ) ,
581- varnames : Box :: new ( [ ] ) ,
582- cellvars : Box :: new ( [ ] ) ,
583- freevars : Box :: new ( [ ] ) ,
584- }
585- }
586-
587560 // like inspect.getargs
588561 pub fn arg_names ( & self ) -> Arguments < C :: Name > {
589562 let nargs = self . arg_count ;
@@ -696,6 +669,7 @@ impl<C: Constant> CodeObject<C> {
696669 arg_count : self . arg_count ,
697670 kwonlyarg_count : self . kwonlyarg_count ,
698671 first_line_number : self . first_line_number ,
672+ max_stacksize : self . max_stacksize ,
699673 cell2arg : self . cell2arg ,
700674 }
701675 }
@@ -727,6 +701,7 @@ impl<C: Constant> CodeObject<C> {
727701 arg_count : self . arg_count ,
728702 kwonlyarg_count : self . kwonlyarg_count ,
729703 first_line_number : self . first_line_number ,
704+ max_stacksize : self . max_stacksize ,
730705 cell2arg : self . cell2arg . clone ( ) ,
731706 }
732707 }
@@ -802,7 +777,7 @@ impl Instruction {
802777 | SetupExcept { handler : l }
803778 | SetupWith { end : l }
804779 | SetupAsyncWith { end : l }
805- | SetupLoop { end : l }
780+ | Break { target : l }
806781 | Continue { target : l } => Some ( l) ,
807782 _ => None ,
808783 }
@@ -822,12 +797,112 @@ impl Instruction {
822797 | SetupExcept { handler : l }
823798 | SetupWith { end : l }
824799 | SetupAsyncWith { end : l }
825- | SetupLoop { end : l }
800+ | Break { target : l }
826801 | Continue { target : l } => Some ( l) ,
827802 _ => None ,
828803 }
829804 }
830805
806+ pub fn unconditional_branch ( & self ) -> bool {
807+ matches ! ( self , Jump { .. } | Continue { .. } | Break { .. } | ReturnValue | Raise { .. } )
808+ }
809+
810+ pub fn stack_effect ( & self , jump : bool ) -> i32 {
811+ match self {
812+ ImportName { .. } | ImportNameless => -1 ,
813+ ImportStar => -1 ,
814+ ImportFrom { .. } => 1 ,
815+ LoadFast ( _) | LoadNameAny ( _) | LoadGlobal ( _) | LoadDeref ( _) | LoadClassDeref ( _) => 1 ,
816+ StoreFast ( _) | StoreLocal ( _) | StoreGlobal ( _) | StoreDeref ( _) => -1 ,
817+ DeleteFast ( _) | DeleteLocal ( _) | DeleteGlobal ( _) | DeleteDeref ( _) => 0 ,
818+ LoadClosure ( _) => 1 ,
819+ Subscript => -1 ,
820+ StoreSubscript => -3 ,
821+ DeleteSubscript => -2 ,
822+ LoadAttr { .. } => 0 ,
823+ StoreAttr { .. } => -2 ,
824+ DeleteAttr { .. } => -1 ,
825+ LoadConst { .. } => 1 ,
826+ UnaryOperation { .. } => 0 ,
827+ BinaryOperation { .. } | BinaryOperationInplace { .. } | CompareOperation { .. } => -1 ,
828+ Pop => -1 ,
829+ Rotate { .. } => 0 ,
830+ Duplicate => 1 ,
831+ GetIter => 0 ,
832+ Continue { .. } => 0 ,
833+ Break { .. } => 0 ,
834+ Jump { .. } => 0 ,
835+ JumpIfTrue { .. } | JumpIfFalse { .. } => -1 ,
836+ JumpIfTrueOrPop { .. } | JumpIfFalseOrPop { .. } => {
837+ if jump {
838+ 0
839+ } else {
840+ -1
841+ }
842+ }
843+ MakeFunction ( flags) => {
844+ -2 - flags. contains ( MakeFunctionFlags :: CLOSURE ) as i32
845+ - flags. contains ( MakeFunctionFlags :: ANNOTATIONS ) as i32
846+ - flags. contains ( MakeFunctionFlags :: KW_ONLY_DEFAULTS ) as i32
847+ - flags. contains ( MakeFunctionFlags :: DEFAULTS ) as i32
848+ + 1
849+ }
850+ CallFunctionPositional { nargs } => -1 - ( * nargs as i32 ) + 1 ,
851+ CallFunctionKeyword { nargs } => -2 - ( * nargs as i32 ) + 1 ,
852+ CallFunctionEx { has_kwargs } => -2 - * has_kwargs as i32 + 1 ,
853+ ForIter { .. } => {
854+ if jump {
855+ -1
856+ } else {
857+ 1
858+ }
859+ }
860+ ReturnValue => -1 ,
861+ YieldValue => 0 ,
862+ YieldFrom => -1 ,
863+ SetupAnnotation
864+ | SetupLoop
865+ | SetupFinally { .. }
866+ | EnterFinally
867+ | EndFinally
868+ | SetupExcept { .. } => 0 ,
869+ SetupWith { .. } => {
870+ if jump {
871+ 0
872+ } else {
873+ 1
874+ }
875+ }
876+ WithCleanupStart => 0 ,
877+ WithCleanupFinish => -1 ,
878+ PopBlock => 0 ,
879+ Raise { kind } => -( * kind as u8 as i32 ) ,
880+ BuildString { size }
881+ | BuildTuple { size, .. }
882+ | BuildList { size, .. }
883+ | BuildSet { size, .. } => -( * size as i32 ) + 1 ,
884+ BuildMap { unpack, size, .. } => {
885+ let nargs = if * unpack { * size } else { * size * 2 } ;
886+ -( nargs as i32 ) + 1
887+ }
888+ BuildSlice { step } => -2 - ( * step as i32 ) + 1 ,
889+ ListAppend { .. } | SetAdd { .. } => -1 ,
890+ MapAdd { .. } | MapAddRev { .. } => -2 ,
891+ PrintExpr => -1 ,
892+ LoadBuildClass => 1 ,
893+ UnpackSequence { size } => -1 + * size as i32 ,
894+ UnpackEx { before, after } => -1 + * before as i32 + 1 + * after as i32 ,
895+ FormatValue { .. } => -1 ,
896+ PopException => 0 ,
897+ Reverse { .. } => 0 ,
898+ GetAwaitable => 0 ,
899+ BeforeAsyncWith => 1 ,
900+ SetupAsyncWith { .. } => 0 ,
901+ GetAIter => 0 ,
902+ GetANext => 1 ,
903+ }
904+ }
905+
831906 #[ allow( clippy:: too_many_arguments) ]
832907 fn fmt_dis < C : Constant > (
833908 & self ,
@@ -922,7 +997,7 @@ impl Instruction {
922997 Duplicate => w ! ( Duplicate ) ,
923998 GetIter => w ! ( GetIter ) ,
924999 Continue { target } => w ! ( Continue , target) ,
925- Break => w ! ( Break ) ,
1000+ Break { target } => w ! ( Break , target ) ,
9261001 Jump { target } => w ! ( Jump , target) ,
9271002 JumpIfTrue { target } => w ! ( JumpIfTrue , target) ,
9281003 JumpIfFalse { target } => w ! ( JumpIfFalse , target) ,
@@ -937,7 +1012,7 @@ impl Instruction {
9371012 YieldValue => w ! ( YieldValue ) ,
9381013 YieldFrom => w ! ( YieldFrom ) ,
9391014 SetupAnnotation => w ! ( SetupAnnotation ) ,
940- SetupLoop { end } => w ! ( SetupLoop , end ) ,
1015+ SetupLoop => w ! ( SetupLoop ) ,
9411016 SetupExcept { handler } => w ! ( SetupExcept , handler) ,
9421017 SetupFinally { handler } => w ! ( SetupFinally , handler) ,
9431018 EnterFinally => w ! ( EnterFinally ) ,
0 commit comments