mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-17 01:51:39 +09:00
Add load and store of global to name protocol.
This commit is contained in:
@@ -129,6 +129,8 @@ pub trait NameProtocol {
|
||||
fn store_name(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef);
|
||||
fn delete_name(&self, vm: &VirtualMachine, name: &str);
|
||||
fn load_cell(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef>;
|
||||
fn load_global(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef>;
|
||||
fn store_global(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef);
|
||||
}
|
||||
|
||||
impl NameProtocol for Scope {
|
||||
@@ -162,6 +164,14 @@ impl NameProtocol for Scope {
|
||||
fn delete_name(&self, vm: &VirtualMachine, key: &str) {
|
||||
self.get_locals().del_item(key, vm).unwrap();
|
||||
}
|
||||
|
||||
fn load_global(&self, vm: &VirtualMachine, name: &str) -> Option<PyObjectRef> {
|
||||
self.globals.get_item_option(name, vm).unwrap()
|
||||
}
|
||||
|
||||
fn store_global(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef) {
|
||||
self.globals.set_item(name, value, vm).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -994,12 +1004,12 @@ impl Frame {
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
name: &str,
|
||||
scope: &bytecode::NameScope,
|
||||
name_scope: &bytecode::NameScope,
|
||||
) -> FrameResult {
|
||||
let obj = self.pop_value();
|
||||
match scope {
|
||||
match name_scope {
|
||||
bytecode::NameScope::Global => {
|
||||
self.scope.globals.set_item(name, obj, vm)?;
|
||||
self.scope.store_global(vm, name, obj);
|
||||
}
|
||||
bytecode::NameScope::Local => {
|
||||
self.scope.store_name(&vm, name, obj);
|
||||
@@ -1017,19 +1027,21 @@ impl Frame {
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
name: &str,
|
||||
scope: &bytecode::NameScope,
|
||||
name_scope: &bytecode::NameScope,
|
||||
) -> FrameResult {
|
||||
let value = match scope {
|
||||
bytecode::NameScope::Global => self.scope.globals.get_item(name, vm)?,
|
||||
bytecode::NameScope::Local => match self.scope.load_name(&vm, name) {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
let name_error_type = vm.ctx.exceptions.name_error.clone();
|
||||
let msg = format!("name '{}' is not defined", name);
|
||||
let name_error = vm.new_exception(name_error_type, msg);
|
||||
return Err(name_error);
|
||||
}
|
||||
},
|
||||
let optional_value = match name_scope {
|
||||
bytecode::NameScope::Global => self.scope.load_global(vm, name),
|
||||
bytecode::NameScope::Local => self.scope.load_name(&vm, name),
|
||||
};
|
||||
|
||||
let value = match optional_value {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
let name_error_type = vm.ctx.exceptions.name_error.clone();
|
||||
let msg = format!("name '{}' is not defined", name);
|
||||
let name_error = vm.new_exception(name_error_type, msg);
|
||||
return Err(name_error);
|
||||
}
|
||||
};
|
||||
|
||||
self.push_value(value);
|
||||
|
||||
@@ -111,6 +111,17 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
|
||||
fn scan_parameter(&mut self, parameter: &ast::Parameter) -> SymbolTableResult {
|
||||
self.register_name(¶meter.arg, SymbolRole::Assigned)
|
||||
}
|
||||
|
||||
fn scan_parameters_annotations(&mut self, parameters: &[ast::Parameter]) -> SymbolTableResult {
|
||||
for parameter in parameters {
|
||||
self.scan_parameter_annotation(parameter)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn scan_parameter_annotation(&mut self, parameter: &ast::Parameter) -> SymbolTableResult {
|
||||
if let Some(annotation) = ¶meter.annotation {
|
||||
self.scan_expression(&annotation)?;
|
||||
}
|
||||
@@ -394,7 +405,19 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
// Annotations are scanned in outer scope:
|
||||
self.scan_parameters_annotations(&args.args)?;
|
||||
self.scan_parameters_annotations(&args.kwonlyargs)?;
|
||||
if let ast::Varargs::Named(name) = &args.vararg {
|
||||
self.scan_parameter_annotation(name)?;
|
||||
}
|
||||
if let ast::Varargs::Named(name) = &args.kwarg {
|
||||
self.scan_parameter_annotation(name)?;
|
||||
}
|
||||
|
||||
self.enter_scope();
|
||||
|
||||
// Fill scope with parameter names:
|
||||
self.scan_parameters(&args.args)?;
|
||||
self.scan_parameters(&args.kwonlyargs)?;
|
||||
if let ast::Varargs::Named(name) = &args.vararg {
|
||||
|
||||
Reference in New Issue
Block a user