use crate::ConstructorBehavior;
use crate::Context;
use crate::Function;
use crate::FunctionBuilder;
use crate::FunctionCallback;
use crate::IndexedDefinerCallback;
use crate::IndexedDeleterCallback;
use crate::IndexedGetterCallback;
use crate::IndexedQueryCallback;
use crate::IndexedSetterCallback;
use crate::Local;
use crate::NamedDefinerCallback;
use crate::NamedDeleterCallback;
use crate::NamedGetterCallback;
use crate::NamedGetterCallbackForAccessor;
use crate::NamedQueryCallback;
use crate::NamedSetterCallback;
use crate::NamedSetterCallbackForAccessor;
use crate::Object;
use crate::PropertyAttribute;
use crate::PropertyEnumeratorCallback;
use crate::PropertyHandlerFlags;
use crate::SideEffectType;
use crate::Signature;
use crate::String;
use crate::Value;
pub use crate::binding::v8__Intercepted as Intercepted;
use crate::data::Data;
use crate::data::FunctionTemplate;
use crate::data::Name;
use crate::data::ObjectTemplate;
use crate::data::Template;
use crate::fast_api::CFunction;
use crate::isolate::RealIsolate;
use crate::scope::PinScope;
use crate::support::MapFnTo;
use crate::support::int;
use std::convert::TryFrom;
use std::ptr::null;
unsafe extern "C" {
fn v8__Template__Set(
this: *const Template,
key: *const Name,
value: *const Data,
attr: PropertyAttribute,
);
fn v8__Template__SetIntrinsicDataProperty(
this: *const Template,
key: *const Name,
intrinsic: Intrinsic,
attr: PropertyAttribute,
);
fn v8__Signature__New(
isolate: *mut RealIsolate,
templ: *const FunctionTemplate,
) -> *const Signature;
fn v8__FunctionTemplate__New(
isolate: *mut RealIsolate,
callback: FunctionCallback,
data_or_null: *const Value,
signature_or_null: *const Signature,
length: i32,
constructor_behavior: ConstructorBehavior,
side_effect_type: SideEffectType,
c_functions: *const CFunction,
c_functions_len: usize,
) -> *const FunctionTemplate;
fn v8__FunctionTemplate__GetFunction(
this: *const FunctionTemplate,
context: *const Context,
) -> *const Function;
fn v8__FunctionTemplate__PrototypeTemplate(
this: *const FunctionTemplate,
) -> *const ObjectTemplate;
fn v8__FunctionTemplate__InstanceTemplate(
this: *const FunctionTemplate,
) -> *const ObjectTemplate;
fn v8__FunctionTemplate__SetClassName(
this: *const FunctionTemplate,
name: *const String,
);
fn v8__FunctionTemplate__Inherit(
this: *const FunctionTemplate,
parent: *const FunctionTemplate,
);
fn v8__FunctionTemplate__ReadOnlyPrototype(this: *const FunctionTemplate);
fn v8__FunctionTemplate__RemovePrototype(this: *const FunctionTemplate);
fn v8__ObjectTemplate__New(
isolate: *mut RealIsolate,
templ: *const FunctionTemplate,
) -> *const ObjectTemplate;
fn v8__ObjectTemplate__NewInstance(
this: *const ObjectTemplate,
context: *const Context,
) -> *const Object;
fn v8__ObjectTemplate__InternalFieldCount(this: *const ObjectTemplate)
-> int;
fn v8__ObjectTemplate__SetInternalFieldCount(
this: *const ObjectTemplate,
value: int,
);
fn v8__ObjectTemplate__SetNativeDataProperty(
this: *const ObjectTemplate,
key: *const Name,
getter: AccessorNameGetterCallback,
setter: Option<AccessorNameSetterCallback>,
data_or_null: *const Value,
attr: PropertyAttribute,
);
fn v8__ObjectTemplate__SetAccessorProperty(
this: *const ObjectTemplate,
key: *const Name,
getter: *const FunctionTemplate,
setter: *const FunctionTemplate,
attr: PropertyAttribute,
);
fn v8__ObjectTemplate__SetNamedPropertyHandler(
this: *const ObjectTemplate,
getter: Option<NamedPropertyGetterCallback>,
setter: Option<NamedPropertySetterCallback>,
query: Option<NamedPropertyQueryCallback>,
deleter: Option<NamedPropertyDeleterCallback>,
enumerator: Option<NamedPropertyEnumeratorCallback>,
definer: Option<NamedPropertyDefinerCallback>,
descriptor: Option<NamedPropertyDescriptorCallback>,
data_or_null: *const Value,
flags: PropertyHandlerFlags,
);
fn v8__ObjectTemplate__SetIndexedPropertyHandler(
this: *const ObjectTemplate,
getter: Option<IndexedPropertyGetterCallback>,
setter: Option<IndexedPropertySetterCallback>,
query: Option<IndexedPropertyQueryCallback>,
deleter: Option<IndexedPropertyDeleterCallback>,
enumerator: Option<IndexedPropertyEnumeratorCallback>,
definer: Option<IndexedPropertyDefinerCallback>,
descriptor: Option<IndexedPropertyDescriptorCallback>,
data_or_null: *const Value,
);
fn v8__ObjectTemplate__SetImmutableProto(this: *const ObjectTemplate);
}
pub type AccessorNameGetterCallback = NamedGetterCallbackForAccessor;
pub type AccessorNameSetterCallback = NamedSetterCallbackForAccessor;
pub type NamedPropertyGetterCallback = NamedGetterCallback;
pub type NamedPropertySetterCallback = NamedSetterCallback;
pub type NamedPropertyQueryCallback = NamedQueryCallback;
pub type NamedPropertyDeleterCallback = NamedDeleterCallback;
pub type NamedPropertyEnumeratorCallback = PropertyEnumeratorCallback;
pub type NamedPropertyDefinerCallback = NamedDefinerCallback;
pub type NamedPropertyDescriptorCallback = NamedGetterCallback;
pub type IndexedPropertyGetterCallback = IndexedGetterCallback;
pub type IndexedPropertySetterCallback = IndexedSetterCallback;
pub type IndexedPropertyQueryCallback = IndexedQueryCallback;
pub type IndexedPropertyDeleterCallback = IndexedDeleterCallback;
pub type IndexedPropertyEnumeratorCallback = PropertyEnumeratorCallback;
pub type IndexedPropertyDefinerCallback = IndexedDefinerCallback;
pub type IndexedPropertyDescriptorCallback = IndexedGetterCallback;
pub struct AccessorConfiguration<'s> {
pub(crate) getter: AccessorNameGetterCallback,
pub(crate) setter: Option<AccessorNameSetterCallback>,
pub(crate) data: Option<Local<'s, Value>>,
pub(crate) property_attribute: PropertyAttribute,
}
impl<'s> AccessorConfiguration<'s> {
pub fn new(getter: impl MapFnTo<AccessorNameGetterCallback>) -> Self {
Self {
getter: getter.map_fn_to(),
setter: None,
data: None,
property_attribute: PropertyAttribute::NONE,
}
}
pub fn setter(
mut self,
setter: impl MapFnTo<AccessorNameSetterCallback>,
) -> Self {
self.setter = Some(setter.map_fn_to());
self
}
pub fn property_attribute(
mut self,
property_attribute: PropertyAttribute,
) -> Self {
self.property_attribute = property_attribute;
self
}
pub fn data(mut self, data: Local<'s, Value>) -> Self {
self.data = Some(data);
self
}
}
#[derive(Default)]
pub struct NamedPropertyHandlerConfiguration<'s> {
pub(crate) getter: Option<NamedPropertyGetterCallback>,
pub(crate) setter: Option<NamedPropertySetterCallback>,
pub(crate) query: Option<NamedPropertyQueryCallback>,
pub(crate) deleter: Option<NamedPropertyDeleterCallback>,
pub(crate) enumerator: Option<NamedPropertyEnumeratorCallback>,
pub(crate) definer: Option<NamedPropertyDefinerCallback>,
pub(crate) descriptor: Option<NamedPropertyDescriptorCallback>,
pub(crate) data: Option<Local<'s, Value>>,
pub(crate) flags: PropertyHandlerFlags,
}
impl<'s> NamedPropertyHandlerConfiguration<'s> {
pub fn new() -> Self {
Self {
getter: None,
setter: None,
query: None,
deleter: None,
enumerator: None,
definer: None,
descriptor: None,
data: None,
flags: PropertyHandlerFlags::NONE,
}
}
pub fn is_some(&self) -> bool {
self.getter.is_some()
|| self.setter.is_some()
|| self.query.is_some()
|| self.deleter.is_some()
|| self.enumerator.is_some()
|| self.definer.is_some()
|| self.descriptor.is_some()
|| !self.flags.is_none()
}
pub fn getter(
mut self,
getter: impl MapFnTo<NamedPropertyGetterCallback>,
) -> Self {
self.getter = Some(getter.map_fn_to());
self
}
pub fn getter_raw(mut self, getter: NamedPropertyGetterCallback) -> Self {
self.getter = Some(getter);
self
}
pub fn setter(
mut self,
setter: impl MapFnTo<NamedPropertySetterCallback>,
) -> Self {
self.setter = Some(setter.map_fn_to());
self
}
pub fn setter_raw(mut self, setter: NamedPropertySetterCallback) -> Self {
self.setter = Some(setter);
self
}
pub fn query(
mut self,
query: impl MapFnTo<NamedPropertyQueryCallback>,
) -> Self {
self.query = Some(query.map_fn_to());
self
}
pub fn query_raw(mut self, query: NamedPropertyQueryCallback) -> Self {
self.query = Some(query);
self
}
pub fn deleter(
mut self,
deleter: impl MapFnTo<NamedPropertyDeleterCallback>,
) -> Self {
self.deleter = Some(deleter.map_fn_to());
self
}
pub fn deleter_raw(mut self, deleter: NamedPropertyDeleterCallback) -> Self {
self.deleter = Some(deleter);
self
}
pub fn enumerator(
mut self,
enumerator: impl MapFnTo<NamedPropertyEnumeratorCallback>,
) -> Self {
self.enumerator = Some(enumerator.map_fn_to());
self
}
pub fn enumerator_raw(
mut self,
enumerator: NamedPropertyEnumeratorCallback,
) -> Self {
self.enumerator = Some(enumerator);
self
}
pub fn definer(
mut self,
definer: impl MapFnTo<NamedPropertyDefinerCallback>,
) -> Self {
self.definer = Some(definer.map_fn_to());
self
}
pub fn definer_raw(mut self, definer: NamedPropertyDefinerCallback) -> Self {
self.definer = Some(definer);
self
}
pub fn descriptor(
mut self,
descriptor: impl MapFnTo<NamedPropertyDescriptorCallback>,
) -> Self {
self.descriptor = Some(descriptor.map_fn_to());
self
}
pub fn descriptor_raw(
mut self,
descriptor: NamedPropertyDescriptorCallback,
) -> Self {
self.descriptor = Some(descriptor);
self
}
pub fn data(mut self, data: Local<'s, Value>) -> Self {
self.data = Some(data);
self
}
pub fn flags(mut self, flags: PropertyHandlerFlags) -> Self {
self.flags = flags;
self
}
}
#[derive(Default)]
pub struct IndexedPropertyHandlerConfiguration<'s> {
pub(crate) getter: Option<IndexedPropertyGetterCallback>,
pub(crate) setter: Option<IndexedPropertySetterCallback>,
pub(crate) query: Option<IndexedPropertyQueryCallback>,
pub(crate) deleter: Option<IndexedPropertyDeleterCallback>,
pub(crate) enumerator: Option<IndexedPropertyEnumeratorCallback>,
pub(crate) definer: Option<IndexedPropertyDefinerCallback>,
pub(crate) descriptor: Option<IndexedPropertyDescriptorCallback>,
pub(crate) data: Option<Local<'s, Value>>,
pub(crate) flags: PropertyHandlerFlags,
}
impl<'s> IndexedPropertyHandlerConfiguration<'s> {
pub fn new() -> Self {
Self {
getter: None,
setter: None,
query: None,
deleter: None,
enumerator: None,
definer: None,
descriptor: None,
data: None,
flags: PropertyHandlerFlags::NONE,
}
}
pub fn is_some(&self) -> bool {
self.getter.is_some()
|| self.setter.is_some()
|| self.query.is_some()
|| self.deleter.is_some()
|| self.enumerator.is_some()
|| self.definer.is_some()
|| self.descriptor.is_some()
|| !self.flags.is_none()
}
pub fn getter(
mut self,
getter: impl MapFnTo<IndexedPropertyGetterCallback>,
) -> Self {
self.getter = Some(getter.map_fn_to());
self
}
pub fn getter_raw(mut self, getter: IndexedPropertyGetterCallback) -> Self {
self.getter = Some(getter);
self
}
pub fn setter(
mut self,
setter: impl MapFnTo<IndexedPropertySetterCallback>,
) -> Self {
self.setter = Some(setter.map_fn_to());
self
}
pub fn setter_raw(mut self, setter: IndexedPropertySetterCallback) -> Self {
self.setter = Some(setter);
self
}
pub fn query(
mut self,
query: impl MapFnTo<IndexedPropertyQueryCallback>,
) -> Self {
self.query = Some(query.map_fn_to());
self
}
pub fn query_raw(mut self, query: IndexedPropertyQueryCallback) -> Self {
self.query = Some(query);
self
}
pub fn deleter(
mut self,
deleter: impl MapFnTo<IndexedPropertyDeleterCallback>,
) -> Self {
self.deleter = Some(deleter.map_fn_to());
self
}
pub fn deleter_raw(
mut self,
deleter: IndexedPropertyDeleterCallback,
) -> Self {
self.deleter = Some(deleter);
self
}
pub fn enumerator(
mut self,
enumerator: impl MapFnTo<IndexedPropertyEnumeratorCallback>,
) -> Self {
self.enumerator = Some(enumerator.map_fn_to());
self
}
pub fn enumerator_raw(
mut self,
enumerator: IndexedPropertyEnumeratorCallback,
) -> Self {
self.enumerator = Some(enumerator);
self
}
pub fn definer(
mut self,
definer: impl MapFnTo<IndexedPropertyDefinerCallback>,
) -> Self {
self.definer = Some(definer.map_fn_to());
self
}
pub fn definer_raw(
mut self,
definer: IndexedPropertyDefinerCallback,
) -> Self {
self.definer = Some(definer);
self
}
pub fn descriptor(
mut self,
descriptor: impl MapFnTo<IndexedPropertyDescriptorCallback>,
) -> Self {
self.descriptor = Some(descriptor.map_fn_to());
self
}
pub fn descriptor_raw(
mut self,
descriptor: IndexedPropertyDescriptorCallback,
) -> Self {
self.descriptor = Some(descriptor);
self
}
pub fn data(mut self, data: Local<'s, Value>) -> Self {
self.data = Some(data);
self
}
pub fn flags(mut self, flags: PropertyHandlerFlags) -> Self {
self.flags = flags;
self
}
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub enum Intrinsic {
ArrayProtoEntries,
ArrayProtoForEach,
ArrayProtoKeys,
ArrayProtoValues,
ArrayPrototype,
AsyncIteratorPrototype,
ErrorPrototype,
IteratorPrototype,
MapIteratorPrototype,
ObjProtoValueOf,
SetIteratorPrototype,
}
impl Template {
#[inline(always)]
pub fn set(&self, key: Local<Name>, value: Local<Data>) {
self.set_with_attr(key, value, PropertyAttribute::NONE);
}
#[inline(always)]
pub fn set_with_attr(
&self,
key: Local<Name>,
value: Local<Data>,
attr: PropertyAttribute,
) {
unsafe { v8__Template__Set(self, &*key, &*value, attr) }
}
#[inline(always)]
pub fn set_intrinsic_data_property(
&self,
key: Local<Name>,
intrinsic: Intrinsic,
attr: PropertyAttribute,
) {
unsafe {
v8__Template__SetIntrinsicDataProperty(self, &*key, intrinsic, attr);
}
}
}
impl<'s> FunctionBuilder<'s, FunctionTemplate> {
#[inline(always)]
pub fn signature(mut self, signature: Local<'s, Signature>) -> Self {
self.signature = Some(signature);
self
}
#[inline(always)]
pub fn build<'i>(
self,
scope: &PinScope<'s, 'i, ()>,
) -> Local<'s, FunctionTemplate> {
unsafe {
scope.cast_local(|sd| {
v8__FunctionTemplate__New(
sd.get_isolate_ptr(),
self.callback,
self.data.map_or_else(null, |p| &*p),
self.signature.map_or_else(null, |p| &*p),
self.length,
self.constructor_behavior,
self.side_effect_type,
null(),
0,
)
})
}
.unwrap()
}
pub fn build_fast<'i>(
self,
scope: &PinScope<'s, 'i>,
overloads: &[CFunction],
) -> Local<'s, FunctionTemplate> {
unsafe {
scope.cast_local(|sd| {
v8__FunctionTemplate__New(
sd.get_isolate_ptr(),
self.callback,
self.data.map_or_else(null, |p| &*p),
self.signature.map_or_else(null, |p| &*p),
self.length,
ConstructorBehavior::Throw,
self.side_effect_type,
overloads.as_ptr(),
overloads.len(),
)
})
}
.unwrap()
}
}
impl Signature {
#[inline(always)]
pub fn new<'s>(
scope: &PinScope<'s, '_, ()>,
templ: Local<FunctionTemplate>,
) -> Local<'s, Self> {
unsafe {
scope.cast_local(|sd| v8__Signature__New(sd.get_isolate_ptr(), &*templ))
}
.unwrap()
}
}
impl FunctionTemplate {
#[inline(always)]
pub fn builder<'s>(
callback: impl MapFnTo<FunctionCallback>,
) -> FunctionBuilder<'s, Self> {
FunctionBuilder::new(callback)
}
#[inline(always)]
pub fn builder_raw<'s>(
callback: FunctionCallback,
) -> FunctionBuilder<'s, Self> {
FunctionBuilder::new_raw(callback)
}
#[inline(always)]
pub fn new<'s>(
scope: &PinScope<'s, '_, ()>,
callback: impl MapFnTo<FunctionCallback>,
) -> Local<'s, FunctionTemplate> {
Self::builder(callback).build(scope)
}
#[inline(always)]
pub fn new_raw<'s>(
scope: &PinScope<'s, '_, ()>,
callback: FunctionCallback,
) -> Local<'s, FunctionTemplate> {
Self::builder_raw(callback).build(scope)
}
#[inline(always)]
pub fn get_function<'s>(
&self,
scope: &PinScope<'s, '_>,
) -> Option<Local<'s, Function>> {
unsafe {
scope.cast_local(|sd| {
v8__FunctionTemplate__GetFunction(self, sd.get_current_context())
})
}
}
#[inline(always)]
pub fn set_class_name(&self, name: Local<String>) {
unsafe { v8__FunctionTemplate__SetClassName(self, &*name) };
}
#[inline(always)]
pub fn prototype_template<'s>(
&self,
scope: &PinScope<'s, '_, ()>,
) -> Local<'s, ObjectTemplate> {
unsafe {
scope.cast_local(|_sd| v8__FunctionTemplate__PrototypeTemplate(self))
}
.unwrap()
}
#[inline(always)]
pub fn instance_template<'s>(
&self,
scope: &PinScope<'s, '_, ()>,
) -> Local<'s, ObjectTemplate> {
unsafe {
scope.cast_local(|_sd| v8__FunctionTemplate__InstanceTemplate(self))
}
.unwrap()
}
#[inline(always)]
pub fn inherit(&self, parent: Local<FunctionTemplate>) {
unsafe { v8__FunctionTemplate__Inherit(self, &*parent) };
}
#[inline(always)]
pub fn read_only_prototype(&self) {
unsafe { v8__FunctionTemplate__ReadOnlyPrototype(self) };
}
#[inline(always)]
pub fn remove_prototype(&self) {
unsafe { v8__FunctionTemplate__RemovePrototype(self) };
}
}
impl ObjectTemplate {
#[inline(always)]
pub fn new<'s>(scope: &PinScope<'s, '_, ()>) -> Local<'s, ObjectTemplate> {
unsafe {
scope.cast_local(|sd| {
v8__ObjectTemplate__New(sd.get_isolate_ptr(), std::ptr::null())
})
}
.unwrap()
}
#[inline(always)]
pub fn new_from_template<'s>(
scope: &PinScope<'s, '_, ()>,
templ: Local<FunctionTemplate>,
) -> Local<'s, ObjectTemplate> {
unsafe {
scope
.cast_local(|sd| v8__ObjectTemplate__New(sd.get_isolate_ptr(), &*templ))
}
.unwrap()
}
#[inline(always)]
pub fn new_instance<'s>(
&self,
scope: &PinScope<'s, '_>,
) -> Option<Local<'s, Object>> {
unsafe {
scope.cast_local(|sd| {
v8__ObjectTemplate__NewInstance(self, sd.get_current_context())
})
}
}
#[inline(always)]
pub fn internal_field_count(&self) -> usize {
let count = unsafe { v8__ObjectTemplate__InternalFieldCount(self) };
usize::try_from(count).expect("bad internal field count") }
#[inline(always)]
pub fn set_internal_field_count(&self, value: usize) -> bool {
match int::try_from(value) {
Err(_) => false,
Ok(value) => {
unsafe { v8__ObjectTemplate__SetInternalFieldCount(self, value) };
true
}
}
}
#[inline(always)]
pub fn set_accessor(
&self,
key: Local<Name>,
getter: impl MapFnTo<AccessorNameGetterCallback>,
) {
self
.set_accessor_with_configuration(key, AccessorConfiguration::new(getter));
}
#[inline(always)]
pub fn set_accessor_with_setter(
&self,
key: Local<Name>,
getter: impl MapFnTo<AccessorNameGetterCallback>,
setter: impl MapFnTo<AccessorNameSetterCallback>,
) {
self.set_accessor_with_configuration(
key,
AccessorConfiguration::new(getter).setter(setter),
);
}
#[inline(always)]
pub fn set_accessor_with_configuration(
&self,
key: Local<Name>,
configuration: AccessorConfiguration,
) {
unsafe {
v8__ObjectTemplate__SetNativeDataProperty(
self,
&*key,
configuration.getter,
configuration.setter,
configuration.data.map_or_else(null, |p| &*p),
configuration.property_attribute,
);
}
}
pub fn set_named_property_handler(
&self,
configuration: NamedPropertyHandlerConfiguration,
) {
assert!(configuration.is_some());
unsafe {
v8__ObjectTemplate__SetNamedPropertyHandler(
self,
configuration.getter,
configuration.setter,
configuration.query,
configuration.deleter,
configuration.enumerator,
configuration.definer,
configuration.descriptor,
configuration.data.map_or_else(null, |p| &*p),
configuration.flags,
);
}
}
pub fn set_indexed_property_handler(
&self,
configuration: IndexedPropertyHandlerConfiguration,
) {
assert!(configuration.is_some());
unsafe {
v8__ObjectTemplate__SetIndexedPropertyHandler(
self,
configuration.getter,
configuration.setter,
configuration.query,
configuration.deleter,
configuration.enumerator,
configuration.definer,
configuration.descriptor,
configuration.data.map_or_else(null, |p| &*p),
);
}
}
#[inline(always)]
pub fn set_accessor_property(
&self,
key: Local<Name>,
getter: Option<Local<FunctionTemplate>>,
setter: Option<Local<FunctionTemplate>>,
attr: PropertyAttribute,
) {
assert!(getter.is_some() || setter.is_some());
unsafe {
let getter = getter.map_or_else(std::ptr::null, |v| &*v);
let setter = setter.map_or_else(std::ptr::null, |v| &*v);
v8__ObjectTemplate__SetAccessorProperty(
self, &*key, getter, setter, attr,
);
}
}
#[inline(always)]
pub fn set_immutable_proto(&self) {
unsafe { v8__ObjectTemplate__SetImmutableProto(self) };
}
}