Add a number of #[inline] annotation through crates

Adding `#[inline]` will typically improve codegen for optimized builds
without LTO (so far the majority in practice) by allowing functions that
otherwise couldn't be inlined across codegen units to get inlined
across codegen units.

Right now `wasm-bindgen` has a lot of functions that are very small and
delegate to other functions, but aren't otherwise candidates for
inlining because they're concrete.

I was poking around in release-mode wasm recently and noticed an
alarming number of functions for tiny pieces of functionality, which
motivates this patch!
This commit is contained in:
Alex Crichton 2018-10-01 15:27:34 -07:00
parent 9c085dc0f5
commit 332beecabe
4 changed files with 70 additions and 7 deletions

View File

@ -546,22 +546,26 @@ impl ToTokens for ast::ImportType {
impl IntoWasmAbi for #rust_name { impl IntoWasmAbi for #rust_name {
type Abi = <JsValue as IntoWasmAbi>::Abi; type Abi = <JsValue as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self, extra: &mut Stack) -> Self::Abi { fn into_abi(self, extra: &mut Stack) -> Self::Abi {
self.obj.into_abi(extra) self.obj.into_abi(extra)
} }
} }
impl OptionIntoWasmAbi for #rust_name { impl OptionIntoWasmAbi for #rust_name {
#[inline]
fn none() -> Self::Abi { 0 } fn none() -> Self::Abi { 0 }
} }
impl<'a> OptionIntoWasmAbi for &'a #rust_name { impl<'a> OptionIntoWasmAbi for &'a #rust_name {
#[inline]
fn none() -> Self::Abi { 0 } fn none() -> Self::Abi { 0 }
} }
impl FromWasmAbi for #rust_name { impl FromWasmAbi for #rust_name {
type Abi = <JsValue as FromWasmAbi>::Abi; type Abi = <JsValue as FromWasmAbi>::Abi;
#[inline]
unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self { unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self {
#rust_name { #rust_name {
obj: JsValue::from_abi(js, extra), obj: JsValue::from_abi(js, extra),
@ -570,12 +574,14 @@ impl ToTokens for ast::ImportType {
} }
impl OptionFromWasmAbi for #rust_name { impl OptionFromWasmAbi for #rust_name {
#[inline]
fn is_none(abi: &Self::Abi) -> bool { *abi == 0 } fn is_none(abi: &Self::Abi) -> bool { *abi == 0 }
} }
impl<'a> IntoWasmAbi for &'a #rust_name { impl<'a> IntoWasmAbi for &'a #rust_name {
type Abi = <&'a JsValue as IntoWasmAbi>::Abi; type Abi = <&'a JsValue as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self, extra: &mut Stack) -> Self::Abi { fn into_abi(self, extra: &mut Stack) -> Self::Abi {
(&self.obj).into_abi(extra) (&self.obj).into_abi(extra)
} }
@ -585,6 +591,7 @@ impl ToTokens for ast::ImportType {
type Abi = <JsValue as RefFromWasmAbi>::Abi; type Abi = <JsValue as RefFromWasmAbi>::Abi;
type Anchor = ManuallyDrop<#rust_name>; type Anchor = ManuallyDrop<#rust_name>;
#[inline]
unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor { unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor {
let tmp = <JsValue as RefFromWasmAbi>::ref_from_abi(js, extra); let tmp = <JsValue as RefFromWasmAbi>::ref_from_abi(js, extra);
ManuallyDrop::new(#rust_name { ManuallyDrop::new(#rust_name {
@ -595,17 +602,20 @@ impl ToTokens for ast::ImportType {
// TODO: remove this on the next major version // TODO: remove this on the next major version
impl From<JsValue> for #rust_name { impl From<JsValue> for #rust_name {
#[inline]
fn from(obj: JsValue) -> #rust_name { fn from(obj: JsValue) -> #rust_name {
#rust_name { obj } #rust_name { obj }
} }
} }
impl AsRef<JsValue> for #rust_name { impl AsRef<JsValue> for #rust_name {
#[inline]
fn as_ref(&self) -> &JsValue { &self.obj } fn as_ref(&self) -> &JsValue { &self.obj }
} }
impl From<#rust_name> for JsValue { impl From<#rust_name> for JsValue {
#[inline]
fn from(obj: #rust_name) -> JsValue { fn from(obj: #rust_name) -> JsValue {
obj.obj obj.obj
} }
@ -630,10 +640,12 @@ impl ToTokens for ast::ImportType {
panic!("cannot check instanceof on non-wasm targets"); panic!("cannot check instanceof on non-wasm targets");
} }
#[inline]
fn unchecked_from_js(val: JsValue) -> Self { fn unchecked_from_js(val: JsValue) -> Self {
#rust_name { obj: val } #rust_name { obj: val }
} }
#[inline]
fn unchecked_from_js_ref(val: &JsValue) -> &Self { fn unchecked_from_js_ref(val: &JsValue) -> &Self {
// Should be safe because `#rust_name` is a transparent // Should be safe because `#rust_name` is a transparent
// wrapper around `val` // wrapper around `val`
@ -648,6 +660,7 @@ impl ToTokens for ast::ImportType {
for superclass in self.extends.iter() { for superclass in self.extends.iter() {
(quote! { (quote! {
impl From<#rust_name> for #superclass { impl From<#rust_name> for #superclass {
#[inline]
fn from(obj: #rust_name) -> #superclass { fn from(obj: #rust_name) -> #superclass {
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
#superclass::unchecked_from_js(obj.into()) #superclass::unchecked_from_js(obj.into())
@ -655,6 +668,7 @@ impl ToTokens for ast::ImportType {
} }
impl AsRef<#superclass> for #rust_name { impl AsRef<#superclass> for #rust_name {
#[inline]
fn as_ref(&self) -> &#superclass { fn as_ref(&self) -> &#superclass {
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
#superclass::unchecked_from_js_ref(self.as_ref()) #superclass::unchecked_from_js_ref(self.as_ref())
@ -724,6 +738,7 @@ impl ToTokens for ast::ImportEnum {
type Abi = <::wasm_bindgen::JsValue as type Abi = <::wasm_bindgen::JsValue as
::wasm_bindgen::convert::IntoWasmAbi>::Abi; ::wasm_bindgen::convert::IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self, extra: &mut ::wasm_bindgen::convert::Stack) -> Self::Abi { fn into_abi(self, extra: &mut ::wasm_bindgen::convert::Stack) -> Self::Abi {
::wasm_bindgen::JsValue::from(self).into_abi(extra) ::wasm_bindgen::JsValue::from(self).into_abi(extra)
} }
@ -971,6 +986,7 @@ impl ToTokens for ast::Enum {
impl ::wasm_bindgen::convert::IntoWasmAbi for #enum_name { impl ::wasm_bindgen::convert::IntoWasmAbi for #enum_name {
type Abi = u32; type Abi = u32;
#[inline]
fn into_abi(self, _extra: &mut ::wasm_bindgen::convert::Stack) -> u32 { fn into_abi(self, _extra: &mut ::wasm_bindgen::convert::Stack) -> u32 {
self as u32 self as u32
} }
@ -1135,11 +1151,13 @@ impl ToTokens for ast::Dictionary {
// interop w/ JsValue // interop w/ JsValue
impl From<#name> for JsValue { impl From<#name> for JsValue {
#[inline]
fn from(val: #name) -> JsValue { fn from(val: #name) -> JsValue {
val.obj.into() val.obj.into()
} }
} }
impl AsRef<JsValue> for #name { impl AsRef<JsValue> for #name {
#[inline]
fn as_ref(&self) -> &JsValue { self.obj.as_ref() } fn as_ref(&self) -> &JsValue { self.obj.as_ref() }
} }
@ -1152,6 +1170,7 @@ impl ToTokens for ast::Dictionary {
impl IntoWasmAbi for #name { impl IntoWasmAbi for #name {
type Abi = <Object as IntoWasmAbi>::Abi; type Abi = <Object as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self, extra: &mut Stack) -> Self::Abi { fn into_abi(self, extra: &mut Stack) -> Self::Abi {
self.obj.into_abi(extra) self.obj.into_abi(extra)
} }
@ -1159,6 +1178,7 @@ impl ToTokens for ast::Dictionary {
impl<'a> IntoWasmAbi for &'a #name { impl<'a> IntoWasmAbi for &'a #name {
type Abi = <&'a Object as IntoWasmAbi>::Abi; type Abi = <&'a Object as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self, extra: &mut Stack) -> Self::Abi { fn into_abi(self, extra: &mut Stack) -> Self::Abi {
(&self.obj).into_abi(extra) (&self.obj).into_abi(extra)
} }
@ -1166,18 +1186,22 @@ impl ToTokens for ast::Dictionary {
impl FromWasmAbi for #name { impl FromWasmAbi for #name {
type Abi = <Object as FromWasmAbi>::Abi; type Abi = <Object as FromWasmAbi>::Abi;
#[inline]
unsafe fn from_abi(abi: Self::Abi, extra: &mut Stack) -> Self { unsafe fn from_abi(abi: Self::Abi, extra: &mut Stack) -> Self {
#name { obj: Object::from_abi(abi, extra) } #name { obj: Object::from_abi(abi, extra) }
} }
} }
impl OptionIntoWasmAbi for #name { impl OptionIntoWasmAbi for #name {
#[inline]
fn none() -> Self::Abi { Object::none() } fn none() -> Self::Abi { Object::none() }
} }
impl<'a> OptionIntoWasmAbi for &'a #name { impl<'a> OptionIntoWasmAbi for &'a #name {
#[inline]
fn none() -> Self::Abi { <&'a Object>::none() } fn none() -> Self::Abi { <&'a Object>::none() }
} }
impl OptionFromWasmAbi for #name { impl OptionFromWasmAbi for #name {
#[inline]
fn is_none(abi: &Self::Abi) -> bool { Object::is_none(abi) } fn is_none(abi: &Self::Abi) -> bool { Object::is_none(abi) }
} }
@ -1185,6 +1209,7 @@ impl ToTokens for ast::Dictionary {
type Abi = <Object as RefFromWasmAbi>::Abi; type Abi = <Object as RefFromWasmAbi>::Abi;
type Anchor = ManuallyDrop<#name>; type Anchor = ManuallyDrop<#name>;
#[inline]
unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor { unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor {
let tmp = <Object as RefFromWasmAbi>::ref_from_abi(js, extra); let tmp = <Object as RefFromWasmAbi>::ref_from_abi(js, extra);
ManuallyDrop::new(#name { ManuallyDrop::new(#name {
@ -1194,14 +1219,17 @@ impl ToTokens for ast::Dictionary {
} }
impl JsCast for #name { impl JsCast for #name {
#[inline]
fn instanceof(val: &JsValue) -> bool { fn instanceof(val: &JsValue) -> bool {
Object::instanceof(val) Object::instanceof(val)
} }
#[inline]
fn unchecked_from_js(val: JsValue) -> Self { fn unchecked_from_js(val: JsValue) -> Self {
#name { obj: Object::unchecked_from_js(val) } #name { obj: Object::unchecked_from_js(val) }
} }
#[inline]
fn unchecked_from_js_ref(val: &JsValue) -> &Self { fn unchecked_from_js_ref(val: &JsValue) -> &Self {
unsafe { &*(val as *const JsValue as *const #name) } unsafe { &*(val as *const JsValue as *const #name) }
} }

View File

@ -327,6 +327,7 @@ macro_rules! doit {
<&Self>::describe(); <&Self>::describe();
} }
#[inline]
fn invoke_fn() -> u32 { fn invoke_fn() -> u32 {
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe extern fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>( unsafe extern fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
@ -354,6 +355,7 @@ macro_rules! doit {
invoke::<$($var,)* R> as u32 invoke::<$($var,)* R> as u32
} }
#[inline]
fn destroy_fn() -> u32 { fn destroy_fn() -> u32 {
unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>( unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
a: usize, a: usize,
@ -376,6 +378,7 @@ macro_rules! doit {
<&mut Self>::describe(); <&mut Self>::describe();
} }
#[inline]
fn invoke_fn() -> u32 { fn invoke_fn() -> u32 {
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe extern fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>( unsafe extern fn invoke<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
@ -404,6 +407,7 @@ macro_rules! doit {
invoke::<$($var,)* R> as u32 invoke::<$($var,)* R> as u32
} }
#[inline]
fn destroy_fn() -> u32 { fn destroy_fn() -> u32 {
unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>( unsafe extern fn destroy<$($var: FromWasmAbi,)* R: ReturnWasmAbi>(
a: usize, a: usize,

View File

@ -77,6 +77,7 @@ macro_rules! type_wasm_native {
impl IntoWasmAbi for Option<$t> { impl IntoWasmAbi for Option<$t> {
type Abi = $r; type Abi = $r;
#[inline]
fn into_abi(self, _extra: &mut Stack) -> $r { fn into_abi(self, _extra: &mut Stack) -> $r {
match self { match self {
None => $r { None => $r {
@ -94,6 +95,7 @@ macro_rules! type_wasm_native {
impl FromWasmAbi for Option<$t> { impl FromWasmAbi for Option<$t> {
type Abi = $r; type Abi = $r;
#[inline]
unsafe fn from_abi(js: $r, _extra: &mut Stack) -> Self { unsafe fn from_abi(js: $r, _extra: &mut Stack) -> Self {
if js.present == 0 { if js.present == 0 {
None None
@ -170,6 +172,7 @@ macro_rules! type_64 {
impl IntoWasmAbi for Option<$t> { impl IntoWasmAbi for Option<$t> {
type Abi = WasmOptional64; type Abi = WasmOptional64;
#[inline]
fn into_abi(self, _extra: &mut Stack) -> WasmOptional64 { fn into_abi(self, _extra: &mut Stack) -> WasmOptional64 {
match self { match self {
None => WasmOptional64 { None => WasmOptional64 {
@ -191,6 +194,7 @@ macro_rules! type_64 {
impl FromWasmAbi for Option<$t> { impl FromWasmAbi for Option<$t> {
type Abi = WasmOptional64; type Abi = WasmOptional64;
#[inline]
unsafe fn from_abi(js: WasmOptional64, _extra: &mut Stack) -> Self { unsafe fn from_abi(js: WasmOptional64, _extra: &mut Stack) -> Self {
if js.present == 0 { if js.present == 0 {
None None
@ -257,6 +261,7 @@ impl FromWasmAbi for char {
impl IntoWasmAbi for Option<char> { impl IntoWasmAbi for Option<char> {
type Abi = WasmOptionalU32; type Abi = WasmOptionalU32;
#[inline]
fn into_abi(self, _extra: &mut Stack) -> WasmOptionalU32 { fn into_abi(self, _extra: &mut Stack) -> WasmOptionalU32 {
match self { match self {
None => WasmOptionalU32 { None => WasmOptionalU32 {
@ -274,6 +279,7 @@ impl IntoWasmAbi for Option<char> {
impl FromWasmAbi for Option<char> { impl FromWasmAbi for Option<char> {
type Abi = WasmOptionalU32; type Abi = WasmOptionalU32;
#[inline]
unsafe fn from_abi(js: WasmOptionalU32, _extra: &mut Stack) -> Self { unsafe fn from_abi(js: WasmOptionalU32, _extra: &mut Stack) -> Self {
if js.present == 0 { if js.present == 0 {
None None

View File

@ -91,6 +91,7 @@ impl JsValue {
/// ///
/// The utf-8 string provided is copied to the JS heap and the string will /// The utf-8 string provided is copied to the JS heap and the string will
/// be owned by the JS garbage collector. /// be owned by the JS garbage collector.
#[inline]
pub fn from_str(s: &str) -> JsValue { pub fn from_str(s: &str) -> JsValue {
unsafe { unsafe {
JsValue { JsValue {
@ -103,6 +104,7 @@ impl JsValue {
/// ///
/// This function creates a JS value representing a number (a heap /// This function creates a JS value representing a number (a heap
/// allocated number) and returns a handle to the JS version of it. /// allocated number) and returns a handle to the JS version of it.
#[inline]
pub fn from_f64(n: f64) -> JsValue { pub fn from_f64(n: f64) -> JsValue {
unsafe { unsafe {
JsValue { JsValue {
@ -115,22 +117,21 @@ impl JsValue {
/// ///
/// This function creates a JS object representing a boolean (a heap /// This function creates a JS object representing a boolean (a heap
/// allocated boolean) and returns a handle to the JS version of it. /// allocated boolean) and returns a handle to the JS version of it.
#[inline]
pub fn from_bool(b: bool) -> JsValue { pub fn from_bool(b: bool) -> JsValue {
JsValue { if b { JsValue::TRUE } else { JsValue::FALSE }
idx: if b { JSIDX_TRUE } else { JSIDX_FALSE },
}
} }
/// Creates a new JS value representing `undefined`. /// Creates a new JS value representing `undefined`.
#[inline]
pub fn undefined() -> JsValue { pub fn undefined() -> JsValue {
JsValue { JsValue::UNDEFINED
idx: JSIDX_UNDEFINED,
}
} }
/// Creates a new JS value representing `null`. /// Creates a new JS value representing `null`.
#[inline]
pub fn null() -> JsValue { pub fn null() -> JsValue {
JsValue { idx: JSIDX_NULL } JsValue::NULL
} }
/// Creates a new JS symbol with the optional description specified. /// Creates a new JS symbol with the optional description specified.
@ -263,50 +264,59 @@ impl JsValue {
} }
/// Tests whether this JS value is `null` /// Tests whether this JS value is `null`
#[inline]
pub fn is_null(&self) -> bool { pub fn is_null(&self) -> bool {
unsafe { __wbindgen_is_null(self.idx) == 1 } unsafe { __wbindgen_is_null(self.idx) == 1 }
} }
/// Tests whether this JS value is `undefined` /// Tests whether this JS value is `undefined`
#[inline]
pub fn is_undefined(&self) -> bool { pub fn is_undefined(&self) -> bool {
unsafe { __wbindgen_is_undefined(self.idx) == 1 } unsafe { __wbindgen_is_undefined(self.idx) == 1 }
} }
/// Tests whether the type of this JS value is `symbol` /// Tests whether the type of this JS value is `symbol`
#[inline]
pub fn is_symbol(&self) -> bool { pub fn is_symbol(&self) -> bool {
unsafe { __wbindgen_is_symbol(self.idx) == 1 } unsafe { __wbindgen_is_symbol(self.idx) == 1 }
} }
/// Tests whether `typeof self == "object" && self !== null`. /// Tests whether `typeof self == "object" && self !== null`.
#[inline]
pub fn is_object(&self) -> bool { pub fn is_object(&self) -> bool {
unsafe { __wbindgen_is_object(self.idx) == 1 } unsafe { __wbindgen_is_object(self.idx) == 1 }
} }
/// Tests whether the type of this JS value is `function`. /// Tests whether the type of this JS value is `function`.
#[inline]
pub fn is_function(&self) -> bool { pub fn is_function(&self) -> bool {
unsafe { __wbindgen_is_function(self.idx) == 1 } unsafe { __wbindgen_is_function(self.idx) == 1 }
} }
} }
impl PartialEq for JsValue { impl PartialEq for JsValue {
#[inline]
fn eq(&self, other: &JsValue) -> bool { fn eq(&self, other: &JsValue) -> bool {
unsafe { __wbindgen_jsval_eq(self.idx, other.idx) != 0 } unsafe { __wbindgen_jsval_eq(self.idx, other.idx) != 0 }
} }
} }
impl PartialEq<bool> for JsValue { impl PartialEq<bool> for JsValue {
#[inline]
fn eq(&self, other: &bool) -> bool { fn eq(&self, other: &bool) -> bool {
self.as_bool() == Some(*other) self.as_bool() == Some(*other)
} }
} }
impl PartialEq<str> for JsValue { impl PartialEq<str> for JsValue {
#[inline]
fn eq(&self, other: &str) -> bool { fn eq(&self, other: &str) -> bool {
*self == JsValue::from_str(other) *self == JsValue::from_str(other)
} }
} }
impl<'a> PartialEq<&'a str> for JsValue { impl<'a> PartialEq<&'a str> for JsValue {
#[inline]
fn eq(&self, other: &&'a str) -> bool { fn eq(&self, other: &&'a str) -> bool {
<JsValue as PartialEq<str>>::eq(self, other) <JsValue as PartialEq<str>>::eq(self, other)
} }
@ -314,11 +324,13 @@ impl<'a> PartialEq<&'a str> for JsValue {
if_std! { if_std! {
impl PartialEq<String> for JsValue { impl PartialEq<String> for JsValue {
#[inline]
fn eq(&self, other: &String) -> bool { fn eq(&self, other: &String) -> bool {
<JsValue as PartialEq<str>>::eq(self, other) <JsValue as PartialEq<str>>::eq(self, other)
} }
} }
impl<'a> PartialEq<&'a String> for JsValue { impl<'a> PartialEq<&'a String> for JsValue {
#[inline]
fn eq(&self, other: &&'a String) -> bool { fn eq(&self, other: &&'a String) -> bool {
<JsValue as PartialEq<str>>::eq(self, other) <JsValue as PartialEq<str>>::eq(self, other)
} }
@ -326,6 +338,7 @@ if_std! {
} }
impl<'a> From<&'a str> for JsValue { impl<'a> From<&'a str> for JsValue {
#[inline]
fn from(s: &'a str) -> JsValue { fn from(s: &'a str) -> JsValue {
JsValue::from_str(s) JsValue::from_str(s)
} }
@ -333,12 +346,14 @@ impl<'a> From<&'a str> for JsValue {
if_std! { if_std! {
impl<'a> From<&'a String> for JsValue { impl<'a> From<&'a String> for JsValue {
#[inline]
fn from(s: &'a String) -> JsValue { fn from(s: &'a String) -> JsValue {
JsValue::from_str(s) JsValue::from_str(s)
} }
} }
impl From<String> for JsValue { impl From<String> for JsValue {
#[inline]
fn from(s: String) -> JsValue { fn from(s: String) -> JsValue {
JsValue::from_str(&s) JsValue::from_str(&s)
} }
@ -346,6 +361,7 @@ if_std! {
} }
impl From<bool> for JsValue { impl From<bool> for JsValue {
#[inline]
fn from(s: bool) -> JsValue { fn from(s: bool) -> JsValue {
JsValue::from_bool(s) JsValue::from_bool(s)
} }
@ -355,6 +371,7 @@ impl<'a, T> From<&'a T> for JsValue
where where
T: JsCast, T: JsCast,
{ {
#[inline]
fn from(s: &'a T) -> JsValue { fn from(s: &'a T) -> JsValue {
s.as_ref().clone() s.as_ref().clone()
} }
@ -364,6 +381,7 @@ impl<T> From<Option<T>> for JsValue
where where
JsValue: From<T>, JsValue: From<T>,
{ {
#[inline]
fn from(s: Option<T>) -> JsValue { fn from(s: Option<T>) -> JsValue {
match s { match s {
Some(s) => s.into(), Some(s) => s.into(),
@ -374,18 +392,22 @@ where
impl JsCast for JsValue { impl JsCast for JsValue {
// everything is a `JsValue`! // everything is a `JsValue`!
#[inline]
fn instanceof(_val: &JsValue) -> bool { fn instanceof(_val: &JsValue) -> bool {
true true
} }
#[inline]
fn unchecked_from_js(val: JsValue) -> Self { fn unchecked_from_js(val: JsValue) -> Self {
val val
} }
#[inline]
fn unchecked_from_js_ref(val: &JsValue) -> &Self { fn unchecked_from_js_ref(val: &JsValue) -> &Self {
val val
} }
} }
impl AsRef<JsValue> for JsValue { impl AsRef<JsValue> for JsValue {
#[inline]
fn as_ref(&self) -> &JsValue { fn as_ref(&self) -> &JsValue {
self self
} }
@ -394,12 +416,14 @@ impl AsRef<JsValue> for JsValue {
macro_rules! numbers { macro_rules! numbers {
($($n:ident)*) => ($( ($($n:ident)*) => ($(
impl PartialEq<$n> for JsValue { impl PartialEq<$n> for JsValue {
#[inline]
fn eq(&self, other: &$n) -> bool { fn eq(&self, other: &$n) -> bool {
self.as_f64() == Some(f64::from(*other)) self.as_f64() == Some(f64::from(*other))
} }
} }
impl From<$n> for JsValue { impl From<$n> for JsValue {
#[inline]
fn from(n: $n) -> JsValue { fn from(n: $n) -> JsValue {
JsValue::from_f64(n.into()) JsValue::from_f64(n.into())
} }
@ -495,6 +519,7 @@ impl fmt::Debug for JsValue {
} }
impl Drop for JsValue { impl Drop for JsValue {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
// if the first bit is set then this is a stack value, so we for // if the first bit is set then this is a stack value, so we for