Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4dd6592

Browse files
committed
Keep a stack of frames in the VM.
1 parent6c8584c commit4dd6592

File tree

6 files changed

+85
-51
lines changed

6 files changed

+85
-51
lines changed

‎tests/snippets/getframe.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ def test_function():
1010
x=17
1111
assertsys._getframe().f_localsisnotlocals_dict
1212
assertsys._getframe().f_locals['x']==17
13+
assertsys._getframe(1).f_locals['foo']=='bar'
14+
print(sys._getframe(1).f_locals)
1315

1416
test_function()
1517

‎vm/src/frame.rs‎

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
externcrate rustpython_parser;
22

33
useself::rustpython_parser::ast;
4+
use std::cell::RefCell;
45
use std::fmt;
5-
use std::mem;
66
use std::path::PathBuf;
77

88
usecrate::builtins;
@@ -49,10 +49,10 @@ enum BlockType {
4949
pubstructFrame{
5050
pubcode: bytecode::CodeObject,
5151
// We need 1 stack per frame
52-
stack:Vec<PyObjectRef>,// The main data frame of the stack machine
53-
blocks:Vec<Block>,// Block frames, for controlling loops and exceptions
54-
publocals:PyObjectRef,// Variables
55-
publasti:usize,// index of last instruction ran
52+
stack:RefCell<Vec<PyObjectRef>>,// The main data frame of the stack machine
53+
blocks:Vec<Block>,// Block frames, for controlling loops and exceptions
54+
publocals:PyObjectRef,// Variables
55+
publasti:usize,// index of last instruction ran
5656
}
5757

5858
// Running a frame can result in one of the below:
@@ -79,7 +79,7 @@ impl Frame {
7979

8080
Frame{
8181
code: objcode::get_value(&code),
82-
stack:vec![],
82+
stack:RefCell::new(vec![]),
8383
blocks:vec![],
8484
// save the callargs as locals
8585
// globals: locals.clone(),
@@ -88,18 +88,9 @@ impl Frame {
8888
}
8989
}
9090

91-
pubfnrun_frame_full(&mutself,vm:&mutVirtualMachine) ->PyResult{
92-
matchself.run_frame(vm)?{
93-
ExecutionResult::Return(value) =>Ok(value),
94-
_ =>panic!("Got unexpected result from function"),
95-
}
96-
}
97-
98-
pubfnrun_frame(&mutself,vm:&mutVirtualMachine) ->Result<ExecutionResult,PyObjectRef>{
91+
pubfnrun(&mutself,vm:&mutVirtualMachine) ->Result<ExecutionResult,PyObjectRef>{
9992
let filename =&self.code.source_path.to_string();
10093

101-
let prev_frame = mem::replace(&mut vm.current_frame,Some(vm.ctx.new_frame(self.clone())));
102-
10394
// This is the name of the object being run:
10495
let run_obj_name =&self.code.obj_name.to_string();
10596

@@ -148,7 +139,6 @@ impl Frame {
148139
}
149140
};
150141

151-
vm.current_frame = prev_frame;
152142
value
153143
}
154144

@@ -1082,50 +1072,51 @@ impl Frame {
10821072
fnpush_block(&mutself,typ:BlockType){
10831073
self.blocks.push(Block{
10841074
typ,
1085-
level:self.stack.len(),
1075+
level:self.stack.borrow().len(),
10861076
});
10871077
}
10881078

10891079
fnpop_block(&mutself) ->Option<Block>{
10901080
let block =self.blocks.pop()?;
1091-
self.stack.truncate(block.level);
1081+
self.stack.borrow_mut().truncate(block.level);
10921082
Some(block)
10931083
}
10941084

10951085
fncurrent_block(&self) ->Option<&Block>{
10961086
self.blocks.last()
10971087
}
10981088

1099-
pubfnpush_value(&mutself,obj:PyObjectRef){
1100-
self.stack.push(obj);
1089+
pubfnpush_value(&self,obj:PyObjectRef){
1090+
self.stack.borrow_mut().push(obj);
11011091
}
11021092

1103-
fnpop_value(&mutself) ->PyObjectRef{
1104-
self.stack.pop().unwrap()
1093+
fnpop_value(&self) ->PyObjectRef{
1094+
self.stack.borrow_mut().pop().unwrap()
11051095
}
11061096

11071097
fnpop_multiple(&mutself,count:usize) ->Vec<PyObjectRef>{
11081098
letmut objs:Vec<PyObjectRef> =Vec::new();
11091099
for _xin0..count{
1110-
objs.push(self.stack.pop().unwrap());
1100+
objs.push(self.pop_value());
11111101
}
11121102
objs.reverse();
11131103
objs
11141104
}
11151105

11161106
fnlast_value(&self) ->PyObjectRef{
1117-
self.stack.last().unwrap().clone()
1107+
self.stack.borrow().last().unwrap().clone()
11181108
}
11191109

11201110
fnnth_value(&self,depth:usize) ->PyObjectRef{
1121-
self.stack[self.stack.len() - depth -1].clone()
1111+
self.stack.borrow_mut()[self.stack.borrow().len() - depth -1].clone()
11221112
}
11231113
}
11241114

11251115
impl fmt::DebugforFrame{
11261116
fnfmt(&self,f:&mut fmt::Formatter) -> fmt::Result{
11271117
let stack_str =self
11281118
.stack
1119+
.borrow()
11291120
.iter()
11301121
.map(|elem|format!("\n > {:?}", elem))
11311122
.collect::<Vec<_>>()

‎vm/src/obj/objgenerator.rs‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
* The mythical generator.
33
*/
44

5-
use std::cell::RefCell;
6-
7-
usecrate::frame::{ExecutionResult,Frame};
5+
usecrate::frame::ExecutionResult;
86
usecrate::pyobject::{
97
PyContext,PyFuncArgs,PyObject,PyObjectPayload,PyObjectRef,PyResult,TypeProtocol,
108
};
@@ -29,11 +27,9 @@ pub fn init(context: &PyContext) {
2927
);
3028
}
3129

32-
pubfnnew_generator(vm:&mutVirtualMachine,frame:Frame) ->PyResult{
30+
pubfnnew_generator(vm:&mutVirtualMachine,frame:PyObjectRef) ->PyResult{
3331
Ok(PyObject::new(
34-
PyObjectPayload::Generator{
35-
frame:RefCell::new(frame),
36-
},
32+
PyObjectPayload::Generator{frame: frame},
3733
vm.ctx.generator_type.clone(),
3834
))
3935
}
@@ -60,9 +56,13 @@ fn generator_send(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
6056

6157
fnsend(vm:&mutVirtualMachine,gen:&PyObjectRef,value:&PyObjectRef) ->PyResult{
6258
ifletPyObjectPayload::Generator{ref frame} = gen.payload{
63-
letmut frame_mut = frame.borrow_mut();
64-
frame_mut.push_value(value.clone());
65-
match frame_mut.run_frame(vm)?{
59+
ifletPyObjectPayload::Frame{ref frame} = frame.payload{
60+
frame.push_value(value.clone());
61+
}else{
62+
panic!("Generator frame isn't a frame.");
63+
}
64+
65+
match vm.run_frame(frame.clone())?{
6666
ExecutionResult::Yield(value) =>Ok(value),
6767
ExecutionResult::Return(_value) =>{
6868
// Stop iteration!

‎vm/src/pyobject.rs‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,8 +591,13 @@ impl PyContext {
591591
)
592592
}
593593

594-
pubfnnew_frame(&self,frame:Frame) ->PyObjectRef{
595-
PyObject::new(PyObjectPayload::Frame{ frame},self.frame_type())
594+
pubfnnew_frame(&self,code:PyObjectRef,scope:PyObjectRef) ->PyObjectRef{
595+
PyObject::new(
596+
PyObjectPayload::Frame{
597+
frame:Frame::new(code, scope),
598+
},
599+
self.frame_type(),
600+
)
596601
}
597602

598603
pubfnnew_property<F:'static +Fn(&mutVirtualMachine,PyFuncArgs) ->PyResult>(
@@ -1246,7 +1251,7 @@ pub enum PyObjectPayload {
12461251
defaults:PyObjectRef,
12471252
},
12481253
Generator{
1249-
frame:RefCell<Frame>,
1254+
frame:PyObjectRef,
12501255
},
12511256
BoundMethod{
12521257
function:PyObjectRef,

‎vm/src/sysmodule.rs‎

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
usecrate::obj::objint;
12
usecrate::pyobject::{DictProtocol,PyContext,PyFuncArgs,PyObjectRef,PyResult,TypeProtocol};
23
usecrate::vm::VirtualMachine;
4+
use num_traits::ToPrimitive;
35
use std::rc::Rc;
46
use std::{env, mem};
57

@@ -13,12 +15,30 @@ fn argv(ctx: &PyContext) -> PyObjectRef {
1315
ctx.new_list(argv)
1416
}
1517

16-
fngetframe(vm:&mutVirtualMachine,_args:PyFuncArgs) ->PyResult{
17-
ifletSome(frame) =&vm.current_frame{
18-
Ok(frame.clone())
19-
}else{
20-
panic!("Current frame is undefined!")
18+
fnframe_idx(vm:&mutVirtualMachine,offset:Option<&PyObjectRef>) ->Result<usize,PyObjectRef>{
19+
ifletSome(int) = offset{
20+
ifletSome(offset) = objint::get_value(&int).to_usize(){
21+
if offset > vm.frames.len() -1{
22+
returnErr(vm.new_value_error("call stack is not deep enough".to_string()));
23+
}
24+
returnOk(offset);
25+
}
2126
}
27+
returnOk(0);
28+
}
29+
30+
fngetframe(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
31+
arg_check!(
32+
vm,
33+
args,
34+
required =[],
35+
optional =[(offset,Some(vm.ctx.int_type()))]
36+
);
37+
38+
let idx =frame_idx(vm, offset)?;
39+
let idx = vm.frames.len() - idx -1;
40+
let frame =&vm.frames[idx];
41+
Ok(frame.clone())
2242
}
2343

2444
fnsys_getrefcount(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{

‎vm/src/vm.rs‎

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ use std::sync::{Mutex, MutexGuard};
1212

1313
usecrate::builtins;
1414
usecrate::bytecode;
15-
usecrate::frame::Frame;
15+
usecrate::frame::ExecutionResult;
1616
usecrate::obj::objbool;
1717
usecrate::obj::objcode;
18+
usecrate::obj::objframe;
1819
usecrate::obj::objgenerator;
1920
usecrate::obj::objiter;
2021
usecrate::obj::objsequence;
@@ -39,7 +40,7 @@ pub struct VirtualMachine {
3940
pubsys_module:PyObjectRef,
4041
pubstdlib_inits:HashMap<String, stdlib::StdlibInitFunc>,
4142
pubctx:PyContext,
42-
pubcurrent_frame:Option<PyObjectRef>,
43+
pubframes:Vec<PyObjectRef>,
4344
pubwasm_id:Option<String>,
4445
}
4546

@@ -62,14 +63,29 @@ impl VirtualMachine {
6263
sys_module: sysmod,
6364
stdlib_inits,
6465
ctx,
65-
current_frame:None,
66+
frames:vec![],
6667
wasm_id:None,
6768
}
6869
}
6970

7071
pubfnrun_code_obj(&mutself,code:PyObjectRef,scope:PyObjectRef) ->PyResult{
71-
letmut frame =Frame::new(code, scope);
72-
frame.run_frame_full(self)
72+
let frame =self.ctx.new_frame(code, scope);
73+
self.run_frame_full(frame)
74+
}
75+
76+
pubfnrun_frame_full(&mutself,frame:PyObjectRef) ->PyResult{
77+
matchself.run_frame(frame)?{
78+
ExecutionResult::Return(value) =>Ok(value),
79+
_ =>panic!("Got unexpected result from function"),
80+
}
81+
}
82+
83+
pubfnrun_frame(&mutself,frame:PyObjectRef) ->Result<ExecutionResult,PyObjectRef>{
84+
self.frames.push(frame.clone());
85+
letmut frame = objframe::get_value(&frame);
86+
let result = frame.run(self);
87+
self.frames.pop();
88+
result
7389
}
7490

7591
/// Create a new python string object.
@@ -312,13 +328,13 @@ impl VirtualMachine {
312328
self.fill_scope_from_args(&code_object,&scope, args, defaults)?;
313329

314330
// Construct frame:
315-
letmutframe =Frame::new(code.clone(), scope);
331+
let frame =self.ctx.new_frame(code.clone(), scope);
316332

317333
// If we have a generator, create a new generator
318334
if code_object.is_generator{
319335
objgenerator::new_generator(self, frame)
320336
}else{
321-
frame.run_frame_full(self)
337+
self.run_frame_full(frame)
322338
}
323339
}
324340

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp