use std::convert::TryFrom;
use std::marker::PhantomData;
use std::ptr::null;
use std::ptr::NonNull;
use crate::scope::CallbackScope;
use crate::script_compiler::CachedData;
use crate::support::MapFnFrom;
use crate::support::MapFnTo;
use crate::support::ToCFn;
use crate::support::UnitType;
use crate::support::{int, Opaque};
use crate::template::Intercepted;
use crate::Array;
use crate::Boolean;
use crate::Context;
use crate::Function;
use crate::HandleScope;
use crate::Integer;
use crate::Isolate;
use crate::Local;
use crate::Name;
use crate::Object;
use crate::PropertyDescriptor;
use crate::Signature;
use crate::String;
use crate::UniqueRef;
use crate::Value;
use crate::{undefined, ScriptOrigin};
extern "C" {
fn v8__Function__New(
context: *const Context,
callback: FunctionCallback,
data_or_null: *const Value,
length: i32,
constructor_behavior: ConstructorBehavior,
side_effect_type: SideEffectType,
) -> *const Function;
fn v8__Function__Call(
this: *const Function,
context: *const Context,
recv: *const Value,
argc: int,
argv: *const *const Value,
) -> *const Value;
fn v8__Function__NewInstance(
this: *const Function,
context: *const Context,
argc: int,
argv: *const *const Value,
) -> *const Object;
fn v8__Function__GetName(this: *const Function) -> *const String;
fn v8__Function__SetName(this: *const Function, name: *const String);
fn v8__Function__GetScriptColumnNumber(this: *const Function) -> int;
fn v8__Function__GetScriptLineNumber(this: *const Function) -> int;
fn v8__Function__ScriptId(this: *const Function) -> int;
fn v8__Function__GetScriptOrigin(
this: *const Function,
) -> *const ScriptOrigin<'static>;
fn v8__Function__CreateCodeCache(
script: *const Function,
) -> *mut CachedData<'static>;
static v8__FunctionCallbackInfo__kArgsLength: int;
fn v8__FunctionCallbackInfo__Data(
this: *const FunctionCallbackInfo,
) -> *const Value;
fn v8__PropertyCallbackInfo__GetIsolate(
this: *const RawPropertyCallbackInfo,
) -> *mut Isolate;
fn v8__PropertyCallbackInfo__Data(
this: *const RawPropertyCallbackInfo,
) -> *const Value;
fn v8__PropertyCallbackInfo__This(
this: *const RawPropertyCallbackInfo,
) -> *const Object;
fn v8__PropertyCallbackInfo__Holder(
this: *const RawPropertyCallbackInfo,
) -> *const Object;
fn v8__PropertyCallbackInfo__GetReturnValue(
this: *const RawPropertyCallbackInfo,
) -> usize;
fn v8__PropertyCallbackInfo__ShouldThrowOnError(
this: *const RawPropertyCallbackInfo,
) -> bool;
fn v8__ReturnValue__Value__Set(
this: *mut RawReturnValue,
value: *const Value,
);
fn v8__ReturnValue__Value__Set__Bool(this: *mut RawReturnValue, value: bool);
fn v8__ReturnValue__Value__Set__Int32(this: *mut RawReturnValue, value: i32);
fn v8__ReturnValue__Value__Set__Uint32(this: *mut RawReturnValue, value: u32);
fn v8__ReturnValue__Value__Set__Double(this: *mut RawReturnValue, value: f64);
fn v8__ReturnValue__Value__SetNull(this: *mut RawReturnValue);
fn v8__ReturnValue__Value__SetUndefined(this: *mut RawReturnValue);
fn v8__ReturnValue__Value__SetEmptyString(this: *mut RawReturnValue);
fn v8__ReturnValue__Value__Get(this: *const RawReturnValue) -> *const Value;
}
#[repr(C)]
pub enum ConstructorBehavior {
Throw,
Allow,
}
#[repr(C)]
pub enum SideEffectType {
HasSideEffect,
HasNoSideEffect,
HasSideEffectToReceiver,
}
#[repr(C)]
#[derive(Debug)]
struct RawReturnValue(usize);
#[derive(Debug)]
pub struct ReturnValue<'cb, T = Value>(RawReturnValue, PhantomData<&'cb T>);
impl<'cb, T> ReturnValue<'cb, T> {
#[inline(always)]
pub fn from_property_callback_info(
info: &'cb PropertyCallbackInfo<T>,
) -> Self {
Self(
unsafe {
RawReturnValue(v8__PropertyCallbackInfo__GetReturnValue(&info.0))
},
PhantomData,
)
}
}
impl<'cb> ReturnValue<'cb, Value> {
#[inline(always)]
pub fn from_function_callback_info(info: &'cb FunctionCallbackInfo) -> Self {
let nn = info.get_return_value_non_null();
Self(RawReturnValue(nn.as_ptr() as _), PhantomData)
}
}
impl<'cb> ReturnValue<'cb, ()> {
#[inline(always)]
pub fn set_bool(&mut self, value: bool) {
unsafe { v8__ReturnValue__Value__Set__Bool(&mut self.0, value) }
}
}
impl<'cb, T> ReturnValue<'cb, T>
where
for<'s> Local<'s, T>: Into<Local<'s, Value>>,
{
#[inline(always)]
pub fn set(&mut self, value: Local<T>) {
unsafe { v8__ReturnValue__Value__Set(&mut self.0, &*value.into()) }
}
#[inline(always)]
pub fn set_bool(&mut self, value: bool) {
unsafe { v8__ReturnValue__Value__Set__Bool(&mut self.0, value) }
}
#[inline(always)]
pub fn set_int32(&mut self, value: i32) {
unsafe { v8__ReturnValue__Value__Set__Int32(&mut self.0, value) }
}
#[inline(always)]
pub fn set_uint32(&mut self, value: u32) {
unsafe { v8__ReturnValue__Value__Set__Uint32(&mut self.0, value) }
}
#[inline(always)]
pub fn set_double(&mut self, value: f64) {
unsafe { v8__ReturnValue__Value__Set__Double(&mut self.0, value) }
}
#[inline(always)]
pub fn set_null(&mut self) {
unsafe { v8__ReturnValue__Value__SetNull(&mut self.0) }
}
#[inline(always)]
pub fn set_undefined(&mut self) {
unsafe { v8__ReturnValue__Value__SetUndefined(&mut self.0) }
}
#[inline(always)]
pub fn set_empty_string(&mut self) {
unsafe { v8__ReturnValue__Value__SetEmptyString(&mut self.0) }
}
#[inline(always)]
pub fn get<'s>(&self, scope: &mut HandleScope<'s>) -> Local<'s, Value> {
unsafe { scope.cast_local(|_| v8__ReturnValue__Value__Get(&self.0)) }
.unwrap()
}
}
#[repr(C)]
#[derive(Debug)]
pub struct FunctionCallbackInfo {
implicit_args: *mut *const Opaque,
values: *mut *const Opaque,
length: int,
}
#[allow(dead_code, non_upper_case_globals)]
impl FunctionCallbackInfo {
const kHolderIndex: i32 = 0;
const kIsolateIndex: i32 = 1;
const kUnusedIndex: i32 = 2;
const kReturnValueIndex: i32 = 3;
const kTargetIndex: i32 = 4;
const kNewTargetIndex: i32 = 5;
const kArgsLength: i32 = 6;
}
impl FunctionCallbackInfo {
#[inline(always)]
pub(crate) fn get_isolate_ptr(&self) -> *mut Isolate {
let arg_nn =
self.get_implicit_arg_non_null::<*mut Isolate>(Self::kIsolateIndex);
*unsafe { arg_nn.as_ref() }
}
#[inline(always)]
pub(crate) fn get_return_value_non_null(&self) -> NonNull<Value> {
self.get_implicit_arg_non_null::<Value>(Self::kReturnValueIndex)
}
#[inline(always)]
pub(crate) fn holder(&self) -> Local<Object> {
unsafe { self.get_implicit_arg_local(Self::kHolderIndex) }
}
#[inline(always)]
pub(crate) fn new_target(&self) -> Local<Value> {
unsafe { self.get_implicit_arg_local(Self::kNewTargetIndex) }
}
#[inline(always)]
pub(crate) fn this(&self) -> Local<Object> {
unsafe { self.get_arg_local(-1) }
}
#[inline(always)]
pub(crate) fn data(&self) -> Local<Value> {
unsafe {
let ptr = v8__FunctionCallbackInfo__Data(self);
let nn = NonNull::new_unchecked(ptr as *mut Value);
Local::from_non_null(nn)
}
}
#[inline(always)]
pub(crate) fn length(&self) -> i32 {
self.length
}
#[inline(always)]
pub(crate) fn get(&self, index: int) -> Local<Value> {
if index >= 0 && index < self.length {
unsafe { self.get_arg_local(index) }
} else {
let isolate = unsafe { &mut *self.get_isolate_ptr() };
undefined(isolate).into()
}
}
#[inline(always)]
fn get_implicit_arg_non_null<T>(&self, index: i32) -> NonNull<T> {
debug_assert_eq!(
unsafe { v8__FunctionCallbackInfo__kArgsLength },
Self::kArgsLength
);
assert!(index >= 0);
assert!(index < Self::kArgsLength);
let ptr = unsafe { self.implicit_args.offset(index as isize) as *mut T };
debug_assert!(!ptr.is_null());
unsafe { NonNull::new_unchecked(ptr) }
}
#[inline(always)]
unsafe fn get_implicit_arg_local<T>(&self, index: i32) -> Local<T> {
let nn = self.get_implicit_arg_non_null::<T>(index);
Local::from_non_null(nn)
}
#[inline(always)]
unsafe fn get_arg_local<T>(&self, index: i32) -> Local<T> {
let ptr = self.values.offset(index as _) as *mut T;
debug_assert!(!ptr.is_null());
let nn = NonNull::new_unchecked(ptr);
Local::from_non_null(nn)
}
}
#[repr(C)]
#[derive(Debug)]
struct RawPropertyCallbackInfo(Opaque);
#[repr(C)]
#[derive(Debug)]
pub struct PropertyCallbackInfo<T>(RawPropertyCallbackInfo, PhantomData<T>);
impl<T> PropertyCallbackInfo<T> {
#[inline(always)]
pub(crate) fn get_isolate_ptr(&self) -> *mut Isolate {
unsafe { v8__PropertyCallbackInfo__GetIsolate(&self.0) }
}
}
#[derive(Debug)]
pub struct FunctionCallbackArguments<'s>(&'s FunctionCallbackInfo);
impl<'s> FunctionCallbackArguments<'s> {
#[inline(always)]
pub fn from_function_callback_info(info: &'s FunctionCallbackInfo) -> Self {
Self(info)
}
#[inline(always)]
pub unsafe fn get_isolate(&mut self) -> &mut Isolate {
&mut *self.0.get_isolate_ptr()
}
#[inline(always)]
pub fn holder(&self) -> Local<'s, Object> {
self.0.holder()
}
#[inline(always)]
pub fn new_target(&self) -> Local<'s, Value> {
self.0.new_target()
}
#[inline(always)]
pub fn this(&self) -> Local<'s, Object> {
self.0.this()
}
#[inline(always)]
pub fn data(&self) -> Local<'s, Value> {
self.0.data()
}
#[inline(always)]
pub fn length(&self) -> int {
self.0.length()
}
#[inline(always)]
pub fn get(&self, i: int) -> Local<'s, Value> {
self.0.get(i)
}
}
#[derive(Debug)]
pub struct PropertyCallbackArguments<'s>(&'s RawPropertyCallbackInfo);
impl<'s> PropertyCallbackArguments<'s> {
#[inline(always)]
pub(crate) fn from_property_callback_info<T>(
info: &'s PropertyCallbackInfo<T>,
) -> Self {
Self(&info.0)
}
#[inline(always)]
pub fn holder(&self) -> Local<'s, Object> {
unsafe {
Local::from_raw(v8__PropertyCallbackInfo__Holder(self.0))
.unwrap_unchecked()
}
}
#[inline(always)]
pub fn this(&self) -> Local<'s, Object> {
unsafe {
Local::from_raw(v8__PropertyCallbackInfo__This(self.0)).unwrap_unchecked()
}
}
#[inline(always)]
pub fn data(&self) -> Local<'s, Value> {
unsafe {
Local::from_raw(v8__PropertyCallbackInfo__Data(self.0)).unwrap_unchecked()
}
}
#[inline(always)]
pub fn should_throw_on_error(&self) -> bool {
unsafe { v8__PropertyCallbackInfo__ShouldThrowOnError(self.0) }
}
}
pub type FunctionCallback = extern "C" fn(*const FunctionCallbackInfo);
impl<F> MapFnFrom<F> for FunctionCallback
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
FunctionCallbackArguments<'s>,
ReturnValue<Value>,
),
{
fn mapping() -> Self {
let f = |info: *const FunctionCallbackInfo| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = FunctionCallbackArguments::from_function_callback_info(info);
let rv = ReturnValue::from_function_callback_info(info);
(F::get())(scope, args, rv);
};
f.to_c_fn()
}
}
pub(crate) type NamedGetterCallbackForAccessor<'s> =
extern "C" fn(Local<'s, Name>, *const PropertyCallbackInfo<Value>);
impl<F> MapFnFrom<F> for NamedGetterCallbackForAccessor<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
Local<'s, Name>,
PropertyCallbackArguments<'s>,
ReturnValue<Value>,
),
{
fn mapping() -> Self {
let f = |key: Local<Name>, info: *const PropertyCallbackInfo<Value>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, args, rv);
};
f.to_c_fn()
}
}
pub(crate) type NamedGetterCallback<'s> = extern "C" fn(
Local<'s, Name>,
*const PropertyCallbackInfo<Value>,
) -> Intercepted;
impl<F> MapFnFrom<F> for NamedGetterCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
Local<'s, Name>,
PropertyCallbackArguments<'s>,
ReturnValue<Value>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |key: Local<Name>, info: *const PropertyCallbackInfo<Value>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type NamedQueryCallback<'s> = extern "C" fn(
Local<'s, Name>,
*const PropertyCallbackInfo<Integer>,
) -> Intercepted;
impl<F> MapFnFrom<F> for NamedQueryCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
Local<'s, Name>,
PropertyCallbackArguments<'s>,
ReturnValue<Integer>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |key: Local<Name>, info: *const PropertyCallbackInfo<Integer>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type NamedSetterCallbackForAccessor<'s> = extern "C" fn(
Local<'s, Name>,
Local<'s, Value>,
*const PropertyCallbackInfo<()>,
);
impl<F> MapFnFrom<F> for NamedSetterCallbackForAccessor<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
Local<'s, Name>,
Local<'s, Value>,
PropertyCallbackArguments<'s>,
ReturnValue<()>,
),
{
fn mapping() -> Self {
let f = |key: Local<Name>,
value: Local<Value>,
info: *const PropertyCallbackInfo<()>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, value, args, rv);
};
f.to_c_fn()
}
}
pub(crate) type NamedSetterCallback<'s> = extern "C" fn(
Local<'s, Name>,
Local<'s, Value>,
*const PropertyCallbackInfo<()>,
) -> Intercepted;
impl<F> MapFnFrom<F> for NamedSetterCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
Local<'s, Name>,
Local<'s, Value>,
PropertyCallbackArguments<'s>,
ReturnValue<()>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |key: Local<Name>,
value: Local<Value>,
info: *const PropertyCallbackInfo<()>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, value, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type PropertyEnumeratorCallback<'s> =
extern "C" fn(*const PropertyCallbackInfo<Array>);
impl<F> MapFnFrom<F> for PropertyEnumeratorCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
PropertyCallbackArguments<'s>,
ReturnValue<Array>,
),
{
fn mapping() -> Self {
let f = |info: *const PropertyCallbackInfo<Array>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, args, rv);
};
f.to_c_fn()
}
}
pub(crate) type NamedDefinerCallback<'s> = extern "C" fn(
Local<'s, Name>,
*const PropertyDescriptor,
*const PropertyCallbackInfo<()>,
) -> Intercepted;
impl<F> MapFnFrom<F> for NamedDefinerCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
Local<'s, Name>,
&PropertyDescriptor,
PropertyCallbackArguments<'s>,
ReturnValue<()>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |key: Local<Name>,
desc: *const PropertyDescriptor,
info: *const PropertyCallbackInfo<()>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let desc = unsafe { &*desc };
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, desc, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type NamedDeleterCallback<'s> = extern "C" fn(
Local<'s, Name>,
*const PropertyCallbackInfo<Boolean>,
) -> Intercepted;
impl<F> MapFnFrom<F> for NamedDeleterCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
Local<'s, Name>,
PropertyCallbackArguments<'s>,
ReturnValue<Boolean>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |key: Local<Name>, info: *const PropertyCallbackInfo<Boolean>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type IndexedGetterCallback<'s> =
extern "C" fn(u32, *const PropertyCallbackInfo<Value>) -> Intercepted;
impl<F> MapFnFrom<F> for IndexedGetterCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
u32,
PropertyCallbackArguments<'s>,
ReturnValue<Value>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |index: u32, info: *const PropertyCallbackInfo<Value>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, index, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type IndexedQueryCallback<'s> =
extern "C" fn(u32, *const PropertyCallbackInfo<Integer>) -> Intercepted;
impl<F> MapFnFrom<F> for IndexedQueryCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
u32,
PropertyCallbackArguments<'s>,
ReturnValue<Integer>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |key: u32, info: *const PropertyCallbackInfo<Integer>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type IndexedSetterCallback<'s> = extern "C" fn(
u32,
Local<'s, Value>,
*const PropertyCallbackInfo<()>,
) -> Intercepted;
impl<F> MapFnFrom<F> for IndexedSetterCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
u32,
Local<'s, Value>,
PropertyCallbackArguments<'s>,
ReturnValue<()>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |index: u32,
value: Local<Value>,
info: *const PropertyCallbackInfo<()>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, index, value, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type IndexedDefinerCallback<'s> = extern "C" fn(
u32,
*const PropertyDescriptor,
*const PropertyCallbackInfo<()>,
) -> Intercepted;
impl<F> MapFnFrom<F> for IndexedDefinerCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
u32,
&PropertyDescriptor,
PropertyCallbackArguments<'s>,
ReturnValue<()>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |index: u32,
desc: *const PropertyDescriptor,
info: *const PropertyCallbackInfo<()>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
let desc = unsafe { &*desc };
(F::get())(scope, index, desc, args, rv)
};
f.to_c_fn()
}
}
pub(crate) type IndexedDeleterCallback<'s> =
extern "C" fn(u32, *const PropertyCallbackInfo<Boolean>) -> Intercepted;
impl<F> MapFnFrom<F> for IndexedDeleterCallback<'_>
where
F: UnitType
+ for<'s> Fn(
&mut HandleScope<'s>,
u32,
PropertyCallbackArguments<'s>,
ReturnValue<Boolean>,
) -> Intercepted,
{
fn mapping() -> Self {
let f = |index: u32, info: *const PropertyCallbackInfo<Boolean>| {
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, index, args, rv)
};
f.to_c_fn()
}
}
pub struct FunctionBuilder<'s, T> {
pub(crate) callback: FunctionCallback,
pub(crate) data: Option<Local<'s, Value>>,
pub(crate) signature: Option<Local<'s, Signature>>,
pub(crate) length: i32,
pub(crate) constructor_behavior: ConstructorBehavior,
pub(crate) side_effect_type: SideEffectType,
phantom: PhantomData<T>,
}
impl<'s, T> FunctionBuilder<'s, T> {
#[inline(always)]
pub fn new(callback: impl MapFnTo<FunctionCallback>) -> Self {
Self::new_raw(callback.map_fn_to())
}
#[inline(always)]
pub fn new_raw(callback: FunctionCallback) -> Self {
Self {
callback,
data: None,
signature: None,
length: 0,
constructor_behavior: ConstructorBehavior::Allow,
side_effect_type: SideEffectType::HasSideEffect,
phantom: PhantomData,
}
}
#[inline(always)]
pub fn data(mut self, data: Local<'s, Value>) -> Self {
self.data = Some(data);
self
}
#[inline(always)]
pub fn length(mut self, length: i32) -> Self {
self.length = length;
self
}
#[inline(always)]
pub fn constructor_behavior(
mut self,
constructor_behavior: ConstructorBehavior,
) -> Self {
self.constructor_behavior = constructor_behavior;
self
}
#[inline(always)]
pub fn side_effect_type(mut self, side_effect_type: SideEffectType) -> Self {
self.side_effect_type = side_effect_type;
self
}
}
impl<'s> FunctionBuilder<'s, Function> {
#[inline(always)]
pub fn build(
self,
scope: &mut HandleScope<'s>,
) -> Option<Local<'s, Function>> {
unsafe {
scope.cast_local(|sd| {
v8__Function__New(
sd.get_current_context(),
self.callback,
self.data.map_or_else(null, |p| &*p),
self.length,
self.constructor_behavior,
self.side_effect_type,
)
})
}
}
}
impl Function {
#[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: &mut HandleScope<'s>,
callback: impl MapFnTo<FunctionCallback>,
) -> Option<Local<'s, Function>> {
Self::builder(callback).build(scope)
}
#[inline(always)]
pub fn new_raw<'s>(
scope: &mut HandleScope<'s>,
callback: FunctionCallback,
) -> Option<Local<'s, Function>> {
Self::builder_raw(callback).build(scope)
}
#[inline]
pub fn call<'s>(
&self,
scope: &mut HandleScope<'s>,
recv: Local<Value>,
args: &[Local<Value>],
) -> Option<Local<'s, Value>> {
let args = Local::slice_into_raw(args);
let argc = int::try_from(args.len()).unwrap();
let argv = args.as_ptr();
unsafe {
scope.cast_local(|sd| {
v8__Function__Call(self, sd.get_current_context(), &*recv, argc, argv)
})
}
}
#[inline]
pub fn call_with_context<'s>(
&self,
scope: &mut HandleScope<'s, ()>,
context: Local<Context>,
recv: Local<Value>,
args: &[Local<Value>],
) -> Option<Local<'s, Value>> {
let args = Local::slice_into_raw(args);
let argc = int::try_from(args.len()).unwrap();
let argv = args.as_ptr();
unsafe {
let ret = v8__Function__Call(
self,
context.as_non_null().as_ptr(),
&*recv,
argc,
argv,
);
if ret.is_null() {
None
} else {
scope.cast_local(|_| ret)
}
}
}
#[inline(always)]
pub fn new_instance<'s>(
&self,
scope: &mut HandleScope<'s>,
args: &[Local<Value>],
) -> Option<Local<'s, Object>> {
let args = Local::slice_into_raw(args);
let argc = int::try_from(args.len()).unwrap();
let argv = args.as_ptr();
unsafe {
scope.cast_local(|sd| {
v8__Function__NewInstance(self, sd.get_current_context(), argc, argv)
})
}
}
#[inline(always)]
pub fn get_name<'s>(&self, scope: &mut HandleScope<'s>) -> Local<'s, String> {
unsafe { scope.cast_local(|_| v8__Function__GetName(self)).unwrap() }
}
#[inline(always)]
pub fn set_name(&self, name: Local<String>) {
unsafe { v8__Function__SetName(self, &*name) }
}
#[inline(always)]
pub fn get_script_column_number(&self) -> Option<u32> {
let ret = unsafe { v8__Function__GetScriptColumnNumber(self) };
(ret >= 0).then_some(ret as u32)
}
#[inline(always)]
pub fn get_script_line_number(&self) -> Option<u32> {
let ret = unsafe { v8__Function__GetScriptLineNumber(self) };
(ret >= 0).then_some(ret as u32)
}
#[inline(always)]
pub fn get_script_origin(&self) -> &ScriptOrigin {
unsafe {
let ptr = v8__Function__GetScriptOrigin(self);
&*ptr
}
}
#[inline(always)]
pub fn script_id(&self) -> i32 {
unsafe { v8__Function__ScriptId(self) }
}
#[inline(always)]
pub fn create_code_cache(&self) -> Option<UniqueRef<CachedData<'static>>> {
let code_cache =
unsafe { UniqueRef::try_from_raw(v8__Function__CreateCodeCache(self)) };
if let Some(code_cache) = &code_cache {
debug_assert_eq!(
code_cache.buffer_policy(),
crate::script_compiler::BufferPolicy::BufferOwned
);
}
code_cache
}
}