Skip to content

Commit

Permalink
Merge pull request #5390 from youknowone/wasmbind
Browse files Browse the repository at this point in the history
recreating wasmbind patch
  • Loading branch information
youknowone authored Aug 9, 2024
2 parents 2919df1 + 42bba69 commit 060db59
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 29 deletions.
15 changes: 8 additions & 7 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -216,13 +216,6 @@ jobs:
- name: Check compilation for freebsd
run: cargo check --target x86_64-unknown-freebsd

- uses: dtolnay/rust-toolchain@stable
with:
target: wasm32-unknown-unknown

- name: Check compilation for wasm32
run: cargo check --target wasm32-unknown-unknown --no-default-features

- uses: dtolnay/rust-toolchain@stable
with:
target: x86_64-unknown-freebsd
Expand Down Expand Up @@ -380,6 +373,14 @@ jobs:
env:
NODE_OPTIONS: "--openssl-legacy-provider"
working-directory: ./wasm/demo
- uses: mwilliamson/setup-wabt-action@v1
with: { wabt-version: "1.0.30" }
- name: check wasm32-unknown without js
run: |
cargo build --release --manifest-path wasm/wasm-unknown-test/Cargo.toml --target wasm32-unknown-unknown --verbose
if wasm-objdump -xj Import target/wasm32-unknown-unknown/release/wasm_unknown_test.wasm; then
echo "ERROR: wasm32-unknown module expects imports from the host environment" >2
fi
- name: build notebook demo
if: github.ref == 'refs/heads/release'
run: |
Expand Down
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ x86_64-pc-windows-msvc = { triplet = "x64-windows-static-md", dev-dependencies =
resolver = "2"
members = [
"compiler", "compiler/core", "compiler/codegen",
".", "common", "derive", "jit", "vm", "vm/sre_engine", "pylib", "stdlib", "wasm/lib", "derive-impl",
".", "common", "derive", "jit", "vm", "vm/sre_engine", "pylib", "stdlib", "derive-impl",
"wasm/lib",
]

[workspace.package]
Expand Down Expand Up @@ -146,6 +147,7 @@ cfg-if = "1.0"
chrono = "0.4.37"
crossbeam-utils = "0.8.19"
flame = "0.2.2"
getrandom = "0.2.12"
glob = "0.3"
hex = "0.4.3"
indexmap = { version = "2.2.6", features = ["std"] }
Expand Down Expand Up @@ -178,6 +180,7 @@ thread_local = "1.1.4"
unicode_names2 = "1.2.0"
widestring = "1.1.0"
windows-sys = "0.52.0"
wasm-bindgen = "0.2.92"

# Lints

Expand Down
2 changes: 1 addition & 1 deletion stdlib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ssl-vendor = ["ssl", "openssl/vendored", "openssl-probe"]
[dependencies]
# rustpython crates
rustpython-derive = { workspace = true }
rustpython-vm = { workspace = true }
rustpython-vm = { workspace = true, default-features = false }
rustpython-common = { workspace = true }

ahash = { workspace = true }
Expand Down
25 changes: 15 additions & 10 deletions stdlib/src/dis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,23 @@ mod decl {
let co = if let Ok(co) = obj.get_attr("__code__", vm) {
// Method or function:
PyRef::try_from_object(vm, co)?
} else if let Ok(_co_str) = PyStrRef::try_from_object(vm, obj.clone()) {
} else if let Ok(co_str) = PyStrRef::try_from_object(vm, obj.clone()) {
#[cfg(not(feature = "compiler"))]
return Err(vm.new_runtime_error(
"dis.dis() with str argument requires `compiler` feature".to_owned(),
));
{
let _ = co_str;
return Err(vm.new_runtime_error(
"dis.dis() with str argument requires `compiler` feature".to_owned(),
));
}
#[cfg(feature = "compiler")]
vm.compile(
_co_str.as_str(),
crate::vm::compiler::Mode::Exec,
"<dis>".to_owned(),
)
.map_err(|err| vm.new_syntax_error(&err, Some(_co_str.as_str())))?
{
vm.compile(
co_str.as_str(),
crate::vm::compiler::Mode::Exec,
"<dis>".to_owned(),
)
.map_err(|err| vm.new_syntax_error(&err, Some(co_str.as_str())))?
}
} else {
PyRef::try_from_object(vm, obj)?
};
Expand Down
10 changes: 6 additions & 4 deletions vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repository.workspace = true
license.workspace = true

[features]
default = ["compiler"]
default = ["compiler", "wasmbind"]
importlib = []
encodings = ["importlib"]
vm-tracing-logging = []
Expand All @@ -23,6 +23,7 @@ ast = ["rustpython-ast"]
codegen = ["rustpython-codegen", "ast"]
parser = ["rustpython-parser", "ast"]
serde = ["dep:serde"]
wasmbind = ["chrono/wasmbind", "getrandom/js", "wasm-bindgen"]

[dependencies]
rustpython-compiler = { workspace = true, optional = true }
Expand All @@ -48,6 +49,7 @@ cfg-if = { workspace = true }
crossbeam-utils = { workspace = true }
chrono = { workspace = true, features = ["wasmbind"] }
flame = { workspace = true, optional = true }
getrandom = { workspace = true }
hex = { workspace = true }
indexmap = { workspace = true }
itertools = { workspace = true }
Expand All @@ -71,7 +73,6 @@ thread_local = { workspace = true }
memchr = { workspace = true }

caseless = "0.2.1"
getrandom = { version = "0.2.12", features = ["js"] }
flamer = { version = "0.4", optional = true }
half = "1.8.2"
memoffset = "0.9.1"
Expand Down Expand Up @@ -140,8 +141,9 @@ features = [
"Win32_UI_WindowsAndMessaging",
]

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.92"
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
wasm-bindgen = { workspace = true, optional = true }
getrandom = { workspace = true, features = ["custom"] }

[build-dependencies]
glob = { workspace = true }
Expand Down
20 changes: 18 additions & 2 deletions vm/src/stdlib/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,19 @@ mod decl {
_time(vm)
}

#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
#[cfg(not(all(
target_arch = "wasm32",
not(any(target_os = "emscripten", target_os = "wasi")),
)))]
fn _time(vm: &VirtualMachine) -> PyResult<f64> {
Ok(duration_since_system_now(vm)?.as_secs_f64())
}

#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
fn _time(_vm: &VirtualMachine) -> PyResult<f64> {
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
Expand All @@ -115,6 +122,15 @@ mod decl {
Ok(Date::now() / 1000.0)
}

#[cfg(all(
target_arch = "wasm32",
not(feature = "wasmbind"),
not(any(target_os = "emscripten", target_os = "wasi"))
))]
fn _time(vm: &VirtualMachine) -> PyResult<f64> {
Err(vm.new_not_implemented_error("time.time".to_owned()))
}

#[pyfunction]
fn monotonic(vm: &VirtualMachine) -> PyResult<f64> {
Ok(get_monotonic_time(vm)?.as_secs_f64())
Expand Down
23 changes: 21 additions & 2 deletions vm/src/vm/vm_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ impl VirtualMachine {
#[track_caller]
#[cold]
fn _py_panic_failed(&self, exc: PyBaseExceptionRef, msg: &str) -> ! {
#[cfg(not(all(target_arch = "wasm32", not(target_os = "wasi"))))]
#[cfg(not(all(
target_arch = "wasm32",
not(any(target_os = "emscripten", target_os = "wasi")),
)))]
{
self.print_exception(exc);
self.flush_std();
panic!("{msg}")
}
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi")),
))]
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))]
{
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
Expand All @@ -32,6 +40,17 @@ impl VirtualMachine {
error(&s);
panic!("{}; exception backtrace above", msg)
}
#[cfg(all(
target_arch = "wasm32",
not(feature = "wasmbind"),
not(any(target_os = "emscripten", target_os = "wasi")),
))]
{
use crate::convert::ToPyObject;
let err_string: String = exc.to_pyobject(self).repr(self).unwrap().to_string();
eprintln!("{err_string}");
panic!("{}; python exception not available", msg)
}
}

pub(crate) fn flush_std(&self) {
Expand Down
4 changes: 2 additions & 2 deletions wasm/lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ rustpython-common = { workspace = true }
rustpython-pylib = { workspace = true, optional = true }
rustpython-stdlib = { workspace = true, default-features = false, optional = true }
# make sure no threading! otherwise wasm build will fail
rustpython-vm = { workspace = true, features = ["compiler", "encodings", "serde"] }
rustpython-vm = { workspace = true, features = ["compiler", "encodings", "serde", "wasmbind"] }

rustpython-parser = { workspace = true }

serde = { workspace = true }
wasm-bindgen = { workspace = true }

console_error_panic_hook = "0.1"
js-sys = "0.3"
serde-wasm-bindgen = "0.3.1"
wasm-bindgen = "0.2.80"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"console",
Expand Down
13 changes: 13 additions & 0 deletions wasm/wasm-unknown-test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "wasm-unknown-test"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
getrandom = { version = "0.2.12", features = ["custom"] }
rustpython-vm = { path = "../../vm", default-features = false, features = ["compiler"] }

[workspace]
1 change: 1 addition & 0 deletions wasm/wasm-unknown-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A test crate to ensure that `rustpython-vm` compiles on `wasm32-unknown-unknown` without a JS host.
16 changes: 16 additions & 0 deletions wasm/wasm-unknown-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use rustpython_vm::{eval, Interpreter};

pub unsafe extern "C" fn eval(s: *const u8, l: usize) -> u32 {
let src = std::slice::from_raw_parts(s, l);
let src = std::str::from_utf8(src).unwrap();
Interpreter::without_stdlib(Default::default()).enter(|vm| {
let res = eval::eval(vm, src, vm.new_scope_with_builtins(), "<string>").unwrap();
res.try_into_value(vm).unwrap()
})
}

fn getrandom_always_fail(_buf: &mut [u8]) -> Result<(), getrandom::Error> {
Err(getrandom::Error::UNSUPPORTED)
}

getrandom::register_custom_getrandom!(getrandom_always_fail);

0 comments on commit 060db59

Please sign in to comment.