Skip to content

Commit 85030e3

Browse files
coolreader18youknowone
authored andcommitted
Make rustpython-vm compatible with non-js wasm32-unknown & add tests
1 parent 2919df1 commit 85030e3

File tree

11 files changed

+66
-9
lines changed

11 files changed

+66
-9
lines changed

.github/workflows/ci.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,14 @@ jobs:
380380
env:
381381
NODE_OPTIONS: "--openssl-legacy-provider"
382382
working-directory: ./wasm/demo
383+
- uses: mwilliamson/setup-wabt-action@v1
384+
with: { wabt-version: "1.0.30" }
385+
- name: check wasm32-unknown without js
386+
run: |
387+
cargo build --release -p wasm-unknown-test --target wasm32-unknown-unknown --verbose
388+
if wasm-objdump -xj Import target/wasm32-unknown-unknown/release/wasm_unknown_test.wasm; then
389+
echo "ERROR: wasm32-unknown module expects imports from the host environment" >2
390+
fi
383391
- name: build notebook demo
384392
if: github.ref == 'refs/heads/release'
385393
run: |

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ x86_64-pc-windows-msvc = { triplet = "x64-windows-static-md", dev-dependencies =
9696
resolver = "2"
9797
members = [
9898
"compiler", "compiler/core", "compiler/codegen",
99-
".", "common", "derive", "jit", "vm", "vm/sre_engine", "pylib", "stdlib", "wasm/lib", "derive-impl",
99+
".", "common", "derive", "jit", "vm", "vm/sre_engine", "pylib", "stdlib", "derive-impl",
100+
"wasm/lib", "wasm/wasm-unknown-test",
100101
]
101102

102103
[workspace.package]

stdlib/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ ssl-vendor = ["ssl", "openssl/vendored", "openssl-probe"]
2222
[dependencies]
2323
# rustpython crates
2424
rustpython-derive = { workspace = true }
25-
rustpython-vm = { workspace = true }
25+
rustpython-vm = { workspace = true, default-features = false }
2626
rustpython-common = { workspace = true }
2727

2828
ahash = { workspace = true }

vm/Cargo.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repository.workspace = true
1010
license.workspace = true
1111

1212
[features]
13-
default = ["compiler"]
13+
default = ["compiler", "js"]
1414
importlib = []
1515
encodings = ["importlib"]
1616
vm-tracing-logging = []
@@ -24,6 +24,8 @@ codegen = ["rustpython-codegen", "ast"]
2424
parser = ["rustpython-parser", "ast"]
2525
serde = ["dep:serde"]
2626

27+
js = ["getrandom/js", "chrono/wasmbind", "wasm-bindgen"]
28+
2729
[dependencies]
2830
rustpython-compiler = { workspace = true, optional = true }
2931
rustpython-codegen = { workspace = true, optional = true }
@@ -71,7 +73,7 @@ thread_local = { workspace = true }
7173
memchr = { workspace = true }
7274

7375
caseless = "0.2.1"
74-
getrandom = { version = "0.2.12", features = ["js"] }
76+
getrandom = { version = "0.2.12" }
7577
flamer = { version = "0.4", optional = true }
7678
half = "1.8.2"
7779
memoffset = "0.9.1"
@@ -140,8 +142,8 @@ features = [
140142
"Win32_UI_WindowsAndMessaging",
141143
]
142144

143-
[target.'cfg(target_arch = "wasm32")'.dependencies]
144-
wasm-bindgen = "0.2.92"
145+
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
146+
wasm-bindgen = { version = "0.2.92", optional = true }
145147

146148
[build-dependencies]
147149
glob = { workspace = true }

vm/src/stdlib/time.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ mod decl {
102102
Ok(duration_since_system_now(vm)?.as_secs_f64())
103103
}
104104

105-
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
105+
#[cfg(all(target_arch = "wasm32", feature = "js", not(target_os = "wasi")))]
106106
fn _time(_vm: &VirtualMachine) -> PyResult<f64> {
107107
use wasm_bindgen::prelude::*;
108108
#[wasm_bindgen]
@@ -115,6 +115,11 @@ mod decl {
115115
Ok(Date::now() / 1000.0)
116116
}
117117

118+
#[cfg(all(target_arch = "wasm32", not(feature = "js"), not(target_os = "wasi")))]
119+
fn _time(vm: &VirtualMachine) -> PyResult<f64> {
120+
Err(vm.new_not_implemented_error("time.time".to_owned()))
121+
}
122+
118123
#[pyfunction]
119124
fn monotonic(vm: &VirtualMachine) -> PyResult<f64> {
120125
Ok(get_monotonic_time(vm)?.as_secs_f64())

vm/src/vm/vm_object.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl VirtualMachine {
1919
self.flush_std();
2020
panic!("{msg}")
2121
}
22-
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
22+
#[cfg(all(target_arch = "wasm32", feature = "js", not(target_os = "wasi")))]
2323
{
2424
use wasm_bindgen::prelude::*;
2525
#[wasm_bindgen]
@@ -32,6 +32,11 @@ impl VirtualMachine {
3232
error(&s);
3333
panic!("{}; exception backtrace above", msg)
3434
}
35+
#[cfg(all(target_arch = "wasm32", not(feature = "js"), not(target_os = "wasi")))]
36+
{
37+
let _ = exc;
38+
panic!("{}; python exception not available", msg)
39+
}
3540
}
3641

3742
pub(crate) fn flush_std(&self) {

wasm/lib/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ rustpython-common = { workspace = true }
2121
rustpython-pylib = { workspace = true, optional = true }
2222
rustpython-stdlib = { workspace = true, default-features = false, optional = true }
2323
# make sure no threading! otherwise wasm build will fail
24-
rustpython-vm = { workspace = true, features = ["compiler", "encodings", "serde"] }
24+
rustpython-vm = { workspace = true, features = ["compiler", "encodings", "serde", "js"] }
2525

2626
rustpython-parser = { workspace = true }
2727

wasm/wasm-unknown-test/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "wasm-unknown-test"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
9+
[dependencies]
10+
getrandom = { version = "0.2.7", features = ["custom"] }
11+
rustpython-vm = { path = "../../vm", default-features = false, features = ["compiler"] }

wasm/wasm-unknown-test/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A test crate to ensure that `rustpython-vm` compiles on `wasm32-unknown-unknown` without a JS host.

wasm/wasm-unknown-test/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use rustpython_vm::{eval, Interpreter};
2+
3+
pub unsafe extern "C" fn eval(s: *const u8, l: usize) -> u32 {
4+
let src = std::slice::from_raw_parts(s, l);
5+
let src = std::str::from_utf8(src).unwrap();
6+
Interpreter::without_stdlib(Default::default()).enter(|vm| {
7+
let res = eval::eval(vm, src, vm.new_scope_with_builtins(), "<string>").unwrap();
8+
res.try_into_value(vm).unwrap()
9+
})
10+
}
11+
12+
fn getrandom_always_fail(_buf: &mut [u8]) -> Result<(), getrandom::Error> {
13+
Err(getrandom::Error::UNSUPPORTED)
14+
}
15+
16+
getrandom::register_custom_getrandom!(getrandom_always_fail);

0 commit comments

Comments
 (0)