Use the wasm_bindgen_downcast crate for downcasting JsValues

We need this because @wasmer/wasi gets minified, which breaks our downcast check.
This commit is contained in:
Michael-F-Bryan
2022-12-01 21:15:37 +08:00
parent a565e73a4f
commit d4041463be
3 changed files with 30 additions and 27 deletions

28
Cargo.lock generated
View File

@@ -3208,9 +3208,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.103" version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -3815,6 +3815,29 @@ dependencies = [
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
[[package]]
name = "wasm-bindgen-downcast"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340"
dependencies = [
"js-sys",
"once_cell",
"wasm-bindgen",
"wasm-bindgen-downcast-macros",
]
[[package]]
name = "wasm-bindgen-downcast-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "wasm-bindgen-futures" name = "wasm-bindgen-futures"
version = "0.4.33" version = "0.4.33"
@@ -3929,6 +3952,7 @@ dependencies = [
"thiserror", "thiserror",
"tracing", "tracing",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-downcast",
"wasm-bindgen-test", "wasm-bindgen-test",
"wasmer-compiler", "wasmer-compiler",
"wasmer-compiler-cranelift", "wasmer-compiler-cranelift",

View File

@@ -62,6 +62,7 @@ macro-wasmer-universal-test = { version = "3.0.2", path = "./macro-wasmer-univer
# - Mandatory dependencies for `js`. # - Mandatory dependencies for `js`.
wasmer-types = { path = "../types", version = "=3.0.2", default-features = false, features = ["std"] } wasmer-types = { path = "../types", version = "=3.0.2", default-features = false, features = ["std"] }
wasm-bindgen = "0.2.74" wasm-bindgen = "0.2.74"
wasm-bindgen-downcast = { version = "0.1.1" }
js-sys = "0.3.51" js-sys = "0.3.51"
#web-sys = { version = "0.3.51", features = [ "console" ] } #web-sys = { version = "0.3.51", features = [ "console" ] }
wasmer-derive = { path = "../derive", version = "=3.0.2" } wasmer-derive = { path = "../derive", version = "=3.0.2" }

View File

@@ -5,6 +5,7 @@ use std::sync::Arc;
use wasm_bindgen::convert::FromWasmAbi; use wasm_bindgen::convert::FromWasmAbi;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use wasm_bindgen_downcast::DowncastJS;
pub trait CoreError: fmt::Debug + fmt::Display { pub trait CoreError: fmt::Debug + fmt::Display {
fn source(&self) -> Option<&(dyn CoreError + 'static)> { fn source(&self) -> Option<&(dyn CoreError + 'static)> {
@@ -92,7 +93,7 @@ impl dyn CoreError {
/// A struct representing an aborted instruction execution, with a message /// A struct representing an aborted instruction execution, with a message
/// indicating the cause. /// indicating the cause.
#[wasm_bindgen] #[wasm_bindgen]
#[derive(Clone)] #[derive(Clone, DowncastJS)]
pub struct WasmerRuntimeError { pub struct WasmerRuntimeError {
inner: Arc<RuntimeErrorSource>, inner: Arc<RuntimeErrorSource>,
} }
@@ -251,35 +252,12 @@ impl std::error::Error for RuntimeError {
} }
} }
pub fn generic_of_jsval<T: FromWasmAbi<Abi = u32>>(
js: JsValue,
classname: &str,
) -> Result<T, JsValue> {
use js_sys::{Object, Reflect};
let ctor_name = Object::get_prototype_of(&js).constructor().name();
if ctor_name == classname {
let ptr = Reflect::get(&js, &JsValue::from_str("ptr"))?;
match ptr.as_f64() {
Some(ptr_f64) => {
let foo = unsafe { T::from_abi(ptr_f64 as u32) };
Ok(foo)
}
None => {
// We simply relay the js value
Err(js)
}
}
} else {
Err(js)
}
}
impl From<JsValue> for RuntimeError { impl From<JsValue> for RuntimeError {
fn from(original: JsValue) -> Self { fn from(original: JsValue) -> Self {
// We try to downcast the error and see if it's // We try to downcast the error and see if it's
// an instance of RuntimeError instead, so we don't need // an instance of RuntimeError instead, so we don't need
// to re-wrap it. // to re-wrap it.
generic_of_jsval(original, "WasmerRuntimeError").unwrap_or_else(|js| RuntimeError { WasmerRuntimeError::downcast_js(original).unwrap_or_else(|js| RuntimeError {
inner: Arc::new(RuntimeErrorSource::Js(js)), inner: Arc::new(RuntimeErrorSource::Js(js)),
}) })
} }