diff --git a/examples/shell.rs b/examples/shell.rs index 9f4cfc0a..916230b1 100644 --- a/examples/shell.rs +++ b/examples/shell.rs @@ -119,7 +119,6 @@ fn execute_string( let mut scope = v8::TryCatch::new(scope); let filename = v8::String::new(&mut scope, filename).unwrap(); - let undefined = v8::undefined(&mut scope); let script = v8::String::new(&mut scope, script).unwrap(); let origin = v8::ScriptOrigin::new( &mut scope, @@ -128,10 +127,11 @@ fn execute_string( 0, false, 0, - undefined.into(), + None, false, false, false, + None, ); let script = if let Some(script) = diff --git a/src/binding.cc b/src/binding.cc index b698a559..ee4db166 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -2631,18 +2631,17 @@ const v8::Value* v8__Script__Run(const v8::Script& script, return maybe_local_to_ptr(ptr_to_local(&script)->Run(ptr_to_local(&context))); } -void v8__ScriptOrigin__CONSTRUCT(uninit_t* buf, - const v8::Value& resource_name, - int resource_line_offset, - int resource_column_offset, - bool resource_is_shared_cross_origin, - int script_id, const v8::Value& source_map_url, - bool resource_is_opaque, bool is_wasm, - bool is_module) { +void v8__ScriptOrigin__CONSTRUCT( + uninit_t* buf, const v8::Value& resource_name, + int resource_line_offset, int resource_column_offset, + bool resource_is_shared_cross_origin, int script_id, + const v8::Value* source_map_url, bool resource_is_opaque, bool is_wasm, + bool is_module, const v8::Data* host_defined_options) { construct_in_place( buf, ptr_to_local(&resource_name), resource_line_offset, resource_column_offset, resource_is_shared_cross_origin, script_id, - ptr_to_local(&source_map_url), resource_is_opaque, is_wasm, is_module); + ptr_to_local(source_map_url), resource_is_opaque, is_wasm, is_module, + ptr_to_local(host_defined_options)); } int v8__ScriptOrigin__ScriptId(const v8::ScriptOrigin& self) { diff --git a/src/isolate.rs b/src/isolate.rs index c91ca80b..6762fee2 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -412,9 +412,6 @@ extern "C" { fn v8__Isolate__Enter(this: *mut Isolate); fn v8__Isolate__Exit(this: *mut Isolate); fn v8__Isolate__GetCurrent() -> *mut Isolate; - fn v8__Isolate__GetCurrentHostDefinedOptions( - this: *mut Isolate, - ) -> *const Data; fn v8__Isolate__MemoryPressureNotification(this: *mut Isolate, level: u8); fn v8__Isolate__ClearKeptObjects(isolate: *mut Isolate); fn v8__Isolate__LowMemoryNotification(isolate: *mut Isolate); @@ -1428,18 +1425,6 @@ impl Isolate { .unwrap(); snapshot_creator.add_context_data(context, data) } - - /// Returns the host defined options set for currently running script or - /// module, if available. - #[inline(always)] - pub fn get_current_host_defined_options<'s>( - &mut self, - scope: &mut HandleScope<'s, ()>, - ) -> Option> { - unsafe { - scope.cast_local(|_| v8__Isolate__GetCurrentHostDefinedOptions(self)) - } - } } pub(crate) struct IsolateAnnex { diff --git a/src/scope.rs b/src/scope.rs index 921138e0..059eb8c9 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -208,6 +208,19 @@ impl<'s> HandleScope<'s> { unsafe { raw::v8__Isolate__GetEnteredOrMicrotaskContext(isolate_ptr) }; unsafe { Local::from_raw(context_ptr) }.unwrap() } + + /// Returns the host defined options set for currently running script or + /// module, if available. + #[inline(always)] + pub fn get_current_host_defined_options(&self) -> Option> { + let data = data::ScopeData::get(self); + let isolate_ptr = data.get_isolate_ptr(); + unsafe { + Local::from_raw(raw::v8__Isolate__GetCurrentHostDefinedOptions( + isolate_ptr, + )) + } + } } impl<'s> HandleScope<'s, ()> { @@ -2114,6 +2127,9 @@ mod raw { this: *mut Isolate, index: usize, ) -> *const Data; + pub(super) fn v8__Isolate__GetCurrentHostDefinedOptions( + this: *mut Isolate, + ) -> *const Data; pub(super) fn v8__Context__EQ( this: *const Context, diff --git a/src/script.rs b/src/script.rs index 04703152..f729241d 100644 --- a/src/script.rs +++ b/src/script.rs @@ -3,6 +3,7 @@ use std::mem::MaybeUninit; use std::ptr::null; use crate::Context; +use crate::Data; use crate::HandleScope; use crate::Local; use crate::Script; @@ -43,6 +44,7 @@ extern "C" { resource_is_opaque: bool, is_wasm: bool, is_module: bool, + host_defined_options: *const Data, ); fn v8__ScriptOrigin__ScriptId(origin: *const ScriptOrigin) -> i32; fn v8__ScriptOrigin__ResourceName( @@ -111,10 +113,11 @@ impl<'s> ScriptOrigin<'s> { resource_column_offset: i32, resource_is_shared_cross_origin: bool, script_id: i32, - source_map_url: Local<'s, Value>, + source_map_url: Option>, resource_is_opaque: bool, is_wasm: bool, is_module: bool, + host_defined_options: Option>, ) -> Self { unsafe { let mut buf = std::mem::MaybeUninit::::uninit(); @@ -125,10 +128,15 @@ impl<'s> ScriptOrigin<'s> { resource_column_offset, resource_is_shared_cross_origin, script_id, - &*source_map_url, + source_map_url + .map(|l| &*l as *const Value) + .unwrap_or_else(null), resource_is_opaque, is_wasm, is_module, + host_defined_options + .map(|l| &*l as *const Data) + .unwrap_or_else(null), ); buf.assume_init() } diff --git a/tests/test_api.rs b/tests/test_api.rs index 4766696b..0c2e6b6c 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -1451,10 +1451,11 @@ fn script_origin() { resource_column_offset, resource_is_shared_cross_origin, script_id, - source_map_url.into(), + Some(source_map_url.into()), resource_is_opaque, is_wasm, is_module, + None, ); let source = v8::String::new(scope, "1+2").unwrap(); @@ -4759,10 +4760,11 @@ fn mock_script_origin<'s>( resource_column_offset, resource_is_shared_cross_origin, script_id, - source_map_url.into(), + Some(source_map_url.into()), resource_is_opaque, is_wasm, is_module, + None, ) } @@ -8631,7 +8633,6 @@ fn get_source_mapping_from_comment() { let resource_column_offset = 0; let resource_is_shared_cross_origin = false; let script_id = -1; - let source_map_url = v8::undefined(scope); let resource_is_opaque = false; let is_wasm = false; let is_module = false; @@ -8643,10 +8644,11 @@ fn get_source_mapping_from_comment() { resource_column_offset, resource_is_shared_cross_origin, script_id, - source_map_url.into(), + None, resource_is_opaque, is_wasm, is_module, + None, ); let code = v8::String::new(scope, "var foo;\n//# sourceMappingURL=foo.js.map") @@ -8694,10 +8696,11 @@ fn origin_source_map_overrides_source_mapping_url_comment() { resource_column_offset, resource_is_shared_cross_origin, script_id, - source_map_url.into(), + Some(source_map_url.into()), resource_is_opaque, is_wasm, is_module, + None, ); let code = v8::String::new(scope, "var foo;\n//# sourceMappingURL=foo.js.map") @@ -8744,10 +8747,11 @@ fn ignore_origin_source_map_empty_string() { resource_column_offset, resource_is_shared_cross_origin, script_id, - source_map_url.into(), + Some(source_map_url.into()), resource_is_opaque, is_wasm, is_module, + None, ); let code = v8::String::new(scope, "var foo;\n//# sourceMappingURL=foo.js.map") @@ -8794,10 +8798,11 @@ fn no_source_map_comment() { resource_column_offset, resource_is_shared_cross_origin, script_id, - source_map_url.into(), + Some(source_map_url.into()), resource_is_opaque, is_wasm, is_module, + None, ); let code = v8::String::new(scope, "var foo;\n").unwrap(); let mut source = v8::script_compiler::Source::new(code, Some(&script_origin)); @@ -9112,7 +9117,6 @@ fn create_module<'s>( ) -> v8::Local<'s, v8::Module> { let source = v8::String::new(scope, source).unwrap(); let resource_name = v8::String::new(scope, "").unwrap(); - let source_map_url = v8::undefined(scope); let script_origin = v8::ScriptOrigin::new( scope, resource_name.into(), @@ -9120,10 +9124,11 @@ fn create_module<'s>( 0, false, 0, - source_map_url.into(), + None, false, false, true, + None, ); let has_cache = code_cache.is_some(); let mut source = match code_cache { @@ -9824,10 +9829,11 @@ fn current_script_name_or_source_url() { resource_column_offset, resource_is_shared_cross_origin, script_id, - source_map_url.into(), + Some(source_map_url.into()), resource_is_opaque, is_wasm, is_module, + None, ); let source = v8::String::new(scope, src).unwrap(); let script = @@ -11810,3 +11816,61 @@ fn string_valueview() { assert_eq!(view.data(), v8::ValueViewData::TwoByte(&[1, 0x1FF, 3])); } } + +#[test] +fn host_defined_options() { + let _setup_guard = setup::parallel_test(); + let mut isolate = v8::Isolate::new(Default::default()); + let mut scope = v8::HandleScope::new(&mut isolate); + let context = v8::Context::new(&mut scope); + let scope = &mut v8::ContextScope::new(&mut scope, context); + + let test = v8::Function::new( + scope, + |scope: &mut v8::HandleScope, + _: v8::FunctionCallbackArguments, + _: v8::ReturnValue| { + let host_defined_options = unsafe { + v8::Local::::cast_unchecked( + scope.get_current_host_defined_options().unwrap(), + ) + }; + let val = host_defined_options.get(scope, 0); + assert_eq!(val, v8::Number::new(scope, 42.5)); + }, + ) + .unwrap(); + let key = v8::String::new(scope, "test").unwrap(); + context + .global(scope) + .set(scope, key.into(), test.into()) + .unwrap(); + + let resource_name = v8::String::new(scope, "file.js").unwrap(); + let host_defined_options = v8::PrimitiveArray::new(scope, 1); + let value = v8::Number::new(scope, 42.5); + host_defined_options.set(scope, 0, value.into()); + let origin = v8::ScriptOrigin::new( + scope, + resource_name.into(), + 0, + 0, + false, + 0, + None, + false, + false, + false, + Some(host_defined_options.into()), + ); + let code = v8::String::new(scope, "test()").unwrap(); + let mut source = v8::script_compiler::Source::new(code, Some(&origin)); + let script = v8::script_compiler::compile( + scope, + &mut source, + v8::script_compiler::CompileOptions::EagerCompile, + v8::script_compiler::NoCacheReason::NoReason, + ) + .unwrap(); + script.run(scope).unwrap(); +}