Skip to content

Commit 0b58527

Browse files
authored
Merge pull request RustPython#2373 from RustPython/coolreader18/blockir
Have a block-based IR for compiling, calculate max stack size
2 parents 1c12a80 + 559123c commit 0b58527

File tree

13 files changed

+1394
-411
lines changed

13 files changed

+1394
-411
lines changed

bytecode/src/lib.rs

Lines changed: 116 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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
@@ -377,6 +378,7 @@ pub enum Instruction {
377378
},
378379
GetAIter,
379380
GetANext,
381+
EndAsyncFor,
380382

381383
/// Reverse order evaluation in MapAdd
382384
/// required to support named expressions of Python 3.8 in dict comprehension
@@ -556,34 +558,6 @@ impl<N: AsRef<str>> fmt::Debug for Arguments<'_, N> {
556558
}
557559

558560
impl<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-
587561
// like inspect.getargs
588562
pub fn arg_names(&self) -> Arguments<C::Name> {
589563
let nargs = self.arg_count;
@@ -696,6 +670,7 @@ impl<C: Constant> CodeObject<C> {
696670
arg_count: self.arg_count,
697671
kwonlyarg_count: self.kwonlyarg_count,
698672
first_line_number: self.first_line_number,
673+
max_stacksize: self.max_stacksize,
699674
cell2arg: self.cell2arg,
700675
}
701676
}
@@ -727,6 +702,7 @@ impl<C: Constant> CodeObject<C> {
727702
arg_count: self.arg_count,
728703
kwonlyarg_count: self.kwonlyarg_count,
729704
first_line_number: self.first_line_number,
705+
max_stacksize: self.max_stacksize,
730706
cell2arg: self.cell2arg.clone(),
731707
}
732708
}
@@ -802,7 +778,7 @@ impl Instruction {
802778
| SetupExcept { handler: l }
803779
| SetupWith { end: l }
804780
| SetupAsyncWith { end: l }
805-
| SetupLoop { end: l }
781+
| Break { target: l }
806782
| Continue { target: l } => Some(l),
807783
_ => None,
808784
}
@@ -822,12 +798,115 @@ impl Instruction {
822798
| SetupExcept { handler: l }
823799
| SetupWith { end: l }
824800
| SetupAsyncWith { end: l }
825-
| SetupLoop { end: l }
801+
| Break { target: l }
826802
| Continue { target: l } => Some(l),
827803
_ => None,
828804
}
829805
}
830806

807+
pub fn unconditional_branch(&self) -> bool {
808+
matches!(self, Jump { .. } | Continue{ .. } | Break { .. } | ReturnValue | Raise { .. })
809+
}
810+
811+
pub fn stack_effect(&self, jump: bool) -> i32 {
812+
match self {
813+
ImportName { .. } | ImportNameless => -1,
814+
ImportStar => -1,
815+
ImportFrom { .. } => 1,
816+
LoadFast(_) | LoadNameAny(_) | LoadGlobal(_) | LoadDeref(_) | LoadClassDeref(_) => 1,
817+
StoreFast(_) | StoreLocal(_) | StoreGlobal(_) | StoreDeref(_) => -1,
818+
DeleteFast(_) | DeleteLocal(_) | DeleteGlobal(_) | DeleteDeref(_) => 0,
819+
LoadClosure(_) => 1,
820+
Subscript => -1,
821+
StoreSubscript => -3,
822+
DeleteSubscript => -2,
823+
LoadAttr { .. } => 0,
824+
StoreAttr { .. } => -2,
825+
DeleteAttr { .. } => -1,
826+
LoadConst { .. } => 1,
827+
UnaryOperation { .. } => 0,
828+
BinaryOperation { .. } | BinaryOperationInplace { .. } | CompareOperation { .. } => -1,
829+
Pop => -1,
830+
Rotate { .. } => 0,
831+
Duplicate => 1,
832+
GetIter => 0,
833+
Continue { .. } => 0,
834+
Break { .. } => 0,
835+
Jump { .. } => 0,
836+
JumpIfTrue { .. } | JumpIfFalse { .. } => -1,
837+
JumpIfTrueOrPop { .. } | JumpIfFalseOrPop { .. } => {
838+
if jump {
839+
0
840+
} else {
841+
-1
842+
}
843+
}
844+
MakeFunction(flags) => {
845+
-2 - flags.contains(MakeFunctionFlags::CLOSURE) as i32
846+
- flags.contains(MakeFunctionFlags::ANNOTATIONS) as i32
847+
- flags.contains(MakeFunctionFlags::KW_ONLY_DEFAULTS) as i32
848+
- flags.contains(MakeFunctionFlags::DEFAULTS) as i32
849+
+ 1
850+
}
851+
CallFunctionPositional { nargs } => -1 - (*nargs as i32) + 1,
852+
CallFunctionKeyword { nargs } => -2 - (*nargs as i32) + 1,
853+
CallFunctionEx { has_kwargs } => -2 - *has_kwargs as i32 + 1,
854+
ForIter { .. } => {
855+
if jump {
856+
-1
857+
} else {
858+
1
859+
}
860+
}
861+
ReturnValue => -1,
862+
YieldValue => 0,
863+
YieldFrom => -1,
864+
SetupAnnotation | SetupLoop | SetupFinally { .. } | EnterFinally | EndFinally => 0,
865+
SetupExcept { .. } => {
866+
if jump {
867+
1
868+
} else {
869+
0
870+
}
871+
}
872+
SetupWith { .. } => {
873+
if jump {
874+
0
875+
} else {
876+
1
877+
}
878+
}
879+
WithCleanupStart => 0,
880+
WithCleanupFinish => -1,
881+
PopBlock => 0,
882+
Raise { kind } => -(*kind as u8 as i32),
883+
BuildString { size }
884+
| BuildTuple { size, .. }
885+
| BuildList { size, .. }
886+
| BuildSet { size, .. } => -(*size as i32) + 1,
887+
BuildMap { unpack, size, .. } => {
888+
let nargs = if *unpack { *size } else { *size * 2 };
889+
-(nargs as i32) + 1
890+
}
891+
BuildSlice { step } => -2 - (*step as i32) + 1,
892+
ListAppend { .. } | SetAdd { .. } => -1,
893+
MapAdd { .. } | MapAddRev { .. } => -2,
894+
PrintExpr => -1,
895+
LoadBuildClass => 1,
896+
UnpackSequence { size } => -1 + *size as i32,
897+
UnpackEx { before, after } => -1 + *before as i32 + 1 + *after as i32,
898+
FormatValue { .. } => -1,
899+
PopException => 0,
900+
Reverse { .. } => 0,
901+
GetAwaitable => 0,
902+
BeforeAsyncWith => 1,
903+
SetupAsyncWith { .. } => 0,
904+
GetAIter => 0,
905+
GetANext => 1,
906+
EndAsyncFor => -1,
907+
}
908+
}
909+
831910
#[allow(clippy::too_many_arguments)]
832911
fn fmt_dis<C: Constant>(
833912
&self,
@@ -922,7 +1001,7 @@ impl Instruction {
9221001
Duplicate => w!(Duplicate),
9231002
GetIter => w!(GetIter),
9241003
Continue { target } => w!(Continue, target),
925-
Break => w!(Break),
1004+
Break { target } => w!(Break, target),
9261005
Jump { target } => w!(Jump, target),
9271006
JumpIfTrue { target } => w!(JumpIfTrue, target),
9281007
JumpIfFalse { target } => w!(JumpIfFalse, target),
@@ -937,7 +1016,7 @@ impl Instruction {
9371016
YieldValue => w!(YieldValue),
9381017
YieldFrom => w!(YieldFrom),
9391018
SetupAnnotation => w!(SetupAnnotation),
940-
SetupLoop { end } => w!(SetupLoop, end),
1019+
SetupLoop => w!(SetupLoop),
9411020
SetupExcept { handler } => w!(SetupExcept, handler),
9421021
SetupFinally { handler } => w!(SetupFinally, handler),
9431022
EnterFinally => w!(EnterFinally),
@@ -972,6 +1051,7 @@ impl Instruction {
9721051
GetAwaitable => w!(GetAwaitable),
9731052
GetAIter => w!(GetAIter),
9741053
GetANext => w!(GetANext),
1054+
EndAsyncFor => w!(EndAsyncFor),
9751055
MapAdd { i } => w!(MapAdd, i),
9761056
}
9771057
}

0 commit comments

Comments
 (0)