Add a settings struct for storage of different settings which influence the VM.

This commit is contained in:
Windel Bouwman committed 2019-07-13 12:23:53 +02:00
1 parent 704b15750e
commit ac765a957b
8 files changed
+123 -30

No files matched your search

+9 -9
View File
@@ -20,7 +20,7 @@ struct Compiler {
current_qualified_path: Option<String>,
in_loop: bool,
in_function_def: bool,
optimize: bool,
optimize: u8,
}
/// Compile a given sourcecode into a bytecode object.
@@ -28,7 +28,7 @@ pub fn compile(
source: &str,
mode: &Mode,
source_path: String,
optimize: bool,
optimize: u8,
) -> Result<CodeObject, CompileError> {
match mode {
Mode::Exec => {
@@ -49,7 +49,7 @@ pub fn compile(
/// A helper function for the shared code of the different compile functions
fn with_compiler(
source_path: String,
optimize: bool,
optimize: u8,
f: impl FnOnce(&mut Compiler) -> Result<(), CompileError>,
) -> Result<CodeObject, CompileError> {
let mut compiler = Compiler::new(optimize);
@@ -65,7 +65,7 @@ fn with_compiler(
pub fn compile_program(
ast: ast::Program,
source_path: String,
optimize: bool,
optimize: u8,
) -> Result<CodeObject, CompileError> {
with_compiler(source_path, optimize, |compiler| {
let symbol_table = make_symbol_table(&ast)?;
@@ -77,7 +77,7 @@ pub fn compile_program(
pub fn compile_statement_eval(
statement: Vec<ast::LocatedStatement>,
source_path: String,
optimize: bool,
optimize: u8,
) -> Result<CodeObject, CompileError> {
with_compiler(source_path, optimize, |compiler| {
let symbol_table = statements_to_symbol_table(&statement)?;
@@ -89,7 +89,7 @@ pub fn compile_statement_eval(
pub fn compile_program_single(
ast: ast::Program,
source_path: String,
optimize: bool,
optimize: u8,
) -> Result<CodeObject, CompileError> {
with_compiler(source_path, optimize, |compiler| {
let symbol_table = make_symbol_table(&ast)?;
@@ -113,12 +113,12 @@ type Label = usize;
impl Default for Compiler {
fn default() -> Self {
Compiler::new(false)
Compiler::new(0)
}
}
impl Compiler {
fn new(optimize: bool) -> Self {
fn new(optimize: u8) -> Self {
Compiler {
code_object_stack: Vec::new(),
scope_stack: Vec::new(),
@@ -455,7 +455,7 @@ impl Compiler {
} => self.compile_class_def(name, body, bases, keywords, decorator_list)?,
ast::Statement::Assert { test, msg } => {
// if some flag, ignore all assert statements!
if !self.optimize {
if self.optimize == 0 {
let end_label = self.new_label();
self.compile_test(test, Some(end_label), None, EvalContext::Statement)?;
self.emit(Instruction::LoadName {
+1 -1
View File
@@ -38,7 +38,7 @@ struct CompilationSource {
impl CompilationSource {
fn compile(self, mode: &compile::Mode, module_name: String) -> Result<CodeObject, Diagnostic> {
let compile = |source| {
compile::compile(source, mode, module_name, false).map_err(|err| {
compile::compile(source, mode, module_name, 0).map_err(|err| {
Diagnostic::spans_error(self.span, format!("Compile error: {}", err))
})
};
+37 -7
View File
@@ -4,6 +4,7 @@ extern crate env_logger;
#[macro_use]
extern crate log;
extern crate rustyline;
use std::convert::TryInto;
use clap::{App, Arg};
use rustpython_compiler::{compile, error::CompileError, error::CompileErrorType};
@@ -14,7 +15,7 @@ use rustpython_vm::{
obj::objstr,
print_exception,
pyobject::{ItemProtocol, PyResult},
util, VirtualMachine,
util, PySettings, VirtualMachine,
};
use rustyline::{error::ReadlineError, Editor};
@@ -37,10 +38,31 @@ fn main() {
.help("Optimize. Set __debug__ to false. Remove debug statements."),
)
.arg(
Arg::with_name("v")
Arg::with_name("verbose")
.short("v")
.multiple(true)
.help("Give the verbosity"),
.help("Give the verbosity (can be applied multiple times)"),
)
.arg(Arg::with_name("debug").short("d").help("Debug the parser."))
.arg(
Arg::with_name("quiet")
.short("q")
.help("Be quiet at startup."),
)
.arg(
Arg::with_name("inspect")
.short("i")
.help("Inspect interactively after running the script."),
)
.arg(
Arg::with_name("no-user-site")
.short("s")
.help("don't add user site directory to sys.path."),
)
.arg(
Arg::with_name("no-site")
.short("S")
.help("don't imply 'import site' on initialization"),
)
.arg(
Arg::with_name("c")
@@ -71,11 +93,19 @@ fn main() {
);
let matches = app.get_matches();
let opt_level = matches.occurrences_of("optimize");
let optimize = opt_level > 0;
debug!("Optimize: {}", optimize);
let opt_level: u8 = matches.occurrences_of("optimize").try_into().unwrap();
let verbosity_level: u8 = matches.occurrences_of("verbose").try_into().unwrap();
// Construct vm:
let vm = VirtualMachine::new(optimize);
let mut settings: PySettings = Default::default();
settings.debug = matches.is_present("debug");
settings.inspect = matches.is_present("inspect");
settings.optimize = opt_level;
settings.no_site = matches.is_present("no-site");
settings.no_user_site = matches.is_present("no-user-site");
settings.verbose = verbosity_level;
settings.quiet = matches.is_present("quiet");
let vm = VirtualMachine::new(settings);
let res = import::init_importlib(&vm, true);
handle_exception(&vm, res);
+1 -1
View File
@@ -798,7 +798,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) {
});
}
let debug_mode = !vm.optimize;
let debug_mode: bool = vm.settings.optimize == 0;
extend_module!(vm, module, {
"__debug__" => ctx.new_bool(debug_mode),
//set __name__ fixes: https://github.com/RustPython/RustPython/issues/146
+7 -2
View File
@@ -55,8 +55,13 @@ pub fn import_file(
file_path: String,
content: String,
) -> PyResult {
let code_obj = compile::compile(&content, &compile::Mode::Exec, file_path, vm.optimize)
.map_err(|err| vm.new_syntax_error(&err))?;
let code_obj = compile::compile(
&content,
&compile::Mode::Exec,
file_path,
vm.settings.optimize,
)
.map_err(|err| vm.new_syntax_error(&err))?;
import_codeobj(vm, module_name, code_obj, true)
}
+1 -1
View File
@@ -70,7 +70,7 @@ mod vm;
// pub use self::pyobject::Executor;
pub use self::exceptions::print_exception;
pub use self::vm::VirtualMachine;
pub use self::vm::{PySettings, VirtualMachine};
pub use rustpython_bytecode::*;
#[doc(hidden)]
+19 -4
View File
@@ -6,7 +6,7 @@ use crate::function::{OptionalArg, PyFuncArgs};
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult};
use crate::version;
use crate::vm::VirtualMachine;
use crate::vm::{PySettings, VirtualMachine};
/*
* The magic sys module.
@@ -51,7 +51,7 @@ struct SysFlags {
/// -E
ignore_environment: bool,
/// -v
verbose: bool,
verbose: u8,
/// -b
bytes_warning: bool,
/// -q
@@ -66,6 +66,22 @@ struct SysFlags {
utf8_mode: bool,
}
impl SysFlags {
fn from_settings(settings: &PySettings) -> Self {
// Start with sensible defaults:
let mut flags: SysFlags = Default::default();
flags.debug = settings.debug;
flags.inspect = settings.inspect;
flags.optimize = settings.optimize;
flags.no_user_site = settings.no_user_site;
flags.no_site = settings.no_site;
flags.ignore_environment = settings.ignore_environment;
flags.verbose = settings.verbose;
flags.quiet = settings.quiet;
flags
}
}
fn sys_getrefcount(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(object, None)]);
let size = Rc::strong_count(&object);
@@ -103,8 +119,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR
let ctx = &vm.ctx;
let flags_type = SysFlags::make_class(ctx);
// TODO parse command line arguments and environment variables to populate SysFlags
let flags = SysFlags::default()
let flags = SysFlags::from_settings(&vm.settings)
.into_struct_sequence(vm, flags_type)
.unwrap();
+48 -5
View File
@@ -56,12 +56,55 @@ pub struct VirtualMachine {
pub exceptions: RefCell<Vec<PyObjectRef>>,
pub frozen: RefCell<HashMap<String, bytecode::CodeObject>>,
pub import_func: RefCell<PyObjectRef>,
pub optimize: bool,
pub settings: PySettings,
}
/// Struct containing all kind of settings for the python vm.
pub struct PySettings {
/// -d command line switch
pub debug: bool,
/// -i
pub inspect: bool,
/// -O optimization switch counter
pub optimize: u8,
/// -s
pub no_user_site: bool,
/// -S
pub no_site: bool,
/// -E
pub ignore_environment: bool,
/// verbosity level (-v switch)
pub verbose: u8,
/// -q
pub quiet: bool,
}
/// Sensible default settings.
impl Default for PySettings {
fn default() -> Self {
PySettings {
debug: false,
inspect: false,
optimize: 0,
no_user_site: false,
no_site: false,
ignore_environment: false,
verbose: 0,
quiet: false,
}
}
}
impl VirtualMachine {
/// Create a new `VirtualMachine` structure.
pub fn new(optimize: bool) -> VirtualMachine {
pub fn new(settings: PySettings) -> VirtualMachine {
flame_guard!("init VirtualMachine");
let ctx = PyContext::new();
@@ -82,7 +125,7 @@ impl VirtualMachine {
exceptions: RefCell::new(vec![]),
frozen,
import_func,
optimize,
settings,
};
builtins::make_module(&vm, builtins.clone());
@@ -751,7 +794,7 @@ impl VirtualMachine {
mode: &compile::Mode,
source_path: String,
) -> Result<PyCodeRef, CompileError> {
compile::compile(source, mode, source_path, self.optimize)
compile::compile(source, mode, source_path, self.settings.optimize)
.map(|codeobj| PyCode::new(codeobj).into_ref(self))
}
@@ -1024,7 +1067,7 @@ impl VirtualMachine {
impl Default for VirtualMachine {
fn default() -> Self {
VirtualMachine::new(false)
VirtualMachine::new(Default::default())
}
}