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

Add safe downcasts for Local<Value> with TryFrom (#166) (#166)

This commit is contained in:
Bert Belder 2020-01-03 14:41:17 +01:00 committed by Ry Dahl
parent 5c9effbeb1
commit 64136e684e
2 changed files with 366 additions and 294 deletions

View file

@ -1,14 +1,26 @@
// Copyright 2019-2020 the Deno authors. All rights reserved. MIT license.
use std::convert::From;
use std::convert::TryFrom;
use std::mem::transmute;
use std::ops::Deref;
use crate::support::Opaque;
use crate::Local;
macro_rules! impl_deref {
{ $a:ident for $b:ident } => {
impl Deref for $a {
type Target = $b;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const _ as *const Self::Target) }
}
}
};
}
macro_rules! impl_from {
($a:ident, $b:ident) => {
{ $a:ident for $b:ident } => {
impl<'sc> From<Local<'sc, $a>> for Local<'sc, $b> {
fn from(l: Local<'sc, $a>) -> Self {
unsafe { transmute(l) }
@ -17,12 +29,18 @@ macro_rules! impl_from {
};
}
macro_rules! impl_deref {
($a:ident, $b:ident) => {
impl Deref for $a {
type Target = $b;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const _ as *const Self::Target) }
#[derive(Clone, Copy, Debug)]
pub struct TryFromTypeError;
macro_rules! impl_try_from {
{ $a:ident for $b:ident if $p:pat => $c:expr } => {
impl<'sc> TryFrom<Local<'sc, $a>> for Local<'sc, $b> {
type Error = TryFromTypeError;
fn try_from(l: Local<'sc, $a>) -> Result<Self, Self::Error> {
match l {
$p if $c => Ok(unsafe { transmute(l) }),
_ => Err(TryFromTypeError)
}
}
}
};
@ -36,25 +54,22 @@ pub struct Data(Opaque);
/// to an accessor callback.
#[repr(C)]
pub struct AccessorSignature(Opaque);
impl_deref!(AccessorSignature, Data);
impl_from!(AccessorSignature, Data);
impl_deref! { AccessorSignature for Data }
impl_from! { AccessorSignature for Data }
/// A compiled JavaScript module.
#[repr(C)]
pub struct Module(Opaque);
impl_deref!(Module, Data);
impl_from!(Module, Data);
impl_deref! { Module for Data }
impl_from! { Module for Data }
/// A private symbol
///
/// This is an experimental feature. Use at your own risk.
#[repr(C)]
pub struct Private(Opaque);
impl_deref!(Private, Data);
impl_from!(Private, Data);
impl_deref! { Private for Data }
impl_from! { Private for Data }
/// A Signature specifies which receiver is valid for a function.
///
@ -64,16 +79,14 @@ impl_from!(Private, Data);
/// signature's FunctionTemplate.
#[repr(C)]
pub struct Signature(Opaque);
impl_deref!(Signature, Data);
impl_from!(Signature, Data);
impl_deref! { Signature for Data }
impl_from! { Signature for Data }
/// The superclass of object and function templates.
#[repr(C)]
pub struct Template(Opaque);
impl_deref!(Template, Data);
impl_from!(Template, Data);
impl_deref! { Template for Data }
impl_from! { Template for Data }
/// A FunctionTemplate is used to create functions at runtime. There
/// can only be one function created from a FunctionTemplate in a
@ -175,10 +188,9 @@ impl_from!(Template, Data);
/// ```
#[repr(C)]
pub struct FunctionTemplate(Opaque);
impl_deref!(FunctionTemplate, Template);
impl_from!(FunctionTemplate, Data);
impl_from!(FunctionTemplate, Template);
impl_deref! { FunctionTemplate for Template }
impl_from! { FunctionTemplate for Data }
impl_from! { FunctionTemplate for Template }
/// An ObjectTemplate is used to create objects at runtime.
///
@ -186,451 +198,514 @@ impl_from!(FunctionTemplate, Template);
/// created from the ObjectTemplate.
#[repr(C)]
pub struct ObjectTemplate(Opaque);
impl_deref!(ObjectTemplate, Template);
impl_from!(ObjectTemplate, Data);
impl_from!(ObjectTemplate, Template);
impl_deref! { ObjectTemplate for Template }
impl_from! { ObjectTemplate for Data }
impl_from! { ObjectTemplate for Template }
/// A compiled JavaScript module, not yet tied to a Context.
#[repr(C)]
pub struct UnboundModuleScript(Opaque);
impl_deref!(UnboundModuleScript, Data);
impl_from!(UnboundModuleScript, Data);
impl_deref! { UnboundModuleScript for Data }
impl_from! { UnboundModuleScript for Data }
/// The superclass of all JavaScript values and objects.
#[repr(C)]
pub struct Value(Opaque);
impl_deref!(Value, Data);
impl_from!(Value, Data);
impl_deref! { Value for Data }
impl_from! { Value for Data }
/// A JavaScript value that wraps a C++ void*. This type of value is mainly used
/// to associate C++ data structures with JavaScript objects.
#[repr(C)]
pub struct External(Opaque);
impl_deref!(External, Value);
impl_from!(External, Data);
impl_from!(External, Value);
impl_deref! { External for Value }
impl_from! { External for Data }
impl_from! { External for Value }
impl_try_from! { Value for External if v => v.is_external() }
/// A JavaScript object (ECMA-262, 4.3.3)
#[repr(C)]
pub struct Object(Opaque);
impl_deref!(Object, Value);
impl_from!(Object, Data);
impl_from!(Object, Value);
impl_deref! { Object for Value }
impl_from! { Object for Data }
impl_from! { Object for Value }
impl_try_from! { Value for Object if v => v.is_object() }
/// An instance of the built-in array constructor (ECMA-262, 15.4.2).
#[repr(C)]
pub struct Array(Opaque);
impl_deref!(Array, Object);
impl_from!(Array, Data);
impl_from!(Array, Value);
impl_from!(Array, Object);
impl_deref! { Array for Object }
impl_from! { Array for Data }
impl_from! { Array for Value }
impl_from! { Array for Object }
impl_try_from! { Object for Array if v => v.is_array() }
impl_try_from! { Value for Array if v => v.is_array() }
/// An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5).
#[repr(C)]
pub struct ArrayBuffer(Opaque);
impl_deref!(ArrayBuffer, Object);
impl_from!(ArrayBuffer, Data);
impl_from!(ArrayBuffer, Value);
impl_from!(ArrayBuffer, Object);
impl_deref! { ArrayBuffer for Object }
impl_from! { ArrayBuffer for Data }
impl_from! { ArrayBuffer for Value }
impl_from! { ArrayBuffer for Object }
impl_try_from! { Object for ArrayBuffer if v => v.is_array_buffer() }
impl_try_from! { Value for ArrayBuffer if v => v.is_array_buffer() }
/// A base class for an instance of one of "views" over ArrayBuffer,
/// including TypedArrays and DataView (ES6 draft 15.13).
#[repr(C)]
pub struct ArrayBufferView(Opaque);
impl_deref!(ArrayBufferView, Object);
impl_from!(ArrayBufferView, Data);
impl_from!(ArrayBufferView, Value);
impl_from!(ArrayBufferView, Object);
impl_deref! { ArrayBufferView for Object }
impl_from! { ArrayBufferView for Data }
impl_from! { ArrayBufferView for Value }
impl_from! { ArrayBufferView for Object }
impl_try_from! { Object for ArrayBufferView if v => v.is_array_buffer_view() }
impl_try_from! { Value for ArrayBufferView if v => v.is_array_buffer_view() }
/// An instance of DataView constructor (ES6 draft 15.13.7).
#[repr(C)]
pub struct DataView(Opaque);
impl_deref!(DataView, ArrayBufferView);
impl_from!(DataView, Data);
impl_from!(DataView, Value);
impl_from!(DataView, Object);
impl_from!(DataView, ArrayBufferView);
impl_deref! { DataView for ArrayBufferView }
impl_from! { DataView for Data }
impl_from! { DataView for Value }
impl_from! { DataView for Object }
impl_from! { DataView for ArrayBufferView }
impl_try_from! { ArrayBufferView for DataView if v => v.is_data_view() }
impl_try_from! { Object for DataView if v => v.is_data_view() }
impl_try_from! { Value for DataView if v => v.is_data_view() }
/// A base class for an instance of TypedArray series of constructors
/// (ES6 draft 15.13.6).
#[repr(C)]
pub struct TypedArray(Opaque);
impl_deref!(TypedArray, ArrayBufferView);
impl_from!(TypedArray, Data);
impl_from!(TypedArray, Value);
impl_from!(TypedArray, Object);
impl_from!(TypedArray, ArrayBufferView);
impl_deref! { TypedArray for ArrayBufferView }
impl_from! { TypedArray for Data }
impl_from! { TypedArray for Value }
impl_from! { TypedArray for Object }
impl_from! { TypedArray for ArrayBufferView }
impl_try_from! { ArrayBufferView for TypedArray if v => v.is_typed_array() }
impl_try_from! { Object for TypedArray if v => v.is_typed_array() }
impl_try_from! { Value for TypedArray if v => v.is_typed_array() }
/// An instance of BigInt64Array constructor.
#[repr(C)]
pub struct BigInt64Array(Opaque);
impl_deref!(BigInt64Array, TypedArray);
impl_from!(BigInt64Array, Data);
impl_from!(BigInt64Array, Value);
impl_from!(BigInt64Array, Object);
impl_from!(BigInt64Array, ArrayBufferView);
impl_from!(BigInt64Array, TypedArray);
impl_deref! { BigInt64Array for TypedArray }
impl_from! { BigInt64Array for Data }
impl_from! { BigInt64Array for Value }
impl_from! { BigInt64Array for Object }
impl_from! { BigInt64Array for ArrayBufferView }
impl_from! { BigInt64Array for TypedArray }
impl_try_from! { TypedArray for BigInt64Array if v => v.is_big_int64_array() }
impl_try_from! { ArrayBufferView for BigInt64Array if v => v.is_big_int64_array() }
impl_try_from! { Object for BigInt64Array if v => v.is_big_int64_array() }
impl_try_from! { Value for BigInt64Array if v => v.is_big_int64_array() }
/// An instance of BigUint64Array constructor.
#[repr(C)]
pub struct BigUint64Array(Opaque);
impl_deref!(BigUint64Array, TypedArray);
impl_from!(BigUint64Array, Data);
impl_from!(BigUint64Array, Value);
impl_from!(BigUint64Array, Object);
impl_from!(BigUint64Array, ArrayBufferView);
impl_from!(BigUint64Array, TypedArray);
impl_deref! { BigUint64Array for TypedArray }
impl_from! { BigUint64Array for Data }
impl_from! { BigUint64Array for Value }
impl_from! { BigUint64Array for Object }
impl_from! { BigUint64Array for ArrayBufferView }
impl_from! { BigUint64Array for TypedArray }
impl_try_from! { TypedArray for BigUint64Array if v => v.is_big_uint64_array() }
impl_try_from! { ArrayBufferView for BigUint64Array if v => v.is_big_uint64_array() }
impl_try_from! { Object for BigUint64Array if v => v.is_big_uint64_array() }
impl_try_from! { Value for BigUint64Array if v => v.is_big_uint64_array() }
/// An instance of Float32Array constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Float32Array(Opaque);
impl_deref!(Float32Array, TypedArray);
impl_from!(Float32Array, Data);
impl_from!(Float32Array, Value);
impl_from!(Float32Array, Object);
impl_from!(Float32Array, ArrayBufferView);
impl_from!(Float32Array, TypedArray);
impl_deref! { Float32Array for TypedArray }
impl_from! { Float32Array for Data }
impl_from! { Float32Array for Value }
impl_from! { Float32Array for Object }
impl_from! { Float32Array for ArrayBufferView }
impl_from! { Float32Array for TypedArray }
impl_try_from! { TypedArray for Float32Array if v => v.is_float32_array() }
impl_try_from! { ArrayBufferView for Float32Array if v => v.is_float32_array() }
impl_try_from! { Object for Float32Array if v => v.is_float32_array() }
impl_try_from! { Value for Float32Array if v => v.is_float32_array() }
/// An instance of Float64Array constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Float64Array(Opaque);
impl_deref!(Float64Array, TypedArray);
impl_from!(Float64Array, Data);
impl_from!(Float64Array, Value);
impl_from!(Float64Array, Object);
impl_from!(Float64Array, ArrayBufferView);
impl_from!(Float64Array, TypedArray);
impl_deref! { Float64Array for TypedArray }
impl_from! { Float64Array for Data }
impl_from! { Float64Array for Value }
impl_from! { Float64Array for Object }
impl_from! { Float64Array for ArrayBufferView }
impl_from! { Float64Array for TypedArray }
impl_try_from! { TypedArray for Float64Array if v => v.is_float64_array() }
impl_try_from! { ArrayBufferView for Float64Array if v => v.is_float64_array() }
impl_try_from! { Object for Float64Array if v => v.is_float64_array() }
impl_try_from! { Value for Float64Array if v => v.is_float64_array() }
/// An instance of Int16Array constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Int16Array(Opaque);
impl_deref!(Int16Array, TypedArray);
impl_from!(Int16Array, Data);
impl_from!(Int16Array, Value);
impl_from!(Int16Array, Object);
impl_from!(Int16Array, ArrayBufferView);
impl_from!(Int16Array, TypedArray);
impl_deref! { Int16Array for TypedArray }
impl_from! { Int16Array for Data }
impl_from! { Int16Array for Value }
impl_from! { Int16Array for Object }
impl_from! { Int16Array for ArrayBufferView }
impl_from! { Int16Array for TypedArray }
impl_try_from! { TypedArray for Int16Array if v => v.is_int16_array() }
impl_try_from! { ArrayBufferView for Int16Array if v => v.is_int16_array() }
impl_try_from! { Object for Int16Array if v => v.is_int16_array() }
impl_try_from! { Value for Int16Array if v => v.is_int16_array() }
/// An instance of Int32Array constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Int32Array(Opaque);
impl_deref!(Int32Array, TypedArray);
impl_from!(Int32Array, Data);
impl_from!(Int32Array, Value);
impl_from!(Int32Array, Object);
impl_from!(Int32Array, ArrayBufferView);
impl_from!(Int32Array, TypedArray);
impl_deref! { Int32Array for TypedArray }
impl_from! { Int32Array for Data }
impl_from! { Int32Array for Value }
impl_from! { Int32Array for Object }
impl_from! { Int32Array for ArrayBufferView }
impl_from! { Int32Array for TypedArray }
impl_try_from! { TypedArray for Int32Array if v => v.is_int32_array() }
impl_try_from! { ArrayBufferView for Int32Array if v => v.is_int32_array() }
impl_try_from! { Object for Int32Array if v => v.is_int32_array() }
impl_try_from! { Value for Int32Array if v => v.is_int32_array() }
/// An instance of Int8Array constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Int8Array(Opaque);
impl_deref!(Int8Array, TypedArray);
impl_from!(Int8Array, Data);
impl_from!(Int8Array, Value);
impl_from!(Int8Array, Object);
impl_from!(Int8Array, ArrayBufferView);
impl_from!(Int8Array, TypedArray);
impl_deref! { Int8Array for TypedArray }
impl_from! { Int8Array for Data }
impl_from! { Int8Array for Value }
impl_from! { Int8Array for Object }
impl_from! { Int8Array for ArrayBufferView }
impl_from! { Int8Array for TypedArray }
impl_try_from! { TypedArray for Int8Array if v => v.is_int8_array() }
impl_try_from! { ArrayBufferView for Int8Array if v => v.is_int8_array() }
impl_try_from! { Object for Int8Array if v => v.is_int8_array() }
impl_try_from! { Value for Int8Array if v => v.is_int8_array() }
/// An instance of Uint16Array constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Uint16Array(Opaque);
impl_deref!(Uint16Array, TypedArray);
impl_from!(Uint16Array, Data);
impl_from!(Uint16Array, Value);
impl_from!(Uint16Array, Object);
impl_from!(Uint16Array, ArrayBufferView);
impl_from!(Uint16Array, TypedArray);
impl_deref! { Uint16Array for TypedArray }
impl_from! { Uint16Array for Data }
impl_from! { Uint16Array for Value }
impl_from! { Uint16Array for Object }
impl_from! { Uint16Array for ArrayBufferView }
impl_from! { Uint16Array for TypedArray }
impl_try_from! { TypedArray for Uint16Array if v => v.is_uint16_array() }
impl_try_from! { ArrayBufferView for Uint16Array if v => v.is_uint16_array() }
impl_try_from! { Object for Uint16Array if v => v.is_uint16_array() }
impl_try_from! { Value for Uint16Array if v => v.is_uint16_array() }
/// An instance of Uint32Array constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Uint32Array(Opaque);
impl_deref!(Uint32Array, TypedArray);
impl_from!(Uint32Array, Data);
impl_from!(Uint32Array, Value);
impl_from!(Uint32Array, Object);
impl_from!(Uint32Array, ArrayBufferView);
impl_from!(Uint32Array, TypedArray);
impl_deref! { Uint32Array for TypedArray }
impl_from! { Uint32Array for Data }
impl_from! { Uint32Array for Value }
impl_from! { Uint32Array for Object }
impl_from! { Uint32Array for ArrayBufferView }
impl_from! { Uint32Array for TypedArray }
impl_try_from! { TypedArray for Uint32Array if v => v.is_uint32_array() }
impl_try_from! { ArrayBufferView for Uint32Array if v => v.is_uint32_array() }
impl_try_from! { Object for Uint32Array if v => v.is_uint32_array() }
impl_try_from! { Value for Uint32Array if v => v.is_uint32_array() }
/// An instance of Uint8Array constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Uint8Array(Opaque);
impl_deref!(Uint8Array, TypedArray);
impl_from!(Uint8Array, Data);
impl_from!(Uint8Array, Value);
impl_from!(Uint8Array, Object);
impl_from!(Uint8Array, ArrayBufferView);
impl_from!(Uint8Array, TypedArray);
impl_deref! { Uint8Array for TypedArray }
impl_from! { Uint8Array for Data }
impl_from! { Uint8Array for Value }
impl_from! { Uint8Array for Object }
impl_from! { Uint8Array for ArrayBufferView }
impl_from! { Uint8Array for TypedArray }
impl_try_from! { TypedArray for Uint8Array if v => v.is_uint8_array() }
impl_try_from! { ArrayBufferView for Uint8Array if v => v.is_uint8_array() }
impl_try_from! { Object for Uint8Array if v => v.is_uint8_array() }
impl_try_from! { Value for Uint8Array if v => v.is_uint8_array() }
/// An instance of Uint8ClampedArray constructor (ES6 draft 15.13.6).
#[repr(C)]
pub struct Uint8ClampedArray(Opaque);
impl_deref!(Uint8ClampedArray, TypedArray);
impl_from!(Uint8ClampedArray, Data);
impl_from!(Uint8ClampedArray, Value);
impl_from!(Uint8ClampedArray, Object);
impl_from!(Uint8ClampedArray, ArrayBufferView);
impl_from!(Uint8ClampedArray, TypedArray);
impl_deref! { Uint8ClampedArray for TypedArray }
impl_from! { Uint8ClampedArray for Data }
impl_from! { Uint8ClampedArray for Value }
impl_from! { Uint8ClampedArray for Object }
impl_from! { Uint8ClampedArray for ArrayBufferView }
impl_from! { Uint8ClampedArray for TypedArray }
impl_try_from! { TypedArray for Uint8ClampedArray if v => v.is_uint8_clamped_array() }
impl_try_from! { ArrayBufferView for Uint8ClampedArray if v => v.is_uint8_clamped_array() }
impl_try_from! { Object for Uint8ClampedArray if v => v.is_uint8_clamped_array() }
impl_try_from! { Value for Uint8ClampedArray if v => v.is_uint8_clamped_array() }
/// A BigInt object (https://tc39.github.io/proposal-bigint)
#[repr(C)]
pub struct BigIntObject(Opaque);
impl_deref!(BigIntObject, Object);
impl_from!(BigIntObject, Data);
impl_from!(BigIntObject, Value);
impl_from!(BigIntObject, Object);
impl_deref! { BigIntObject for Object }
impl_from! { BigIntObject for Data }
impl_from! { BigIntObject for Value }
impl_from! { BigIntObject for Object }
impl_try_from! { Object for BigIntObject if v => v.is_big_int_object() }
impl_try_from! { Value for BigIntObject if v => v.is_big_int_object() }
/// A Boolean object (ECMA-262, 4.3.15).
#[repr(C)]
pub struct BooleanObject(Opaque);
impl_deref!(BooleanObject, Object);
impl_from!(BooleanObject, Data);
impl_from!(BooleanObject, Value);
impl_from!(BooleanObject, Object);
impl_deref! { BooleanObject for Object }
impl_from! { BooleanObject for Data }
impl_from! { BooleanObject for Value }
impl_from! { BooleanObject for Object }
impl_try_from! { Object for BooleanObject if v => v.is_boolean_object() }
impl_try_from! { Value for BooleanObject if v => v.is_boolean_object() }
/// An instance of the built-in Date constructor (ECMA-262, 15.9).
#[repr(C)]
pub struct Date(Opaque);
impl_deref!(Date, Object);
impl_from!(Date, Data);
impl_from!(Date, Value);
impl_from!(Date, Object);
impl_deref! { Date for Object }
impl_from! { Date for Data }
impl_from! { Date for Value }
impl_from! { Date for Object }
impl_try_from! { Object for Date if v => v.is_date() }
impl_try_from! { Value for Date if v => v.is_date() }
/// An instance of the built-in FinalizationGroup constructor.
///
/// This API is experimental and may change significantly.
#[repr(C)]
pub struct FinalizationGroup(Opaque);
impl_deref!(FinalizationGroup, Object);
impl_from!(FinalizationGroup, Data);
impl_from!(FinalizationGroup, Value);
impl_from!(FinalizationGroup, Object);
impl_deref! { FinalizationGroup for Object }
impl_from! { FinalizationGroup for Data }
impl_from! { FinalizationGroup for Value }
impl_from! { FinalizationGroup for Object }
/// A JavaScript function object (ECMA-262, 15.3).
#[repr(C)]
pub struct Function(Opaque);
impl_deref!(Function, Object);
impl_from!(Function, Data);
impl_from!(Function, Value);
impl_from!(Function, Object);
impl_deref! { Function for Object }
impl_from! { Function for Data }
impl_from! { Function for Value }
impl_from! { Function for Object }
impl_try_from! { Object for Function if v => v.is_function() }
impl_try_from! { Value for Function if v => v.is_function() }
/// An instance of the built-in Map constructor (ECMA-262, 6th Edition, 23.1.1).
#[repr(C)]
pub struct Map(Opaque);
impl_deref!(Map, Object);
impl_from!(Map, Data);
impl_from!(Map, Value);
impl_from!(Map, Object);
impl_deref! { Map for Object }
impl_from! { Map for Data }
impl_from! { Map for Value }
impl_from! { Map for Object }
impl_try_from! { Object for Map if v => v.is_map() }
impl_try_from! { Value for Map if v => v.is_map() }
/// A Number object (ECMA-262, 4.3.21).
#[repr(C)]
pub struct NumberObject(Opaque);
impl_deref!(NumberObject, Object);
impl_from!(NumberObject, Data);
impl_from!(NumberObject, Value);
impl_from!(NumberObject, Object);
impl_deref! { NumberObject for Object }
impl_from! { NumberObject for Data }
impl_from! { NumberObject for Value }
impl_from! { NumberObject for Object }
impl_try_from! { Object for NumberObject if v => v.is_number_object() }
impl_try_from! { Value for NumberObject if v => v.is_number_object() }
/// An instance of the built-in Promise constructor (ES6 draft).
#[repr(C)]
pub struct Promise(Opaque);
impl_deref!(Promise, Object);
impl_from!(Promise, Data);
impl_from!(Promise, Value);
impl_from!(Promise, Object);
impl_deref! { Promise for Object }
impl_from! { Promise for Data }
impl_from! { Promise for Value }
impl_from! { Promise for Object }
impl_try_from! { Object for Promise if v => v.is_promise() }
impl_try_from! { Value for Promise if v => v.is_promise() }
#[repr(C)]
pub struct PromiseResolver(Opaque);
impl_deref!(PromiseResolver, Object);
impl_from!(PromiseResolver, Data);
impl_from!(PromiseResolver, Value);
impl_from!(PromiseResolver, Object);
impl_deref! { PromiseResolver for Object }
impl_from! { PromiseResolver for Data }
impl_from! { PromiseResolver for Value }
impl_from! { PromiseResolver for Object }
/// An instance of the built-in Proxy constructor (ECMA-262, 6th Edition,
/// 26.2.1).
#[repr(C)]
pub struct Proxy(Opaque);
impl_deref!(Proxy, Object);
impl_from!(Proxy, Data);
impl_from!(Proxy, Value);
impl_from!(Proxy, Object);
impl_deref! { Proxy for Object }
impl_from! { Proxy for Data }
impl_from! { Proxy for Value }
impl_from! { Proxy for Object }
impl_try_from! { Object for Proxy if v => v.is_proxy() }
impl_try_from! { Value for Proxy if v => v.is_proxy() }
/// An instance of the built-in RegExp constructor (ECMA-262, 15.10).
#[repr(C)]
pub struct RegExp(Opaque);
impl_deref!(RegExp, Object);
impl_from!(RegExp, Data);
impl_from!(RegExp, Value);
impl_from!(RegExp, Object);
impl_deref! { RegExp for Object }
impl_from! { RegExp for Data }
impl_from! { RegExp for Value }
impl_from! { RegExp for Object }
impl_try_from! { Object for RegExp if v => v.is_reg_exp() }
impl_try_from! { Value for RegExp if v => v.is_reg_exp() }
/// An instance of the built-in Set constructor (ECMA-262, 6th Edition, 23.2.1).
#[repr(C)]
pub struct Set(Opaque);
impl_deref!(Set, Object);
impl_from!(Set, Data);
impl_from!(Set, Value);
impl_from!(Set, Object);
impl_deref! { Set for Object }
impl_from! { Set for Data }
impl_from! { Set for Value }
impl_from! { Set for Object }
impl_try_from! { Object for Set if v => v.is_set() }
impl_try_from! { Value for Set if v => v.is_set() }
/// An instance of the built-in SharedArrayBuffer constructor.
/// This API is experimental and may change significantly.
#[repr(C)]
pub struct SharedArrayBuffer(Opaque);
impl_deref!(SharedArrayBuffer, Object);
impl_from!(SharedArrayBuffer, Data);
impl_from!(SharedArrayBuffer, Value);
impl_from!(SharedArrayBuffer, Object);
impl_deref! { SharedArrayBuffer for Object }
impl_from! { SharedArrayBuffer for Data }
impl_from! { SharedArrayBuffer for Value }
impl_from! { SharedArrayBuffer for Object }
impl_try_from! { Object for SharedArrayBuffer if v => v.is_shared_array_buffer() }
impl_try_from! { Value for SharedArrayBuffer if v => v.is_shared_array_buffer() }
/// A String object (ECMA-262, 4.3.18).
#[repr(C)]
pub struct StringObject(Opaque);
impl_deref!(StringObject, Object);
impl_from!(StringObject, Data);
impl_from!(StringObject, Value);
impl_from!(StringObject, Object);
impl_deref! { StringObject for Object }
impl_from! { StringObject for Data }
impl_from! { StringObject for Value }
impl_from! { StringObject for Object }
impl_try_from! { Object for StringObject if v => v.is_string_object() }
impl_try_from! { Value for StringObject if v => v.is_string_object() }
/// A Symbol object (ECMA-262 edition 6).
#[repr(C)]
pub struct SymbolObject(Opaque);
impl_deref!(SymbolObject, Object);
impl_from!(SymbolObject, Data);
impl_from!(SymbolObject, Value);
impl_from!(SymbolObject, Object);
impl_deref! { SymbolObject for Object }
impl_from! { SymbolObject for Data }
impl_from! { SymbolObject for Value }
impl_from! { SymbolObject for Object }
impl_try_from! { Object for SymbolObject if v => v.is_symbol_object() }
impl_try_from! { Value for SymbolObject if v => v.is_symbol_object() }
#[repr(C)]
pub struct WasmModuleObject(Opaque);
impl_deref!(WasmModuleObject, Object);
impl_from!(WasmModuleObject, Data);
impl_from!(WasmModuleObject, Value);
impl_from!(WasmModuleObject, Object);
impl_deref! { WasmModuleObject for Object }
impl_from! { WasmModuleObject for Data }
impl_from! { WasmModuleObject for Value }
impl_from! { WasmModuleObject for Object }
/// The superclass of primitive values. See ECMA-262 4.3.2.
#[repr(C)]
pub struct Primitive(Opaque);
impl_deref!(Primitive, Value);
impl_from!(Primitive, Data);
impl_from!(Primitive, Value);
impl_deref! { Primitive for Value }
impl_from! { Primitive for Data }
impl_from! { Primitive for Value }
impl_try_from! { Value for Primitive if v => v.is_null_or_undefined() || v.is_boolean() || v.is_name() || v.is_number() || v.is_big_int() }
/// A JavaScript BigInt value (https://tc39.github.io/proposal-bigint)
#[repr(C)]
pub struct BigInt(Opaque);
impl_deref!(BigInt, Primitive);
impl_from!(BigInt, Data);
impl_from!(BigInt, Value);
impl_from!(BigInt, Primitive);
impl_deref! { BigInt for Primitive }
impl_from! { BigInt for Data }
impl_from! { BigInt for Value }
impl_from! { BigInt for Primitive }
impl_try_from! { Primitive for BigInt if v => v.is_big_int() }
impl_try_from! { Value for BigInt if v => v.is_big_int() }
/// A primitive boolean value (ECMA-262, 4.3.14). Either the true
/// or false value.
#[repr(C)]
pub struct Boolean(Opaque);
impl_deref!(Boolean, Primitive);
impl_from!(Boolean, Data);
impl_from!(Boolean, Value);
impl_from!(Boolean, Primitive);
impl_deref! { Boolean for Primitive }
impl_from! { Boolean for Data }
impl_from! { Boolean for Value }
impl_from! { Boolean for Primitive }
impl_try_from! { Primitive for Boolean if v => v.is_boolean() }
impl_try_from! { Value for Boolean if v => v.is_boolean() }
/// A superclass for symbols and strings.
#[repr(C)]
pub struct Name(Opaque);
impl_deref!(Name, Primitive);
impl_from!(Name, Data);
impl_from!(Name, Value);
impl_from!(Name, Primitive);
impl_deref! { Name for Primitive }
impl_from! { Name for Data }
impl_from! { Name for Value }
impl_from! { Name for Primitive }
impl_try_from! { Primitive for Name if v => v.is_name() }
impl_try_from! { Value for Name if v => v.is_name() }
/// A JavaScript string value (ECMA-262, 4.3.17).
#[repr(C)]
pub struct String(Opaque);
impl_deref!(String, Name);
impl_from!(String, Data);
impl_from!(String, Value);
impl_from!(String, Primitive);
impl_from!(String, Name);
impl_deref! { String for Name }
impl_from! { String for Data }
impl_from! { String for Value }
impl_from! { String for Primitive }
impl_from! { String for Name }
impl_try_from! { Name for String if v => v.is_string() }
impl_try_from! { Primitive for String if v => v.is_string() }
impl_try_from! { Value for String if v => v.is_string() }
/// A JavaScript symbol (ECMA-262 edition 6)
#[repr(C)]
pub struct Symbol(Opaque);
impl_deref!(Symbol, Name);
impl_from!(Symbol, Data);
impl_from!(Symbol, Value);
impl_from!(Symbol, Primitive);
impl_from!(Symbol, Name);
impl_deref! { Symbol for Name }
impl_from! { Symbol for Data }
impl_from! { Symbol for Value }
impl_from! { Symbol for Primitive }
impl_from! { Symbol for Name }
impl_try_from! { Name for Symbol if v => v.is_symbol() }
impl_try_from! { Primitive for Symbol if v => v.is_symbol() }
impl_try_from! { Value for Symbol if v => v.is_symbol() }
/// A JavaScript number value (ECMA-262, 4.3.20)
#[repr(C)]
pub struct Number(Opaque);
impl_deref!(Number, Primitive);
impl_from!(Number, Data);
impl_from!(Number, Value);
impl_from!(Number, Primitive);
impl_deref! { Number for Primitive }
impl_from! { Number for Data }
impl_from! { Number for Value }
impl_from! { Number for Primitive }
impl_try_from! { Primitive for Number if v => v.is_number() }
impl_try_from! { Value for Number if v => v.is_number() }
/// A JavaScript value representing a signed integer.
#[repr(C)]
pub struct Integer(Opaque);
impl_deref!(Integer, Number);
impl_from!(Integer, Data);
impl_from!(Integer, Value);
impl_from!(Integer, Primitive);
impl_from!(Integer, Number);
impl_deref! { Integer for Number }
impl_from! { Integer for Data }
impl_from! { Integer for Value }
impl_from! { Integer for Primitive }
impl_from! { Integer for Number }
impl_try_from! { Number for Integer if v => v.is_int32() || v.is_uint32() }
impl_try_from! { Primitive for Integer if v => v.is_int32() || v.is_uint32() }
impl_try_from! { Value for Integer if v => v.is_int32() || v.is_uint32() }
/// A JavaScript value representing a 32-bit signed integer.
#[repr(C)]
pub struct Int32(Opaque);
impl_deref!(Int32, Integer);
impl_from!(Int32, Data);
impl_from!(Int32, Value);
impl_from!(Int32, Primitive);
impl_from!(Int32, Number);
impl_from!(Int32, Integer);
impl_deref! { Int32 for Integer }
impl_from! { Int32 for Data }
impl_from! { Int32 for Value }
impl_from! { Int32 for Primitive }
impl_from! { Int32 for Number }
impl_from! { Int32 for Integer }
impl_try_from! { Integer for Int32 if v => v.is_int32() }
impl_try_from! { Number for Int32 if v => v.is_int32() }
impl_try_from! { Primitive for Int32 if v => v.is_int32() }
impl_try_from! { Value for Int32 if v => v.is_int32() }
/// A JavaScript value representing a 32-bit unsigned integer.
#[repr(C)]
pub struct Uint32(Opaque);
impl_deref!(Uint32, Integer);
impl_from!(Uint32, Data);
impl_from!(Uint32, Value);
impl_from!(Uint32, Primitive);
impl_from!(Uint32, Number);
impl_from!(Uint32, Integer);
impl_deref! { Uint32 for Integer }
impl_from! { Uint32 for Data }
impl_from! { Uint32 for Value }
impl_from! { Uint32 for Primitive }
impl_from! { Uint32 for Number }
impl_from! { Uint32 for Integer }
impl_try_from! { Integer for Uint32 if v => v.is_uint32() }
impl_try_from! { Number for Uint32 if v => v.is_uint32() }
impl_try_from! { Primitive for Uint32 if v => v.is_uint32() }
impl_try_from! { Value for Uint32 if v => v.is_uint32() }

View file

@ -5,7 +5,7 @@ extern crate lazy_static;
use rusty_v8 as v8;
use rusty_v8::{new_null, FunctionCallbackInfo, InIsolate, Local, ToLocal};
use std::convert::Into;
use std::convert::{Into, TryInto};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Mutex;
@ -1470,9 +1470,8 @@ fn array_buffer_view() {
let source = v8::String::new(s, "new Uint8Array([23,23,23,23])").unwrap();
let mut script = v8::Script::compile(s, context, source, None).unwrap();
source.to_rust_string_lossy(s);
let result = script.run(s, context).unwrap();
// TODO: safer casts.
let result = unsafe { Local::<v8::ArrayBufferView>::cast(result) };
let result: Local<v8::ArrayBufferView> =
script.run(s, context).unwrap().try_into().unwrap();
assert_eq!(result.byte_length(), 4);
assert_eq!(result.byte_offset(), 0);
let mut dest = [0; 4];
@ -1654,9 +1653,8 @@ fn uint8_array() {
let source = v8::String::new(s, "new Uint8Array([23,23,23,23])").unwrap();
let mut script = v8::Script::compile(s, context, source, None).unwrap();
source.to_rust_string_lossy(s);
let result = script.run(s, context).unwrap();
// TODO: safer casts.
let result = unsafe { Local::<v8::ArrayBufferView>::cast(result) };
let result: Local<v8::ArrayBufferView> =
script.run(s, context).unwrap().try_into().unwrap();
assert_eq!(result.byte_length(), 4);
assert_eq!(result.byte_offset(), 0);
let mut dest = [0; 4];
@ -1761,9 +1759,8 @@ fn shared_array_buffer() {
.unwrap();
let mut script = v8::Script::compile(s, context, source, None).unwrap();
source.to_rust_string_lossy(s);
let result = script.run(s, context).unwrap();
// TODO: safer casts.
let result = unsafe { Local::<v8::Integer>::cast(result) };
let result: Local<v8::Integer> =
script.run(s, context).unwrap().try_into().unwrap();
assert_eq!(result.value(), 64);
assert_eq!(shared_buf[2], 16);
assert_eq!(shared_buf[14], 62);