0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-11-28 16:21:04 -05:00

chore: Add a couple convenience casting functions to v8::Local (#1533)

* Rename cast -> cast_unchecked

* Add cast helpers

* Change a couple tests to use it

* Add some small docs

* Fmt

* Add inline hint

* Address comments
This commit is contained in:
Nathan Whitaker 2024-07-19 18:34:32 -07:00 committed by GitHub
parent b590c12fe9
commit 6385bd6f32
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 56 additions and 16 deletions

View file

@ -324,8 +324,10 @@ where
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
request: v8::Local<v8::Object>, request: v8::Local<v8::Object>,
) -> *mut Box<dyn HttpRequest> { ) -> *mut Box<dyn HttpRequest> {
let external = request.get_internal_field(scope, 0).unwrap(); let external = request
let external = unsafe { v8::Local::<v8::External>::cast(external) }; .get_internal_field(scope, 0)
.unwrap()
.cast::<v8::External>();
external.value() as *mut Box<dyn HttpRequest> external.value() as *mut Box<dyn HttpRequest>
} }

View file

@ -224,7 +224,8 @@ fn report_exceptions(mut try_catch: v8::TryCatch<v8::HandleScope>) {
} else { } else {
return; return;
}; };
let stack_trace = unsafe { v8::Local::<v8::String>::cast(stack_trace) }; let stack_trace =
unsafe { v8::Local::<v8::String>::cast_unchecked(stack_trace) };
let stack_trace = stack_trace let stack_trace = stack_trace
.to_string(&mut try_catch) .to_string(&mut try_catch)
.map(|s| s.to_rust_string_lossy(&mut try_catch)); .map(|s| s.to_rust_string_lossy(&mut try_catch));

View file

@ -105,9 +105,9 @@ impl<'s, T> Local<'s, T> {
/// Create a local handle by downcasting from one of its super types. /// Create a local handle by downcasting from one of its super types.
/// This function is unsafe because the cast is unchecked. /// This function is unsafe because the cast is unchecked.
#[inline(always)] #[inline(always)]
pub unsafe fn cast<A>(other: Local<'s, A>) -> Self pub unsafe fn cast_unchecked<A>(other: Local<'s, A>) -> Self
where where
Local<'s, A>: From<Self>, Local<'s, A>: TryFrom<Self>,
{ {
transmute(other) transmute(other)
} }
@ -153,6 +153,48 @@ impl<'s, T> Deref for Local<'s, T> {
} }
} }
impl<'s, T> Local<'s, T> {
/// Attempts to cast the contained type to another,
/// returning an error if the conversion fails.
///
/// # Examples
///
/// ```
/// let value: Local<'_, Value> = get_v8_value();
///
/// if let Ok(func) = value.try_cast::<Function<() {
/// //
/// }
/// ```
#[inline(always)]
pub fn try_cast<A>(
self,
) -> Result<Local<'s, A>, <Self as TryInto<Local<'s, A>>>::Error>
where
Self: TryInto<Local<'s, A>>,
{
self.try_into()
}
/// Attempts to cast the contained type to another,
/// panicking if the conversion fails.
///
/// # Example
///
/// ```
/// let value: Local<'_, Value> = get_v8_value();
///
/// let func = value.cast::<Function>();
/// ```
#[inline(always)]
pub fn cast<A>(self) -> Local<'s, A>
where
Self: TryInto<Local<'s, A>, Error: std::fmt::Debug>,
{
self.try_into().unwrap()
}
}
/// An object reference that is independent of any handle scope. Where /// An object reference that is independent of any handle scope. Where
/// a Local handle only lives as long as the HandleScope in which it was /// a Local handle only lives as long as the HandleScope in which it was
/// allocated, a global handle remains valid until it is dropped. /// allocated, a global handle remains valid until it is dropped.

View file

@ -97,8 +97,8 @@ fn handle_scope_numbers() {
{ {
let scope2 = &mut v8::HandleScope::new(scope1); let scope2 = &mut v8::HandleScope::new(scope1);
let l3 = v8::Number::new(scope2, 78.9); let l3 = v8::Number::new(scope2, 78.9);
let l4 = v8::Local::<v8::Int32>::try_from(l1).unwrap(); let l4 = l1.cast::<v8::Int32>();
let l5 = v8::Local::<v8::Uint32>::try_from(l2).unwrap(); let l5 = l2.cast::<v8::Uint32>();
assert_eq!(l1.value(), -123); assert_eq!(l1.value(), -123);
assert_eq!(l2.value(), 456); assert_eq!(l2.value(), 456);
assert_eq!(l3.value(), 78.9); assert_eq!(l3.value(), 78.9);
@ -2493,20 +2493,15 @@ fn object_template_set_named_property_handler() {
name.into(), name.into(),
obj.into(), obj.into(),
); );
let arr = v8::Local::<v8::Array>::try_from( let arr = eval(scope, "Object.keys(obj)").unwrap().cast::<v8::Array>();
eval(scope, "Object.keys(obj)").unwrap(),
)
.unwrap();
assert_eq!(arr.length(), 1); assert_eq!(arr.length(), 1);
let index = v8::Integer::new(scope, 0); let index = v8::Integer::new(scope, 0);
let result = arr.get(scope, index.into()).unwrap(); let result = arr.get(scope, index.into()).unwrap();
let expected = v8::String::new(scope, "key").unwrap(); let expected = v8::String::new(scope, "key").unwrap();
assert!(expected.strict_equals(result)); assert!(expected.strict_equals(result));
eval(scope, "obj.fallthrough = 'a'").unwrap(); eval(scope, "obj.fallthrough = 'a'").unwrap();
let arr = v8::Local::<v8::Array>::try_from( let arr = eval(scope, "Object.keys(obj)").unwrap().cast::<v8::Array>();
eval(scope, "Object.keys(obj)").unwrap(),
)
.unwrap();
assert_eq!(arr.length(), 2); assert_eq!(arr.length(), 2);
// definer // definer
@ -10935,7 +10930,7 @@ fn test_fast_calls_callback_options_data() {
return; return;
} }
let data = v8::Local::<v8::External>::cast(options.data.data); let data = v8::Local::<v8::External>::cast_unchecked(options.data.data);
let data = &mut *(data.value() as *mut bool); let data = &mut *(data.value() as *mut bool);
*data = true; *data = true;
} }