diff --git a/moli-v8-test-util/tests/object_template_bindings.rs b/moli-v8-test-util/tests/object_template_bindings.rs index 36e8eb49d..9f813170c 100644 --- a/moli-v8-test-util/tests/object_template_bindings.rs +++ b/moli-v8-test-util/tests/object_template_bindings.rs @@ -6,6 +6,30 @@ fn eval<'s>(scope: &mut v8::PinScope<'s, '_>, source: &str) -> v8::Local<'s, v8: script.run(scope).expect("test source should run") } +fn return_42( + _scope: &mut v8::PinScope<'_, '_>, + _args: v8::FunctionCallbackArguments<'_>, + mut rv: v8::ReturnValue, +) { + rv.set_int32(42); +} + +fn record_setter_value( + scope: &mut v8::PinScope<'_, '_>, + args: v8::FunctionCallbackArguments<'_>, + _rv: v8::ReturnValue, +) { + let key = v8::String::new(scope, "setterValue").unwrap(); + assert_eq!(args.this().set(scope, key.into(), args.get(0)), Some(true)); +} + +fn empty_constructor( + _scope: &mut v8::PinScope<'_, '_>, + _args: v8::FunctionCallbackArguments<'_>, + _rv: v8::ReturnValue, +) { +} + unsafe extern "C" fn deny_cross_context_access( _accessing_context: v8::Local<'_, v8::Context>, _accessed_object: v8::Local<'_, v8::Object>, @@ -149,3 +173,81 @@ JSON.stringify([ "[false,false,true,true]" ); } + +#[test] +fn nullable_object_and_function_template_handles_remain_empty_v8_locals() { + moli_v8_test_util::ensure_v8(); + let mut isolate = v8::Isolate::new(v8::CreateParams::default()); + let scope = pin!(v8::HandleScope::new(&mut isolate)); + let scope = &mut scope.init(); + let context = v8::Context::new(scope, Default::default()); + let scope = &mut v8::ContextScope::new(scope, context); + + let getter = v8::FunctionTemplate::new(scope, return_42); + let setter = v8::FunctionTemplate::new(scope, record_setter_value); + + let object_template = v8::ObjectTemplate::new(scope); + let getter_only = v8::String::new(scope, "getterOnly").unwrap(); + object_template.set_accessor_property( + getter_only.into(), + Some(getter), + None, + v8::PropertyAttribute::NONE, + ); + let setter_only = v8::String::new(scope, "setterOnly").unwrap(); + object_template.set_accessor_property( + setter_only.into(), + None, + Some(setter), + v8::PropertyAttribute::NONE, + ); + let object = object_template + .new_instance(scope) + .expect("object template with nullable accessors should instantiate"); + let object_name = v8::String::new(scope, "object").unwrap(); + assert_eq!( + context + .global(scope) + .set(scope, object_name.into(), object.into()), + Some(true) + ); + + let function_template = v8::FunctionTemplate::new(scope, empty_constructor); + let getter_only = v8::String::new(scope, "getterOnly").unwrap(); + function_template.set_accessor_property( + getter_only.into(), + Some(getter), + None, + v8::PropertyAttribute::NONE, + ); + let setter_only = v8::String::new(scope, "setterOnly").unwrap(); + function_template.set_accessor_property( + setter_only.into(), + None, + Some(setter), + v8::PropertyAttribute::NONE, + ); + let function = function_template + .get_function(scope) + .expect("function template with nullable accessors should instantiate"); + let function_name = v8::String::new(scope, "TemplateFunction").unwrap(); + assert_eq!( + context + .global(scope) + .set(scope, function_name.into(), function.into()), + Some(true) + ); + + let result = eval( + scope, + r#" +JSON.stringify([ + object.getterOnly, + (object.setterOnly = 7, object.setterValue), + TemplateFunction.getterOnly, + (TemplateFunction.setterOnly = 9, TemplateFunction.setterValue) +]) +"#, + ); + assert_eq!(result.to_rust_string_lossy(scope), "[42,7,42,9]"); +} diff --git a/vendor/v8-152.2.0/src/binding.cc b/vendor/v8-152.2.0/src/binding.cc index bf44a8e2e..3090f1c52 100644 --- a/vendor/v8-152.2.0/src/binding.cc +++ b/vendor/v8-152.2.0/src/binding.cc @@ -1487,8 +1487,8 @@ void v8__Template__SetIntrinsicDataProperty(const v8::Template& self, } const v8::ObjectTemplate* v8__ObjectTemplate__New( - v8::Isolate* isolate, const v8::FunctionTemplate& templ) { - return local_to_ptr(v8::ObjectTemplate::New(isolate, ptr_to_local(&templ))); + v8::Isolate* isolate, const v8::FunctionTemplate* templ) { + return local_to_ptr(v8::ObjectTemplate::New(isolate, ptr_to_local(templ))); } const v8::Object* v8__ObjectTemplate__NewInstance( @@ -1545,11 +1545,11 @@ void v8__ObjectTemplate__SetIndexedPropertyHandler( void v8__ObjectTemplate__SetAccessorProperty(const v8::ObjectTemplate& self, const v8::Name& key, - v8::FunctionTemplate& getter, - v8::FunctionTemplate& setter, + const v8::FunctionTemplate* getter, + const v8::FunctionTemplate* setter, v8::PropertyAttribute attr) { ptr_to_local(&self)->SetAccessorProperty( - ptr_to_local(&key), ptr_to_local(&getter), ptr_to_local(&setter), attr); + ptr_to_local(&key), ptr_to_local(getter), ptr_to_local(setter), attr); } void v8__ObjectTemplate__SetImmutableProto(const v8::ObjectTemplate& self) { @@ -2544,11 +2544,11 @@ void v8__FunctionTemplate__SetClassName(const v8::FunctionTemplate& self, void v8__FunctionTemplate__SetAccessorProperty(const v8::FunctionTemplate& self, const v8::Name& key, - v8::FunctionTemplate& getter, - v8::FunctionTemplate& setter, + const v8::FunctionTemplate* getter, + const v8::FunctionTemplate* setter, v8::PropertyAttribute attr) { ptr_to_local(&self)->SetAccessorProperty( - ptr_to_local(&key), ptr_to_local(&getter), ptr_to_local(&setter), attr); + ptr_to_local(&key), ptr_to_local(getter), ptr_to_local(setter), attr); } void v8__FunctionTemplate__Inherit(const v8::FunctionTemplate& self,