0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-11-24 15:19:31 -05:00

feat: support adding raw pointers to ExternalReferences (#901)

This commit is contained in:
Divy Srivastava 2022-02-19 05:38:54 +05:30 committed by GitHub
parent da7ef32ead
commit fe447c88df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 12 deletions

View file

@ -3,15 +3,17 @@ use crate::support::intptr_t;
use crate::AccessorNameGetterCallback;
use crate::FunctionCallback;
use crate::MessageCallback;
use std::os::raw::c_void;
#[derive(Clone, Copy)]
pub union ExternalReference<'s> {
pub function: FunctionCallback,
pub getter: AccessorNameGetterCallback<'s>,
pub message: MessageCallback,
pub pointer: *mut c_void,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct ExternalReferences {
null_terminated: Vec<intptr_t>,
}

View file

@ -1946,6 +1946,22 @@ fn proxy() {
}
}
fn fn_callback_external(
scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
assert_eq!(args.length(), 0);
let data = args.data().unwrap();
let external = v8::Local::<v8::External>::try_from(data).unwrap();
let data =
unsafe { std::slice::from_raw_parts(external.value() as *mut u8, 5) };
assert_eq!(&[0, 1, 2, 3, 4], data);
let s = v8::String::new(scope, "Hello callback!").unwrap();
assert!(rv.get(scope).is_undefined());
rv.set(s.into());
}
fn fn_callback(
scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
@ -2934,21 +2950,33 @@ fn snapshot_creator() {
}
}
lazy_static! {
static ref EXTERNAL_REFERENCES: v8::ExternalReferences =
v8::ExternalReferences::new(&[v8::ExternalReference {
function: fn_callback.map_fn_to()
}]);
}
#[test]
fn external_references() {
let _setup_guard = setup();
// Allocate externals for the test.
let external_ptr = Box::into_raw(vec![0_u8, 1, 2, 3, 4].into_boxed_slice())
as *mut [u8] as *mut c_void;
// Push them to the external reference table.
let refs = v8::ExternalReferences::new(&[
v8::ExternalReference {
function: fn_callback.map_fn_to(),
},
v8::ExternalReference {
function: fn_callback_external.map_fn_to(),
},
v8::ExternalReference {
pointer: external_ptr,
},
]);
// TODO(piscisaureus): leaking the `ExternalReferences` collection shouldn't
// be necessary. The reference needs to remain valid for the lifetime of the
// `SnapshotCreator` or `Isolate` that uses it, which would be the case here
// even without leaking.
let refs: &'static v8::ExternalReferences = Box::leak(Box::new(refs));
// First we create the snapshot, there is a single global variable 'a' set to
// the value 3.
let startup_data = {
let mut snapshot_creator =
v8::SnapshotCreator::new(Some(&EXTERNAL_REFERENCES));
let mut snapshot_creator = v8::SnapshotCreator::new(Some(refs));
// TODO(ry) this shouldn't be necessary. workaround unfinished business in
// the scope type system.
let mut isolate = unsafe { snapshot_creator.get_owned_isolate() };
@ -2958,7 +2986,10 @@ fn external_references() {
let scope = &mut v8::ContextScope::new(scope, context);
// create function using template
let fn_template = v8::FunctionTemplate::new(scope, fn_callback);
let external = v8::External::new(scope, external_ptr);
let fn_template = v8::FunctionTemplate::builder(fn_callback_external)
.data(external.into())
.build(scope);
let function = fn_template
.get_function(scope)
.expect("Unable to create function");
@ -2980,7 +3011,7 @@ fn external_references() {
{
let params = v8::Isolate::create_params()
.snapshot_blob(startup_data)
.external_references(&**EXTERNAL_REFERENCES);
.external_references(&**refs);
let isolate = &mut v8::Isolate::new(params);
{
let scope = &mut v8::HandleScope::new(isolate);