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

feat: raw APIs to build v8::Functions from ptrs (#917)

Unblocks https://github.com/denoland/deno/pull/13861

The MapFnTo trait is quite contrived and can't be turned into a trait object thus blocking declarative ops
This commit is contained in:
Aaron O'Mullan 2022-03-10 23:04:48 +01:00 committed by GitHub
parent 184467a9cc
commit aaacaa292f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 1 deletions

View file

@ -362,8 +362,12 @@ pub struct FunctionBuilder<'s, T> {
impl<'s, T> FunctionBuilder<'s, T> {
/// Create a new FunctionBuilder.
pub fn new(callback: impl MapFnTo<FunctionCallback>) -> Self {
Self::new_raw(callback.map_fn_to())
}
pub fn new_raw(callback: FunctionCallback) -> Self {
Self {
callback: callback.map_fn_to(),
callback,
data: None,
signature: None,
length: 0,
@ -431,6 +435,12 @@ impl Function {
FunctionBuilder::new(callback)
}
pub fn builder_raw<'s>(
callback: FunctionCallback,
) -> FunctionBuilder<'s, Self> {
FunctionBuilder::new_raw(callback)
}
/// Create a function in the current execution context
/// for a given FunctionCallback.
pub fn new<'s>(
@ -440,6 +450,13 @@ impl Function {
Self::builder(callback).build(scope)
}
pub fn new_raw<'s>(
scope: &mut HandleScope<'s>,
callback: FunctionCallback,
) -> Option<Local<'s, Function>> {
Self::builder_raw(callback).build(scope)
}
pub fn call<'s>(
&self,
scope: &mut HandleScope<'s>,

View file

@ -174,6 +174,12 @@ impl FunctionTemplate {
FunctionBuilder::new(callback)
}
pub fn builder_raw<'s>(
callback: FunctionCallback,
) -> FunctionBuilder<'s, Self> {
FunctionBuilder::new_raw(callback)
}
/// Creates a function template.
pub fn new<'s>(
scope: &mut HandleScope<'s, ()>,
@ -182,6 +188,13 @@ impl FunctionTemplate {
Self::builder(callback).build(scope)
}
pub fn new_raw<'s>(
scope: &mut HandleScope<'s, ()>,
callback: FunctionCallback,
) -> Local<'s, FunctionTemplate> {
Self::builder_raw(callback).build(scope)
}
/// Returns the unique function instance in the current execution context.
pub fn get_function<'s>(
&self,

View file

@ -2148,6 +2148,22 @@ fn function() {
let rust_str = value_str.to_rust_string_lossy(scope);
assert_eq!(rust_str, "Hello callback!".to_string());
// create function using template from a raw ptr
let fn_template =
v8::FunctionTemplate::new_raw(scope, fn_callback.map_fn_to());
let function = fn_template
.get_function(scope)
.expect("Unable to create function");
let lhs = function.get_creation_context(scope).unwrap().global(scope);
let rhs = context.global(scope);
assert!(lhs.strict_equals(rhs.into()));
let value = function
.call(scope, recv, &[])
.expect("Function call failed");
let value_str = value.to_string(scope).unwrap();
let rust_str = value_str.to_rust_string_lossy(scope);
assert_eq!(rust_str, "Hello callback!".to_string());
// create function without a template
let function = v8::Function::new(scope, fn_callback2)
.expect("Unable to create function");
@ -2160,6 +2176,18 @@ fn function() {
let rust_str = value_str.to_rust_string_lossy(scope);
assert_eq!(rust_str, "Hello callback!".to_string());
// create function without a template from a raw ptr
let function = v8::Function::new_raw(scope, fn_callback2.map_fn_to())
.expect("Unable to create function");
let arg1 = v8::String::new(scope, "arg1").unwrap();
let arg2 = v8::Integer::new(scope, 2);
let value = function
.call(scope, recv, &[arg1.into(), arg2.into()])
.unwrap();
let value_str = value.to_string(scope).unwrap();
let rust_str = value_str.to_rust_string_lossy(scope);
assert_eq!(rust_str, "Hello callback!".to_string());
// create a function with associated data
let true_data = v8::Boolean::new(scope, true);
let function = v8::Function::builder(data_is_true_callback)
@ -2171,6 +2199,17 @@ fn function() {
.expect("Function call failed");
assert!(value.is_undefined());
// create a function with associated data from a raw ptr
let true_data = v8::Boolean::new(scope, true);
let function = v8::Function::builder_raw(data_is_true_callback.map_fn_to())
.data(true_data.into())
.build(scope)
.expect("Unable to create function with data");
let value = function
.call(scope, recv, &[])
.expect("Function call failed");
assert!(value.is_undefined());
// create a prototype-less function that throws on new
let function = v8::Function::builder(fn_callback)
.length(42)