2024-01-01 14:58:21 -05:00
|
|
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
2022-10-05 10:06:44 -04:00
|
|
|
use crate::*;
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct CallbackInfo {
|
2024-06-11 20:40:44 -04:00
|
|
|
pub env: *mut Env,
|
2022-10-05 10:06:44 -04:00
|
|
|
pub cb: napi_callback,
|
|
|
|
pub cb_info: napi_callback_info,
|
|
|
|
pub args: *const c_void,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CallbackInfo {
|
|
|
|
#[inline]
|
|
|
|
pub fn new_raw(
|
2024-06-11 20:40:44 -04:00
|
|
|
env: *mut Env,
|
2022-10-05 10:06:44 -04:00
|
|
|
cb: napi_callback,
|
|
|
|
cb_info: napi_callback_info,
|
|
|
|
) -> *mut Self {
|
|
|
|
Box::into_raw(Box::new(Self {
|
|
|
|
env,
|
|
|
|
cb,
|
|
|
|
cb_info,
|
|
|
|
args: std::ptr::null(),
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" fn call_fn(info: *const v8::FunctionCallbackInfo) {
|
2024-06-10 12:20:44 -04:00
|
|
|
let callback_info = unsafe { &*info };
|
|
|
|
let args =
|
|
|
|
v8::FunctionCallbackArguments::from_function_callback_info(callback_info);
|
|
|
|
let mut rv = v8::ReturnValue::from_function_callback_info(callback_info);
|
2022-10-05 10:06:44 -04:00
|
|
|
// SAFETY: create_function guarantees that the data is a CallbackInfo external.
|
|
|
|
let info_ptr: *mut CallbackInfo = unsafe {
|
2024-07-23 20:11:38 -04:00
|
|
|
let external_value = v8::Local::<v8::External>::cast_unchecked(args.data());
|
2022-10-05 10:06:44 -04:00
|
|
|
external_value.value() as _
|
|
|
|
};
|
|
|
|
|
|
|
|
// SAFETY: pointer from Box::into_raw.
|
2023-07-13 17:16:24 -04:00
|
|
|
let info = unsafe { &mut *info_ptr };
|
2022-10-05 10:06:44 -04:00
|
|
|
info.args = &args as *const _ as *const c_void;
|
|
|
|
|
2024-06-11 20:40:44 -04:00
|
|
|
// SAFETY: calling user provided function pointer.
|
|
|
|
let value = unsafe { (info.cb)(info.env as napi_env, info_ptr as *mut _) };
|
|
|
|
if let Some(exc) = unsafe { &mut *info.env }.last_exception.take() {
|
|
|
|
let scope = unsafe { &mut v8::CallbackScope::new(callback_info) };
|
|
|
|
let exc = v8::Local::new(scope, exc);
|
|
|
|
scope.throw_exception(exc);
|
|
|
|
}
|
|
|
|
if let Some(value) = *value {
|
|
|
|
rv.set(value);
|
2022-10-05 10:06:44 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-11 20:40:44 -04:00
|
|
|
pub fn create_function<'s>(
|
|
|
|
scope: &mut v8::HandleScope<'s>,
|
|
|
|
env: *mut Env,
|
2023-01-22 04:34:18 -05:00
|
|
|
name: Option<v8::Local<v8::String>>,
|
2022-10-05 10:06:44 -04:00
|
|
|
cb: napi_callback,
|
|
|
|
cb_info: napi_callback_info,
|
2024-06-11 20:40:44 -04:00
|
|
|
) -> v8::Local<'s, v8::Function> {
|
|
|
|
let external =
|
|
|
|
v8::External::new(scope, CallbackInfo::new_raw(env, cb, cb_info) as *mut _);
|
2022-10-05 10:06:44 -04:00
|
|
|
let function = v8::Function::builder_raw(call_fn)
|
|
|
|
.data(external.into())
|
|
|
|
.build(scope)
|
|
|
|
.unwrap();
|
|
|
|
|
2023-01-22 04:34:18 -05:00
|
|
|
if let Some(v8str) = name {
|
2022-10-05 10:06:44 -04:00
|
|
|
function.set_name(v8str);
|
|
|
|
}
|
|
|
|
|
|
|
|
function
|
|
|
|
}
|
|
|
|
|
2024-06-11 20:40:44 -04:00
|
|
|
pub fn create_function_template<'s>(
|
|
|
|
scope: &mut v8::HandleScope<'s>,
|
|
|
|
env: *mut Env,
|
2024-06-10 12:20:44 -04:00
|
|
|
name: Option<v8::Local<v8::String>>,
|
2022-10-05 10:06:44 -04:00
|
|
|
cb: napi_callback,
|
|
|
|
cb_info: napi_callback_info,
|
2024-06-11 20:40:44 -04:00
|
|
|
) -> v8::Local<'s, v8::FunctionTemplate> {
|
|
|
|
let external =
|
|
|
|
v8::External::new(scope, CallbackInfo::new_raw(env, cb, cb_info) as *mut _);
|
2022-10-05 10:06:44 -04:00
|
|
|
let function = v8::FunctionTemplate::builder_raw(call_fn)
|
|
|
|
.data(external.into())
|
|
|
|
.build(scope);
|
|
|
|
|
2024-06-10 12:20:44 -04:00
|
|
|
if let Some(v8str) = name {
|
2022-10-05 10:06:44 -04:00
|
|
|
function.set_class_name(v8str);
|
|
|
|
}
|
|
|
|
|
|
|
|
function
|
|
|
|
}
|