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

Commitee86229

Browse files
committed
Keep a stack of frames on the VM.
1 parent96c1c5a commitee86229

File tree

5 files changed

+63
-31
lines changed

5 files changed

+63
-31
lines changed

‎tests/snippets/getframe.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
deftest_function():
1010
x=17
1111
assertsys._getframe().f_localsisnotlocals_dict
12-
assertsys._getframe().f_locals['x']==17
12+
assertsys._getframe(0).f_locals['x']==17
13+
assertsys._getframe(1).f_locals['foo']=='bar'
1314

1415
test_function()
1516

@@ -18,3 +19,8 @@ def __init__(self):
1819
assertsys._getframe().f_locals['self']==self
1920

2021
TestClass()
22+
23+
try:
24+
sys._getframe(100)
25+
exceptValueError:
26+
pass

‎vm/src/frame.rs‎

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ extern crate rustpython_parser;
33
useself::rustpython_parser::ast;
44
use std::collections::hash_map::HashMap;
55
use std::fmt;
6-
use std::mem;
76
use std::path::PathBuf;
87

98
usesuper::builtins;
@@ -82,22 +81,13 @@ impl Frame {
8281
}
8382
}
8483

85-
pubfnrun_frame_full(&mutself,vm:&mutVirtualMachine) ->PyResult{
86-
matchself.run_frame(vm)?{
87-
ExecutionResult::Return(value) =>Ok(value),
88-
_ =>panic!("Got unexpected result from function"),
89-
}
90-
}
91-
92-
pubfnrun_frame(&mutself,vm:&mutVirtualMachine) ->Result<ExecutionResult,PyObjectRef>{
84+
pubfnrun(&mutself,vm:&mutVirtualMachine) ->Result<ExecutionResult,PyObjectRef>{
9385
let filename =ifletSome(source_path) =&self.code.source_path{
9486
source_path.to_string()
9587
}else{
9688
"<unknown>".to_string()
9789
};
9890

99-
let prev_frame = mem::replace(&mut vm.current_frame,Some(vm.ctx.new_frame(self.clone())));
100-
10191
// This is the name of the object being run:
10292
let run_obj_name =&self.code.obj_name.to_string();
10393

@@ -146,7 +136,6 @@ impl Frame {
146136
}
147137
};
148138

149-
vm.current_frame = prev_frame;
150139
value
151140
}
152141

‎vm/src/obj/objgenerator.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn generator_send(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
4848
fnsend(vm:&mutVirtualMachine,gen:&PyObjectRef,value:&PyObjectRef) ->PyResult{
4949
ifletPyObjectKind::Generator{refmut frame} = gen.borrow_mut().kind{
5050
frame.push_value(value.clone());
51-
matchframe.run_frame(vm)?{
51+
matchvm.run_frame(frame.clone())?{
5252
ExecutionResult::Yield(value) =>Ok(value),
5353
ExecutionResult::Return(_value) =>{
5454
// Stop iteration!

‎vm/src/sysmodule.rs‎

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
usesuper::obj::objint;
2+
usesuper::obj::objtype;
3+
usesuper::pyobject::{DictProtocol,PyContext,PyFuncArgs,PyObjectRef,PyResult,TypeProtocol};
4+
usesuper::vm::VirtualMachine;
15
use num_bigint::ToBigInt;
2-
useobj::objtype;
3-
usepyobject::{DictProtocol,PyContext,PyFuncArgs,PyObjectRef,PyResult,TypeProtocol};
6+
usenum_traits::ToPrimitive;
7+
usestd::env;
48
use std::rc::Rc;
5-
use std::{env, mem};
6-
use vm::VirtualMachine;
79

810
/*
911
* The magic sys module.
@@ -15,12 +17,31 @@ fn argv(ctx: &PyContext) -> PyObjectRef {
1517
ctx.new_list(argv)
1618
}
1719

18-
fngetframe(vm:&mutVirtualMachine,_args:PyFuncArgs) ->PyResult{
19-
ifletSome(frame) =&vm.current_frame{
20-
Ok(frame.clone())
21-
}else{
22-
panic!("Current frame is undefined!")
23-
}
20+
fngetframe(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{
21+
arg_check!(
22+
vm,
23+
args,
24+
required =[],
25+
optional =[(offset,Some(vm.ctx.int_type()))]
26+
);
27+
let idx =match offset{
28+
Some(int) =>{
29+
ifletSome(offset) = objint::get_value(int).to_usize(){
30+
if offset > vm.frames.len() -1{
31+
returnErr(vm.new_value_error("call stack is not deep enough".to_string()));
32+
}
33+
offset
34+
}else{
35+
0
36+
}
37+
}
38+
None =>0,
39+
};
40+
41+
let idx = vm.frames.len() - idx -1;
42+
43+
let frame =&vm.frames[idx];
44+
Ok(frame.clone())
2445
}
2546

2647
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
@@ -10,8 +10,9 @@ use std::collections::hash_map::HashMap;
1010

1111
usesuper::builtins;
1212
usesuper::bytecode;
13-
usesuper::frame::Frame;
13+
usesuper::frame::{ExecutionResult,Frame};
1414
usesuper::obj::objcode::copy_code;
15+
usesuper::obj::objframe;
1516
usesuper::obj::objgenerator;
1617
usesuper::obj::objiter;
1718
usesuper::obj::objsequence;
@@ -35,7 +36,7 @@ pub struct VirtualMachine {
3536
pubsys_module:PyObjectRef,
3637
pubstdlib_inits:HashMap<String, stdlib::StdlibInitFunc>,
3738
pubctx:PyContext,
38-
pubcurrent_frame:Option<PyObjectRef>,
39+
pubframes:Vec<PyObjectRef>,
3940
}
4041

4142
implVirtualMachine{
@@ -52,13 +53,28 @@ impl VirtualMachine {
5253
sys_module: sysmod,
5354
stdlib_inits,
5455
ctx: ctx,
55-
current_frame:None,
56+
frames:vec![],
5657
}
5758
}
5859

5960
pubfnrun_code_obj(&mutself,code:PyObjectRef,scope:PyObjectRef) ->PyResult{
60-
letmut frame =Frame::new(code, scope);
61-
frame.run_frame_full(self)
61+
self.run_frame_full(Frame::new(code, scope))
62+
}
63+
64+
pubfnrun_frame_full(&mutself,frame:Frame) ->PyResult{
65+
matchself.run_frame(frame)?{
66+
ExecutionResult::Return(value) =>Ok(value),
67+
_ =>panic!("Got unexpected result from function"),
68+
}
69+
}
70+
71+
pubfnrun_frame(&mutself,frame:Frame) ->Result<ExecutionResult,PyObjectRef>{
72+
let frame =self.ctx.new_frame(frame);
73+
self.frames.push(frame.clone());
74+
letmut frame = objframe::get_value(&frame);
75+
let result = frame.run(self);
76+
self.frames.pop();
77+
result
6278
}
6379

6480
/// Create a new python string object.
@@ -260,13 +276,13 @@ impl VirtualMachine {
260276
self.fill_scope_from_args(&code_object,&scope, args, defaults)?;
261277

262278
// Construct frame:
263-
letmutframe =Frame::new(code.clone(), scope);
279+
let frame =Frame::new(code.clone(), scope);
264280

265281
// If we have a generator, create a new generator
266282
if code_object.is_generator{
267283
objgenerator::new_generator(self, frame)
268284
}else{
269-
frame.run_frame_full(self)
285+
self.run_frame_full(frame)
270286
}
271287
}
272288

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp