Skip to content

Commit

Permalink
Merge pull request #3400 from wasmerio/fix-downcasting
Browse files Browse the repository at this point in the history
Use the wasm_bindgen_downcast crate for downcasting JsValues
  • Loading branch information
syrusakbary authored Dec 1, 2022
2 parents a565e73 + d404146 commit ecde2aa
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 27 deletions.
28 changes: 26 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ macro-wasmer-universal-test = { version = "3.0.2", path = "./macro-wasmer-univer
# - Mandatory dependencies for `js`.
wasmer-types = { path = "../types", version = "=3.0.2", default-features = false, features = ["std"] }
wasm-bindgen = "0.2.74"
wasm-bindgen-downcast = { version = "0.1.1" }
js-sys = "0.3.51"
#web-sys = { version = "0.3.51", features = [ "console" ] }
wasmer-derive = { path = "../derive", version = "=3.0.2" }
Expand Down
28 changes: 3 additions & 25 deletions lib/api/src/js/trap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::sync::Arc;
use wasm_bindgen::convert::FromWasmAbi;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsValue;
use wasm_bindgen_downcast::DowncastJS;

pub trait CoreError: fmt::Debug + fmt::Display {
fn source(&self) -> Option<&(dyn CoreError + 'static)> {
Expand Down Expand Up @@ -92,7 +93,7 @@ impl dyn CoreError {
/// A struct representing an aborted instruction execution, with a message
/// indicating the cause.
#[wasm_bindgen]
#[derive(Clone)]
#[derive(Clone, DowncastJS)]
pub struct WasmerRuntimeError {
inner: Arc<RuntimeErrorSource>,
}
Expand Down Expand Up @@ -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 {
fn from(original: JsValue) -> Self {
// We try to downcast the error and see if it's
// an instance of RuntimeError instead, so we don't need
// 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)),
})
}
Expand Down

0 comments on commit ecde2aa

Please sign in to comment.