From 7a233e277ea89f864a486734db56d490c66cc2ad Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Fri, 6 Dec 2019 09:36:34 -0500 Subject: [PATCH] Add Value::{is_undefined, is_null, is_null_or_undefined} --- BUILD.gn | 1 + src/lib.rs | 5 ++--- src/primitives.rs | 17 +++++++++++++++++ src/value.cc | 17 +++++++++++++++++ src/value.rs | 28 ++++++++++++++++++++++++++++ tests/test_api.rs | 23 +++++++++++++++++++---- 6 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 src/value.cc create mode 100644 src/value.rs diff --git a/BUILD.gn b/BUILD.gn index 4647b64c..453a59ae 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -18,6 +18,7 @@ v8_static_library("rusty_v8") { "src/primitives.cc", "src/script.cc", "src/string.cc", + "src/value.cc", ] deps = [ ":v8", diff --git a/src/lib.rs b/src/lib.rs index b6a9c20a..ff3279eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ mod primitives; mod script; mod string; mod support; +mod value; pub mod array_buffer; pub mod inspector; @@ -40,6 +41,4 @@ pub use primitives::*; pub use script::{Script, ScriptOrigin}; pub use string::NewStringType; pub use string::String; - -#[repr(C)] -pub struct Value(support::Opaque); +pub use value::Value; diff --git a/src/primitives.rs b/src/primitives.rs index 1b189a37..bbb28968 100644 --- a/src/primitives.rs +++ b/src/primitives.rs @@ -1,8 +1,11 @@ +use std::ops::Deref; + use crate::isolate::CxxIsolate; use crate::isolate::LockedIsolate; use crate::support::Opaque; use crate::HandleScope; use crate::Local; +use crate::Value; /// The superclass of primitive values. See ECMA-262 4.3.2. #[repr(C)] @@ -40,3 +43,17 @@ pub fn new_true<'sc>(scope: &mut HandleScope<'sc>) -> Local<'sc, Boolean> { pub fn new_false<'sc>(scope: &mut HandleScope<'sc>) -> Local<'sc, Boolean> { unsafe { Local::from_raw(v8__False(scope.cxx_isolate())) }.unwrap() } + +impl Deref for Primitive { + type Target = Value; + fn deref(&self) -> &Self::Target { + unsafe { &*(self as *const _ as *const Value) } + } +} + +impl Deref for Boolean { + type Target = Primitive; + fn deref(&self) -> &Self::Target { + unsafe { &*(self as *const _ as *const Primitive) } + } +} diff --git a/src/value.cc b/src/value.cc new file mode 100644 index 00000000..28f4f71e --- /dev/null +++ b/src/value.cc @@ -0,0 +1,17 @@ +#include + +#include "support.h" +#include "v8/include/v8.h" + +using namespace v8; +using namespace support; + +extern "C" { +bool v8__Value__IsUndefined(const Value &self) { return self.IsUndefined(); } + +bool v8__Value__IsNull(const Value &self) { return self.IsNull(); } + +bool v8__Value__IsNullOrUndefined(const Value &self) { + return self.IsNullOrUndefined(); +} +} diff --git a/src/value.rs b/src/value.rs new file mode 100644 index 00000000..6a348afd --- /dev/null +++ b/src/value.rs @@ -0,0 +1,28 @@ +use crate::support; + +extern "C" { + fn v8__Value__IsUndefined(this: &Value) -> bool; + fn v8__Value__IsNull(this: &Value) -> bool; + fn v8__Value__IsNullOrUndefined(this: &Value) -> bool; +} + +#[repr(C)] +pub struct Value(support::Opaque); + +impl Value { + /// Returns true if this value is the undefined value. See ECMA-262 4.3.10. + pub fn is_undefined(&self) -> bool { + unsafe { v8__Value__IsUndefined(self) } + } + + /// Returns true if this value is the null value. See ECMA-262 4.3.11. + pub fn is_null(&self) -> bool { + unsafe { v8__Value__IsNull(self) } + } + + /// Returns true if this value is either the null or the undefined value. + /// See ECMA-262 4.3.11. and 4.3.12 + pub fn is_null_or_undefined(&self) -> bool { + unsafe { v8__Value__IsNullOrUndefined(self) } + } +} diff --git a/tests/test_api.rs b/tests/test_api.rs index d2b46248..24c5284e 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -190,9 +190,24 @@ fn test_primitives() { let mut isolate = v8::Isolate::new(params); let mut locker = v8::Locker::new(&mut isolate); v8::HandleScope::enter(&mut locker, |scope| { - let _null = v8::new_null(scope); - let _undefined = v8::new_undefined(scope); - let _true = v8::new_true(scope); - let _false = v8::new_false(scope); + let null = v8::new_null(scope); + assert!(!null.is_undefined()); + assert!(null.is_null()); + assert!(null.is_null_or_undefined()); + + let undefined = v8::new_undefined(scope); + assert!(undefined.is_undefined()); + assert!(!undefined.is_null()); + assert!(undefined.is_null_or_undefined()); + + let true_ = v8::new_true(scope); + assert!(!true_.is_undefined()); + assert!(!true_.is_null()); + assert!(!true_.is_null_or_undefined()); + + let false_ = v8::new_false(scope); + assert!(!false_.is_undefined()); + assert!(!false_.is_null()); + assert!(!false_.is_null_or_undefined()); }); }