Skip to content

Commit 662910e

Browse files
authored
Merge pull request #4031 from youknowone/encodings-feature
encodings as vm feature
2 parents 0294d10 + 003af16 commit 662910e

9 files changed

Lines changed: 59 additions & 21 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ members = [
1919
]
2020

2121
[features]
22-
default = ["threading", "pylib", "stdlib", "zlib"]
22+
default = ["threading", "pylib", "stdlib", "zlib", "importlib", "encodings"]
23+
importlib = ["rustpython-vm/importlib"]
24+
encodings = ["rustpython-vm/encodings"]
2325
stdlib = ["rustpython-stdlib"]
2426
flame-it = ["rustpython-vm/flame-it", "flame", "flamescope"]
2527
freeze-stdlib = ["rustpython-vm/freeze-stdlib"]

vm/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ include = ["src/**/*.rs", "Cargo.toml", "build.rs", "Lib/**/*.py"]
1010

1111
[features]
1212
default = ["compile-parse", "pylib"]
13+
importlib = []
14+
encodings = ["importlib"]
1315
vm-tracing-logging = []
1416
flame-it = ["flame", "flamer"]
1517
pylib = ["rustpython-pylib"]

vm/Lib/core_modules/codecs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../Lib/codecs.py
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../Lib/encodings/utf_8.py

vm/src/codecs.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,25 @@ impl CodecsRegistry {
210210
Ok(())
211211
}
212212

213+
#[cfg(not(feature = "encodings"))]
214+
pub(crate) fn register_manual(&self, name: &str, codec: PyCodec) -> PyResult<()> {
215+
self.inner
216+
.write()
217+
.search_cache
218+
.insert(name.to_owned(), codec);
219+
Ok(())
220+
}
221+
213222
pub fn lookup(&self, encoding: &str, vm: &VirtualMachine) -> PyResult<PyCodec> {
214223
let encoding = normalize_encoding_name(encoding);
215-
let inner = self.inner.read();
216-
if let Some(codec) = inner.search_cache.get(encoding.as_ref()) {
217-
return Ok(codec.clone());
218-
}
219-
let search_path = inner.search_path.clone();
220-
drop(inner); // don't want to deadlock
224+
let search_path = {
225+
let inner = self.inner.read();
226+
if let Some(codec) = inner.search_cache.get(encoding.as_ref()) {
227+
// hit cache
228+
return Ok(codec.clone());
229+
}
230+
inner.search_path.clone()
231+
};
221232
let encoding = PyStr::from(encoding.into_owned()).into_ref(vm);
222233
for func in search_path {
223234
let res = vm.invoke(&func, (encoding.clone(),))?;

vm/src/import.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ pub fn import_codeobj(
153153
sys_modules.set_item(module_name, module.clone(), vm)?;
154154

155155
// Execute main code in module:
156-
vm.run_code_obj(code_obj, Scope::with_builtins(None, attrs, vm))?;
156+
let scope = Scope::with_builtins(None, attrs, vm);
157+
vm.run_code_obj(code_obj, scope)?;
157158
Ok(module)
158159
}
159160

vm/src/vm/mod.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,36 @@ impl VirtualMachine {
187187
vm
188188
}
189189

190+
/// set up the encodings search function
191+
/// init_importlib must be called before this call
192+
#[cfg(feature = "encodings")]
193+
fn import_encodings(&mut self) -> PyResult<()> {
194+
self.import("encodings", None, 0).map_err(|import_err| {
195+
let err = self.new_runtime_error(
196+
"Could not import encodings. Is your RUSTPYTHONPATH set? If you don't have \
197+
access to a consistent external environment (e.g. if you're embedding \
198+
rustpython in another application), try enabling the freeze-stdlib feature"
199+
.to_owned(),
200+
);
201+
err.set_cause(Some(import_err));
202+
err
203+
})?;
204+
Ok(())
205+
}
206+
207+
/// init only utf-8 encoding
208+
#[cfg(not(feature = "encodings"))]
209+
fn import_encodings(&mut self) -> PyResult<()> {
210+
import::import_frozen(self, "codecs")?;
211+
let encoding_module = import::import_frozen(self, "encodings_utf_8")?;
212+
let getregentry = encoding_module.get_attr("getregentry", self)?;
213+
let codec_info = self.invoke(&getregentry, ())?;
214+
self.state
215+
.codec_registry
216+
.register_manual("utf-8", codec_info.try_into_value(self)?)?;
217+
Ok(())
218+
}
219+
190220
fn initialize(&mut self) {
191221
flame_guard!("init VirtualMachine");
192222

@@ -202,17 +232,7 @@ impl VirtualMachine {
202232
import::import_builtin(self, "_signal")?;
203233
import::init_importlib(self, self.state.settings.allow_external_library)?;
204234

205-
// set up the encodings search function
206-
self.import("encodings", None, 0).map_err(|import_err| {
207-
let err = self.new_runtime_error(
208-
"Could not import encodings. Is your RUSTPYTHONPATH set? If you don't have \
209-
access to a consistent external environment (e.g. if you're embedding \
210-
rustpython in another application), try enabling the freeze-stdlib feature"
211-
.to_owned(),
212-
);
213-
err.set_cause(Some(import_err));
214-
err
215-
})?;
235+
self.import_encodings()?;
216236

217237
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
218238
{

vm/src/vm/setting.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl Default for Settings {
9393
argv: vec![],
9494
hash_seed: None,
9595
stdio_unbuffered: false,
96-
allow_external_library: true,
96+
allow_external_library: cfg!(feature = "importlib"),
9797
}
9898
}
9999
}

wasm/lib/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ no-start-func = []
1919
rustpython-parser = { path = "../../parser" }
2020
rustpython-common = { path = "../../common" }
2121
# make sure no threading! otherwise wasm build will fail
22-
rustpython-vm = { path = "../../vm", default-features = false, features = ["compile-parse"] }
22+
rustpython-vm = { path = "../../vm", default-features = false, features = ["compile-parse", "encodings"] }
2323
rustpython-stdlib = { path = "../../stdlib", default-features = false, features = ["compile-parse"], optional = true }
2424
wasm-bindgen = "0.2"
2525
wasm-bindgen-futures = "0.4"

0 commit comments

Comments
 (0)