0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-12-25 00:29:14 -05:00

Implement TryFrom<Data> for subclasses of Data (#453)

This commit is contained in:
Gus Caplan 2020-09-02 09:43:25 -05:00 committed by Bert Belder
parent 6409d8b112
commit 3b27748a17
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
3 changed files with 122 additions and 1 deletions

View file

@ -307,6 +307,20 @@ bool v8__Data__EQ(const v8::Data& self, const v8::Data& other) {
return ptr_to_local(&self) == ptr_to_local(&other); return ptr_to_local(&self) == ptr_to_local(&other);
} }
bool v8__Data__IsValue(const v8::Data& self) { return self.IsValue(); }
bool v8__Data__IsModule(const v8::Data& self) { return self.IsModule(); }
bool v8__Data__IsPrivate(const v8::Data& self) { return self.IsPrivate(); }
bool v8__Data__IsObjectTemplate(const v8::Data& self) {
return self.IsObjectTemplate();
}
bool v8__Data__IsFunctionTemplate(const v8::Data& self) {
return self.IsFunctionTemplate();
}
bool v8__Value__IsUndefined(const v8::Value& self) { bool v8__Value__IsUndefined(const v8::Value& self) {
return self.IsUndefined(); return self.IsUndefined();
} }

View file

@ -17,6 +17,12 @@ use crate::Local;
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__Data__IsValue(this: *const Data) -> bool;
fn v8__Data__IsModule(this: *const Data) -> bool;
fn v8__Data__IsPrivate(this: *const Data) -> bool;
fn v8__Data__IsObjectTemplate(this: *const Data) -> bool;
fn v8__Data__IsFunctionTemplate(this: *const Data) -> bool;
fn v8__internal__Object__GetHash(this: *const Data) -> int; fn v8__internal__Object__GetHash(this: *const Data) -> int;
fn v8__Value__SameValue(this: *const Value, other: *const Value) -> bool; fn v8__Value__SameValue(this: *const Value, other: *const Value) -> bool;
@ -32,6 +38,31 @@ impl Data {
pub fn get_hash(&self) -> int { pub fn get_hash(&self) -> int {
unsafe { v8__internal__Object__GetHash(self) } unsafe { v8__internal__Object__GetHash(self) }
} }
/// Returns true if this data is a `Value`.
pub fn is_value(&self) -> bool {
unsafe { v8__Data__IsValue(self) }
}
/// Returns true if this data is a `Module`.
pub fn is_module(&self) -> bool {
unsafe { v8__Data__IsModule(self) }
}
/// Returns true if this data is a `Private`.
pub fn is_private(&self) -> bool {
unsafe { v8__Data__IsPrivate(self) }
}
/// Returns true if this data is an `ObjectTemplate`
pub fn is_object_template(&self) -> bool {
unsafe { v8__Data__IsObjectTemplate(self) }
}
/// Returns true if this data is a `FunctionTemplate.`
pub fn is_function_template(&self) -> bool {
unsafe { v8__Data__IsFunctionTemplate(self) }
}
} }
macro_rules! impl_deref { macro_rules! impl_deref {
@ -292,6 +323,7 @@ impl_partial_eq! { Message for Message use identity }
pub struct Module(Opaque); pub struct Module(Opaque);
impl_deref! { Data for Module } impl_deref! { Data for Module }
impl_try_from! { Data for Module if d => d.is_module() }
impl_eq! { for Module } impl_eq! { for Module }
impl_hash! { for Module } impl_hash! { for Module }
impl_partial_eq! { Data for Module use identity } impl_partial_eq! { Data for Module use identity }
@ -318,6 +350,7 @@ impl_partial_eq! { PrimitiveArray for PrimitiveArray use identity }
pub struct Private(Opaque); pub struct Private(Opaque);
impl_deref! { Data for Private } impl_deref! { Data for Private }
impl_try_from! { Data for Private if d => d.is_private() }
impl_eq! { for Private } impl_eq! { for Private }
impl_hash! { for Private } impl_hash! { for Private }
impl_partial_eq! { Data for Private use identity } impl_partial_eq! { Data for Private use identity }
@ -507,6 +540,7 @@ impl_partial_eq! { ObjectTemplate for Template use identity }
pub struct FunctionTemplate(Opaque); pub struct FunctionTemplate(Opaque);
impl_deref! { Template for FunctionTemplate } impl_deref! { Template for FunctionTemplate }
impl_try_from! { Data for FunctionTemplate if d => d.is_function_template() }
impl_eq! { for FunctionTemplate } impl_eq! { for FunctionTemplate }
impl_hash! { for FunctionTemplate } impl_hash! { for FunctionTemplate }
impl_partial_eq! { Data for FunctionTemplate use identity } impl_partial_eq! { Data for FunctionTemplate use identity }
@ -521,6 +555,7 @@ impl_partial_eq! { FunctionTemplate for FunctionTemplate use identity }
pub struct ObjectTemplate(Opaque); pub struct ObjectTemplate(Opaque);
impl_deref! { Template for ObjectTemplate } impl_deref! { Template for ObjectTemplate }
impl_try_from! { Data for ObjectTemplate if d => d.is_object_template() }
impl_eq! { for ObjectTemplate } impl_eq! { for ObjectTemplate }
impl_hash! { for ObjectTemplate } impl_hash! { for ObjectTemplate }
impl_partial_eq! { Data for ObjectTemplate use identity } impl_partial_eq! { Data for ObjectTemplate use identity }
@ -552,6 +587,7 @@ impl_partial_eq! { UnboundScript for UnboundScript use identity }
pub struct Value(Opaque); pub struct Value(Opaque);
impl_deref! { Data for Value } impl_deref! { Data for Value }
impl_try_from! { Data for Value if d => d.is_value() }
impl_from! { External for Value } impl_from! { External for Value }
impl_from! { Object for Value } impl_from! { Object for Value }
impl_from! { Array for Value } impl_from! { Array for Value }

View file

@ -2700,7 +2700,78 @@ fn value_checker() {
} }
#[test] #[test]
fn try_from_local() { fn try_from_data() {
let _setup_guard = setup();
let isolate = &mut v8::Isolate::new(Default::default());
let scope = &mut v8::HandleScope::new(isolate);
let context = v8::Context::new(scope);
let scope = &mut v8::ContextScope::new(scope, context);
let module_source = mock_source(scope, "answer.js", "fail()");
let function_callback =
|_: &mut v8::HandleScope,
_: v8::FunctionCallbackArguments,
_: v8::ReturnValue| { unreachable!() };
let function_template = v8::FunctionTemplate::new(scope, function_callback);
let d: v8::Local<v8::Data> = function_template.into();
assert!(d.is_function_template());
assert!(!d.is_module());
assert!(!d.is_object_template());
assert!(!d.is_private());
assert!(!d.is_value());
assert!(
v8::Local::<v8::FunctionTemplate>::try_from(d).unwrap()
== function_template
);
let module =
v8::script_compiler::compile_module(scope, module_source).unwrap();
let d: v8::Local<v8::Data> = module.into();
assert!(!d.is_function_template());
assert!(d.is_module());
assert!(!d.is_object_template());
assert!(!d.is_private());
assert!(!d.is_value());
assert!(v8::Local::<v8::Module>::try_from(d).unwrap() == module);
let object_template = v8::ObjectTemplate::new(scope);
let d: v8::Local<v8::Data> = object_template.into();
assert!(!d.is_function_template());
assert!(!d.is_module());
assert!(d.is_object_template());
assert!(!d.is_private());
assert!(!d.is_value());
assert!(
v8::Local::<v8::ObjectTemplate>::try_from(d).unwrap() == object_template
);
// There is currently no way to construct instances of `v8::Private`,
// therefore we don't have a test where `is_private()` succeeds.
let values: &[v8::Local<v8::Value>] = &[
v8::null(scope).into(),
v8::undefined(scope).into(),
v8::Boolean::new(scope, true).into(),
v8::Function::new(scope, function_callback).unwrap().into(),
v8::Number::new(scope, 42.0).into(),
v8::Object::new(scope).into(),
v8::String::new(scope, "hello").unwrap().into(),
];
for &v in values {
let d: v8::Local<v8::Data> = v.into();
assert!(!d.is_function_template());
assert!(!d.is_module());
assert!(!d.is_object_template());
assert!(!d.is_private());
assert!(d.is_value());
assert!(v8::Local::<v8::Value>::try_from(d).unwrap() == v);
}
}
#[test]
fn try_from_value() {
let _setup_guard = setup(); let _setup_guard = setup();
let isolate = &mut v8::Isolate::new(Default::default()); let isolate = &mut v8::Isolate::new(Default::default());
{ {