0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-03-10 05:56:52 -04:00

Implement 'Eq' for all subtypes of 'Value' and its handles (#414)

This commit is contained in:
Bert Belder 2020-07-04 07:05:50 +02:00
parent d3f6e4d36c
commit 91c8c7d1c7
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
3 changed files with 67 additions and 52 deletions

View file

@ -49,12 +49,13 @@ macro_rules! impl_try_from {
macro_rules! impl_eq { macro_rules! impl_eq {
{ for $type:ident } => { { for $type:ident } => {
impl<'s> Eq for Local<'s, $type> {} impl<'s> Eq for $type {}
}; };
} }
extern "C" { extern "C" {
fn v8__Data__EQ(this: *const Data, other: *const Data) -> bool; fn v8__Data__EQ(this: *const Data, other: *const Data) -> bool;
fn v8__Value__SameValue(this: *const Value, other: *const Value) -> bool;
fn v8__Value__StrictEquals(this: *const Value, other: *const Value) -> bool; fn v8__Value__StrictEquals(this: *const Value, other: *const Value) -> bool;
} }
@ -62,23 +63,31 @@ macro_rules! impl_partial_eq {
{ $rhs:ident for $type:ident use identity } => { { $rhs:ident for $type:ident use identity } => {
impl<'s> PartialEq<$rhs> for $type { impl<'s> PartialEq<$rhs> for $type {
fn eq(&self, other: &$rhs) -> bool { fn eq(&self, other: &$rhs) -> bool {
unsafe { let a = self as *const _ as *const Data;
v8__Data__EQ( let b = other as *const _ as *const Data;
self as *const _ as *const Data, unsafe { v8__Data__EQ(a, b) }
other as *const _ as *const Data,
)
}
} }
} }
}; };
{ $rhs:ident for $type:ident use strict_equals } => { { $rhs:ident for $type:ident use strict_equals } => {
impl<'s> PartialEq<$rhs> for $type { impl<'s> PartialEq<$rhs> for $type {
fn eq(&self, other: &$rhs) -> bool { fn eq(&self, other: &$rhs) -> bool {
let a = self as *const _ as *const Value;
let b = other as *const _ as *const Value;
unsafe { v8__Value__StrictEquals(a, b) }
}
}
};
{ $rhs:ident for $type:ident use same_value_zero } => {
impl<'s> PartialEq<$rhs> for $type {
fn eq(&self, other: &$rhs) -> bool {
let a = self as *const _ as *const Value;
let b = other as *const _ as *const Value;
unsafe { unsafe {
v8__Value__StrictEquals( v8__Value__SameValue(a, b) || {
self as *const _ as *const Value, let zero = &*Local::<Value>::from(Integer::zero());
other as *const _ as *const Value, v8__Value__StrictEquals(a, zero) && v8__Value__StrictEquals(b, zero)
) }
} }
} }
} }
@ -544,7 +553,8 @@ impl_from! { Number for Value }
impl_from! { Integer for Value } impl_from! { Integer for Value }
impl_from! { Int32 for Value } impl_from! { Int32 for Value }
impl_from! { Uint32 for Value } impl_from! { Uint32 for Value }
impl_partial_eq! { Value for Value use strict_equals } impl_eq! { for Value }
impl_partial_eq! { Value for Value use same_value_zero }
impl_partial_eq! { External for Value use identity } impl_partial_eq! { External for Value use identity }
impl_partial_eq! { Object for Value use identity } impl_partial_eq! { Object for Value use identity }
impl_partial_eq! { Array for Value use identity } impl_partial_eq! { Array for Value use identity }
@ -578,16 +588,16 @@ impl_partial_eq! { SharedArrayBuffer for Value use identity }
impl_partial_eq! { StringObject for Value use identity } impl_partial_eq! { StringObject for Value use identity }
impl_partial_eq! { SymbolObject for Value use identity } impl_partial_eq! { SymbolObject for Value use identity }
impl_partial_eq! { WasmModuleObject for Value use identity } impl_partial_eq! { WasmModuleObject for Value use identity }
impl_partial_eq! { Primitive for Value use strict_equals } impl_partial_eq! { Primitive for Value use same_value_zero }
impl_partial_eq! { BigInt for Value use strict_equals } impl_partial_eq! { BigInt for Value use same_value_zero }
impl_partial_eq! { Boolean for Value use identity } impl_partial_eq! { Boolean for Value use identity }
impl_partial_eq! { Name for Value use strict_equals } impl_partial_eq! { Name for Value use same_value_zero }
impl_partial_eq! { String for Value use strict_equals } impl_partial_eq! { String for Value use same_value_zero }
impl_partial_eq! { Symbol for Value use identity } impl_partial_eq! { Symbol for Value use identity }
impl_partial_eq! { Number for Value use strict_equals } impl_partial_eq! { Number for Value use same_value_zero }
impl_partial_eq! { Integer for Value use strict_equals } impl_partial_eq! { Integer for Value use same_value_zero }
impl_partial_eq! { Int32 for Value use strict_equals } impl_partial_eq! { Int32 for Value use same_value_zero }
impl_partial_eq! { Uint32 for Value use strict_equals } impl_partial_eq! { Uint32 for Value use same_value_zero }
/// A JavaScript value that wraps a C++ void*. This type of value is mainly used /// A JavaScript value that wraps a C++ void*. This type of value is mainly used
/// to associate C++ data structures with JavaScript objects. /// to associate C++ data structures with JavaScript objects.
@ -1187,17 +1197,18 @@ impl_from! { Number for Primitive }
impl_from! { Integer for Primitive } impl_from! { Integer for Primitive }
impl_from! { Int32 for Primitive } impl_from! { Int32 for Primitive }
impl_from! { Uint32 for Primitive } impl_from! { Uint32 for Primitive }
impl_partial_eq! { Value for Primitive use strict_equals } impl_eq! { for Primitive }
impl_partial_eq! { Primitive for Primitive use strict_equals } impl_partial_eq! { Value for Primitive use same_value_zero }
impl_partial_eq! { BigInt for Primitive use strict_equals } impl_partial_eq! { Primitive for Primitive use same_value_zero }
impl_partial_eq! { BigInt for Primitive use same_value_zero }
impl_partial_eq! { Boolean for Primitive use identity } impl_partial_eq! { Boolean for Primitive use identity }
impl_partial_eq! { Name for Primitive use strict_equals } impl_partial_eq! { Name for Primitive use same_value_zero }
impl_partial_eq! { String for Primitive use strict_equals } impl_partial_eq! { String for Primitive use same_value_zero }
impl_partial_eq! { Symbol for Primitive use identity } impl_partial_eq! { Symbol for Primitive use identity }
impl_partial_eq! { Number for Primitive use strict_equals } impl_partial_eq! { Number for Primitive use same_value_zero }
impl_partial_eq! { Integer for Primitive use strict_equals } impl_partial_eq! { Integer for Primitive use same_value_zero }
impl_partial_eq! { Int32 for Primitive use strict_equals } impl_partial_eq! { Int32 for Primitive use same_value_zero }
impl_partial_eq! { Uint32 for Primitive use strict_equals } impl_partial_eq! { Uint32 for Primitive use same_value_zero }
/// A JavaScript BigInt value (https://tc39.github.io/proposal-bigint) /// A JavaScript BigInt value (https://tc39.github.io/proposal-bigint)
#[repr(C)] #[repr(C)]
@ -1207,8 +1218,8 @@ impl_deref! { Primitive for BigInt }
impl_try_from! { Value for BigInt if v => v.is_big_int() } impl_try_from! { Value for BigInt if v => v.is_big_int() }
impl_try_from! { Primitive for BigInt if v => v.is_big_int() } impl_try_from! { Primitive for BigInt if v => v.is_big_int() }
impl_eq! { for BigInt } impl_eq! { for BigInt }
impl_partial_eq! { Value for BigInt use strict_equals } impl_partial_eq! { Value for BigInt use same_value_zero }
impl_partial_eq! { Primitive for BigInt use strict_equals } impl_partial_eq! { Primitive for BigInt use same_value_zero }
impl_partial_eq! { BigInt for BigInt use strict_equals } impl_partial_eq! { BigInt for BigInt use strict_equals }
/// A primitive boolean value (ECMA-262, 4.3.14). Either the true /// A primitive boolean value (ECMA-262, 4.3.14). Either the true
@ -1235,8 +1246,8 @@ impl_try_from! { Primitive for Name if v => v.is_name() }
impl_from! { String for Name } impl_from! { String for Name }
impl_from! { Symbol for Name } impl_from! { Symbol for Name }
impl_eq! { for Name } impl_eq! { for Name }
impl_partial_eq! { Value for Name use strict_equals } impl_partial_eq! { Value for Name use same_value_zero }
impl_partial_eq! { Primitive for Name use strict_equals } impl_partial_eq! { Primitive for Name use same_value_zero }
impl_partial_eq! { Name for Name use strict_equals } impl_partial_eq! { Name for Name use strict_equals }
impl_partial_eq! { String for Name use strict_equals } impl_partial_eq! { String for Name use strict_equals }
impl_partial_eq! { Symbol for Name use identity } impl_partial_eq! { Symbol for Name use identity }
@ -1250,8 +1261,8 @@ impl_try_from! { Value for String if v => v.is_string() }
impl_try_from! { Primitive for String if v => v.is_string() } impl_try_from! { Primitive for String if v => v.is_string() }
impl_try_from! { Name for String if v => v.is_string() } impl_try_from! { Name for String if v => v.is_string() }
impl_eq! { for String } impl_eq! { for String }
impl_partial_eq! { Value for String use strict_equals } impl_partial_eq! { Value for String use same_value_zero }
impl_partial_eq! { Primitive for String use strict_equals } impl_partial_eq! { Primitive for String use same_value_zero }
impl_partial_eq! { Name for String use strict_equals } impl_partial_eq! { Name for String use strict_equals }
impl_partial_eq! { String for String use strict_equals } impl_partial_eq! { String for String use strict_equals }
@ -1280,12 +1291,13 @@ impl_try_from! { Primitive for Number if v => v.is_number() }
impl_from! { Integer for Number } impl_from! { Integer for Number }
impl_from! { Int32 for Number } impl_from! { Int32 for Number }
impl_from! { Uint32 for Number } impl_from! { Uint32 for Number }
impl_partial_eq! { Value for Number use strict_equals } impl_eq! { for Number }
impl_partial_eq! { Primitive for Number use strict_equals } impl_partial_eq! { Value for Number use same_value_zero }
impl_partial_eq! { Number for Number use strict_equals } impl_partial_eq! { Primitive for Number use same_value_zero }
impl_partial_eq! { Integer for Number use strict_equals } impl_partial_eq! { Number for Number use same_value_zero }
impl_partial_eq! { Int32 for Number use strict_equals } impl_partial_eq! { Integer for Number use same_value_zero }
impl_partial_eq! { Uint32 for Number use strict_equals } impl_partial_eq! { Int32 for Number use same_value_zero }
impl_partial_eq! { Uint32 for Number use same_value_zero }
/// A JavaScript value representing a signed integer. /// A JavaScript value representing a signed integer.
#[repr(C)] #[repr(C)]
@ -1298,9 +1310,9 @@ impl_try_from! { Number for Integer if v => v.is_int32() || v.is_uint32() }
impl_from! { Int32 for Integer } impl_from! { Int32 for Integer }
impl_from! { Uint32 for Integer } impl_from! { Uint32 for Integer }
impl_eq! { for Integer } impl_eq! { for Integer }
impl_partial_eq! { Value for Integer use strict_equals } impl_partial_eq! { Value for Integer use same_value_zero }
impl_partial_eq! { Primitive for Integer use strict_equals } impl_partial_eq! { Primitive for Integer use same_value_zero }
impl_partial_eq! { Number for Integer use strict_equals } impl_partial_eq! { Number for Integer use same_value_zero }
impl_partial_eq! { Integer for Integer use strict_equals } impl_partial_eq! { Integer for Integer use strict_equals }
impl_partial_eq! { Int32 for Integer use strict_equals } impl_partial_eq! { Int32 for Integer use strict_equals }
impl_partial_eq! { Uint32 for Integer use strict_equals } impl_partial_eq! { Uint32 for Integer use strict_equals }
@ -1315,9 +1327,9 @@ impl_try_from! { Primitive for Int32 if v => v.is_int32() }
impl_try_from! { Number for Int32 if v => v.is_int32() } impl_try_from! { Number for Int32 if v => v.is_int32() }
impl_try_from! { Integer for Int32 if v => v.is_int32() } impl_try_from! { Integer for Int32 if v => v.is_int32() }
impl_eq! { for Int32 } impl_eq! { for Int32 }
impl_partial_eq! { Value for Int32 use strict_equals } impl_partial_eq! { Value for Int32 use same_value_zero }
impl_partial_eq! { Primitive for Int32 use strict_equals } impl_partial_eq! { Primitive for Int32 use same_value_zero }
impl_partial_eq! { Number for Int32 use strict_equals } impl_partial_eq! { Number for Int32 use same_value_zero }
impl_partial_eq! { Integer for Int32 use strict_equals } impl_partial_eq! { Integer for Int32 use strict_equals }
impl_partial_eq! { Int32 for Int32 use strict_equals } impl_partial_eq! { Int32 for Int32 use strict_equals }
@ -1331,8 +1343,8 @@ impl_try_from! { Primitive for Uint32 if v => v.is_uint32() }
impl_try_from! { Number for Uint32 if v => v.is_uint32() } impl_try_from! { Number for Uint32 if v => v.is_uint32() }
impl_try_from! { Integer for Uint32 if v => v.is_uint32() } impl_try_from! { Integer for Uint32 if v => v.is_uint32() }
impl_eq! { for Uint32 } impl_eq! { for Uint32 }
impl_partial_eq! { Value for Uint32 use strict_equals } impl_partial_eq! { Value for Uint32 use same_value_zero }
impl_partial_eq! { Primitive for Uint32 use strict_equals } impl_partial_eq! { Primitive for Uint32 use same_value_zero }
impl_partial_eq! { Number for Uint32 use strict_equals } impl_partial_eq! { Number for Uint32 use same_value_zero }
impl_partial_eq! { Integer for Uint32 use strict_equals } impl_partial_eq! { Integer for Uint32 use strict_equals }
impl_partial_eq! { Uint32 for Uint32 use strict_equals } impl_partial_eq! { Uint32 for Uint32 use strict_equals }

View file

@ -237,6 +237,9 @@ impl<'a, T> Handle for &'a Global<T> {
} }
} }
impl<'s, T> Eq for Local<'s, T> where T: Eq {}
impl<T> Eq for Global<T> where T: Eq {}
impl<'s, T, Rhs: Handle> PartialEq<Rhs> for Local<'s, T> impl<'s, T, Rhs: Handle> PartialEq<Rhs> for Local<'s, T>
where where
T: PartialEq<Rhs::Data>, T: PartialEq<Rhs::Data>,

View file

@ -1797,7 +1797,7 @@ fn equality_edge_cases() {
assert!(neg_zero.same_value_zero(pos_zero)); assert!(neg_zero.same_value_zero(pos_zero));
assert!(pos_zero.strict_equals(pos_zero)); assert!(pos_zero.strict_equals(pos_zero));
assert!(nan != nan); assert!(nan == nan);
assert!(nan.same_value(nan)); assert!(nan.same_value(nan));
assert!(nan.same_value_zero(nan)); assert!(nan.same_value_zero(nan));
assert!(!nan.strict_equals(nan)); assert!(!nan.strict_equals(nan));
@ -2258,7 +2258,7 @@ fn value_checker() {
assert!(value.is_number()); assert!(value.is_number());
assert!(!value.is_int32()); assert!(!value.is_int32());
assert!(!value.is_uint32()); assert!(!value.is_uint32());
assert!(value != value); assert!(!value.strict_equals(value));
assert!( assert!(
value.to_string(scope).unwrap() == v8::String::new(scope, "NaN").unwrap() value.to_string(scope).unwrap() == v8::String::new(scope, "NaN").unwrap()
); );