forked from Rust-related/RustPython
Merge pull request #1933 from RustPython/coolreader18/arc-vm-state
Move some vm fields to an Arc-wrapped struct
This commit is contained in:
@@ -736,7 +736,7 @@ fn builtin_sum(iterable: PyIterable, start: OptionalArg, vm: &VirtualMachine) ->
|
||||
|
||||
// Should be renamed to builtin___import__?
|
||||
fn builtin_import(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
vm.invoke(&vm.import_func.borrow(), args)
|
||||
vm.invoke(&vm.import_func, args)
|
||||
}
|
||||
|
||||
fn builtin_vars(obj: OptionalArg, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -761,7 +761,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) {
|
||||
});
|
||||
}
|
||||
|
||||
let debug_mode: bool = vm.settings.optimize == 0;
|
||||
let debug_mode: bool = vm.state.settings.optimize == 0;
|
||||
extend_module!(vm, module, {
|
||||
"__debug__" => ctx.new_bool(debug_mode),
|
||||
//set __name__ fixes: https://github.com/RustPython/RustPython/issues/146
|
||||
|
||||
@@ -14,14 +14,13 @@ use crate::vm::{InitParameter, VirtualMachine};
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
use rustpython_compiler::compile;
|
||||
|
||||
pub fn init_importlib(vm: &VirtualMachine, initialize_parameter: InitParameter) -> PyResult {
|
||||
pub fn init_importlib(vm: &mut VirtualMachine, initialize_parameter: InitParameter) -> PyResult {
|
||||
flame_guard!("init importlib");
|
||||
let importlib = import_frozen(vm, "_frozen_importlib")?;
|
||||
let impmod = import_builtin(vm, "_imp")?;
|
||||
let install = vm.get_attribute(importlib.clone(), "_install")?;
|
||||
vm.invoke(&install, vec![vm.sys_module.clone(), impmod])?;
|
||||
vm.import_func
|
||||
.replace(vm.get_attribute(importlib.clone(), "__import__")?);
|
||||
vm.import_func = vm.get_attribute(importlib.clone(), "__import__")?;
|
||||
|
||||
match initialize_parameter {
|
||||
InitParameter::InitializeExternal if cfg!(feature = "rustpython-compiler") => {
|
||||
@@ -58,16 +57,16 @@ pub fn init_importlib(vm: &VirtualMachine, initialize_parameter: InitParameter)
|
||||
}
|
||||
|
||||
pub fn import_frozen(vm: &VirtualMachine, module_name: &str) -> PyResult {
|
||||
vm.frozen
|
||||
.borrow()
|
||||
vm.state
|
||||
.frozen
|
||||
.get(module_name)
|
||||
.ok_or_else(|| vm.new_import_error(format!("Cannot import frozen module {}", module_name)))
|
||||
.and_then(|frozen| import_codeobj(vm, module_name, frozen.code.clone(), false))
|
||||
}
|
||||
|
||||
pub fn import_builtin(vm: &VirtualMachine, module_name: &str) -> PyResult {
|
||||
vm.stdlib_inits
|
||||
.borrow()
|
||||
vm.state
|
||||
.stdlib_inits
|
||||
.get(module_name)
|
||||
.ok_or_else(|| vm.new_import_error(format!("Cannot import bultin module {}", module_name)))
|
||||
.and_then(|make_module_func| {
|
||||
|
||||
@@ -26,11 +26,11 @@ fn imp_lock_held(_vm: &VirtualMachine) -> PyResult<()> {
|
||||
}
|
||||
|
||||
fn imp_is_builtin(name: PyStringRef, vm: &VirtualMachine) -> bool {
|
||||
vm.stdlib_inits.borrow().contains_key(name.as_str())
|
||||
vm.state.stdlib_inits.contains_key(name.as_str())
|
||||
}
|
||||
|
||||
fn imp_is_frozen(name: PyStringRef, vm: &VirtualMachine) -> bool {
|
||||
vm.frozen.borrow().contains_key(name.as_str())
|
||||
vm.state.frozen.contains_key(name.as_str())
|
||||
}
|
||||
|
||||
fn imp_create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -40,7 +40,7 @@ fn imp_create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
|
||||
if let Ok(module) = sys_modules.get_item(name, vm) {
|
||||
Ok(module)
|
||||
} else if let Some(make_module_func) = vm.stdlib_inits.borrow().get(name) {
|
||||
} else if let Some(make_module_func) = vm.state.stdlib_inits.get(name) {
|
||||
Ok(make_module_func(vm))
|
||||
} else {
|
||||
Ok(vm.get_none())
|
||||
@@ -53,8 +53,8 @@ fn imp_exec_builtin(_mod: PyModuleRef) -> i32 {
|
||||
}
|
||||
|
||||
fn imp_get_frozen_object(name: PyStringRef, vm: &VirtualMachine) -> PyResult<PyCode> {
|
||||
vm.frozen
|
||||
.borrow()
|
||||
vm.state
|
||||
.frozen
|
||||
.get(name.as_str())
|
||||
.map(|frozen| {
|
||||
let mut frozen = frozen.code.clone();
|
||||
@@ -71,8 +71,8 @@ fn imp_init_frozen(name: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
}
|
||||
|
||||
fn imp_is_frozen_package(name: PyStringRef, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
vm.frozen
|
||||
.borrow()
|
||||
vm.state
|
||||
.frozen
|
||||
.get(name.as_str())
|
||||
.map(|frozen| frozen.package)
|
||||
.ok_or_else(|| {
|
||||
|
||||
@@ -38,6 +38,10 @@ fn assert_in_range(signum: i32, vm: &VirtualMachine) -> PyResult<()> {
|
||||
|
||||
fn signal(signalnum: i32, handler: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
assert_in_range(signalnum, vm)?;
|
||||
let signal_handlers = vm
|
||||
.signal_handlers
|
||||
.as_ref()
|
||||
.ok_or_else(|| vm.new_value_error("signal only works in main thread".to_owned()))?;
|
||||
|
||||
let sig_handler = match usize::try_from_object(vm, handler.clone()).ok() {
|
||||
Some(SIG_DFL) => SIG_DFL,
|
||||
@@ -68,7 +72,7 @@ fn signal(signalnum: i32, handler: PyObjectRef, vm: &VirtualMachine) -> PyResult
|
||||
|
||||
let mut old_handler = handler;
|
||||
std::mem::swap(
|
||||
&mut vm.signal_handlers.borrow_mut()[signalnum as usize],
|
||||
&mut signal_handlers.borrow_mut()[signalnum as usize],
|
||||
&mut old_handler,
|
||||
);
|
||||
Ok(old_handler)
|
||||
@@ -76,7 +80,11 @@ fn signal(signalnum: i32, handler: PyObjectRef, vm: &VirtualMachine) -> PyResult
|
||||
|
||||
fn getsignal(signalnum: i32, vm: &VirtualMachine) -> PyResult {
|
||||
assert_in_range(signalnum, vm)?;
|
||||
Ok(vm.signal_handlers.borrow()[signalnum as usize].clone())
|
||||
let signal_handlers = vm
|
||||
.signal_handlers
|
||||
.as_ref()
|
||||
.ok_or_else(|| vm.new_value_error("getsignal only works in main thread".to_owned()))?;
|
||||
Ok(signal_handlers.borrow()[signalnum as usize].clone())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -91,13 +99,18 @@ fn alarm(time: u32) -> u32 {
|
||||
|
||||
#[cfg_attr(feature = "flame-it", flame)]
|
||||
pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> {
|
||||
let signal_handlers = match vm.signal_handlers {
|
||||
Some(ref h) => h.borrow(),
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
if !ANY_TRIGGERED.swap(false, Ordering::Relaxed) {
|
||||
return Ok(());
|
||||
}
|
||||
for (signum, trigger) in TRIGGERS.iter().enumerate().skip(1) {
|
||||
let triggerd = trigger.swap(false, Ordering::Relaxed);
|
||||
if triggerd {
|
||||
let handler = &vm.signal_handlers.borrow()[signum];
|
||||
let handler = &signal_handlers[signum];
|
||||
if vm.is_callable(handler) {
|
||||
vm.invoke(handler, vec![vm.new_int(signum), vm.get_none()])?;
|
||||
}
|
||||
@@ -145,7 +158,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
} else {
|
||||
vm.get_none()
|
||||
};
|
||||
vm.signal_handlers.borrow_mut()[signum] = py_handler;
|
||||
vm.signal_handlers.as_ref().unwrap().borrow_mut()[signum] = py_handler;
|
||||
}
|
||||
|
||||
signal(libc::SIGINT, int_handler, vm).expect("Failed to set sigint handler");
|
||||
|
||||
@@ -18,7 +18,8 @@ use crate::vm::{PySettings, VirtualMachine};
|
||||
|
||||
fn argv(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.new_list(
|
||||
vm.settings
|
||||
vm.state
|
||||
.settings
|
||||
.argv
|
||||
.iter()
|
||||
.map(|arg| vm.new_str(arg.to_owned()))
|
||||
@@ -150,7 +151,7 @@ fn update_use_tracing(vm: &VirtualMachine) {
|
||||
let trace_is_none = vm.is_none(&vm.trace_func.borrow());
|
||||
let profile_is_none = vm.is_none(&vm.profile_func.borrow());
|
||||
let tracing = !(trace_is_none && profile_is_none);
|
||||
vm.use_tracing.replace(tracing);
|
||||
vm.use_tracing.set(tracing);
|
||||
}
|
||||
|
||||
fn sys_getrecursionlimit(vm: &VirtualMachine) -> usize {
|
||||
@@ -225,7 +226,7 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
let flags_type = SysFlags::make_class(ctx);
|
||||
let flags = SysFlags::from_settings(&vm.settings)
|
||||
let flags = SysFlags::from_settings(&vm.state.settings)
|
||||
.into_struct_sequence(vm, flags_type)
|
||||
.unwrap();
|
||||
|
||||
@@ -246,7 +247,8 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR
|
||||
});
|
||||
|
||||
let path = ctx.new_list(
|
||||
vm.settings
|
||||
vm.state
|
||||
.settings
|
||||
.path_list
|
||||
.iter()
|
||||
.map(|path| ctx.new_str(path.clone()))
|
||||
@@ -348,7 +350,7 @@ setprofile() -- set the global profiling function
|
||||
setrecursionlimit() -- set the max recursion depth for the interpreter
|
||||
settrace() -- set the global debug tracing function
|
||||
";
|
||||
let mut module_names: Vec<String> = vm.stdlib_inits.borrow().keys().cloned().collect();
|
||||
let mut module_names: Vec<String> = vm.state.stdlib_inits.keys().cloned().collect();
|
||||
module_names.push("sys".to_owned());
|
||||
module_names.push("builtins".to_owned());
|
||||
module_names.sort();
|
||||
@@ -399,7 +401,7 @@ settrace() -- set the global debug tracing function
|
||||
"path_hooks" => ctx.new_list(vec![]),
|
||||
"path_importer_cache" => ctx.new_dict(),
|
||||
"pycache_prefix" => vm.get_none(),
|
||||
"dont_write_bytecode" => vm.new_bool(vm.settings.dont_write_bytecode),
|
||||
"dont_write_bytecode" => vm.new_bool(vm.state.settings.dont_write_bytecode),
|
||||
"setprofile" => ctx.new_function(sys_setprofile),
|
||||
"setrecursionlimit" => ctx.new_function(sys_setrecursionlimit),
|
||||
"settrace" => ctx.new_function(sys_settrace),
|
||||
|
||||
55
vm/src/vm.rs
55
vm/src/vm.rs
@@ -56,23 +56,26 @@ use crate::sysmodule;
|
||||
pub struct VirtualMachine {
|
||||
pub builtins: PyObjectRef,
|
||||
pub sys_module: PyObjectRef,
|
||||
pub stdlib_inits: RefCell<HashMap<String, stdlib::StdlibInitFunc>>,
|
||||
pub ctx: PyContext,
|
||||
pub frames: RefCell<Vec<FrameRef>>,
|
||||
pub wasm_id: Option<String>,
|
||||
pub exceptions: RefCell<Vec<PyBaseExceptionRef>>,
|
||||
pub frozen: RefCell<HashMap<String, bytecode::FrozenModule>>,
|
||||
pub import_func: RefCell<PyObjectRef>,
|
||||
pub import_func: PyObjectRef,
|
||||
pub profile_func: RefCell<PyObjectRef>,
|
||||
pub trace_func: RefCell<PyObjectRef>,
|
||||
pub use_tracing: RefCell<bool>,
|
||||
pub signal_handlers: RefCell<[PyObjectRef; NSIG]>,
|
||||
pub settings: PySettings,
|
||||
pub use_tracing: Cell<bool>,
|
||||
pub recursion_limit: Cell<usize>,
|
||||
pub codec_registry: RefCell<Vec<PyObjectRef>>,
|
||||
pub signal_handlers: Option<RefCell<[PyObjectRef; NSIG]>>,
|
||||
pub state: Arc<PyGlobalState>,
|
||||
pub initialized: bool,
|
||||
}
|
||||
|
||||
pub struct PyGlobalState {
|
||||
pub settings: PySettings,
|
||||
pub stdlib_inits: HashMap<String, stdlib::StdlibInitFunc>,
|
||||
pub frozen: HashMap<String, bytecode::FrozenModule>,
|
||||
}
|
||||
|
||||
pub const NSIG: usize = 64;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@@ -175,31 +178,33 @@ impl VirtualMachine {
|
||||
let sysmod_dict = ctx.new_dict();
|
||||
let sysmod = new_module(sysmod_dict.clone());
|
||||
|
||||
let stdlib_inits = RefCell::new(stdlib::get_module_inits());
|
||||
let frozen = RefCell::new(frozen::get_module_inits());
|
||||
let import_func = RefCell::new(ctx.none());
|
||||
let import_func = ctx.none();
|
||||
let profile_func = RefCell::new(ctx.none());
|
||||
let trace_func = RefCell::new(ctx.none());
|
||||
let signal_handlers = RefCell::new(arr![ctx.none(); 64]);
|
||||
let initialize_parameter = settings.initialization_parameter;
|
||||
|
||||
let stdlib_inits = stdlib::get_module_inits();
|
||||
let frozen = frozen::get_module_inits();
|
||||
|
||||
let mut vm = VirtualMachine {
|
||||
builtins: builtins.clone(),
|
||||
sys_module: sysmod.clone(),
|
||||
stdlib_inits,
|
||||
ctx,
|
||||
frames: RefCell::new(vec![]),
|
||||
wasm_id: None,
|
||||
exceptions: RefCell::new(vec![]),
|
||||
frozen,
|
||||
import_func,
|
||||
profile_func,
|
||||
trace_func,
|
||||
use_tracing: RefCell::new(false),
|
||||
signal_handlers,
|
||||
settings,
|
||||
use_tracing: Cell::new(false),
|
||||
recursion_limit: Cell::new(if cfg!(debug_assertions) { 256 } else { 512 }),
|
||||
codec_registry: RefCell::default(),
|
||||
signal_handlers: Some(signal_handlers),
|
||||
state: Arc::new(PyGlobalState {
|
||||
settings,
|
||||
stdlib_inits,
|
||||
frozen,
|
||||
}),
|
||||
initialized: false,
|
||||
};
|
||||
|
||||
@@ -232,7 +237,7 @@ impl VirtualMachine {
|
||||
builtins::make_module(self, self.builtins.clone());
|
||||
sysmodule::make_module(self, self.sys_module.clone(), self.builtins.clone());
|
||||
|
||||
let inner_init = || -> PyResult<()> {
|
||||
let mut inner_init = || -> PyResult<()> {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
import::import_builtin(self, "signal")?;
|
||||
|
||||
@@ -266,7 +271,9 @@ impl VirtualMachine {
|
||||
Ok(())
|
||||
};
|
||||
|
||||
self.expect_pyresult(inner_init(), "initializiation failed");
|
||||
let res = inner_init();
|
||||
|
||||
self.expect_pyresult(res, "initializiation failed");
|
||||
|
||||
self.initialized = true;
|
||||
}
|
||||
@@ -814,7 +821,7 @@ impl VirtualMachine {
|
||||
|
||||
/// Call registered trace function.
|
||||
fn trace_event(&self, event: TraceEvent) -> PyResult<()> {
|
||||
if *self.use_tracing.borrow() {
|
||||
if self.use_tracing.get() {
|
||||
let frame = self.get_none();
|
||||
let event = self.new_str(event.to_string());
|
||||
let arg = self.get_none();
|
||||
@@ -824,17 +831,17 @@ impl VirtualMachine {
|
||||
// tracing function itself.
|
||||
let trace_func = self.trace_func.borrow().clone();
|
||||
if !self.is_none(&trace_func) {
|
||||
self.use_tracing.replace(false);
|
||||
self.use_tracing.set(false);
|
||||
let res = self.invoke(&trace_func, args.clone());
|
||||
self.use_tracing.replace(true);
|
||||
self.use_tracing.set(true);
|
||||
res?;
|
||||
}
|
||||
|
||||
let profile_func = self.profile_func.borrow().clone();
|
||||
if !self.is_none(&profile_func) {
|
||||
self.use_tracing.replace(false);
|
||||
self.use_tracing.set(false);
|
||||
let res = self.invoke(&profile_func, args);
|
||||
self.use_tracing.replace(true);
|
||||
self.use_tracing.set(true);
|
||||
res?;
|
||||
}
|
||||
}
|
||||
@@ -1033,7 +1040,7 @@ impl VirtualMachine {
|
||||
#[cfg(feature = "rustpython-compiler")]
|
||||
pub fn compile_opts(&self) -> CompileOpts {
|
||||
CompileOpts {
|
||||
optimize: self.settings.optimize,
|
||||
optimize: self.state.settings.optimize,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use futures::Future;
|
||||
use js_sys::Promise;
|
||||
use std::sync::Arc;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::{future_to_promise, JsFuture};
|
||||
@@ -375,11 +376,12 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn setup_browser_module(vm: &VirtualMachine) {
|
||||
vm.stdlib_inits
|
||||
.borrow_mut()
|
||||
pub fn setup_browser_module(vm: &mut VirtualMachine) {
|
||||
let state = Arc::get_mut(&mut vm.state).unwrap();
|
||||
state
|
||||
.stdlib_inits
|
||||
.insert("_browser".to_owned(), Box::new(make_module));
|
||||
vm.frozen.borrow_mut().extend(py_compile_bytecode!(
|
||||
state.frozen.extend(py_compile_bytecode!(
|
||||
file = "src/browser.py",
|
||||
module_name = "browser",
|
||||
));
|
||||
|
||||
@@ -5,6 +5,7 @@ use rustpython_vm::obj::{objfloat::PyFloatRef, objstr::PyStringRef, objtype::PyC
|
||||
use rustpython_vm::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject};
|
||||
use rustpython_vm::types::create_type;
|
||||
use rustpython_vm::VirtualMachine;
|
||||
use std::sync::Arc;
|
||||
use wasm_bindgen::{prelude::*, JsCast};
|
||||
|
||||
#[wasm_bindgen(inline_js = "
|
||||
@@ -257,8 +258,9 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn setup_js_module(vm: &VirtualMachine) {
|
||||
vm.stdlib_inits
|
||||
.borrow_mut()
|
||||
pub fn setup_js_module(vm: &mut VirtualMachine) {
|
||||
let state = Arc::get_mut(&mut vm.state).unwrap();
|
||||
state
|
||||
.stdlib_inits
|
||||
.insert("_js".to_owned(), Box::new(make_module));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::Arc;
|
||||
|
||||
use js_sys::{Object, TypeError};
|
||||
use wasm_bindgen::prelude::*;
|
||||
@@ -36,9 +37,9 @@ impl StoredVirtualMachine {
|
||||
vm.wasm_id = Some(id);
|
||||
let scope = vm.new_scope_with_builtins();
|
||||
|
||||
js_module::setup_js_module(&vm);
|
||||
js_module::setup_js_module(&mut vm);
|
||||
if inject_browser_module {
|
||||
vm.stdlib_inits.borrow_mut().insert(
|
||||
Arc::get_mut(&mut vm.state).unwrap().stdlib_inits.insert(
|
||||
"_window".to_owned(),
|
||||
Box::new(|vm| {
|
||||
py_module!(vm, "_window", {
|
||||
@@ -46,7 +47,7 @@ impl StoredVirtualMachine {
|
||||
})
|
||||
}),
|
||||
);
|
||||
setup_browser_module(&vm);
|
||||
setup_browser_module(&mut vm);
|
||||
}
|
||||
|
||||
vm.initialize(InitParameter::InitializeInternal);
|
||||
@@ -288,26 +289,19 @@ impl WASMVirtualMachine {
|
||||
#[wasm_bindgen(js_name = injectJSModule)]
|
||||
pub fn inject_js_module(&self, name: String, module: Object) -> Result<(), JsValue> {
|
||||
self.with(|StoredVirtualMachine { ref vm, .. }| {
|
||||
let mut module_items: HashMap<String, PyObjectRef> = HashMap::new();
|
||||
let py_module = vm.new_module(&name, vm.ctx.new_dict());
|
||||
for entry in convert::object_entries(&module) {
|
||||
let (key, value) = entry?;
|
||||
let key = Object::from(key).to_string();
|
||||
module_items.insert(key.into(), convert::js_to_py(vm, value));
|
||||
extend_module!(vm, py_module, {
|
||||
String::from(key) => convert::js_to_py(vm, value),
|
||||
});
|
||||
}
|
||||
|
||||
let mod_name = name.clone();
|
||||
|
||||
let stdlib_init_fn = move |vm: &VirtualMachine| {
|
||||
let module = vm.new_module(&name, vm.ctx.new_dict());
|
||||
for (key, value) in module_items.clone() {
|
||||
vm.set_attr(&module, key, value).unwrap();
|
||||
}
|
||||
module
|
||||
};
|
||||
|
||||
vm.stdlib_inits
|
||||
.borrow_mut()
|
||||
.insert(mod_name, Box::new(stdlib_init_fn));
|
||||
let sys_modules = vm
|
||||
.get_attribute(vm.sys_module.clone(), "modules")
|
||||
.to_js(vm)?;
|
||||
sys_modules.set_item(&name, py_module, vm).to_js(vm)?;
|
||||
|
||||
Ok(())
|
||||
})?
|
||||
|
||||
Reference in New Issue
Block a user