From 34bab511e5e7e818523154e29dcc59dd8b0bea2b Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Wed, 9 Jan 2019 17:10:24 +0000 Subject: [PATCH 01/14] Use JSON serialization to get better debug printouts. --- crates/cli-support/src/js/mod.rs | 12 ++++++++++++ src/lib.rs | 32 ++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index c63470ed..403f3863 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -299,6 +299,18 @@ impl<'a> Context<'a> { )) })?; + self.bind("__wbindgen_is_array", &|me| { + me.expose_get_object(); + Ok(String::from( + " + function(i) { + const val = getObject(i); + return Array.isArray(val) ? 1 : 0; + } + ", + )) + })?; + self.bind("__wbindgen_is_function", &|me| { me.expose_get_object(); Ok(String::from( diff --git a/src/lib.rs b/src/lib.rs index f8a0f12f..be65dd99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -204,13 +204,7 @@ impl JsValue { where T: for<'a> serde::de::Deserialize<'a>, { - unsafe { - let mut ptr = ptr::null_mut(); - let len = __wbindgen_json_serialize(self.idx, &mut ptr); - let s = Vec::from_raw_parts(ptr, len, len); - let s = String::from_utf8_unchecked(s); - serde_json::from_str(&s) - } + serde_json::from_str(&self.as_json()) } /// Returns the `f64` value of this JS value if it's an instance of a @@ -298,11 +292,27 @@ impl JsValue { unsafe { __wbindgen_is_object(self.idx) == 1 } } + /// Tests whether `Array.isArray(self)`. + #[inline] + pub fn is_array(&self) -> bool { + unsafe { __wbindgen_is_array(self.idx) == 1 } + } + /// Tests whether the type of this JS value is `function`. #[inline] pub fn is_function(&self) -> bool { unsafe { __wbindgen_is_function(self.idx) == 1 } } + + /// Helper method to get the value as a json String (serialized in javascript) + fn as_json(&self) -> String { + unsafe { + let mut ptr = ptr::null_mut(); + let len = __wbindgen_json_serialize(self.idx, &mut ptr); + let s = Vec::from_raw_parts(ptr, len, len); + String::from_utf8_unchecked(s) + } + } } impl PartialEq for JsValue { @@ -474,6 +484,7 @@ externs! { fn __wbindgen_symbol_new(ptr: *const u8, len: usize) -> u32; fn __wbindgen_is_symbol(idx: u32) -> u32; fn __wbindgen_is_object(idx: u32) -> u32; + fn __wbindgen_is_array(idx: u32) -> u32; fn __wbindgen_is_function(idx: u32) -> u32; fn __wbindgen_is_string(idx: u32) -> u32; fn __wbindgen_string_get(idx: u32, len: *mut usize) -> *mut u8; @@ -526,7 +537,12 @@ impl fmt::Debug for JsValue { if self.is_symbol() { return fmt::Display::fmt("Symbol(..)", f); } - fmt::Display::fmt("[object]", f) + let json = self.as_json(); + if json == "{}" { + f.write_str("[object]") + } else { + f.write_str(&json) + } } } From 5b51d279b4523e8baaaaae7e2d898064acad40f1 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Wed, 9 Jan 2019 17:42:56 +0000 Subject: [PATCH 02/14] Use `toString` where `JSON.stringify` didn't work --- crates/cli-support/src/js/mod.rs | 17 +++++++++++++++++ src/lib.rs | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 403f3863..173df872 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -350,6 +350,23 @@ impl<'a> Context<'a> { )) })?; + self.bind("__wbindgen_to_string", &|me| { + me.expose_pass_string_to_wasm()?; + me.expose_get_object(); + me.expose_uint32_memory(); + Ok(String::from( + " + function(i, len_ptr) { + let toString = getObject(i).toString(); + if (typeof(toString) !== 'string') return 0; + const ptr = passStringToWasm(toString); + getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN; + return ptr; + } + ", + )) + })?; + self.bind("__wbindgen_cb_drop", &|me| { me.expose_drop_ref(); Ok(String::from( diff --git a/src/lib.rs b/src/lib.rs index be65dd99..e507af0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -313,6 +313,21 @@ impl JsValue { String::from_utf8_unchecked(s) } } + + /// Get the string value of self using the JS `toString` method. + #[cfg(feature = "std")] + fn js_to_string(&self) -> String { + unsafe { + let mut len = 0; + let ptr = __wbindgen_to_string(self.idx, &mut len); + if ptr.is_null() { + unreachable!("Object.toString must return a valid string") + } else { + let data = Vec::from_raw_parts(ptr, len, len); + String::from_utf8_unchecked(data) + } + } + } } impl PartialEq for JsValue { @@ -488,6 +503,7 @@ externs! { fn __wbindgen_is_function(idx: u32) -> u32; fn __wbindgen_is_string(idx: u32) -> u32; fn __wbindgen_string_get(idx: u32, len: *mut usize) -> *mut u8; + fn __wbindgen_to_string(idx: u32, len: *mut usize) -> *mut u8; fn __wbindgen_throw(a: *const u8, b: usize) -> !; fn __wbindgen_rethrow(a: u32) -> !; @@ -539,7 +555,7 @@ impl fmt::Debug for JsValue { } let json = self.as_json(); if json == "{}" { - f.write_str("[object]") + f.write_str(&self.js_to_string()) } else { f.write_str(&json) } From 126efd5a954d4ce1d787759596bad240b5e8f1b4 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Thu, 10 Jan 2019 23:37:12 +0000 Subject: [PATCH 03/14] Redo as js function + fix tests --- crates/cli-support/src/js/mod.rs | 59 ++++++++++++++++++++++++++-- src/lib.rs | 66 +++++++++++--------------------- tests/wasm/api.rs | 2 +- 3 files changed, 79 insertions(+), 48 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 173df872..62d2deec 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -350,16 +350,67 @@ impl<'a> Context<'a> { )) })?; - self.bind("__wbindgen_to_string", &|me| { + self.bind("__wbindgen_debug_string", &|me| { me.expose_pass_string_to_wasm()?; me.expose_get_object(); me.expose_uint32_memory(); Ok(String::from( " function(i, len_ptr) { - let toString = getObject(i).toString(); - if (typeof(toString) !== 'string') return 0; - const ptr = passStringToWasm(toString); + const debug_str = val => { + // primitive types + const type = typeof val; + if (type == 'number' || type == 'boolean' || val == null) { + return val + ''; + } + if (type == 'string') { + return '\"' + val + '\"'; + } + if (type == 'symbol') { + const description = val.description; + if (description == null) { + return 'Symbol()'; + } else { + return 'Symbol(' + description + ')'; + } + } + if (type == 'function') { + return 'Function'; + } + // objects + if (Array.isArray(val)) { + const length = val.length; + let debug = '['; + if (length > 0) { + debug += debug_str(val[0]); + } + for(let i = 1; i < length; i++) { + debug += debug_str(val[i]) + ', '; + } + debug += ']'; + return debug; + } + // Test for built-in + const builtInMatches = /\\[object ([^])+\\]/.exec(val.toString()); + let className; + if (builtInMatches.len > 0) { + className = builtInMatches[0]; + } else { + // Failed to match the standard '[object ClassName]' + return val.toString(); + } + if (className == 'Object') { + // we're a user defined class or Object + // JSON.stringify avoids problems with cycles, and is generally much + // easier than looping through ownProperties of `val`. + return 'Object(' + JSON.stringify(val) + ')'; + } else { + return className; + } + }; + const val = getObject(i); + const debug = debug_str(val); + const ptr = passStringToWasm(debug); getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN; return ptr; } diff --git a/src/lib.rs b/src/lib.rs index e507af0e..7834819b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -204,7 +204,13 @@ impl JsValue { where T: for<'a> serde::de::Deserialize<'a>, { - serde_json::from_str(&self.as_json()) + unsafe { + let mut ptr = ptr::null_mut(); + let len = __wbindgen_json_serialize(self.idx, &mut ptr); + let s = Vec::from_raw_parts(ptr, len, len); + let s = String::from_utf8_unchecked(s); + serde_json::from_str(&s) + } } /// Returns the `f64` value of this JS value if it's an instance of a @@ -304,24 +310,14 @@ impl JsValue { unsafe { __wbindgen_is_function(self.idx) == 1 } } - /// Helper method to get the value as a json String (serialized in javascript) - fn as_json(&self) -> String { - unsafe { - let mut ptr = ptr::null_mut(); - let len = __wbindgen_json_serialize(self.idx, &mut ptr); - let s = Vec::from_raw_parts(ptr, len, len); - String::from_utf8_unchecked(s) - } - } - - /// Get the string value of self using the JS `toString` method. + /// Get a string representation of the JavaScript object for debugging #[cfg(feature = "std")] - fn js_to_string(&self) -> String { + fn as_debug_string(&self) -> String { unsafe { let mut len = 0; - let ptr = __wbindgen_to_string(self.idx, &mut len); + let ptr = __wbindgen_debug_string(self.idx, &mut len); if ptr.is_null() { - unreachable!("Object.toString must return a valid string") + unreachable!("`__wbindgen_debug_string` must return a valid string") } else { let data = Vec::from_raw_parts(ptr, len, len); String::from_utf8_unchecked(data) @@ -503,7 +499,7 @@ externs! { fn __wbindgen_is_function(idx: u32) -> u32; fn __wbindgen_is_string(idx: u32) -> u32; fn __wbindgen_string_get(idx: u32, len: *mut usize) -> *mut u8; - fn __wbindgen_to_string(idx: u32, len: *mut usize) -> *mut u8; + fn __wbindgen_debug_string(idx: u32, len: *mut usize) -> *mut u8; fn __wbindgen_throw(a: *const u8, b: usize) -> !; fn __wbindgen_rethrow(a: u32) -> !; @@ -530,35 +526,19 @@ impl Clone for JsValue { } } +#[cfg(feature = "std")] impl fmt::Debug for JsValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(n) = self.as_f64() { - return n.fmt(f); - } - #[cfg(feature = "std")] - { - if let Some(n) = self.as_string() { - return n.fmt(f); - } - } - if let Some(n) = self.as_bool() { - return n.fmt(f); - } - if self.is_null() { - return fmt::Display::fmt("null", f); - } - if self.is_undefined() { - return fmt::Display::fmt("undefined", f); - } - if self.is_symbol() { - return fmt::Display::fmt("Symbol(..)", f); - } - let json = self.as_json(); - if json == "{}" { - f.write_str(&self.js_to_string()) - } else { - f.write_str(&json) - } + f.write_str(&self.as_debug_string()) + } +} + +#[cfg(not(feature = "std"))] +impl fmt::Debug for JsValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // TODO before merge - this is less info than before - is this OK? Can we do the above + // without using allocation (no_std)? + f.write_str("[object]") } } diff --git a/tests/wasm/api.rs b/tests/wasm/api.rs index e7d95133..5a2e11c8 100644 --- a/tests/wasm/api.rs +++ b/tests/wasm/api.rs @@ -80,7 +80,7 @@ pub fn api_test_bool(a: &JsValue, b: &JsValue, c: &JsValue) { pub fn api_mk_symbol() -> JsValue { let a = JsValue::symbol(None); assert!(a.is_symbol()); - assert_eq!(format!("{:?}", a), "Symbol(..)"); + assert_eq!(format!("{:?}", a), "Symbol()"); return a; } From 36cb50445f88e925acf713e0a448d6e7cceeed79 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Thu, 10 Jan 2019 23:39:36 +0000 Subject: [PATCH 04/14] Make clear it's a JsValue. --- src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7834819b..ac961fec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -529,7 +529,8 @@ impl Clone for JsValue { #[cfg(feature = "std")] impl fmt::Debug for JsValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(&self.as_debug_string()) + use std::fmt::Write; + write!(f, "JsValue({})", self.as_debug_string()) } } @@ -538,7 +539,7 @@ impl fmt::Debug for JsValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // TODO before merge - this is less info than before - is this OK? Can we do the above // without using allocation (no_std)? - f.write_str("[object]") + f.write_str("JsValue(..)") } } From 72765757ef924acc10272f63b9fa41cfe2228575 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Thu, 10 Jan 2019 23:42:28 +0000 Subject: [PATCH 05/14] Fix tests again. --- crates/cli-support/src/js/mod.rs | 2 +- src/lib.rs | 1 - tests/wasm/api.rs | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 62d2deec..54b7961f 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -369,7 +369,7 @@ impl<'a> Context<'a> { if (type == 'symbol') { const description = val.description; if (description == null) { - return 'Symbol()'; + return 'Symbol'; } else { return 'Symbol(' + description + ')'; } diff --git a/src/lib.rs b/src/lib.rs index ac961fec..c853e19a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -529,7 +529,6 @@ impl Clone for JsValue { #[cfg(feature = "std")] impl fmt::Debug for JsValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use std::fmt::Write; write!(f, "JsValue({})", self.as_debug_string()) } } diff --git a/tests/wasm/api.rs b/tests/wasm/api.rs index 5a2e11c8..ce64c000 100644 --- a/tests/wasm/api.rs +++ b/tests/wasm/api.rs @@ -71,7 +71,7 @@ pub fn api_get_false() -> JsValue { #[wasm_bindgen] pub fn api_test_bool(a: &JsValue, b: &JsValue, c: &JsValue) { assert_eq!(a.as_bool(), Some(true)); - assert_eq!(format!("{:?}", a), "true"); + assert_eq!(format!("{:?}", a), "JsValue(true)"); assert_eq!(b.as_bool(), Some(false)); assert_eq!(c.as_bool(), None); } @@ -80,7 +80,7 @@ pub fn api_test_bool(a: &JsValue, b: &JsValue, c: &JsValue) { pub fn api_mk_symbol() -> JsValue { let a = JsValue::symbol(None); assert!(a.is_symbol()); - assert_eq!(format!("{:?}", a), "Symbol()"); + assert_eq!(format!("{:?}", a), "JsValue(Symbol)"); return a; } @@ -100,7 +100,7 @@ pub fn api_assert_symbols(a: &JsValue, b: &JsValue) { #[wasm_bindgen] pub fn api_acquire_string(a: &JsValue, b: &JsValue) { assert_eq!(a.as_string().unwrap(), "foo"); - assert_eq!(format!("{:?}", a), "\"foo\""); + assert_eq!(format!("{:?}", a), "JsValue(\"foo\")"); assert_eq!(b.as_string(), None); } From b60d82a531a3c76f619fb23c836cd45203534e75 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Fri, 11 Jan 2019 19:23:33 +0000 Subject: [PATCH 06/14] Implement suggestings from @fitzgen. --- crates/cli-support/src/js/mod.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 54b7961f..87fc3fa9 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -357,25 +357,31 @@ impl<'a> Context<'a> { Ok(String::from( " function(i, len_ptr) { + const toString = Object.prototype.toString; const debug_str = val => { // primitive types const type = typeof val; if (type == 'number' || type == 'boolean' || val == null) { - return val + ''; + return `${val}`; } if (type == 'string') { - return '\"' + val + '\"'; + return `\"${val}\"`; } if (type == 'symbol') { const description = val.description; if (description == null) { return 'Symbol'; } else { - return 'Symbol(' + description + ')'; + return `Symbol(${description})`; } } if (type == 'function') { - return 'Function'; + const name = val.name; + if (typeof name == 'string') { + return `Function(${name})`; + } else { + return 'Function'; + } } // objects if (Array.isArray(val)) { @@ -391,19 +397,23 @@ impl<'a> Context<'a> { return debug; } // Test for built-in - const builtInMatches = /\\[object ([^])+\\]/.exec(val.toString()); + const builtInMatches = /\\[object ([^])+\\]/.exec(toString.call(val)); let className; if (builtInMatches.len > 0) { className = builtInMatches[0]; } else { // Failed to match the standard '[object ClassName]' - return val.toString(); + return toString.call(val); } if (className == 'Object') { // we're a user defined class or Object // JSON.stringify avoids problems with cycles, and is generally much // easier than looping through ownProperties of `val`. - return 'Object(' + JSON.stringify(val) + ')'; + try { + return 'Object(' + JSON.stringify(val) + ')'; + } catch (_) { + return 'Object'; + } } else { return className; } From fab9d1dff69b247b5c56dbf9afa93995048a8a26 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Fri, 11 Jan 2019 19:24:24 +0000 Subject: [PATCH 07/14] Resolve what to do with no_std. --- src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c853e19a..fc35b0db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -536,9 +536,7 @@ impl fmt::Debug for JsValue { #[cfg(not(feature = "std"))] impl fmt::Debug for JsValue { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // TODO before merge - this is less info than before - is this OK? Can we do the above - // without using allocation (no_std)? - f.write_str("JsValue(..)") + f.write_str("JsValue") } } From f3dd38690ad4498280c707aedc4a3bb2b9470d4d Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Fri, 11 Jan 2019 21:17:52 +0000 Subject: [PATCH 08/14] Remove Array.isArray test. --- src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fc35b0db..c0c2c519 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -298,12 +298,6 @@ impl JsValue { unsafe { __wbindgen_is_object(self.idx) == 1 } } - /// Tests whether `Array.isArray(self)`. - #[inline] - pub fn is_array(&self) -> bool { - unsafe { __wbindgen_is_array(self.idx) == 1 } - } - /// Tests whether the type of this JS value is `function`. #[inline] pub fn is_function(&self) -> bool { From 5bffc286312280089b964139bbddb307c232669f Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Sat, 12 Jan 2019 10:45:38 +0000 Subject: [PATCH 09/14] Add a proper test. And fix loads of bugs. --- crates/cli-support/src/js/mod.rs | 11 ++++++----- tests/wasm/api.js | 14 ++++++++++++++ tests/wasm/api.rs | 22 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 87fc3fa9..a170224a 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -377,7 +377,7 @@ impl<'a> Context<'a> { } if (type == 'function') { const name = val.name; - if (typeof name == 'string') { + if (typeof name == 'string' && name.length > 0) { return `Function(${name})`; } else { return 'Function'; @@ -391,16 +391,16 @@ impl<'a> Context<'a> { debug += debug_str(val[0]); } for(let i = 1; i < length; i++) { - debug += debug_str(val[i]) + ', '; + debug += ', ' + debug_str(val[i]); } debug += ']'; return debug; } // Test for built-in - const builtInMatches = /\\[object ([^])+\\]/.exec(toString.call(val)); + const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val)); let className; - if (builtInMatches.len > 0) { - className = builtInMatches[0]; + if (builtInMatches.length > 1) { + className = builtInMatches[1]; } else { // Failed to match the standard '[object ClassName]' return toString.call(val); @@ -414,6 +414,7 @@ impl<'a> Context<'a> { } catch (_) { return 'Object'; } + // TODO we could test for more things here, like `Set`s and `Map`s. } else { return className; } diff --git a/tests/wasm/api.js b/tests/wasm/api.js index 7136b5db..4c2dec0e 100644 --- a/tests/wasm/api.js +++ b/tests/wasm/api.js @@ -41,3 +41,17 @@ exports.js_eq_works = () => { assert.strictEqual(wasm.eq_test(x, x), true); assert.strictEqual(wasm.eq_test1(x), true); }; + +exports.debug_values = () => ([ + null, + undefined, + 0, + 1.0, + true, + [1,2,3], + "string", + {test: "object"}, + [1.0, [2.0, 3.0]], + () => (null), + new Set(), +]); diff --git a/tests/wasm/api.rs b/tests/wasm/api.rs index ce64c000..b7263515 100644 --- a/tests/wasm/api.rs +++ b/tests/wasm/api.rs @@ -8,6 +8,7 @@ extern "C" { fn js_works(); fn js_eq_works(); fn assert_null(v: JsValue); + fn debug_values() -> JsValue; } #[wasm_bindgen_test] @@ -145,3 +146,24 @@ fn memory_accessor_appears_to_work() { .for_each(&mut |val, _, _| v.push(val)); assert_eq!(v, [3, 0, 0, 0]); } + +#[wasm_bindgen_test] +fn debug_output() { + let test_iter = debug_values().dyn_into::().unwrap().values().into_iter(); + let expecteds = vec![ + "JsValue(null)", + "JsValue(undefined)", + "JsValue(0)", + "JsValue(1)", + "JsValue(true)", + "JsValue([1, 2, 3])", + "JsValue(\"string\")", + "JsValue(Object({\"test\":\"object\"}))", + "JsValue([1, [2, 3]])", + "JsValue(Function)", + "JsValue(Set)", + ]; + for (test, expected) in test_iter.zip(expecteds) { + assert_eq!(format!("{:?}", test.unwrap()), expected); + } +} From 5f2ba3f98ef10766d688b5f555d6ee83493a4a4f Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Wed, 16 Jan 2019 10:46:26 +0000 Subject: [PATCH 10/14] Add better support for errors. --- crates/cli-support/src/js/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index a170224a..6de8a967 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -414,10 +414,13 @@ impl<'a> Context<'a> { } catch (_) { return 'Object'; } - // TODO we could test for more things here, like `Set`s and `Map`s. - } else { - return className; } + // errors + if (val instanceof Error) { + return `${className}: ${val.message}\n${val.stack}`; + } + // TODO we could test for more things here, like `Set`s and `Map`s. + return className; }; const val = getObject(i); const debug = debug_str(val); From b0906fddbaf7ba28d852001758a849c4c2b77532 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Wed, 16 Jan 2019 15:36:13 +0000 Subject: [PATCH 11/14] Better recognition of error type. --- crates/cli-support/src/js/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 6de8a967..3b413fda 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -417,7 +417,7 @@ impl<'a> Context<'a> { } // errors if (val instanceof Error) { - return `${className}: ${val.message}\n${val.stack}`; + return `${val.name}: ${val.message}\n${val.stack}`; } // TODO we could test for more things here, like `Set`s and `Map`s. return className; From 7fe76061af302f74ee5ef9632e84ca6cf5fd842d Mon Sep 17 00:00:00 2001 From: "Richard Dodd (dodj)" Date: Thu, 17 Jan 2019 12:59:16 +0000 Subject: [PATCH 12/14] Update node to support Array.values in tests. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3f1a7fb2..d84248e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ INSTALL_NODE_VIA_NVM: &INSTALL_NODE_VIA_NVM rustup target add wasm32-unknown-unknown curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash source ~/.nvm/nvm.sh - nvm install v10.5 + nvm install v10.9 INSTALL_GECKODRIVER: &INSTALL_GECKODRIVER | From 867b13b65e7a88c89baa252ebdf0775876a5a12c Mon Sep 17 00:00:00 2001 From: "Richard Dodd (dodj)" Date: Thu, 17 Jan 2019 21:07:23 +0000 Subject: [PATCH 13/14] remove array check --- crates/cli-support/src/js/mod.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 3b413fda..97a062f4 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -299,18 +299,6 @@ impl<'a> Context<'a> { )) })?; - self.bind("__wbindgen_is_array", &|me| { - me.expose_get_object(); - Ok(String::from( - " - function(i) { - const val = getObject(i); - return Array.isArray(val) ? 1 : 0; - } - ", - )) - })?; - self.bind("__wbindgen_is_function", &|me| { me.expose_get_object(); Ok(String::from( From f8680a0c1094b1f887848628921ae9f3fda94c73 Mon Sep 17 00:00:00 2001 From: "Richard Dodd (dodj)" Date: Thu, 17 Jan 2019 21:08:32 +0000 Subject: [PATCH 14/14] remove is array function --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index c0c2c519..7b2ffb94 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -489,7 +489,6 @@ externs! { fn __wbindgen_symbol_new(ptr: *const u8, len: usize) -> u32; fn __wbindgen_is_symbol(idx: u32) -> u32; fn __wbindgen_is_object(idx: u32) -> u32; - fn __wbindgen_is_array(idx: u32) -> u32; fn __wbindgen_is_function(idx: u32) -> u32; fn __wbindgen_is_string(idx: u32) -> u32; fn __wbindgen_string_get(idx: u32, len: *mut usize) -> *mut u8;