Skip to content

Commit ac765a9

Browse files
committed
Add a settings struct for storage of different settings which influence the VM.
1 parent 704b157 commit ac765a9

File tree

8 files changed

+123
-30
lines changed

8 files changed

+123
-30
lines changed

compiler/src/compile.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ struct Compiler {
2020
current_qualified_path: Option<String>,
2121
in_loop: bool,
2222
in_function_def: bool,
23-
optimize: bool,
23+
optimize: u8,
2424
}
2525

2626
/// Compile a given sourcecode into a bytecode object.
2727
pub fn compile(
2828
source: &str,
2929
mode: &Mode,
3030
source_path: String,
31-
optimize: bool,
31+
optimize: u8,
3232
) -> Result<CodeObject, CompileError> {
3333
match mode {
3434
Mode::Exec => {
@@ -49,7 +49,7 @@ pub fn compile(
4949
/// A helper function for the shared code of the different compile functions
5050
fn with_compiler(
5151
source_path: String,
52-
optimize: bool,
52+
optimize: u8,
5353
f: impl FnOnce(&mut Compiler) -> Result<(), CompileError>,
5454
) -> Result<CodeObject, CompileError> {
5555
let mut compiler = Compiler::new(optimize);
@@ -65,7 +65,7 @@ fn with_compiler(
6565
pub fn compile_program(
6666
ast: ast::Program,
6767
source_path: String,
68-
optimize: bool,
68+
optimize: u8,
6969
) -> Result<CodeObject, CompileError> {
7070
with_compiler(source_path, optimize, |compiler| {
7171
let symbol_table = make_symbol_table(&ast)?;
@@ -77,7 +77,7 @@ pub fn compile_program(
7777
pub fn compile_statement_eval(
7878
statement: Vec<ast::LocatedStatement>,
7979
source_path: String,
80-
optimize: bool,
80+
optimize: u8,
8181
) -> Result<CodeObject, CompileError> {
8282
with_compiler(source_path, optimize, |compiler| {
8383
let symbol_table = statements_to_symbol_table(&statement)?;
@@ -89,7 +89,7 @@ pub fn compile_statement_eval(
8989
pub fn compile_program_single(
9090
ast: ast::Program,
9191
source_path: String,
92-
optimize: bool,
92+
optimize: u8,
9393
) -> Result<CodeObject, CompileError> {
9494
with_compiler(source_path, optimize, |compiler| {
9595
let symbol_table = make_symbol_table(&ast)?;
@@ -113,12 +113,12 @@ type Label = usize;
113113

114114
impl Default for Compiler {
115115
fn default() -> Self {
116-
Compiler::new(false)
116+
Compiler::new(0)
117117
}
118118
}
119119

120120
impl Compiler {
121-
fn new(optimize: bool) -> Self {
121+
fn new(optimize: u8) -> Self {
122122
Compiler {
123123
code_object_stack: Vec::new(),
124124
scope_stack: Vec::new(),
@@ -455,7 +455,7 @@ impl Compiler {
455455
} => self.compile_class_def(name, body, bases, keywords, decorator_list)?,
456456
ast::Statement::Assert { test, msg } => {
457457
// if some flag, ignore all assert statements!
458-
if !self.optimize {
458+
if self.optimize == 0 {
459459
let end_label = self.new_label();
460460
self.compile_test(test, Some(end_label), None, EvalContext::Statement)?;
461461
self.emit(Instruction::LoadName {

derive/src/compile_bytecode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct CompilationSource {
3838
impl CompilationSource {
3939
fn compile(self, mode: &compile::Mode, module_name: String) -> Result<CodeObject, Diagnostic> {
4040
let compile = |source| {
41-
compile::compile(source, mode, module_name, false).map_err(|err| {
41+
compile::compile(source, mode, module_name, 0).map_err(|err| {
4242
Diagnostic::spans_error(self.span, format!("Compile error: {}", err))
4343
})
4444
};

src/main.rs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ extern crate env_logger;
44
#[macro_use]
55
extern crate log;
66
extern crate rustyline;
7+
use std::convert::TryInto;
78

89
use clap::{App, Arg};
910
use rustpython_compiler::{compile, error::CompileError, error::CompileErrorType};
@@ -14,7 +15,7 @@ use rustpython_vm::{
1415
obj::objstr,
1516
print_exception,
1617
pyobject::{ItemProtocol, PyResult},
17-
util, VirtualMachine,
18+
util, PySettings, VirtualMachine,
1819
};
1920

2021
use rustyline::{error::ReadlineError, Editor};
@@ -37,10 +38,31 @@ fn main() {
3738
.help("Optimize. Set __debug__ to false. Remove debug statements."),
3839
)
3940
.arg(
40-
Arg::with_name("v")
41+
Arg::with_name("verbose")
4142
.short("v")
4243
.multiple(true)
43-
.help("Give the verbosity"),
44+
.help("Give the verbosity (can be applied multiple times)"),
45+
)
46+
.arg(Arg::with_name("debug").short("d").help("Debug the parser."))
47+
.arg(
48+
Arg::with_name("quiet")
49+
.short("q")
50+
.help("Be quiet at startup."),
51+
)
52+
.arg(
53+
Arg::with_name("inspect")
54+
.short("i")
55+
.help("Inspect interactively after running the script."),
56+
)
57+
.arg(
58+
Arg::with_name("no-user-site")
59+
.short("s")
60+
.help("don't add user site directory to sys.path."),
61+
)
62+
.arg(
63+
Arg::with_name("no-site")
64+
.short("S")
65+
.help("don't imply 'import site' on initialization"),
4466
)
4567
.arg(
4668
Arg::with_name("c")
@@ -71,11 +93,19 @@ fn main() {
7193
);
7294
let matches = app.get_matches();
7395

74-
let opt_level = matches.occurrences_of("optimize");
75-
let optimize = opt_level > 0;
76-
debug!("Optimize: {}", optimize);
96+
let opt_level: u8 = matches.occurrences_of("optimize").try_into().unwrap();
97+
let verbosity_level: u8 = matches.occurrences_of("verbose").try_into().unwrap();
98+
7799
// Construct vm:
78-
let vm = VirtualMachine::new(optimize);
100+
let mut settings: PySettings = Default::default();
101+
settings.debug = matches.is_present("debug");
102+
settings.inspect = matches.is_present("inspect");
103+
settings.optimize = opt_level;
104+
settings.no_site = matches.is_present("no-site");
105+
settings.no_user_site = matches.is_present("no-user-site");
106+
settings.verbose = verbosity_level;
107+
settings.quiet = matches.is_present("quiet");
108+
let vm = VirtualMachine::new(settings);
79109

80110
let res = import::init_importlib(&vm, true);
81111
handle_exception(&vm, res);

vm/src/builtins.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) {
798798
});
799799
}
800800

801-
let debug_mode = !vm.optimize;
801+
let debug_mode: bool = vm.settings.optimize == 0;
802802
extend_module!(vm, module, {
803803
"__debug__" => ctx.new_bool(debug_mode),
804804
//set __name__ fixes: https://github.com/RustPython/RustPython/issues/146

vm/src/import.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,13 @@ pub fn import_file(
5555
file_path: String,
5656
content: String,
5757
) -> PyResult {
58-
let code_obj = compile::compile(&content, &compile::Mode::Exec, file_path, vm.optimize)
59-
.map_err(|err| vm.new_syntax_error(&err))?;
58+
let code_obj = compile::compile(
59+
&content,
60+
&compile::Mode::Exec,
61+
file_path,
62+
vm.settings.optimize,
63+
)
64+
.map_err(|err| vm.new_syntax_error(&err))?;
6065
import_codeobj(vm, module_name, code_obj, true)
6166
}
6267

vm/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ mod vm;
7070

7171
// pub use self::pyobject::Executor;
7272
pub use self::exceptions::print_exception;
73-
pub use self::vm::VirtualMachine;
73+
pub use self::vm::{PySettings, VirtualMachine};
7474
pub use rustpython_bytecode::*;
7575

7676
#[doc(hidden)]

vm/src/sysmodule.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::function::{OptionalArg, PyFuncArgs};
66
use crate::obj::objstr::PyStringRef;
77
use crate::pyobject::{IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult};
88
use crate::version;
9-
use crate::vm::VirtualMachine;
9+
use crate::vm::{PySettings, VirtualMachine};
1010

1111
/*
1212
* The magic sys module.
@@ -51,7 +51,7 @@ struct SysFlags {
5151
/// -E
5252
ignore_environment: bool,
5353
/// -v
54-
verbose: bool,
54+
verbose: u8,
5555
/// -b
5656
bytes_warning: bool,
5757
/// -q
@@ -66,6 +66,22 @@ struct SysFlags {
6666
utf8_mode: bool,
6767
}
6868

69+
impl SysFlags {
70+
fn from_settings(settings: &PySettings) -> Self {
71+
// Start with sensible defaults:
72+
let mut flags: SysFlags = Default::default();
73+
flags.debug = settings.debug;
74+
flags.inspect = settings.inspect;
75+
flags.optimize = settings.optimize;
76+
flags.no_user_site = settings.no_user_site;
77+
flags.no_site = settings.no_site;
78+
flags.ignore_environment = settings.ignore_environment;
79+
flags.verbose = settings.verbose;
80+
flags.quiet = settings.quiet;
81+
flags
82+
}
83+
}
84+
6985
fn sys_getrefcount(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
7086
arg_check!(vm, args, required = [(object, None)]);
7187
let size = Rc::strong_count(&object);
@@ -103,8 +119,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR
103119
let ctx = &vm.ctx;
104120

105121
let flags_type = SysFlags::make_class(ctx);
106-
// TODO parse command line arguments and environment variables to populate SysFlags
107-
let flags = SysFlags::default()
122+
let flags = SysFlags::from_settings(&vm.settings)
108123
.into_struct_sequence(vm, flags_type)
109124
.unwrap();
110125

vm/src/vm.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,55 @@ pub struct VirtualMachine {
5656
pub exceptions: RefCell<Vec<PyObjectRef>>,
5757
pub frozen: RefCell<HashMap<String, bytecode::CodeObject>>,
5858
pub import_func: RefCell<PyObjectRef>,
59-
pub optimize: bool,
59+
pub settings: PySettings,
60+
}
61+
62+
/// Struct containing all kind of settings for the python vm.
63+
pub struct PySettings {
64+
/// -d command line switch
65+
pub debug: bool,
66+
67+
/// -i
68+
pub inspect: bool,
69+
70+
/// -O optimization switch counter
71+
pub optimize: u8,
72+
73+
/// -s
74+
pub no_user_site: bool,
75+
76+
/// -S
77+
pub no_site: bool,
78+
79+
/// -E
80+
pub ignore_environment: bool,
81+
82+
/// verbosity level (-v switch)
83+
pub verbose: u8,
84+
85+
/// -q
86+
pub quiet: bool,
87+
}
88+
89+
/// Sensible default settings.
90+
impl Default for PySettings {
91+
fn default() -> Self {
92+
PySettings {
93+
debug: false,
94+
inspect: false,
95+
optimize: 0,
96+
no_user_site: false,
97+
no_site: false,
98+
ignore_environment: false,
99+
verbose: 0,
100+
quiet: false,
101+
}
102+
}
60103
}
61104

62105
impl VirtualMachine {
63106
/// Create a new `VirtualMachine` structure.
64-
pub fn new(optimize: bool) -> VirtualMachine {
107+
pub fn new(settings: PySettings) -> VirtualMachine {
65108
flame_guard!("init VirtualMachine");
66109
let ctx = PyContext::new();
67110

@@ -82,7 +125,7 @@ impl VirtualMachine {
82125
exceptions: RefCell::new(vec![]),
83126
frozen,
84127
import_func,
85-
optimize,
128+
settings,
86129
};
87130

88131
builtins::make_module(&vm, builtins.clone());
@@ -751,7 +794,7 @@ impl VirtualMachine {
751794
mode: &compile::Mode,
752795
source_path: String,
753796
) -> Result<PyCodeRef, CompileError> {
754-
compile::compile(source, mode, source_path, self.optimize)
797+
compile::compile(source, mode, source_path, self.settings.optimize)
755798
.map(|codeobj| PyCode::new(codeobj).into_ref(self))
756799
}
757800

@@ -1024,7 +1067,7 @@ impl VirtualMachine {
10241067

10251068
impl Default for VirtualMachine {
10261069
fn default() -> Self {
1027-
VirtualMachine::new(false)
1070+
VirtualMachine::new(Default::default())
10281071
}
10291072
}
10301073

0 commit comments

Comments
 (0)