Skip to content

Commit 35e8394

Browse files
committed
Apply review suggestions: lazy locals in invoke_exact_args, hoist mapping(), avoid redundant locals clone in setup_annotations
1 parent 1538fed commit 35e8394

3 files changed

Lines changed: 16 additions & 18 deletions

File tree

benches/microbenchmarks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ fn bench_rustpython_code(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenc
135135
scope
136136
.locals
137137
.as_ref()
138-
.unwrap()
138+
.expect("new_scope_with_builtins always provides locals")
139139
.as_object()
140140
.set_item("ITERATIONS", vm.new_pyobj(idx), vm)
141141
.expect("Error adding ITERATIONS local variable");

crates/vm/src/builtins/function.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,11 +628,9 @@ impl Py<PyFunction> {
628628
pub fn invoke_exact_args(&self, args: &[PyObjectRef], vm: &VirtualMachine) -> PyResult {
629629
let code = self.code.lock().clone();
630630

631-
let locals = ArgMapping::from_dict_exact(vm.ctx.new_dict());
632-
633631
let frame = Frame::new(
634632
code.clone(),
635-
Scope::new(Some(locals), self.globals.clone()),
633+
Scope::new(None, self.globals.clone()),
636634
self.builtins.clone(),
637635
self.closure.as_ref().map_or(&[], |c| c.as_slice()),
638636
Some(self.to_owned().into()),

crates/vm/src/frame.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -460,11 +460,12 @@ impl Frame {
460460
let code = &**self.code;
461461
// SAFETY: Called before generator resume; no concurrent access.
462462
let fastlocals = unsafe { self.fastlocals.borrow_mut() };
463+
let locals_map = self.locals.mapping(vm);
463464
for (i, &varname) in code.varnames.iter().enumerate() {
464465
if i >= fastlocals.len() {
465466
break;
466467
}
467-
match self.locals.mapping(vm).subscript(varname, vm) {
468+
match locals_map.subscript(varname, vm) {
468469
Ok(value) => fastlocals[i] = Some(value),
469470
Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => {}
470471
Err(e) => return Err(e),
@@ -483,12 +484,13 @@ impl Frame {
483484
let code = &**self.code;
484485
let map = &code.varnames;
485486
let j = core::cmp::min(map.len(), code.varnames.len());
487+
let locals_map = locals.mapping(vm);
486488
if !code.varnames.is_empty() {
487489
// SAFETY: Either _guard holds the state mutex (frame not executing),
488490
// or we're in a trace callback on the same thread that holds it.
489491
let fastlocals = unsafe { self.fastlocals.borrow() };
490492
for (&k, v) in zip(&map[..j], fastlocals) {
491-
match locals.mapping(vm).ass_subscript(k, v.clone(), vm) {
493+
match locals_map.ass_subscript(k, v.clone(), vm) {
492494
Ok(()) => {}
493495
Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => {}
494496
Err(e) => return Err(e),
@@ -498,7 +500,7 @@ impl Frame {
498500
if !code.cellvars.is_empty() || !code.freevars.is_empty() {
499501
for (i, &k) in code.cellvars.iter().enumerate() {
500502
let cell_value = self.get_cell_contents(i);
501-
match locals.mapping(vm).ass_subscript(k, cell_value, vm) {
503+
match locals_map.ass_subscript(k, cell_value, vm) {
502504
Ok(()) => {}
503505
Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => {}
504506
Err(e) => return Err(e),
@@ -507,7 +509,7 @@ impl Frame {
507509
if code.flags.contains(bytecode::CodeFlags::OPTIMIZED) {
508510
for (i, &k) in code.freevars.iter().enumerate() {
509511
let cell_value = self.get_cell_contents(code.cellvars.len() + i);
510-
match locals.mapping(vm).ass_subscript(k, cell_value, vm) {
512+
match locals_map.ass_subscript(k, cell_value, vm) {
511513
Ok(()) => {}
512514
Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => {}
513515
Err(e) => return Err(e),
@@ -4324,18 +4326,16 @@ impl ExecutingFrame<'_> {
43244326
#[cold]
43254327
fn setup_annotations(&mut self, vm: &VirtualMachine) -> FrameResult {
43264328
let __annotations__ = identifier!(vm, __annotations__);
4329+
let locals_obj = self.locals.as_object(vm);
43274330
// Try using locals as dict first, if not, fallback to generic method.
4328-
let has_annotations = match self.locals.into_object(vm).downcast_exact::<PyDict>(vm) {
4329-
Ok(d) => d.contains_key(__annotations__, vm),
4330-
Err(o) => {
4331-
let needle = __annotations__.as_object();
4332-
self._in(vm, needle, &o)?
4333-
}
4334-
};
4331+
let has_annotations =
4332+
if let Some(d) = locals_obj.downcast_ref_if_exact::<PyDict>(vm) {
4333+
d.contains_key(__annotations__, vm)
4334+
} else {
4335+
self._in(vm, __annotations__.as_object(), locals_obj)?
4336+
};
43354337
if !has_annotations {
4336-
self.locals
4337-
.as_object(vm)
4338-
.set_item(__annotations__, vm.ctx.new_dict().into(), vm)?;
4338+
locals_obj.set_item(__annotations__, vm.ctx.new_dict().into(), vm)?;
43394339
}
43404340
Ok(None)
43414341
}

0 commit comments

Comments
 (0)