Skip to content

Commit c08f11a

Browse files
committed
Change FunctionOpArg to CodeFlags, stored in CodeObject
1 parent 1edf7c8 commit c08f11a

File tree

9 files changed

+82
-83
lines changed

9 files changed

+82
-83
lines changed

bytecode/src/bytecode.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,28 @@ pub struct CodeObject {
3737
/// Jump targets.
3838
pub label_map: HashMap<Label, usize>,
3939
pub locations: Vec<Location>,
40+
pub flags: CodeFlags,
4041
pub arg_names: Vec<String>, // Names of positional arguments
4142
pub varargs: Varargs, // *args or *
4243
pub kwonlyarg_names: Vec<String>,
4344
pub varkeywords: Varargs, // **kwargs or **
4445
pub source_path: String,
4546
pub first_line_number: usize,
4647
pub obj_name: String, // Name of the object that created this code object
47-
pub is_generator: bool,
4848
}
4949

5050
bitflags! {
5151
#[derive(Serialize, Deserialize)]
52-
pub struct FunctionOpArg: u8 {
52+
pub struct CodeFlags: u8 {
5353
const HAS_DEFAULTS = 0x01;
5454
const HAS_KW_ONLY_DEFAULTS = 0x02;
5555
const HAS_ANNOTATIONS = 0x04;
5656
const NEW_LOCALS = 0x08;
57+
const IS_GENERATOR = 0x10;
5758
}
5859
}
5960

60-
impl Default for FunctionOpArg {
61+
impl Default for CodeFlags {
6162
fn default() -> Self {
6263
Self::NEW_LOCALS
6364
}
@@ -176,9 +177,7 @@ pub enum Instruction {
176177
JumpIfFalseOrPop {
177178
target: Label,
178179
},
179-
MakeFunction {
180-
flags: FunctionOpArg,
181-
},
180+
MakeFunction,
182181
CallFunction {
183182
typ: CallType,
184183
},
@@ -355,6 +354,7 @@ pub enum BlockType {
355354

356355
impl CodeObject {
357356
pub fn new(
357+
flags: CodeFlags,
358358
arg_names: Vec<String>,
359359
varargs: Varargs,
360360
kwonlyarg_names: Vec<String>,
@@ -367,14 +367,14 @@ impl CodeObject {
367367
instructions: Vec::new(),
368368
label_map: HashMap::new(),
369369
locations: Vec::new(),
370+
flags,
370371
arg_names,
371372
varargs,
372373
kwonlyarg_names,
373374
varkeywords,
374375
source_path,
375376
first_line_number,
376377
obj_name,
377-
is_generator: false,
378378
}
379379
}
380380

@@ -513,7 +513,7 @@ impl Instruction {
513513
JumpIfFalse { target } => w!(JumpIfFalse, label_map[target]),
514514
JumpIfTrueOrPop { target } => w!(JumpIfTrueOrPop, label_map[target]),
515515
JumpIfFalseOrPop { target } => w!(JumpIfFalseOrPop, label_map[target]),
516-
MakeFunction { flags } => w!(MakeFunction, format!("{:?}", flags)),
516+
MakeFunction => w!(MakeFunction),
517517
CallFunction { typ } => w!(CallFunction, format!("{:?}", typ)),
518518
ForIter { target } => w!(ForIter, label_map[target]),
519519
ReturnValue => w!(ReturnValue),

compiler/src/compile.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ impl<O: OutputStream> Compiler<O> {
137137
fn push_new_code_object(&mut self, obj_name: String) {
138138
let line_number = self.get_source_line_number();
139139
self.push_output(CodeObject::new(
140+
Default::default(),
140141
Vec::new(),
141142
Varargs::None,
142143
Vec::new(),
@@ -595,11 +596,7 @@ impl<O: OutputStream> Compiler<O> {
595596
Ok(())
596597
}
597598

598-
fn enter_function(
599-
&mut self,
600-
name: &str,
601-
args: &ast::Parameters,
602-
) -> Result<bytecode::FunctionOpArg, CompileError> {
599+
fn enter_function(&mut self, name: &str, args: &ast::Parameters) -> Result<(), CompileError> {
603600
let have_defaults = !args.defaults.is_empty();
604601
if have_defaults {
605602
// Construct a tuple:
@@ -633,8 +630,17 @@ impl<O: OutputStream> Compiler<O> {
633630
});
634631
}
635632

633+
let mut flags = bytecode::CodeFlags::default();
634+
if have_defaults {
635+
flags |= bytecode::CodeFlags::HAS_DEFAULTS;
636+
}
637+
if num_kw_only_defaults > 0 {
638+
flags |= bytecode::CodeFlags::HAS_KW_ONLY_DEFAULTS;
639+
}
640+
636641
let line_number = self.get_source_line_number();
637642
self.push_output(CodeObject::new(
643+
flags,
638644
args.args.iter().map(|a| a.arg.clone()).collect(),
639645
compile_varargs(&args.vararg),
640646
args.kwonlyargs.iter().map(|a| a.arg.clone()).collect(),
@@ -645,15 +651,7 @@ impl<O: OutputStream> Compiler<O> {
645651
));
646652
self.enter_scope();
647653

648-
let mut flags = bytecode::FunctionOpArg::default();
649-
if have_defaults {
650-
flags |= bytecode::FunctionOpArg::HAS_DEFAULTS;
651-
}
652-
if num_kw_only_defaults > 0 {
653-
flags |= bytecode::FunctionOpArg::HAS_KW_ONLY_DEFAULTS;
654-
}
655-
656-
Ok(flags)
654+
Ok(())
657655
}
658656

659657
fn prepare_decorators(
@@ -813,7 +811,7 @@ impl<O: OutputStream> Compiler<O> {
813811

814812
self.prepare_decorators(decorator_list)?;
815813

816-
let mut flags = self.enter_function(name, args)?;
814+
self.enter_function(name, args)?;
817815

818816
let (body, doc_str) = get_doc(body);
819817

@@ -832,7 +830,7 @@ impl<O: OutputStream> Compiler<O> {
832830
}
833831
}
834832

835-
let code = self.pop_code_object();
833+
let mut code = self.pop_code_object();
836834
self.leave_scope();
837835

838836
// Prepare type annotations:
@@ -864,7 +862,7 @@ impl<O: OutputStream> Compiler<O> {
864862
}
865863

866864
if num_annotations > 0 {
867-
flags |= bytecode::FunctionOpArg::HAS_ANNOTATIONS;
865+
code.flags |= bytecode::CodeFlags::HAS_ANNOTATIONS;
868866
self.emit(Instruction::BuildMap {
869867
size: num_annotations,
870868
unpack: false,
@@ -884,7 +882,7 @@ impl<O: OutputStream> Compiler<O> {
884882
});
885883

886884
// Turn code object into function object:
887-
self.emit(Instruction::MakeFunction { flags });
885+
self.emit(Instruction::MakeFunction);
888886
self.store_docstring(doc_str);
889887
self.apply_decorators(decorator_list);
890888

@@ -915,6 +913,7 @@ impl<O: OutputStream> Compiler<O> {
915913
self.emit(Instruction::LoadBuildClass);
916914
let line_number = self.get_source_line_number();
917915
self.push_output(CodeObject::new(
916+
Default::default(),
918917
vec![],
919918
Varargs::None,
920919
vec![],
@@ -950,7 +949,8 @@ impl<O: OutputStream> Compiler<O> {
950949
});
951950
self.emit(Instruction::ReturnValue);
952951

953-
let code = self.pop_code_object();
952+
let mut code = self.pop_code_object();
953+
code.flags &= !bytecode::CodeFlags::NEW_LOCALS;
954954
self.leave_scope();
955955

956956
self.emit(Instruction::LoadConst {
@@ -965,9 +965,7 @@ impl<O: OutputStream> Compiler<O> {
965965
});
966966

967967
// Turn code object into function object:
968-
self.emit(Instruction::MakeFunction {
969-
flags: bytecode::FunctionOpArg::default() & !bytecode::FunctionOpArg::NEW_LOCALS,
970-
});
968+
self.emit(Instruction::MakeFunction);
971969

972970
self.emit(Instruction::LoadConst {
973971
value: bytecode::Constant::String {
@@ -1615,7 +1613,7 @@ impl<O: OutputStream> Compiler<O> {
16151613
Lambda { args, body } => {
16161614
let name = "<lambda>".to_string();
16171615
// no need to worry about the self.loop_depth because there are no loops in lambda expressions
1618-
let flags = self.enter_function(&name, args)?;
1616+
self.enter_function(&name, args)?;
16191617
self.compile_expression(body)?;
16201618
self.emit(Instruction::ReturnValue);
16211619
let code = self.pop_code_object();
@@ -1629,7 +1627,7 @@ impl<O: OutputStream> Compiler<O> {
16291627
value: bytecode::Constant::String { value: name },
16301628
});
16311629
// Turn code object into function object:
1632-
self.emit(Instruction::MakeFunction { flags });
1630+
self.emit(Instruction::MakeFunction);
16331631
}
16341632
Comprehension { kind, generators } => {
16351633
self.compile_comprehension(kind, generators)?;
@@ -1810,6 +1808,7 @@ impl<O: OutputStream> Compiler<O> {
18101808
let line_number = self.get_source_line_number();
18111809
// Create magnificent function <listcomp>:
18121810
self.push_output(CodeObject::new(
1811+
Default::default(),
18131812
vec![".0".to_string()],
18141813
Varargs::None,
18151814
vec![],
@@ -1945,9 +1944,7 @@ impl<O: OutputStream> Compiler<O> {
19451944
});
19461945

19471946
// Turn code object into function object:
1948-
self.emit(Instruction::MakeFunction {
1949-
flags: bytecode::FunctionOpArg::default(),
1950-
});
1947+
self.emit(Instruction::MakeFunction);
19511948

19521949
// Evaluate iterated item:
19531950
self.compile_expression(&generators[0].iter)?;

compiler/src/output_stream.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustpython_bytecode::bytecode::{CodeObject, Instruction, Label, Location};
1+
use rustpython_bytecode::bytecode::{CodeFlags, CodeObject, Instruction, Label, Location};
22

33
pub trait OutputStream: From<CodeObject> + Into<CodeObject> {
44
/// Output an instruction
@@ -34,6 +34,6 @@ impl OutputStream for CodeObjectStream {
3434
self.code.label_map.insert(label, position);
3535
}
3636
fn mark_generator(&mut self) {
37-
self.code.is_generator = true;
37+
self.code.flags |= CodeFlags::IS_GENERATOR;
3838
}
3939
}

vm/src/frame.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,18 @@ enum UnwindReason {
7979
Continue,
8080
}
8181

82+
#[pyclass]
8283
pub struct Frame {
83-
pub code: bytecode::CodeObject,
84+
pub code: PyCodeRef,
8485
// We need 1 stack per frame
85-
stack: RefCell<Vec<PyObjectRef>>, // The main data frame of the stack machine
86-
blocks: RefCell<Vec<Block>>, // Block frames, for controlling loops and exceptions
87-
pub scope: Scope, // Variables
88-
pub lasti: RefCell<usize>, // index of last instruction ran
86+
/// The main data frame of the stack machine
87+
stack: RefCell<Vec<PyObjectRef>>,
88+
/// Block frames, for controlling loops and exceptions
89+
blocks: RefCell<Vec<Block>>,
90+
/// Variables
91+
pub scope: Scope,
92+
/// index of last instruction ran
93+
pub lasti: RefCell<usize>,
8994
}
9095

9196
impl PyValue for Frame {
@@ -117,7 +122,7 @@ impl Frame {
117122
// locals.extend(callargs);
118123

119124
Frame {
120-
code: code.code.clone(),
125+
code,
121126
stack: RefCell::new(vec![]),
122127
blocks: RefCell::new(vec![]),
123128
// save the callargs as locals
@@ -400,7 +405,7 @@ impl Frame {
400405
Ok(None)
401406
}
402407
bytecode::Instruction::ForIter { target } => self.execute_for_iter(vm, *target),
403-
bytecode::Instruction::MakeFunction { flags } => self.execute_make_function(vm, *flags),
408+
bytecode::Instruction::MakeFunction => self.execute_make_function(vm),
404409
bytecode::Instruction::CallFunction { typ } => self.execute_call_function(vm, typ),
405410
bytecode::Instruction::Jump { target } => {
406411
self.jump(*target);
@@ -1030,27 +1035,25 @@ impl Frame {
10301035
}
10311036
}
10321037
}
1033-
fn execute_make_function(
1034-
&self,
1035-
vm: &VirtualMachine,
1036-
flags: bytecode::FunctionOpArg,
1037-
) -> FrameResult {
1038+
fn execute_make_function(&self, vm: &VirtualMachine) -> FrameResult {
10381039
let qualified_name = self
10391040
.pop_value()
10401041
.downcast::<PyString>()
10411042
.expect("qualified name to be a string");
1042-
let code_obj = self
1043+
let code_obj: PyCodeRef = self
10431044
.pop_value()
10441045
.downcast()
10451046
.expect("Second to top value on the stack must be a code object");
10461047

1047-
let annotations = if flags.contains(bytecode::FunctionOpArg::HAS_ANNOTATIONS) {
1048+
let flags = code_obj.flags;
1049+
1050+
let annotations = if flags.contains(bytecode::CodeFlags::HAS_ANNOTATIONS) {
10481051
self.pop_value()
10491052
} else {
10501053
vm.ctx.new_dict().into_object()
10511054
};
10521055

1053-
let kw_only_defaults = if flags.contains(bytecode::FunctionOpArg::HAS_KW_ONLY_DEFAULTS) {
1056+
let kw_only_defaults = if flags.contains(bytecode::CodeFlags::HAS_KW_ONLY_DEFAULTS) {
10541057
Some(
10551058
self.pop_value()
10561059
.downcast::<PyDict>()
@@ -1060,7 +1063,7 @@ impl Frame {
10601063
None
10611064
};
10621065

1063-
let defaults = if flags.contains(bytecode::FunctionOpArg::HAS_DEFAULTS) {
1066+
let defaults = if flags.contains(bytecode::CodeFlags::HAS_DEFAULTS) {
10641067
Some(
10651068
self.pop_value()
10661069
.downcast::<PyTuple>()
@@ -1073,13 +1076,9 @@ impl Frame {
10731076
// pop argc arguments
10741077
// argument: name, args, globals
10751078
let scope = self.scope.clone();
1076-
let func_obj = vm.ctx.new_function(
1077-
code_obj,
1078-
scope,
1079-
defaults,
1080-
kw_only_defaults,
1081-
flags.contains(bytecode::FunctionOpArg::NEW_LOCALS),
1082-
);
1079+
let func_obj = vm
1080+
.ctx
1081+
.new_function(code_obj, scope, defaults, kw_only_defaults);
10831082

10841083
let name = qualified_name.as_str().split('.').next_back().unwrap();
10851084
vm.set_attr(&func_obj, "__name__", vm.new_str(name.to_string()))?;

vm/src/obj/objcode.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
use std::fmt;
6+
use std::ops::Deref;
67

78
use super::objtype::PyClassRef;
89
use crate::bytecode;
@@ -15,6 +16,13 @@ pub struct PyCode {
1516
pub code: bytecode::CodeObject,
1617
}
1718

19+
impl Deref for PyCode {
20+
type Target = bytecode::CodeObject;
21+
fn deref(&self) -> &Self::Target {
22+
&self.code
23+
}
24+
}
25+
1826
impl PyCode {
1927
pub fn new(code: bytecode::CodeObject) -> PyCode {
2028
PyCode { code }

0 commit comments

Comments
 (0)