From d4041463bed13a336ea97a43d8317cb08481ed5a Mon Sep 17 00:00:00 2001 From: Michael-F-Bryan Date: Thu, 1 Dec 2022 21:15:37 +0800 Subject: [PATCH] Use the wasm_bindgen_downcast crate for downcasting JsValues We need this because @wasmer/wasi gets minified, which breaks our downcast check. --- Cargo.lock | 28 ++++++++++++++++++++++++++-- lib/api/Cargo.toml | 1 + lib/api/src/js/trap.rs | 28 +++------------------------- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c1696a4834..65436293f0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3208,9 +3208,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", @@ -3815,6 +3815,29 @@ dependencies = [ "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]] name = "wasm-bindgen-futures" version = "0.4.33" @@ -3929,6 +3952,7 @@ dependencies = [ "thiserror", "tracing", "wasm-bindgen", + "wasm-bindgen-downcast", "wasm-bindgen-test", "wasmer-compiler", "wasmer-compiler-cranelift", diff --git a/lib/api/Cargo.toml b/lib/api/Cargo.toml index eb9e6ab45e8..a07c564a755 100644 --- a/lib/api/Cargo.toml +++ b/lib/api/Cargo.toml @@ -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" } diff --git a/lib/api/src/js/trap.rs b/lib/api/src/js/trap.rs index c9d1ac3f389..e871be1c5d9 100644 --- a/lib/api/src/js/trap.rs +++ b/lib/api/src/js/trap.rs @@ -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)> { @@ -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, } @@ -251,35 +252,12 @@ impl std::error::Error for RuntimeError { } } -pub fn generic_of_jsval>( - js: JsValue, - classname: &str, -) -> Result { - 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 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)), }) }