From 42af31ff382aee1c8c371d7c35ffd6cba596b454 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 19 Jan 2020 00:38:41 +0100 Subject: [PATCH] Add Context::new_from_template() (#225) --- src/binding.cc | 9 ++++----- src/context.rs | 22 ++++++++++++++++++++-- tests/test_api.rs | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/binding.cc b/src/binding.cc index 7c0b1e3e..50f69cdf 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -767,11 +767,10 @@ void DeserializeInternalFields(v8::Local holder, int index, deserialized_data.push_back(embedder_field); } -v8::Context* v8__Context__New(v8::Isolate* isolate) { - // TODO: optional arguments. - return *v8::Context::New(isolate, nullptr, - v8::MaybeLocal(), - v8::MaybeLocal(), +v8::Context* v8__Context__New(v8::Isolate* isolate, + v8::MaybeLocal templ, + v8::MaybeLocal global_object) { + return *v8::Context::New(isolate, nullptr, templ, global_object, v8::DeserializeInternalFieldsCallback( DeserializeInternalFields, nullptr)); } diff --git a/src/context.rs b/src/context.rs index 8ba5a47b..2aea63e9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -3,10 +3,17 @@ use crate::isolate::Isolate; use crate::support::Opaque; use crate::Local; use crate::Object; +use crate::ObjectTemplate; use crate::ToLocal; +use crate::Value; +use std::ptr::null; extern "C" { - fn v8__Context__New(isolate: &Isolate) -> *mut Context; + fn v8__Context__New( + isolate: &Isolate, + templ: *const ObjectTemplate, + data: *const Value, + ) -> *mut Context; fn v8__Context__Enter(this: &mut Context); fn v8__Context__Exit(this: &mut Context); fn v8__Context__Global(this: *mut Context) -> *mut Object; @@ -18,9 +25,20 @@ extern "C" { pub struct Context(Opaque); impl Context { + /// Creates a new context. pub fn new<'sc>(scope: &mut impl ToLocal<'sc>) -> Local<'sc, Context> { // TODO: optional arguments; - let ptr = unsafe { v8__Context__New(scope.isolate()) }; + let ptr = unsafe { v8__Context__New(scope.isolate(), null(), null()) }; + unsafe { scope.to_local(ptr) }.unwrap() + } + + /// Creates a new context using the object template as the template for + /// the global object. + pub fn new_from_template<'sc>( + scope: &mut impl ToLocal<'sc>, + templ: Local, + ) -> Local<'sc, Context> { + let ptr = unsafe { v8__Context__New(scope.isolate(), &*templ, null()) }; unsafe { scope.to_local(ptr) }.unwrap() } diff --git a/tests/test_api.rs b/tests/test_api.rs index 7cb4f422..7870b14f 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -2247,3 +2247,26 @@ fn inspector_dispatch_protocol_message() { assert_eq!(channel.send_notification_count, 0); assert_eq!(channel.flush_protocol_notifications_count, 0); } + +#[test] +fn context_from_object_template() { + let _setup_guard = setup(); + let mut params = v8::Isolate::create_params(); + params.set_array_buffer_allocator(v8::new_default_allocator()); + let isolate = v8::Isolate::new(params); + let mut locker = v8::Locker::new(&isolate); + { + let mut hs = v8::HandleScope::new(&mut locker); + let scope = hs.enter(); + let object_templ = v8::ObjectTemplate::new(scope); + let function_templ = v8::FunctionTemplate::new(scope, fortytwo_callback); + let name = v8_str(scope, "f"); + object_templ.set(name.into(), function_templ.into()); + let context = v8::Context::new_from_template(scope, object_templ); + let mut cs = v8::ContextScope::new(scope, context); + let scope = cs.enter(); + let actual = eval(scope, context, "f()").unwrap(); + let expected = v8::Integer::new(scope, 42); + assert!(expected.strict_equals(actual)); + } +}