Skip to content

Commit 9199599

Browse files
committed
Make rustpython-vm compatible with non-js wasm32-unknown & add tests
1 parent 273ffd9 commit 9199599

File tree

11 files changed

+70
-14
lines changed

11 files changed

+70
-14
lines changed

.github/workflows/ci.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,14 @@ jobs:
407407
npm install
408408
npm run test
409409
working-directory: ./wasm/demo
410+
- uses: mwilliamson/setup-wabt-action@v1
411+
with: { wabt-version: "1.0.30" }
412+
- name: check wasm32-unknown without js
413+
run: |
414+
cargo build --release -p wasm-unknown-test --target wasm32-unknown-unknown --verbose
415+
if wasm-objdump -xj Import target/wasm32-unknown-unknown/release/wasm_unknown_test.wasm; then
416+
echo "ERROR: wasm32-unknown module expects imports from the host environment" >2
417+
fi
410418
- name: build notebook demo
411419
if: github.ref == 'refs/heads/release'
412420
run: |

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ include = ["LICENSE", "Cargo.toml", "src/**/*.rs"]
1515
resolver = "2"
1616
members = [
1717
"compiler", "compiler/ast", "compiler/core", "compiler/codegen", "compiler/parser",
18-
".", "common", "derive", "jit", "vm", "pylib", "stdlib", "wasm/lib",
18+
".", "common", "derive", "jit", "vm", "pylib", "stdlib", "wasm/lib", "wasm/wasm-unknown-test",
1919
]
2020

2121
[features]

stdlib/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ssl-vendor = ["ssl", "openssl/vendored", "openssl-probe"]
1515
[dependencies]
1616
# rustpython crates
1717
rustpython-derive = { path = "../derive" }
18-
rustpython-vm = { path = "../vm" }
18+
rustpython-vm = { path = "../vm", default-features = false }
1919
rustpython-common = { path = "../common" }
2020

2121
# random

vm/Cargo.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ edition = "2021"
99
include = ["src/**/*.rs", "Cargo.toml", "build.rs", "Lib/**/*.py"]
1010

1111
[features]
12-
default = ["compiler"]
12+
default = ["compiler", "js"]
1313
importlib = []
1414
encodings = ["importlib"]
1515
vm-tracing-logging = []
@@ -22,6 +22,8 @@ ast = ["rustpython-ast"]
2222
codegen = ["rustpython-codegen", "ast"]
2323
parser = ["rustpython-parser", "ast"]
2424

25+
js = ["getrandom/js", "chrono/wasmbind", "wasm-bindgen"]
26+
2527
[dependencies]
2628
rustpython-compiler = { path = "../compiler", optional = true, version = "0.1.2" }
2729
rustpython-ast = { path = "../compiler/ast", optional = true, version = "0.1" }
@@ -38,11 +40,11 @@ num-traits = "0.2.14"
3840
num-integer = "0.1.44"
3941
num-rational = "0.4.0"
4042
rand = "0.8.5"
41-
getrandom = { version = "0.2.6", features = ["js"] }
43+
getrandom = { version = "0.2.6" }
4244
log = "0.4.16"
4345
serde = { version = "1.0.136", features = ["derive"] }
4446
caseless = "0.2.1"
45-
chrono = { version = "0.4.19", features = ["wasmbind"] }
47+
chrono = { version = "0.4.19", default-features = false, features = ["clock", "std", "oldtime"] }
4648
itertools = "0.10.3"
4749
hex = "0.4.3"
4850
hexf-parse = "0.2.1"
@@ -126,8 +128,8 @@ features = [
126128
"impl-default", "vcruntime", "ifdef", "netioapi", "memoryapi",
127129
]
128130

129-
[target.'cfg(target_arch = "wasm32")'.dependencies]
130-
wasm-bindgen = "0.2.80"
131+
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
132+
wasm-bindgen = { version = "0.2.80", optional = true }
131133

132134
[build-dependencies]
133135
itertools = "0.10.3"

vm/src/stdlib/time.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ mod time {
8989
Ok(duration_since_system_now(vm)?.as_secs_f64())
9090
}
9191

92-
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
92+
#[cfg(all(target_arch = "wasm32", feature = "js", not(target_os = "wasi")))]
9393
fn _time(_vm: &VirtualMachine) -> PyResult<f64> {
9494
use wasm_bindgen::prelude::*;
9595
#[wasm_bindgen]
@@ -102,6 +102,11 @@ mod time {
102102
Ok(Date::now() / 1000.0)
103103
}
104104

105+
#[cfg(all(target_arch = "wasm32", not(feature = "js"), not(target_os = "wasi")))]
106+
fn _time(vm: &VirtualMachine) -> PyResult<f64> {
107+
Err(vm.new_not_implemented_error("time.time".to_owned()))
108+
}
109+
105110
#[pyfunction]
106111
fn monotonic(vm: &VirtualMachine) -> PyResult<f64> {
107112
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
@@ -40,7 +40,7 @@ impl VirtualMachine {
4040
};
4141
panic!("{}; {}", msg, after)
4242
}
43-
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
43+
#[cfg(all(target_arch = "wasm32", feature = "js", not(target_os = "wasi")))]
4444
{
4545
use wasm_bindgen::prelude::*;
4646
#[wasm_bindgen]
@@ -53,6 +53,11 @@ impl VirtualMachine {
5353
error(&s);
5454
panic!("{}; exception backtrace above", msg)
5555
}
56+
#[cfg(all(target_arch = "wasm32", not(feature = "js"), not(target_os = "wasi")))]
57+
{
58+
let _ = exc;
59+
panic!("{}; python exception not available", msg)
60+
}
5661
}
5762

5863
#[track_caller]

wasm/lib/Cargo.toml

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

2626
console_error_panic_hook = "0.1"
2727
js-sys = "0.3"

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)