Skip to content

Commit 8f536b9

Browse files
committed
Use boxvec for frame.stack
1 parent 1ca5ca7 commit 8f536b9

File tree

5 files changed

+84
-76
lines changed

5 files changed

+84
-76
lines changed

bytecode/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -860,12 +860,14 @@ impl Instruction {
860860
ReturnValue => -1,
861861
YieldValue => 0,
862862
YieldFrom => -1,
863-
SetupAnnotation
864-
| SetupLoop
865-
| SetupFinally { .. }
866-
| EnterFinally
867-
| EndFinally
868-
| SetupExcept { .. } => 0,
863+
SetupAnnotation | SetupLoop | SetupFinally { .. } | EnterFinally | EndFinally => 0,
864+
SetupExcept { .. } => {
865+
if jump {
866+
1
867+
} else {
868+
0
869+
}
870+
}
869871
SetupWith { .. } => {
870872
if jump {
871873
0

common/src/boxvec.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,12 @@ impl<T> DoubleEndedIterator for Drain<'_, T> {
491491

492492
impl<T> ExactSizeIterator for Drain<'_, T> {}
493493

494+
impl<'a, T> Drain<'a, T> {
495+
pub fn as_slice(&self) -> &'a [T] {
496+
self.iter.as_slice()
497+
}
498+
}
499+
494500
impl<T> Drop for Drain<'_, T> {
495501
fn drop(&mut self) {
496502
// len is currently 0 so panicking while dropping will not cause a double drop.

compiler/src/compile.rs

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,11 @@ impl Compiler {
178178
posonlyarg_count: usize,
179179
arg_count: usize,
180180
kwonlyarg_count: usize,
181-
source_path: String,
182-
first_line_number: usize,
183181
obj_name: String,
184182
) {
183+
let source_path = self.source_path.clone();
184+
let first_line_number = self.get_source_line_number();
185+
185186
let table = self
186187
.symbol_table_stack
187188
.last_mut()
@@ -824,14 +825,11 @@ impl Compiler {
824825
funcflags |= bytecode::MakeFunctionFlags::KW_ONLY_DEFAULTS;
825826
}
826827

827-
let line_number = self.get_source_line_number();
828828
self.push_output(
829829
bytecode::CodeFlags::NEW_LOCALS | bytecode::CodeFlags::IS_OPTIMIZED,
830830
args.posonlyargs_count,
831831
args.args.len(),
832832
args.kwonlyargs.len(),
833-
self.source_path.clone(),
834-
line_number,
835833
name.to_owned(),
836834
);
837835

@@ -900,8 +898,9 @@ impl Compiler {
900898
// except handlers:
901899
self.switch_to_block(handler_block);
902900
// Exception is on top of stack now
903-
let mut next_handler = self.new_block();
904901
for handler in handlers {
902+
let next_handler = self.new_block();
903+
905904
// If we gave a typ,
906905
// check if this handler can handle the exception:
907906
if let Some(exc_type) = &handler.typ {
@@ -937,7 +936,7 @@ impl Compiler {
937936
self.emit(Instruction::PopException);
938937

939938
if finalbody.is_some() {
940-
self.emit(Instruction::PopBlock); // pop finally block
939+
self.emit(Instruction::PopBlock); // pop excepthandler block
941940
// We enter the finally block, without exception.
942941
self.emit(Instruction::EnterFinally);
943942
}
@@ -948,13 +947,8 @@ impl Compiler {
948947

949948
// Emit a new label for the next handler
950949
self.switch_to_block(next_handler);
951-
next_handler = self.new_block();
952950
}
953951

954-
self.emit(Instruction::Jump {
955-
target: next_handler,
956-
});
957-
self.switch_to_block(next_handler);
958952
// If code flows here, we have an unhandled exception,
959953
// raise the exception again!
960954
self.emit(Instruction::Raise {
@@ -971,7 +965,7 @@ impl Compiler {
971965
if finalbody.is_some() {
972966
self.emit(Instruction::PopBlock); // pop finally block
973967

974-
// We enter the finally block, without return / exception.
968+
// We enter the finallyhandler block, without return / exception.
975969
self.emit(Instruction::EnterFinally);
976970
}
977971

@@ -998,6 +992,9 @@ impl Compiler {
998992

999993
self.prepare_decorators(decorator_list)?;
1000994
let mut funcflags = self.enter_function(name, args)?;
995+
self.current_codeinfo()
996+
.flags
997+
.set(bytecode::CodeFlags::IS_COROUTINE, is_async);
1001998

1002999
// remember to restore self.ctx.in_loop to the original after the function is compiled
10031000
let prev_ctx = self.ctx;
@@ -1031,7 +1028,7 @@ impl Compiler {
10311028
}
10321029
}
10331030

1034-
let mut code = self.pop_code_object();
1031+
let code = self.pop_code_object();
10351032
self.current_qualified_path = old_qualified_path;
10361033
self.ctx = prev_ctx;
10371034

@@ -1081,10 +1078,6 @@ impl Compiler {
10811078
});
10821079
}
10831080

1084-
if is_async {
1085-
code.flags |= bytecode::CodeFlags::IS_COROUTINE;
1086-
}
1087-
10881081
if self.build_closure(&code) {
10891082
funcflags |= bytecode::MakeFunctionFlags::CLOSURE;
10901083
}
@@ -1221,16 +1214,7 @@ impl Compiler {
12211214
self.current_qualified_path = Some(qualified_name.clone());
12221215

12231216
self.emit(Instruction::LoadBuildClass);
1224-
let line_number = self.get_source_line_number();
1225-
self.push_output(
1226-
bytecode::CodeFlags::empty(),
1227-
0,
1228-
0,
1229-
0,
1230-
self.source_path.clone(),
1231-
line_number,
1232-
name.to_owned(),
1233-
);
1217+
self.push_output(bytecode::CodeFlags::empty(), 0, 0, 0, name.to_owned());
12341218

12351219
let (new_body, doc_str) = get_doc(body);
12361220

@@ -2175,22 +2159,24 @@ impl Compiler {
21752159
}
21762160
.to_owned();
21772161

2178-
let line_number = self.get_source_line_number();
21792162
// Create magnificent function <listcomp>:
21802163
self.push_output(
21812164
bytecode::CodeFlags::NEW_LOCALS | bytecode::CodeFlags::IS_OPTIMIZED,
21822165
1,
21832166
1,
21842167
0,
2185-
self.source_path.clone(),
2186-
line_number,
21872168
name.clone(),
21882169
);
21892170
let arg0 = self.varname(".0");
21902171

2172+
let is_genexpr = matches!(kind, ast::ComprehensionKind::GeneratorExpression { .. });
2173+
21912174
// Create empty object of proper type:
21922175
match kind {
2193-
ast::ComprehensionKind::GeneratorExpression { .. } => {}
2176+
ast::ComprehensionKind::GeneratorExpression { .. } => {
2177+
// pop the None that was passed to kickstart the generator
2178+
self.emit(Instruction::Pop);
2179+
}
21942180
ast::ComprehensionKind::List { .. } => {
21952181
self.emit(Instruction::BuildList {
21962182
size: 0,
@@ -2300,6 +2286,10 @@ impl Compiler {
23002286
self.emit(Instruction::PopBlock);
23012287
}
23022288

2289+
if is_genexpr {
2290+
self.emit_constant(ConstantData::None)
2291+
}
2292+
23032293
// Return freshly filled list:
23042294
self.emit(Instruction::ReturnValue);
23052295

compiler/src/ir.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,20 @@ impl CodeInfo {
161161
}
162162

163163
fn max_stacksize(&self) -> u32 {
164-
let mut maxdepth = 0;
164+
let mut maxdepth = 0u32;
165165
let mut stack = Vec::with_capacity(self.blocks.len());
166-
let mut startdepths = vec![0; self.blocks.len()];
166+
let mut startdepths = vec![u32::MAX; self.blocks.len()];
167+
// if it's a generator or a coroutine, it starts with something already on the stack
168+
startdepths[0] =
169+
self.flags
170+
.intersects(CodeFlags::IS_GENERATOR | CodeFlags::IS_COROUTINE) as u32;
167171
stack.push((Label(0), 0));
168172
'process_blocks: while let Some((block, blockorder)) = stack.pop() {
169173
let mut depth = startdepths[block.0 as usize];
170174
for i in &self.blocks[block.0 as usize].instructions {
171175
let instr = &i.instr;
172176
let effect = instr.stack_effect(false);
173-
let new_depth = depth + effect;
177+
let new_depth = add_ui(depth, effect);
174178
if new_depth > maxdepth {
175179
maxdepth = new_depth
176180
}
@@ -182,7 +186,7 @@ impl CodeInfo {
182186
);
183187
if let Some(&target_block) = jump_label {
184188
let effect = instr.stack_effect(true);
185-
let target_depth = depth + effect;
189+
let target_depth = add_ui(depth, effect);
186190
if target_depth > maxdepth {
187191
maxdepth = target_depth
188192
}
@@ -206,19 +210,27 @@ impl CodeInfo {
206210
let next = self.block_order[next_blockorder as usize];
207211
stackdepth_push(&mut stack, &mut startdepths, (next, next_blockorder), depth);
208212
}
209-
maxdepth as u32
213+
maxdepth
210214
}
211215
}
212216

213217
fn stackdepth_push(
214218
stack: &mut Vec<(Label, u32)>,
215-
startdepths: &mut [i32],
219+
startdepths: &mut [u32],
216220
target: (Label, u32),
217-
depth: i32,
221+
depth: u32,
218222
) {
219223
let block_depth = &mut startdepths[target.0 .0 as usize];
220-
if depth > *block_depth {
224+
if *block_depth == u32::MAX || depth > *block_depth {
221225
*block_depth = depth;
222226
stack.push(target);
223227
}
224228
}
229+
230+
fn add_ui(a: u32, b: i32) -> u32 {
231+
if b < 0 {
232+
a - b.abs() as u32
233+
} else {
234+
a + b as u32
235+
}
236+
}

0 commit comments

Comments
 (0)