/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ext/napi/function.rs
105 строк
3 KB
Nathan Whitaker
fix(ext/napi): scope callback info per invocation (#36076)
16 июл 2026, 12:21
Не верифицирован
16 июл 2026, 12:21
7324701
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. use crate::*; #[repr(C)] #[derive(Debug)] pub struct CallbackInfo { pub env: *mut Env, pub cb: napi_callback, pub data: *mut c_void, } #[repr(C)] #[derive(Debug)] pub struct CallbackInfoScope { pub function_info: *const CallbackInfo, pub args: *const c_void, } impl CallbackInfo { #[inline] pub fn new_raw( env: *mut Env, cb: napi_callback, data: *mut c_void, ) -> *mut Self { Box::into_raw(Box::new(Self { env, cb, data })) } } extern "C" fn call_fn(info: *const v8::FunctionCallbackInfo) { let v8_callback_info = unsafe { &*info }; let args = v8::FunctionCallbackArguments::from_function_callback_info( v8_callback_info, ); let mut rv = v8::ReturnValue::from_function_callback_info(v8_callback_info); // SAFETY: create_function guarantees that the data is a CallbackInfo external. let info_ptr: *mut CallbackInfo = unsafe { let external_value = v8::Local::<v8::External>::cast_unchecked(args.data()); external_value.value() as _ }; // SAFETY: pointer from Box::into_raw. let info = unsafe { &*info_ptr }; let mut callback_info_scope = CallbackInfoScope { function_info: info_ptr, args: &args as *const _ as *const c_void, }; // SAFETY: calling user provided function pointer. let value = unsafe { (info.cb)( info.env as napi_env, &mut callback_info_scope as *mut _ as *mut c_void, ) }; if let Some(exc) = unsafe { &mut *info.env }.last_exception.take() { v8::callback_scope!(unsafe scope, v8_callback_info); let exc = v8::Local::new(scope, exc); scope.throw_exception(exc); } if let Some(value) = *value { rv.set(value); } } pub fn create_function<'s>( scope: &mut v8::PinScope<'s, '_>, env: *mut Env, name: Option<v8::Local<v8::String>>, cb: napi_callback, data: *mut c_void, ) -> v8::Local<'s, v8::Function> { let external = v8::External::new(scope, CallbackInfo::new_raw(env, cb, data) as *mut _); let function = v8::Function::builder_raw(call_fn) .data(external.into()) .build(scope) .unwrap(); if let Some(v8str) = name { function.set_name(v8str); } function } pub fn create_function_template<'s>( scope: &mut v8::PinScope<'s, '_>, env: *mut Env, name: Option<v8::Local<v8::String>>, cb: napi_callback, cb_info: napi_callback_info, ) -> v8::Local<'s, v8::FunctionTemplate> { let external = v8::External::new(scope, CallbackInfo::new_raw(env, cb, cb_info) as *mut _); let function = v8::FunctionTemplate::builder_raw(call_fn) .data(external.into()) .build(scope); if let Some(v8str) = name { function.set_class_name(v8str); } function }