mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Add a settings struct for storage of different settings which influence the VM.
This commit is contained in:
1 parent
704b15750e
commit
ac765a957b
8 files changed
+123
-30
No files matched your search
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user