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

Commitc5789a0

Browse files
committed
Proper construction of scope for exec/eval.
1 parent5d28f9b commitc5789a0

File tree

4 files changed

+43
-18
lines changed

4 files changed

+43
-18
lines changed

‎tests/snippets/test_exec.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
exec("def square(x):\n return x * x\n")
2+
assert16==square(4)
3+
4+
d= {}
5+
exec("def square(x):\n return x * x\n", {},d)
6+
assert16==d['square'](4)
7+
8+
exec("assert 2 == x", {}, {'x':2})
9+
exec("assert 2 == x", {'x':2}, {})
10+
exec("assert 4 == x", {'x':2}, {'x':4})
11+
12+
exec("assert max(1, 2) == 2", {}, {})

‎vm/src/builtins.rs‎

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use crate::frame::{Scope, ScopeRef};
1818
usecrate::pyobject::{
1919
AttributeProtocol,IdProtocol,PyContext,PyFuncArgs,PyObjectRef,PyResult,TypeProtocol,
2020
};
21-
use std::rc::Rc;
2221

2322
#[cfg(not(target_arch ="wasm32"))]
2423
usecrate::stdlib::io::io_open;
@@ -192,7 +191,7 @@ fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
192191
args,
193192
required =[(source,None)],
194193
optional =[
195-
(_globals,Some(vm.ctx.dict_type())),
194+
(globals,Some(vm.ctx.dict_type())),
196195
(locals,Some(vm.ctx.dict_type()))
197196
]
198197
);
@@ -215,7 +214,7 @@ fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
215214
returnErr(vm.new_type_error("code argument must be str or code object".to_string()));
216215
};
217216

218-
let scope =make_scope(vm, locals);
217+
let scope =make_scope(vm,globals,locals);
219218

220219
// Run the source:
221220
vm.run_code_obj(code_obj.clone(), scope)
@@ -229,7 +228,7 @@ fn builtin_exec(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
229228
args,
230229
required =[(source,None)],
231230
optional =[
232-
(_globals,Some(vm.ctx.dict_type())),
231+
(globals,Some(vm.ctx.dict_type())),
233232
(locals,Some(vm.ctx.dict_type()))
234233
]
235234
);
@@ -252,26 +251,28 @@ fn builtin_exec(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
252251
returnErr(vm.new_type_error("source argument must be str or code object".to_string()));
253252
};
254253

255-
let scope =make_scope(vm, locals);
254+
let scope =make_scope(vm,globals,locals);
256255

257256
// Run the code:
258257
vm.run_code_obj(code_obj, scope)
259258
}
260259

261-
fnmake_scope(vm:&mutVirtualMachine,locals:Option<&PyObjectRef>) ->ScopeRef{
262-
// handle optional global and locals
263-
let locals =ifletSome(locals) = locals{
264-
locals.clone()
265-
}else{
266-
vm.new_dict()
260+
fnmake_scope(
261+
vm:&mutVirtualMachine,
262+
globals:Option<&PyObjectRef>,
263+
locals:Option<&PyObjectRef>,
264+
) ->ScopeRef{
265+
let current_scope = vm.current_scope();
266+
let parent =match globals{
267+
Some(dict) =>Some(Scope::new(dict.clone(),Some(vm.get_builtin_scope()))),
268+
None => current_scope.parent.clone(),
269+
};
270+
let locals =match locals{
271+
Some(dict) => dict.clone(),
272+
None => current_scope.locals.clone(),
267273
};
268274

269-
// TODO: handle optional globals
270-
// Construct new scope:
271-
Rc::new(Scope{
272-
locals,
273-
parent:None,
274-
})
275+
Scope::new(locals, parent)
275276
}
276277

277278
fnbuiltin_format(vm:&mutVirtualMachine,args:PyFuncArgs) ->PyResult{

‎vm/src/frame.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ pub struct Scope {
3535
}
3636
pubtypeScopeRef =Rc<Scope>;
3737

38+
implScope{
39+
pubfnnew(locals:PyObjectRef,parent:Option<ScopeRef>) ->ScopeRef{
40+
Rc::new(Scope{ locals, parent})
41+
}
42+
}
43+
3844
#[derive(Clone,Debug)]
3945
structBlock{
4046
/// The type of block.

‎vm/src/vm.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ impl VirtualMachine {
9090
result
9191
}
9292

93+
pubfncurrent_scope(&self) ->&ScopeRef{
94+
let current_frame =&self.frames[self.frames.len() -1];
95+
let frame = objframe::get_value(current_frame);
96+
&frame.scope
97+
}
98+
9399
/// Create a new python string object.
94100
pubfnnew_str(&self,s:String) ->PyObjectRef{
95101
self.ctx.new_str(s)
@@ -218,7 +224,7 @@ impl VirtualMachine {
218224
&self.ctx
219225
}
220226

221-
pubfnget_builtin_scope(&mutself) ->ScopeRef{
227+
pubfnget_builtin_scope(&self) ->ScopeRef{
222228
let a2 =&*self.builtins;
223229
match a2.payload{
224230
PyObjectPayload::Module{ref scope, ..} => scope.clone(),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp