0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-12-24 08:09:16 -05:00

Move get_*_context() methods to scope::Entered, remove InContext trait (#279)

The `get_current_context()` and `get_entered_or_microtask_context()`
methods now return `Option<Local<Context>>` to reflect that an isolate
may not have entered any context.

They're also moved from `Isolate` to `struct Entered` because it turns
out that the underlying V8 API calls actually create new local handles,
hence they should only be used inside an active HandleScope.

The `InContext` trait has been removed.

A test exercising `ContextScope` and the `get_*_context()` methods
mentioned above was added.

Closes: #248.
This commit is contained in:
Bert Belder 2020-02-12 21:23:19 -08:00
parent ffdf69bd00
commit ddc8062644
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
8 changed files with 173 additions and 125 deletions

View file

@ -478,57 +478,68 @@ bool v8__Value__SameValue(const v8::Value& self, v8::Value* that) {
return self.SameValue(ptr_to_local(that)); return self.SameValue(ptr_to_local(that));
} }
v8::Uint32* v8__Value__ToUint32(const v8::Value& self, v8::Context* context) { v8::Uint32* v8__Value__ToUint32(const v8::Value& self,
return maybe_local_to_ptr(self.ToUint32(ptr_to_local(context))); v8::Local<v8::Context> context) {
return maybe_local_to_ptr(self.ToUint32(context));
} }
v8::Int32* v8__Value__ToInt32(const v8::Value& self, v8::Context* context) { v8::Int32* v8__Value__ToInt32(const v8::Value& self,
return maybe_local_to_ptr(self.ToInt32(ptr_to_local(context))); v8::Local<v8::Context> context) {
return maybe_local_to_ptr(self.ToInt32(context));
} }
v8::Integer* v8__Value__ToInteger(const v8::Value& self, v8::Context* context) { v8::Integer* v8__Value__ToInteger(const v8::Value& self,
return maybe_local_to_ptr(self.ToInteger(ptr_to_local(context))); v8::Local<v8::Context> context) {
return maybe_local_to_ptr(self.ToInteger(context));
} }
v8::BigInt* v8__Value__ToBigInt(const v8::Value& self, v8::Context* context) { v8::BigInt* v8__Value__ToBigInt(const v8::Value& self,
return maybe_local_to_ptr(self.ToBigInt(ptr_to_local(context))); v8::Local<v8::Context> context) {
return maybe_local_to_ptr(self.ToBigInt(context));
} }
v8::String* v8__Value__ToString(const v8::Value& self, v8::Context* context) { v8::String* v8__Value__ToString(const v8::Value& self,
return maybe_local_to_ptr(self.ToString(ptr_to_local(context))); v8::Local<v8::Context> context) {
return maybe_local_to_ptr(self.ToString(context));
} }
v8::String* v8__Value__ToDetailString(const v8::Value& self, v8::String* v8__Value__ToDetailString(const v8::Value& self,
v8::Context* context) { v8::Local<v8::Context> context) {
return maybe_local_to_ptr(self.ToDetailString(ptr_to_local(context))); return maybe_local_to_ptr(self.ToDetailString(context));
} }
v8::Number* v8__Value__ToNumber(const v8::Value& self, v8::Context* context) { v8::Number* v8__Value__ToNumber(const v8::Value& self,
return maybe_local_to_ptr(self.ToNumber(ptr_to_local(context))); v8::Local<v8::Context> context) {
return maybe_local_to_ptr(self.ToNumber(context));
} }
v8::Object* v8__Value__ToObject(const v8::Value& self, v8::Context* context) { v8::Object* v8__Value__ToObject(const v8::Value& self,
return maybe_local_to_ptr(self.ToObject(ptr_to_local(context))); v8::Local<v8::Context> context) {
return maybe_local_to_ptr(self.ToObject(context));
} }
void v8__Value__NumberValue(const v8::Value& self, v8::Context* context, void v8__Value__NumberValue(const v8::Value& self,
v8::Local<v8::Context> context,
v8::Maybe<double>* out) { v8::Maybe<double>* out) {
*out = self.NumberValue(ptr_to_local(context)); *out = self.NumberValue(context);
} }
void v8__Value__IntegerValue(const v8::Value& self, v8::Context* context, void v8__Value__IntegerValue(const v8::Value& self,
v8::Local<v8::Context> context,
v8::Maybe<int64_t>* out) { v8::Maybe<int64_t>* out) {
*out = self.IntegerValue(ptr_to_local(context)); *out = self.IntegerValue(context);
} }
void v8__Value__Uint32Value(const v8::Value& self, v8::Context* context, void v8__Value__Uint32Value(const v8::Value& self,
v8::Local<v8::Context> context,
v8::Maybe<uint32_t>* out) { v8::Maybe<uint32_t>* out) {
*out = self.Uint32Value(ptr_to_local(context)); *out = self.Uint32Value(context);
} }
void v8__Value__Int32Value(const v8::Value& self, v8::Context* context, void v8__Value__Int32Value(const v8::Value& self,
v8::Local<v8::Context> context,
v8::Maybe<int32_t>* out) { v8::Maybe<int32_t>* out) {
*out = self.Int32Value(ptr_to_local(context)); *out = self.Int32Value(context);
} }
v8::Primitive* v8__Null(v8::Isolate* isolate) { v8::Primitive* v8__Null(v8::Isolate* isolate) {

View file

@ -78,10 +78,6 @@ extern "C" {
fn v8__Isolate__GetNumberOfDataSlots(this: *const Isolate) -> u32; fn v8__Isolate__GetNumberOfDataSlots(this: *const Isolate) -> u32;
fn v8__Isolate__Enter(this: *mut Isolate); fn v8__Isolate__Enter(this: *mut Isolate);
fn v8__Isolate__Exit(this: *mut Isolate); fn v8__Isolate__Exit(this: *mut Isolate);
fn v8__Isolate__GetCurrentContext(this: *mut Isolate) -> *mut Context;
fn v8__Isolate__GetEnteredOrMicrotaskContext(
this: *mut Isolate,
) -> *mut Context;
fn v8__Isolate__SetCaptureStackTraceForUncaughtExceptions( fn v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(
this: *mut Isolate, this: *mut Isolate,
caputre: bool, caputre: bool,
@ -204,24 +200,6 @@ impl Isolate {
unsafe { v8__Isolate__Exit(self) } unsafe { v8__Isolate__Exit(self) }
} }
/// Returns the context of the currently running JavaScript, or the context
/// on the top of the stack if no JavaScript is running.
pub fn get_current_context<'sc>(&mut self) -> Local<'sc, Context> {
unsafe { Local::from_raw(v8__Isolate__GetCurrentContext(self)).unwrap() }
}
/// Returns either the last context entered through V8's C++ API, or the
/// context of the currently running microtask while processing microtasks.
/// If a context is entered while executing a microtask, that context is
/// returned.
pub fn get_entered_or_microtask_context<'sc>(
&mut self,
) -> Local<'sc, Context> {
unsafe {
Local::from_raw(v8__Isolate__GetEnteredOrMicrotaskContext(self)).unwrap()
}
}
/// Tells V8 to capture current stack trace when uncaught exception occurs /// Tells V8 to capture current stack trace when uncaught exception occurs
/// and report it to the message listeners. The option is off by default. /// and report it to the message listeners. The option is off by default.
pub fn set_capture_stack_trace_for_uncaught_exceptions( pub fn set_capture_stack_trace_for_uncaught_exceptions(

View file

@ -47,17 +47,14 @@
//! InIsolate which gives access to &mut Isolate is implemented for all scopes, //! InIsolate which gives access to &mut Isolate is implemented for all scopes,
//! ToLocal (I might rename that) is implemented for all Scopes in which new //! ToLocal (I might rename that) is implemented for all Scopes in which new
//! Local handles can be created and it sets the appropriate lifetime on them. //! Local handles can be created and it sets the appropriate lifetime on them.
//! InContext means that a context has been entered (I'll make sure they have a
//! get_context() method), etc.
//! //!
//! Furthermore, many callbacks will receive receive an appropriate Scope object //! Furthermore, many callbacks will receive receive an appropriate Scope object
//! as their first argument, which 'encodes' the the state the isolate is in //! as their first argument, which 'encodes' the the state the isolate is in
//! when the callback is called. E.g. a FunctionCallbackScope implements //! when the callback is called. E.g. a FunctionCallbackScope implements
//! InIsolate + InContext + (there is an active context) and ToLocal (it acts as //! InIsolate + and ToLocal (it acts as a HandleScope).
//! a handlescope). HostImportModuleDynamicallyScope would also implement //! HostImportModuleDynamicallyScope would also implement InIsolate plus
//! InIsolate + InContext plus EscapeLocal (it doesn't act like a HandleScope, //! EscapeLocal (it doesn't act like a HandleScope, but it lets you safely
//! but it lets you safely escape one MaybeLocal which is returned to the //! escape one MaybeLocal which is returned to the caller).
//! caller.
//! //!
//! In a nutshell, that's it. //! In a nutshell, that's it.
//! //!

View file

@ -141,20 +141,28 @@ where
} }
} }
pub trait InContext: InIsolate {} extern "C" {
impl<'s> InContext for Entered<'s, FunctionCallbackInfo, ()> {} fn v8__Isolate__GetCurrentContext(this: *mut Isolate) -> *mut Context;
impl<'s> InContext for Entered<'s, PropertyCallbackInfo, ()> {} fn v8__Isolate__GetEnteredOrMicrotaskContext(
impl<'s, X> InContext for Entered<'s, CallbackScope<X>> {} this: *mut Isolate,
impl<'s, P> InContext for Entered<'s, ContextScope, P> {} ) -> *mut Context;
impl<'s, P> InContext for Entered<'s, HandleScope, P> where P: InContext {} }
impl<'s, P> InContext for Entered<'s, EscapableHandleScope, P> where P: InContext
{}
/// When scope implements this trait, this means that Local handles can be /// When scope implements this trait, this means that Local handles can be
/// created inside it. /// created inside it.
pub trait ToLocal<'s>: InIsolate { pub trait ToLocal<'s>: InIsolate {
unsafe fn to_local<T>(&mut self, ptr: *mut T) -> Option<Local<'s, T>> { unsafe fn to_local<T>(&mut self, ptr: *mut T) -> Option<Local<'s, T>> {
crate::Local::<'s, T>::from_raw(ptr) Local::from_raw(ptr)
}
fn get_current_context(&mut self) -> Option<Local<'s, Context>> {
unsafe { Local::from_raw(v8__Isolate__GetCurrentContext(self.isolate())) }
}
fn get_entered_or_microtask_context(&mut self) -> Option<Local<'s, Context>> {
unsafe {
Local::from_raw(v8__Isolate__GetEnteredOrMicrotaskContext(self.isolate()))
}
} }
} }
@ -162,7 +170,10 @@ impl<'s> ToLocal<'s> for Entered<'s, FunctionCallbackInfo> {}
impl<'s> ToLocal<'s> for Entered<'s, PropertyCallbackInfo> {} impl<'s> ToLocal<'s> for Entered<'s, PropertyCallbackInfo> {}
impl<'s, P> ToLocal<'s> for Entered<'s, HandleScope, P> {} impl<'s, P> ToLocal<'s> for Entered<'s, HandleScope, P> {}
impl<'s, P> ToLocal<'s> for Entered<'s, EscapableHandleScope, P> {} impl<'s, P> ToLocal<'s> for Entered<'s, EscapableHandleScope, P> {}
impl<'s, P> ToLocal<'s> for Entered<'s, ContextScope, P> where P: ToLocal<'s> {} impl<'s, 'p: 's, P> ToLocal<'p> for Entered<'s, ContextScope, P> where
P: ToLocal<'p>
{
}
pub trait ToLocalOrReturnsLocal<'s>: InIsolate {} pub trait ToLocalOrReturnsLocal<'s>: InIsolate {}
impl<'s, E> ToLocalOrReturnsLocal<'s> for E where E: ToLocal<'s> {} impl<'s, E> ToLocalOrReturnsLocal<'s> for E where E: ToLocal<'s> {}
@ -213,10 +224,33 @@ where
} }
} }
impl<'s, 'p: 's, S, P> Entered<'s, S, P>
where
Self: ToLocal<'p>,
{
/// Returns the context of the currently running JavaScript, or the context
/// on the top of the stack if no JavaScript is running.
pub fn get_current_context(&mut self) -> Option<Local<'p, Context>> {
<Self as ToLocal<'p>>::get_current_context(self)
}
/// Returns either the last context entered through V8's C++ API, or the
/// context of the currently running microtask while processing microtasks.
/// If a context is entered while executing a microtask, that context is
/// returned.
pub fn get_entered_or_microtask_context(
&mut self,
) -> Option<Local<'p, Context>> {
<Self as ToLocal<'p>>::get_entered_or_microtask_context(self)
}
}
impl<'s, 'p: 's, S, P> Entered<'s, S, P> impl<'s, 'p: 's, S, P> Entered<'s, S, P>
where where
Self: EscapeLocal<'s, 'p>, Self: EscapeLocal<'s, 'p>,
{ {
/// Pushes the value into the previous scope and returns a handle to it.
/// Cannot be called twice.
pub fn escape<T>(&mut self, local: Local<T>) -> Local<'p, T> { pub fn escape<T>(&mut self, local: Local<T>) -> Local<'p, T> {
<Self as EscapeLocal<'s, 'p>>::escape(self, local) <Self as EscapeLocal<'s, 'p>>::escape(self, local)
} }

View file

@ -5,7 +5,6 @@ use std::ptr::null;
use crate::support::Opaque; use crate::support::Opaque;
use crate::Boolean; use crate::Boolean;
use crate::Context; use crate::Context;
use crate::InContext;
use crate::Integer; use crate::Integer;
use crate::Local; use crate::Local;
use crate::String; use crate::String;
@ -46,7 +45,7 @@ pub struct Script(Opaque);
impl Script { impl Script {
/// A shorthand for ScriptCompiler::Compile(). /// A shorthand for ScriptCompiler::Compile().
pub fn compile<'sc>( pub fn compile<'sc>(
scope: &mut (impl ToLocal<'sc> + InContext), scope: &mut impl ToLocal<'sc>,
mut context: Local<Context>, mut context: Local<Context>,
mut source: Local<String>, mut source: Local<String>,
origin: Option<&ScriptOrigin>, origin: Option<&ScriptOrigin>,

View file

@ -69,36 +69,39 @@ extern "C" {
fn v8__Value__StrictEquals(this: &Value, that: &Value) -> bool; fn v8__Value__StrictEquals(this: &Value, that: &Value) -> bool;
fn v8__Value__SameValue(this: &Value, that: &Value) -> bool; fn v8__Value__SameValue(this: &Value, that: &Value) -> bool;
fn v8__Value__ToBigInt(this: &Value, context: *mut Context) -> *mut BigInt; fn v8__Value__ToBigInt(this: &Value, context: Local<Context>) -> *mut BigInt;
fn v8__Value__ToNumber(this: &Value, context: *mut Context) -> *mut Number; fn v8__Value__ToNumber(this: &Value, context: Local<Context>) -> *mut Number;
fn v8__Value__ToString(this: &Value, context: *mut Context) -> *mut String; fn v8__Value__ToString(this: &Value, context: Local<Context>) -> *mut String;
fn v8__Value__ToDetailString( fn v8__Value__ToDetailString(
this: &Value, this: &Value,
context: *mut Context, context: Local<Context>,
) -> *mut String; ) -> *mut String;
fn v8__Value__ToObject(this: &Value, context: *mut Context) -> *mut Object; fn v8__Value__ToObject(this: &Value, context: Local<Context>) -> *mut Object;
fn v8__Value__ToInteger(this: &Value, context: *mut Context) -> *mut Integer; fn v8__Value__ToInteger(
fn v8__Value__ToUint32(this: &Value, context: *mut Context) -> *mut Uint32; this: &Value,
fn v8__Value__ToInt32(this: &Value, context: *mut Context) -> *mut Int32; context: Local<Context>,
) -> *mut Integer;
fn v8__Value__ToUint32(this: &Value, context: Local<Context>) -> *mut Uint32;
fn v8__Value__ToInt32(this: &Value, context: Local<Context>) -> *mut Int32;
fn v8__Value__NumberValue( fn v8__Value__NumberValue(
this: &Value, this: &Value,
context: *mut Context, context: Local<Context>,
out: *mut Maybe<f64>, out: *mut Maybe<f64>,
); );
fn v8__Value__IntegerValue( fn v8__Value__IntegerValue(
this: &Value, this: &Value,
context: *mut Context, context: Local<Context>,
out: *mut Maybe<i64>, out: *mut Maybe<i64>,
); );
fn v8__Value__Uint32Value( fn v8__Value__Uint32Value(
this: &Value, this: &Value,
context: *mut Context, context: Local<Context>,
out: *mut Maybe<u32>, out: *mut Maybe<u32>,
); );
fn v8__Value__Int32Value( fn v8__Value__Int32Value(
this: &Value, this: &Value,
context: *mut Context, context: Local<Context>,
out: *mut Maybe<i32>, out: *mut Maybe<i32>,
); );
} }
@ -396,112 +399,112 @@ impl Value {
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<Local<'sc, BigInt>> { ) -> Option<Local<'sc, BigInt>> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); Local::from_raw(v8__Value__ToBigInt(self, context))
unsafe { Local::from_raw(v8__Value__ToBigInt(self, &mut *context)) } })
} }
pub fn to_number<'sc>( pub fn to_number<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<Local<'sc, Number>> { ) -> Option<Local<'sc, Number>> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); Local::from_raw(v8__Value__ToNumber(self, context))
unsafe { Local::from_raw(v8__Value__ToNumber(self, &mut *context)) } })
} }
pub fn to_string<'sc>( pub fn to_string<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<Local<'sc, String>> { ) -> Option<Local<'sc, String>> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); Local::from_raw(v8__Value__ToString(self, context))
unsafe { Local::from_raw(v8__Value__ToString(self, &mut *context)) } })
} }
pub fn to_detail_string<'sc>( pub fn to_detail_string<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<Local<'sc, String>> { ) -> Option<Local<'sc, String>> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); Local::from_raw(v8__Value__ToDetailString(self, context))
unsafe { Local::from_raw(v8__Value__ToDetailString(self, &mut *context)) } })
} }
pub fn to_object<'sc>( pub fn to_object<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<Local<'sc, Object>> { ) -> Option<Local<'sc, Object>> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); Local::from_raw(v8__Value__ToObject(self, context))
unsafe { Local::from_raw(v8__Value__ToObject(self, &mut *context)) } })
} }
pub fn to_integer<'sc>( pub fn to_integer<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<Local<'sc, Integer>> { ) -> Option<Local<'sc, Integer>> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); Local::from_raw(v8__Value__ToInteger(self, context))
unsafe { Local::from_raw(v8__Value__ToInteger(self, &mut *context)) } })
} }
pub fn to_uint32<'sc>( pub fn to_uint32<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<Local<'sc, Uint32>> { ) -> Option<Local<'sc, Uint32>> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); Local::from_raw(v8__Value__ToUint32(self, context))
unsafe { Local::from_raw(v8__Value__ToUint32(self, &mut *context)) } })
} }
pub fn to_int32<'sc>( pub fn to_int32<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<Local<'sc, Int32>> { ) -> Option<Local<'sc, Int32>> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); Local::from_raw(v8__Value__ToInt32(self, context))
unsafe { Local::from_raw(v8__Value__ToInt32(self, &mut *context)) } })
} }
pub fn number_value<'sc>( pub fn number_value<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<f64> { ) -> Option<f64> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); let mut out = Maybe::<f64>::default();
let mut out = Maybe::<f64>::default(); v8__Value__NumberValue(self, context, &mut out);
unsafe { v8__Value__NumberValue(self, &mut *context, &mut out) }; out.into()
out.into() })
} }
pub fn integer_value<'sc>( pub fn integer_value<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<i64> { ) -> Option<i64> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); let mut out = Maybe::<i64>::default();
let mut out = Maybe::<i64>::default(); v8__Value__IntegerValue(self, context, &mut out);
unsafe { v8__Value__IntegerValue(self, &mut *context, &mut out) }; out.into()
out.into() })
} }
pub fn uint32_value<'sc>( pub fn uint32_value<'sc>(
&self, &self,
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
) -> Option<u32> { ) -> Option<u32> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); let mut out = Maybe::<u32>::default();
let mut out = Maybe::<u32>::default(); v8__Value__Uint32Value(self, context, &mut out);
unsafe { v8__Value__Uint32Value(self, &mut *context, &mut out) }; out.into()
out.into() })
} }
pub fn int32_value<'sc>(&self, scope: &mut impl ToLocal<'sc>) -> Option<i32> { pub fn int32_value<'sc>(&self, scope: &mut impl ToLocal<'sc>) -> Option<i32> {
let isolate = scope.isolate(); scope.get_current_context().and_then(|context| unsafe {
let mut context = isolate.get_current_context(); let mut out = Maybe::<i32>::default();
let mut out = Maybe::<i32>::default(); v8__Value__Int32Value(self, context, &mut out);
unsafe { v8__Value__Int32Value(self, &mut *context, &mut out) }; out.into()
out.into() })
} }
} }

View file

@ -14,5 +14,5 @@ error[E0277]: the trait bound `rusty_v8::scope::Entered<'_, rusty_v8::scope::Cal
<rusty_v8::scope::Entered<'s, rusty_v8::function::PropertyCallbackInfo> as rusty_v8::scope_traits::ToLocal<'s>> <rusty_v8::scope::Entered<'s, rusty_v8::function::PropertyCallbackInfo> as rusty_v8::scope_traits::ToLocal<'s>>
<rusty_v8::scope::Entered<'s, rusty_v8::handle_scope::EscapableHandleScope, P> as rusty_v8::scope_traits::ToLocal<'s>> <rusty_v8::scope::Entered<'s, rusty_v8::handle_scope::EscapableHandleScope, P> as rusty_v8::scope_traits::ToLocal<'s>>
<rusty_v8::scope::Entered<'s, rusty_v8::handle_scope::HandleScope, P> as rusty_v8::scope_traits::ToLocal<'s>> <rusty_v8::scope::Entered<'s, rusty_v8::handle_scope::HandleScope, P> as rusty_v8::scope_traits::ToLocal<'s>>
<rusty_v8::scope::Entered<'s, rusty_v8::scope::ContextScope, P> as rusty_v8::scope_traits::ToLocal<'s>> <rusty_v8::scope::Entered<'s, rusty_v8::scope::ContextScope, P> as rusty_v8::scope_traits::ToLocal<'p>>
= note: required because of the requirements on the impl of `rusty_v8::scope_traits::ToLocalOrReturnsLocal<'_>` for `rusty_v8::scope::Entered<'_, rusty_v8::scope::CallbackScope>` = note: required because of the requirements on the impl of `rusty_v8::scope_traits::ToLocalOrReturnsLocal<'_>` for `rusty_v8::scope::Entered<'_, rusty_v8::scope::CallbackScope>`

View file

@ -226,6 +226,32 @@ fn escapable_handle_scope() {
} }
} }
#[test]
fn context_scope() {
let _setup_guard = setup();
let mut params = v8::Isolate::create_params();
params.set_array_buffer_allocator(v8::new_default_allocator());
let mut isolate = v8::Isolate::new(params);
let mut hs = v8::HandleScope::new(&mut isolate);
let scope = hs.enter();
assert!(scope.get_current_context().is_none());
assert!(scope.get_entered_or_microtask_context().is_none());
{
let context = v8::Context::new(scope);
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
scope.get_current_context().unwrap();
scope.get_entered_or_microtask_context().unwrap();
}
assert!(scope.get_current_context().is_none());
assert!(scope.get_entered_or_microtask_context().is_none());
}
#[test] #[test]
fn microtasks() { fn microtasks() {
let _setup_guard = setup(); let _setup_guard = setup();
@ -378,7 +404,7 @@ fn v8_str<'sc>(
} }
fn eval<'sc>( fn eval<'sc>(
scope: &mut (impl v8::ToLocal<'sc> + v8::InContext), scope: &mut impl v8::ToLocal<'sc>,
context: v8::Local<v8::Context>, context: v8::Local<v8::Context>,
code: &'static str, code: &'static str,
) -> Option<v8::Local<'sc, v8::Value>> { ) -> Option<v8::Local<'sc, v8::Value>> {
@ -601,7 +627,7 @@ fn add_message_listener() {
let mut sc = v8::CallbackScope::new(message); let mut sc = v8::CallbackScope::new(message);
let mut sc = v8::HandleScope::new(sc.enter()); let mut sc = v8::HandleScope::new(sc.enter());
let scope = sc.enter(); let scope = sc.enter();
let context = scope.isolate().get_current_context(); let context = scope.get_current_context().unwrap();
let message_str = message.get(scope); let message_str = message.get(scope);
assert_eq!(message_str.to_rust_string_lossy(scope), "Uncaught foo"); assert_eq!(message_str.to_rust_string_lossy(scope), "Uncaught foo");
assert_eq!(Some(1), message.get_line_number(context)); assert_eq!(Some(1), message.get_line_number(context));
@ -1135,7 +1161,7 @@ fn object_set_accessor() {
key: v8::Local<v8::Name>, key: v8::Local<v8::Name>,
args: v8::PropertyCallbackArguments, args: v8::PropertyCallbackArguments,
mut rv: v8::ReturnValue| { mut rv: v8::ReturnValue| {
let context = scope.isolate().get_current_context(); let context = scope.get_current_context().unwrap();
let this = args.this(); let this = args.this();
let expected_key = v8::String::new(scope, "getter_key").unwrap(); let expected_key = v8::String::new(scope, "getter_key").unwrap();