Skip to content

Commit 7dfb760

Browse files
coolreader18youknowone
authored andcommitted
Make rustpython-vm compatible with non-js wasm32-unknown & add tests
1 parent b6e9a3f commit 7dfb760

File tree

10 files changed

+79
-17
lines changed

10 files changed

+79
-17
lines changed

.github/workflows/ci.yaml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,6 @@ jobs:
216216
- name: Check compilation for freebsd
217217
run: cargo check --target x86_64-unknown-freebsd
218218

219-
- uses: dtolnay/rust-toolchain@stable
220-
with:
221-
target: wasm32-unknown-unknown
222-
223-
- name: Check compilation for wasm32
224-
run: cargo check --target wasm32-unknown-unknown --no-default-features
225-
226219
- uses: dtolnay/rust-toolchain@stable
227220
with:
228221
target: x86_64-unknown-freebsd
@@ -380,6 +373,14 @@ jobs:
380373
env:
381374
NODE_OPTIONS: "--openssl-legacy-provider"
382375
working-directory: ./wasm/demo
376+
- uses: mwilliamson/setup-wabt-action@v1
377+
with: { wabt-version: "1.0.30" }
378+
- name: check wasm32-unknown without js
379+
run: |
380+
cargo build --release -p wasm-unknown-test --target wasm32-unknown-unknown --verbose
381+
if wasm-objdump -xj Import target/wasm32-unknown-unknown/release/wasm_unknown_test.wasm; then
382+
echo "ERROR: wasm32-unknown module expects imports from the host environment" >2
383+
fi
383384
- name: build notebook demo
384385
if: github.ref == 'refs/heads/release'
385386
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: 4 additions & 5 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", "wasmbind"]
1414
importlib = []
1515
encodings = ["importlib"]
1616
vm-tracing-logging = []
@@ -23,8 +23,7 @@ ast = ["rustpython-ast"]
2323
codegen = ["rustpython-codegen", "ast"]
2424
parser = ["rustpython-parser", "ast"]
2525
serde = ["dep:serde"]
26-
wasmbind = ["chrono/wasmbind", "getrandom/js"]
27-
26+
wasmbind = ["chrono/wasmbind", "getrandom/js", "wasm-bindgen"]
2827

2928
[dependencies]
3029
rustpython-compiler = { workspace = true, optional = true }
@@ -142,8 +141,8 @@ features = [
142141
"Win32_UI_WindowsAndMessaging",
143142
]
144143

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

148147
[build-dependencies]
149148
glob = { workspace = true }

vm/src/stdlib/time.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,7 @@ mod decl {
9999

100100
#[cfg(not(all(
101101
target_arch = "wasm32",
102-
feature = "wasmbind",
103-
not(any(target_os = "emscripten", target_os = "wasi"))
102+
not(any(target_os = "emscripten", target_os = "wasi")),
104103
)))]
105104
fn _time(vm: &VirtualMachine) -> PyResult<f64> {
106105
Ok(duration_since_system_now(vm)?.as_secs_f64())
@@ -123,6 +122,15 @@ mod decl {
123122
Ok(Date::now() / 1000.0)
124123
}
125124

125+
#[cfg(all(
126+
target_arch = "wasm32",
127+
not(feature = "wasmbind"),
128+
not(any(target_os = "emscripten", target_os = "wasi"))
129+
))]
130+
fn _time(vm: &VirtualMachine) -> PyResult<f64> {
131+
Err(vm.new_not_implemented_error("time.time".to_owned()))
132+
}
133+
126134
#[pyfunction]
127135
fn monotonic(vm: &VirtualMachine) -> PyResult<f64> {
128136
Ok(get_monotonic_time(vm)?.as_secs_f64())

vm/src/vm/vm_object.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,20 @@ impl VirtualMachine {
1313
#[track_caller]
1414
#[cold]
1515
fn _py_panic_failed(&self, exc: PyBaseExceptionRef, msg: &str) -> ! {
16-
#[cfg(not(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind")))]
16+
#[cfg(not(all(
17+
target_arch = "wasm32",
18+
not(any(target_os = "emscripten", target_os = "wasi")),
19+
)))]
1720
{
1821
self.print_exception(exc);
1922
self.flush_std();
2023
panic!("{msg}")
2124
}
25+
#[cfg(all(
26+
target_arch = "wasm32",
27+
feature = "wasmbind",
28+
not(any(target_os = "emscripten", target_os = "wasi")),
29+
))]
2230
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))]
2331
{
2432
use wasm_bindgen::prelude::*;
@@ -32,6 +40,15 @@ impl VirtualMachine {
3240
error(&s);
3341
panic!("{}; exception backtrace above", msg)
3442
}
43+
#[cfg(all(
44+
target_arch = "wasm32",
45+
not(feature = "wasmbind"),
46+
not(any(target_os = "emscripten", target_os = "wasi")),
47+
))]
48+
{
49+
let _ = exc;
50+
panic!("{}; python exception not available", msg)
51+
}
3552
}
3653

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

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)