Skip to content

Commit 6ed172d

Browse files
authored
Merge pull request #1933 from RustPython/coolreader18/arc-vm-state
Move some vm fields to an Arc-wrapped struct
2 parents 901e766 + 198e449 commit 6ed172d

File tree

9 files changed

+94
-75
lines changed

9 files changed

+94
-75
lines changed

vm/src/builtins.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ fn builtin_sum(iterable: PyIterable, start: OptionalArg, vm: &VirtualMachine) ->
736736

737737
// Should be renamed to builtin___import__?
738738
fn builtin_import(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
739-
vm.invoke(&vm.import_func.borrow(), args)
739+
vm.invoke(&vm.import_func, args)
740740
}
741741

742742
fn builtin_vars(obj: OptionalArg, vm: &VirtualMachine) -> PyResult {
@@ -761,7 +761,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) {
761761
});
762762
}
763763

764-
let debug_mode: bool = vm.settings.optimize == 0;
764+
let debug_mode: bool = vm.state.settings.optimize == 0;
765765
extend_module!(vm, module, {
766766
"__debug__" => ctx.new_bool(debug_mode),
767767
//set __name__ fixes: https://github.com/RustPython/RustPython/issues/146

vm/src/import.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@ use crate::vm::{InitParameter, VirtualMachine};
1414
#[cfg(feature = "rustpython-compiler")]
1515
use rustpython_compiler::compile;
1616

17-
pub fn init_importlib(vm: &VirtualMachine, initialize_parameter: InitParameter) -> PyResult {
17+
pub fn init_importlib(vm: &mut VirtualMachine, initialize_parameter: InitParameter) -> PyResult {
1818
flame_guard!("init importlib");
1919
let importlib = import_frozen(vm, "_frozen_importlib")?;
2020
let impmod = import_builtin(vm, "_imp")?;
2121
let install = vm.get_attribute(importlib.clone(), "_install")?;
2222
vm.invoke(&install, vec![vm.sys_module.clone(), impmod])?;
23-
vm.import_func
24-
.replace(vm.get_attribute(importlib.clone(), "__import__")?);
23+
vm.import_func = vm.get_attribute(importlib.clone(), "__import__")?;
2524

2625
match initialize_parameter {
2726
InitParameter::InitializeExternal if cfg!(feature = "rustpython-compiler") => {
@@ -58,16 +57,16 @@ pub fn init_importlib(vm: &VirtualMachine, initialize_parameter: InitParameter)
5857
}
5958

6059
pub fn import_frozen(vm: &VirtualMachine, module_name: &str) -> PyResult {
61-
vm.frozen
62-
.borrow()
60+
vm.state
61+
.frozen
6362
.get(module_name)
6463
.ok_or_else(|| vm.new_import_error(format!("Cannot import frozen module {}", module_name)))
6564
.and_then(|frozen| import_codeobj(vm, module_name, frozen.code.clone(), false))
6665
}
6766

6867
pub fn import_builtin(vm: &VirtualMachine, module_name: &str) -> PyResult {
69-
vm.stdlib_inits
70-
.borrow()
68+
vm.state
69+
.stdlib_inits
7170
.get(module_name)
7271
.ok_or_else(|| vm.new_import_error(format!("Cannot import bultin module {}", module_name)))
7372
.and_then(|make_module_func| {

vm/src/stdlib/imp.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ fn imp_lock_held(_vm: &VirtualMachine) -> PyResult<()> {
2626
}
2727

2828
fn imp_is_builtin(name: PyStringRef, vm: &VirtualMachine) -> bool {
29-
vm.stdlib_inits.borrow().contains_key(name.as_str())
29+
vm.state.stdlib_inits.contains_key(name.as_str())
3030
}
3131

3232
fn imp_is_frozen(name: PyStringRef, vm: &VirtualMachine) -> bool {
33-
vm.frozen.borrow().contains_key(name.as_str())
33+
vm.state.frozen.contains_key(name.as_str())
3434
}
3535

3636
fn imp_create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
@@ -40,7 +40,7 @@ fn imp_create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
4040

4141
if let Ok(module) = sys_modules.get_item(name, vm) {
4242
Ok(module)
43-
} else if let Some(make_module_func) = vm.stdlib_inits.borrow().get(name) {
43+
} else if let Some(make_module_func) = vm.state.stdlib_inits.get(name) {
4444
Ok(make_module_func(vm))
4545
} else {
4646
Ok(vm.get_none())
@@ -53,8 +53,8 @@ fn imp_exec_builtin(_mod: PyModuleRef) -> i32 {
5353
}
5454

5555
fn imp_get_frozen_object(name: PyStringRef, vm: &VirtualMachine) -> PyResult<PyCode> {
56-
vm.frozen
57-
.borrow()
56+
vm.state
57+
.frozen
5858
.get(name.as_str())
5959
.map(|frozen| {
6060
let mut frozen = frozen.code.clone();
@@ -71,8 +71,8 @@ fn imp_init_frozen(name: PyStringRef, vm: &VirtualMachine) -> PyResult {
7171
}
7272

7373
fn imp_is_frozen_package(name: PyStringRef, vm: &VirtualMachine) -> PyResult<bool> {
74-
vm.frozen
75-
.borrow()
74+
vm.state
75+
.frozen
7676
.get(name.as_str())
7777
.map(|frozen| frozen.package)
7878
.ok_or_else(|| {

vm/src/stdlib/signal.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ fn assert_in_range(signum: i32, vm: &VirtualMachine) -> PyResult<()> {
3838

3939
fn signal(signalnum: i32, handler: PyObjectRef, vm: &VirtualMachine) -> PyResult {
4040
assert_in_range(signalnum, vm)?;
41+
let signal_handlers = vm
42+
.signal_handlers
43+
.as_ref()
44+
.ok_or_else(|| vm.new_value_error("signal only works in main thread".to_owned()))?;
4145

4246
let sig_handler = match usize::try_from_object(vm, handler.clone()).ok() {
4347
Some(SIG_DFL) => SIG_DFL,
@@ -68,15 +72,19 @@ fn signal(signalnum: i32, handler: PyObjectRef, vm: &VirtualMachine) -> PyResult
6872

6973
let mut old_handler = handler;
7074
std::mem::swap(
71-
&mut vm.signal_handlers.borrow_mut()[signalnum as usize],
75+
&mut signal_handlers.borrow_mut()[signalnum as usize],
7276
&mut old_handler,
7377
);
7478
Ok(old_handler)
7579
}
7680

7781
fn getsignal(signalnum: i32, vm: &VirtualMachine) -> PyResult {
7882
assert_in_range(signalnum, vm)?;
79-
Ok(vm.signal_handlers.borrow()[signalnum as usize].clone())
83+
let signal_handlers = vm
84+
.signal_handlers
85+
.as_ref()
86+
.ok_or_else(|| vm.new_value_error("getsignal only works in main thread".to_owned()))?;
87+
Ok(signal_handlers.borrow()[signalnum as usize].clone())
8088
}
8189

8290
#[cfg(unix)]
@@ -91,13 +99,18 @@ fn alarm(time: u32) -> u32 {
9199

92100
#[cfg_attr(feature = "flame-it", flame)]
93101
pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> {
102+
let signal_handlers = match vm.signal_handlers {
103+
Some(ref h) => h.borrow(),
104+
None => return Ok(()),
105+
};
106+
94107
if !ANY_TRIGGERED.swap(false, Ordering::Relaxed) {
95108
return Ok(());
96109
}
97110
for (signum, trigger) in TRIGGERS.iter().enumerate().skip(1) {
98111
let triggerd = trigger.swap(false, Ordering::Relaxed);
99112
if triggerd {
100-
let handler = &vm.signal_handlers.borrow()[signum];
113+
let handler = &signal_handlers[signum];
101114
if vm.is_callable(handler) {
102115
vm.invoke(handler, vec![vm.new_int(signum), vm.get_none()])?;
103116
}
@@ -145,7 +158,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
145158
} else {
146159
vm.get_none()
147160
};
148-
vm.signal_handlers.borrow_mut()[signum] = py_handler;
161+
vm.signal_handlers.as_ref().unwrap().borrow_mut()[signum] = py_handler;
149162
}
150163

151164
signal(libc::SIGINT, int_handler, vm).expect("Failed to set sigint handler");

vm/src/sysmodule.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use crate::vm::{PySettings, VirtualMachine};
1818

1919
fn argv(vm: &VirtualMachine) -> PyObjectRef {
2020
vm.ctx.new_list(
21-
vm.settings
21+
vm.state
22+
.settings
2223
.argv
2324
.iter()
2425
.map(|arg| vm.new_str(arg.to_owned()))
@@ -150,7 +151,7 @@ fn update_use_tracing(vm: &VirtualMachine) {
150151
let trace_is_none = vm.is_none(&vm.trace_func.borrow());
151152
let profile_is_none = vm.is_none(&vm.profile_func.borrow());
152153
let tracing = !(trace_is_none && profile_is_none);
153-
vm.use_tracing.replace(tracing);
154+
vm.use_tracing.set(tracing);
154155
}
155156

156157
fn sys_getrecursionlimit(vm: &VirtualMachine) -> usize {
@@ -225,7 +226,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR
225226
let ctx = &vm.ctx;
226227

227228
let flags_type = SysFlags::make_class(ctx);
228-
let flags = SysFlags::from_settings(&vm.settings)
229+
let flags = SysFlags::from_settings(&vm.state.settings)
229230
.into_struct_sequence(vm, flags_type)
230231
.unwrap();
231232

@@ -246,7 +247,8 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR
246247
});
247248

248249
let path = ctx.new_list(
249-
vm.settings
250+
vm.state
251+
.settings
250252
.path_list
251253
.iter()
252254
.map(|path| ctx.new_str(path.clone()))
@@ -348,7 +350,7 @@ setprofile() -- set the global profiling function
348350
setrecursionlimit() -- set the max recursion depth for the interpreter
349351
settrace() -- set the global debug tracing function
350352
";
351-
let mut module_names: Vec<String> = vm.stdlib_inits.borrow().keys().cloned().collect();
353+
let mut module_names: Vec<String> = vm.state.stdlib_inits.keys().cloned().collect();
352354
module_names.push("sys".to_owned());
353355
module_names.push("builtins".to_owned());
354356
module_names.sort();
@@ -399,7 +401,7 @@ settrace() -- set the global debug tracing function
399401
"path_hooks" => ctx.new_list(vec![]),
400402
"path_importer_cache" => ctx.new_dict(),
401403
"pycache_prefix" => vm.get_none(),
402-
"dont_write_bytecode" => vm.new_bool(vm.settings.dont_write_bytecode),
404+
"dont_write_bytecode" => vm.new_bool(vm.state.settings.dont_write_bytecode),
403405
"setprofile" => ctx.new_function(sys_setprofile),
404406
"setrecursionlimit" => ctx.new_function(sys_setrecursionlimit),
405407
"settrace" => ctx.new_function(sys_settrace),

vm/src/vm.rs

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,26 @@ use crate::sysmodule;
5656
pub struct VirtualMachine {
5757
pub builtins: PyObjectRef,
5858
pub sys_module: PyObjectRef,
59-
pub stdlib_inits: RefCell<HashMap<String, stdlib::StdlibInitFunc>>,
6059
pub ctx: PyContext,
6160
pub frames: RefCell<Vec<FrameRef>>,
6261
pub wasm_id: Option<String>,
6362
pub exceptions: RefCell<Vec<PyBaseExceptionRef>>,
64-
pub frozen: RefCell<HashMap<String, bytecode::FrozenModule>>,
65-
pub import_func: RefCell<PyObjectRef>,
63+
pub import_func: PyObjectRef,
6664
pub profile_func: RefCell<PyObjectRef>,
6765
pub trace_func: RefCell<PyObjectRef>,
68-
pub use_tracing: RefCell<bool>,
69-
pub signal_handlers: RefCell<[PyObjectRef; NSIG]>,
70-
pub settings: PySettings,
66+
pub use_tracing: Cell<bool>,
7167
pub recursion_limit: Cell<usize>,
72-
pub codec_registry: RefCell<Vec<PyObjectRef>>,
68+
pub signal_handlers: Option<RefCell<[PyObjectRef; NSIG]>>,
69+
pub state: Arc<PyGlobalState>,
7370
pub initialized: bool,
7471
}
7572

73+
pub struct PyGlobalState {
74+
pub settings: PySettings,
75+
pub stdlib_inits: HashMap<String, stdlib::StdlibInitFunc>,
76+
pub frozen: HashMap<String, bytecode::FrozenModule>,
77+
}
78+
7679
pub const NSIG: usize = 64;
7780

7881
#[derive(Copy, Clone)]
@@ -175,31 +178,33 @@ impl VirtualMachine {
175178
let sysmod_dict = ctx.new_dict();
176179
let sysmod = new_module(sysmod_dict.clone());
177180

178-
let stdlib_inits = RefCell::new(stdlib::get_module_inits());
179-
let frozen = RefCell::new(frozen::get_module_inits());
180-
let import_func = RefCell::new(ctx.none());
181+
let import_func = ctx.none();
181182
let profile_func = RefCell::new(ctx.none());
182183
let trace_func = RefCell::new(ctx.none());
183184
let signal_handlers = RefCell::new(arr![ctx.none(); 64]);
184185
let initialize_parameter = settings.initialization_parameter;
185186

187+
let stdlib_inits = stdlib::get_module_inits();
188+
let frozen = frozen::get_module_inits();
189+
186190
let mut vm = VirtualMachine {
187191
builtins: builtins.clone(),
188192
sys_module: sysmod.clone(),
189-
stdlib_inits,
190193
ctx,
191194
frames: RefCell::new(vec![]),
192195
wasm_id: None,
193196
exceptions: RefCell::new(vec![]),
194-
frozen,
195197
import_func,
196198
profile_func,
197199
trace_func,
198-
use_tracing: RefCell::new(false),
199-
signal_handlers,
200-
settings,
200+
use_tracing: Cell::new(false),
201201
recursion_limit: Cell::new(if cfg!(debug_assertions) { 256 } else { 512 }),
202-
codec_registry: RefCell::default(),
202+
signal_handlers: Some(signal_handlers),
203+
state: Arc::new(PyGlobalState {
204+
settings,
205+
stdlib_inits,
206+
frozen,
207+
}),
203208
initialized: false,
204209
};
205210

@@ -232,7 +237,7 @@ impl VirtualMachine {
232237
builtins::make_module(self, self.builtins.clone());
233238
sysmodule::make_module(self, self.sys_module.clone(), self.builtins.clone());
234239

235-
let inner_init = || -> PyResult<()> {
240+
let mut inner_init = || -> PyResult<()> {
236241
#[cfg(not(target_arch = "wasm32"))]
237242
import::import_builtin(self, "signal")?;
238243

@@ -266,7 +271,9 @@ impl VirtualMachine {
266271
Ok(())
267272
};
268273

269-
self.expect_pyresult(inner_init(), "initializiation failed");
274+
let res = inner_init();
275+
276+
self.expect_pyresult(res, "initializiation failed");
270277

271278
self.initialized = true;
272279
}
@@ -814,7 +821,7 @@ impl VirtualMachine {
814821

815822
/// Call registered trace function.
816823
fn trace_event(&self, event: TraceEvent) -> PyResult<()> {
817-
if *self.use_tracing.borrow() {
824+
if self.use_tracing.get() {
818825
let frame = self.get_none();
819826
let event = self.new_str(event.to_string());
820827
let arg = self.get_none();
@@ -824,17 +831,17 @@ impl VirtualMachine {
824831
// tracing function itself.
825832
let trace_func = self.trace_func.borrow().clone();
826833
if !self.is_none(&trace_func) {
827-
self.use_tracing.replace(false);
834+
self.use_tracing.set(false);
828835
let res = self.invoke(&trace_func, args.clone());
829-
self.use_tracing.replace(true);
836+
self.use_tracing.set(true);
830837
res?;
831838
}
832839

833840
let profile_func = self.profile_func.borrow().clone();
834841
if !self.is_none(&profile_func) {
835-
self.use_tracing.replace(false);
842+
self.use_tracing.set(false);
836843
let res = self.invoke(&profile_func, args);
837-
self.use_tracing.replace(true);
844+
self.use_tracing.set(true);
838845
res?;
839846
}
840847
}
@@ -1033,7 +1040,7 @@ impl VirtualMachine {
10331040
#[cfg(feature = "rustpython-compiler")]
10341041
pub fn compile_opts(&self) -> CompileOpts {
10351042
CompileOpts {
1036-
optimize: self.settings.optimize,
1043+
optimize: self.state.settings.optimize,
10371044
}
10381045
}
10391046

wasm/lib/src/browser_module.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use futures::Future;
22
use js_sys::Promise;
3+
use std::sync::Arc;
34
use wasm_bindgen::prelude::*;
45
use wasm_bindgen::JsCast;
56
use wasm_bindgen_futures::{future_to_promise, JsFuture};
@@ -375,11 +376,12 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
375376
})
376377
}
377378

378-
pub fn setup_browser_module(vm: &VirtualMachine) {
379-
vm.stdlib_inits
380-
.borrow_mut()
379+
pub fn setup_browser_module(vm: &mut VirtualMachine) {
380+
let state = Arc::get_mut(&mut vm.state).unwrap();
381+
state
382+
.stdlib_inits
381383
.insert("_browser".to_owned(), Box::new(make_module));
382-
vm.frozen.borrow_mut().extend(py_compile_bytecode!(
384+
state.frozen.extend(py_compile_bytecode!(
383385
file = "src/browser.py",
384386
module_name = "browser",
385387
));

0 commit comments

Comments
 (0)