2019-12-21 06:08:00 +01:00
|
|
|
use std::marker::PhantomData;
|
|
|
|
use std::mem::MaybeUninit;
|
|
|
|
|
2019-12-11 04:43:22 +01:00
|
|
|
use crate::support::{int, Opaque};
|
|
|
|
use crate::Context;
|
2019-12-20 16:01:45 +01:00
|
|
|
use crate::HandleScope;
|
2019-12-19 20:11:22 -05:00
|
|
|
use crate::Isolate;
|
2019-12-11 04:43:22 +01:00
|
|
|
use crate::Local;
|
|
|
|
use crate::Value;
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
fn v8__Function__New(
|
|
|
|
context: *mut Context,
|
|
|
|
callback: extern "C" fn(&FunctionCallbackInfo),
|
|
|
|
) -> *mut Function;
|
|
|
|
fn v8__Function__Call(
|
|
|
|
function: *mut Function,
|
|
|
|
context: *mut Context,
|
|
|
|
recv: *mut Value,
|
|
|
|
argc: int,
|
|
|
|
argv: *mut *mut Value,
|
|
|
|
) -> *mut Value;
|
|
|
|
|
|
|
|
fn v8__FunctionTemplate__New(
|
2019-12-19 20:11:22 -05:00
|
|
|
isolate: &Isolate,
|
2019-12-11 04:43:22 +01:00
|
|
|
callback: extern "C" fn(&FunctionCallbackInfo),
|
|
|
|
) -> *mut FunctionTemplate;
|
|
|
|
fn v8__FunctionTemplate__GetFunction(
|
|
|
|
fn_template: *mut FunctionTemplate,
|
|
|
|
context: *mut Context,
|
|
|
|
) -> *mut Function;
|
|
|
|
|
|
|
|
fn v8__FunctionCallbackInfo__GetIsolate(
|
|
|
|
info: &FunctionCallbackInfo,
|
2019-12-19 19:15:52 -05:00
|
|
|
) -> &mut Isolate;
|
2019-12-11 04:43:22 +01:00
|
|
|
fn v8__FunctionCallbackInfo__Length(info: &FunctionCallbackInfo) -> int;
|
2019-12-14 23:14:09 +01:00
|
|
|
fn v8__FunctionCallbackInfo__GetReturnValue(
|
|
|
|
info: &FunctionCallbackInfo,
|
2019-12-20 18:16:44 +01:00
|
|
|
out: *mut ReturnValue,
|
|
|
|
);
|
2019-12-17 19:19:40 +01:00
|
|
|
|
2019-12-21 06:08:00 +01:00
|
|
|
fn v8__ReturnValue__Set(rv: &mut ReturnValue, value: *mut Value);
|
|
|
|
fn v8__ReturnValue__Get(rv: &ReturnValue) -> *mut Value;
|
2019-12-19 16:58:39 -05:00
|
|
|
fn v8__ReturnValue__GetIsolate(rv: &ReturnValue) -> *mut Isolate;
|
2019-12-14 23:14:09 +01:00
|
|
|
}
|
|
|
|
|
2019-12-21 06:08:00 +01:00
|
|
|
// Npte: the 'cb lifetime is required because the ReturnValue object must not
|
|
|
|
// outlive the FunctionCallbackInfo/PropertyCallbackInfo object from which it
|
|
|
|
// is derived.
|
2019-12-14 23:14:09 +01:00
|
|
|
#[repr(C)]
|
2019-12-21 06:08:00 +01:00
|
|
|
pub struct ReturnValue<'cb>(*mut Opaque, PhantomData<&'cb ()>);
|
2019-12-14 23:14:09 +01:00
|
|
|
|
2019-12-17 19:19:40 +01:00
|
|
|
/// In V8 ReturnValue<> has a type parameter, but
|
|
|
|
/// it turns out that in most of the APIs it's ReturnValue<Value>
|
|
|
|
/// and for our purposes we currently don't need
|
|
|
|
/// other types. So for now it's a simplified version.
|
2019-12-21 06:08:00 +01:00
|
|
|
impl<'cb> ReturnValue<'cb> {
|
2019-12-14 23:14:09 +01:00
|
|
|
// NOTE: simplest setter, possibly we'll need to add
|
|
|
|
// more setters specialized per type
|
2019-12-19 23:36:29 -05:00
|
|
|
pub fn set(&mut self, mut value: Local<Value>) {
|
2019-12-17 19:19:40 +01:00
|
|
|
unsafe { v8__ReturnValue__Set(&mut *self, &mut *value) }
|
2019-12-14 23:14:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Convenience getter for Isolate
|
2019-12-19 16:58:39 -05:00
|
|
|
pub fn get_isolate(&self) -> &Isolate {
|
|
|
|
unsafe { v8__ReturnValue__GetIsolate(self).as_ref().unwrap() }
|
2019-12-14 23:14:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Getter. Creates a new Local<> so it comes with a certain performance
|
|
|
|
/// hit. If the ReturnValue was not yet set, this will return the undefined
|
|
|
|
/// value.
|
2019-12-20 16:01:45 +01:00
|
|
|
pub fn get<'sc>(
|
|
|
|
&mut self,
|
|
|
|
_scope: &mut HandleScope<'sc>,
|
|
|
|
) -> Local<'sc, Value> {
|
2019-12-21 06:08:00 +01:00
|
|
|
unsafe { Local::from_raw(v8__ReturnValue__Get(self)).unwrap() }
|
2019-12-14 23:14:09 +01:00
|
|
|
}
|
2019-12-11 04:43:22 +01:00
|
|
|
}
|
|
|
|
|
2019-12-19 14:14:19 +01:00
|
|
|
/// The argument information given to function call callbacks. This
|
|
|
|
/// class provides access to information about the context of the call,
|
|
|
|
/// including the receiver, the number and values of arguments, and
|
|
|
|
/// the holder of the function.
|
2019-12-11 04:43:22 +01:00
|
|
|
#[repr(C)]
|
|
|
|
pub struct FunctionCallbackInfo(Opaque);
|
|
|
|
|
|
|
|
impl FunctionCallbackInfo {
|
2019-12-19 14:14:19 +01:00
|
|
|
/// The ReturnValue for the call.
|
2019-12-20 18:16:44 +01:00
|
|
|
pub fn get_return_value(&self) -> ReturnValue {
|
|
|
|
let mut rv = MaybeUninit::<ReturnValue>::uninit();
|
|
|
|
unsafe {
|
2019-12-21 06:08:00 +01:00
|
|
|
v8__FunctionCallbackInfo__GetReturnValue(self, rv.as_mut_ptr());
|
2019-12-20 18:16:44 +01:00
|
|
|
rv.assume_init()
|
|
|
|
}
|
2019-12-14 23:14:09 +01:00
|
|
|
}
|
|
|
|
|
2019-12-19 14:14:19 +01:00
|
|
|
/// The current Isolate.
|
2019-12-21 06:08:00 +01:00
|
|
|
#[allow(clippy::mut_from_ref)]
|
|
|
|
pub unsafe fn get_isolate(&self) -> &mut Isolate {
|
|
|
|
v8__FunctionCallbackInfo__GetIsolate(self)
|
2019-12-11 04:43:22 +01:00
|
|
|
}
|
|
|
|
|
2019-12-19 14:14:19 +01:00
|
|
|
/// The number of available arguments.
|
2019-12-11 04:43:22 +01:00
|
|
|
pub fn length(&self) -> int {
|
2019-12-21 06:08:00 +01:00
|
|
|
unsafe { v8__FunctionCallbackInfo__Length(self) }
|
2019-12-11 04:43:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-19 14:14:19 +01:00
|
|
|
/// A FunctionTemplate is used to create functions at runtime. There
|
|
|
|
/// can only be one function created from a FunctionTemplate in a
|
|
|
|
/// context. The lifetime of the created function is equal to the
|
|
|
|
/// lifetime of the context. So in case the embedder needs to create
|
|
|
|
/// temporary functions that can be collected using Scripts is
|
|
|
|
/// preferred.
|
|
|
|
///
|
|
|
|
/// Any modification of a FunctionTemplate after first instantiation will trigger
|
|
|
|
/// a crash.
|
|
|
|
///
|
|
|
|
/// A FunctionTemplate can have properties, these properties are added to the
|
|
|
|
/// function object when it is created.
|
|
|
|
///
|
|
|
|
/// A FunctionTemplate has a corresponding instance template which is
|
|
|
|
/// used to create object instances when the function is used as a
|
|
|
|
/// constructor. Properties added to the instance template are added to
|
|
|
|
/// each object instance.
|
|
|
|
///
|
|
|
|
/// A FunctionTemplate can have a prototype template. The prototype template
|
|
|
|
/// is used to create the prototype object of the function.
|
2019-12-11 04:43:22 +01:00
|
|
|
#[repr(C)]
|
|
|
|
pub struct FunctionTemplate(Opaque);
|
|
|
|
|
|
|
|
impl FunctionTemplate {
|
|
|
|
/// Creates a function template.
|
2019-12-20 16:01:45 +01:00
|
|
|
pub fn new<'sc>(
|
|
|
|
scope: &mut HandleScope<'sc>,
|
2019-12-11 04:43:22 +01:00
|
|
|
callback: extern "C" fn(&FunctionCallbackInfo),
|
2019-12-20 16:01:45 +01:00
|
|
|
) -> Local<'sc, FunctionTemplate> {
|
2019-12-11 04:43:22 +01:00
|
|
|
unsafe {
|
2019-12-20 16:01:45 +01:00
|
|
|
Local::from_raw(v8__FunctionTemplate__New(scope.as_mut(), callback))
|
|
|
|
.unwrap()
|
2019-12-11 04:43:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-19 14:14:19 +01:00
|
|
|
/// Returns the unique function instance in the current execution context.
|
2019-12-20 16:01:45 +01:00
|
|
|
pub fn get_function<'sc>(
|
2019-12-11 04:43:22 +01:00
|
|
|
&mut self,
|
2019-12-20 16:01:45 +01:00
|
|
|
_scope: &mut HandleScope<'sc>,
|
2019-12-19 23:36:29 -05:00
|
|
|
mut context: Local<Context>,
|
2019-12-20 16:01:45 +01:00
|
|
|
) -> Option<Local<'sc, Function>> {
|
2019-12-11 04:43:22 +01:00
|
|
|
unsafe {
|
|
|
|
Local::from_raw(v8__FunctionTemplate__GetFunction(
|
|
|
|
&mut *self,
|
|
|
|
&mut *context,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-19 14:14:19 +01:00
|
|
|
/// A JavaScript function object (ECMA-262, 15.3).
|
2019-12-11 04:43:22 +01:00
|
|
|
#[repr(C)]
|
|
|
|
pub struct Function(Opaque);
|
|
|
|
|
|
|
|
impl Function {
|
|
|
|
// TODO: add remaining arguments from C++
|
|
|
|
/// Create a function in the current execution context
|
|
|
|
/// for a given FunctionCallback.
|
2019-12-20 16:01:45 +01:00
|
|
|
pub fn new<'sc>(
|
|
|
|
_scope: &mut HandleScope<'sc>,
|
2019-12-19 23:36:29 -05:00
|
|
|
mut context: Local<Context>,
|
2019-12-11 04:43:22 +01:00
|
|
|
callback: extern "C" fn(&FunctionCallbackInfo),
|
2019-12-20 16:01:45 +01:00
|
|
|
) -> Option<Local<'sc, Function>> {
|
2019-12-11 04:43:22 +01:00
|
|
|
unsafe { Local::from_raw(v8__Function__New(&mut *context, callback)) }
|
|
|
|
}
|
|
|
|
|
2019-12-20 16:01:45 +01:00
|
|
|
pub fn call<'sc>(
|
2019-12-11 04:43:22 +01:00
|
|
|
&mut self,
|
2019-12-20 16:01:45 +01:00
|
|
|
_scope: &mut HandleScope<'sc>,
|
2019-12-19 23:36:29 -05:00
|
|
|
mut context: Local<Context>,
|
|
|
|
mut recv: Local<Value>,
|
2019-12-11 04:43:22 +01:00
|
|
|
arc: i32,
|
2019-12-19 23:36:29 -05:00
|
|
|
argv: Vec<Local<Value>>,
|
2019-12-20 16:01:45 +01:00
|
|
|
) -> Option<Local<'sc, Value>> {
|
2019-12-11 04:43:22 +01:00
|
|
|
let mut argv_: Vec<*mut Value> = vec![];
|
|
|
|
for mut arg in argv {
|
|
|
|
argv_.push(&mut *arg);
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
Local::from_raw(v8__Function__Call(
|
|
|
|
&mut *self,
|
|
|
|
&mut *context,
|
|
|
|
&mut *recv,
|
|
|
|
arc,
|
|
|
|
argv_.as_mut_ptr(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|