Skip to content

Commit

Permalink
Upgrade to rusty_v8 0.7.0 (#6801)
Browse files Browse the repository at this point in the history
  • Loading branch information
piscisaureus committed Jul 18, 2020
1 parent aebea6b commit faa64ed
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 172 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion cli/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,11 @@ impl DenoInspector {
});

// Tell the inspector about the global context.
let context = core_state.global_context.get(scope).unwrap();
let context = core_state
.global_context
.as_ref()
.map(|context| v8::Local::new(scope, context))
.unwrap();
let context_name = v8::inspector::StringView::from(&b"global context"[..]);
self_.context_created(context, Self::CONTEXT_GROUP_ID, context_name);

Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ futures = { version = "0.3.5", features = ["thread-pool", "compat"] }
lazy_static = "1.4.0"
libc = "0.2.71"
log = "0.4.8"
rusty_v8 = "0.6.0"
rusty_v8 = "0.7.0"
serde_json = "1.0.55"
smallvec = "1.4.0"
url = "2.1.1"
Expand Down
113 changes: 63 additions & 50 deletions core/bindings.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.

use crate::CoreIsolate;
use crate::CoreIsolateState;
use crate::EsIsolate;
use crate::JSError;
use crate::ZeroCopyBuf;
Expand Down Expand Up @@ -236,9 +237,7 @@ pub extern "C" fn host_import_module_dynamically_callback(
let resolver = v8::PromiseResolver::new(scope).unwrap();
let promise = resolver.get_promise(scope);

let mut resolver_handle = v8::Global::new();
resolver_handle.set(scope, resolver);

let resolver_handle = v8::Global::new(scope, resolver);
{
let state_rc = EsIsolate::state(scope);
let mut state = state_rc.borrow_mut();
Expand Down Expand Up @@ -283,18 +282,13 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
match message.get_event() {
v8::PromiseRejectEvent::PromiseRejectWithNoHandler => {
let error = message.get_value();
let mut error_global = v8::Global::<v8::Value>::new();
error_global.set(scope, error);
let error_global = v8::Global::new(scope, error);
state
.pending_promise_exceptions
.insert(promise_id, error_global);
}
v8::PromiseRejectEvent::PromiseHandlerAddedAfterReject => {
if let Some(mut handle) =
state.pending_promise_exceptions.remove(&promise_id)
{
handle.reset(scope);
}
state.pending_promise_exceptions.remove(&promise_id);
}
v8::PromiseRejectEvent::PromiseRejectAfterResolved => {}
v8::PromiseRejectEvent::PromiseResolveAfterResolved => {
Expand Down Expand Up @@ -364,14 +358,17 @@ fn recv(
let state_rc = CoreIsolate::state(scope);
let mut state = state_rc.borrow_mut();

if !state.js_recv_cb.is_empty() {
let msg = v8::String::new(scope, "Deno.core.recv already called.").unwrap();
scope.throw_exception(msg.into());
return;
}
let cb = match v8::Local::<v8::Function>::try_from(args.get(0)) {
Ok(cb) => cb,
Err(err) => return throw_type_error(scope, err.to_string()),
};

let slot = match &mut state.js_recv_cb {
slot @ None => slot,
_ => return throw_type_error(scope, "Deno.core.recv() already called"),
};

let recv_fn = v8::Local::<v8::Function>::try_from(args.get(0)).unwrap();
state.js_recv_cb.set(scope, recv_fn);
slot.replace(v8::Global::new(scope, cb));
}

fn send(
Expand All @@ -391,7 +388,6 @@ fn send(

let state_rc = CoreIsolate::state(scope);
let mut state = state_rc.borrow_mut();
assert!(!state.global_context.is_empty());

let buf_iter = (1..args.length()).map(|idx| {
v8::Local::<v8::ArrayBufferView>::try_from(args.get(idx))
Expand Down Expand Up @@ -433,17 +429,22 @@ fn set_macrotask_callback(
let state_rc = CoreIsolate::state(scope);
let mut state = state_rc.borrow_mut();

if !state.js_macrotask_cb.is_empty() {
let msg =
v8::String::new(scope, "Deno.core.setMacrotaskCallback already called.")
.unwrap();
scope.throw_exception(msg.into());
return;
}
let cb = match v8::Local::<v8::Function>::try_from(args.get(0)) {
Ok(cb) => cb,
Err(err) => return throw_type_error(scope, err.to_string()),
};

let slot = match &mut state.js_macrotask_cb {
slot @ None => slot,
_ => {
return throw_type_error(
scope,
"Deno.core.setMacrotaskCallback() already called",
);
}
};

let macrotask_cb_fn =
v8::Local::<v8::Function>::try_from(args.get(0)).unwrap();
state.js_macrotask_cb.set(scope, macrotask_cb_fn);
slot.replace(v8::Global::new(scope, cb));
}

fn eval_context(
Expand Down Expand Up @@ -668,18 +669,23 @@ fn shared_getter(
) {
let state_rc = CoreIsolate::state(scope);
let mut state = state_rc.borrow_mut();
let CoreIsolateState {
shared_ab, shared, ..
} = &mut *state;

// Lazily initialize the persistent external ArrayBuffer.
if state.shared_ab.is_empty() {
let ab = v8::SharedArrayBuffer::with_backing_store(
scope,
state.shared.get_backing_store(),
);
state.shared_ab.set(scope, ab);
}

let shared_ab = state.shared_ab.get(scope).unwrap();
rv.set(shared_ab.into());
let shared_ab = match shared_ab {
Some(ref ab) => v8::Local::new(scope, ab),
slot @ None => {
let ab = v8::SharedArrayBuffer::with_backing_store(
scope,
shared.get_backing_store(),
);
slot.replace(v8::Global::new(scope, ab));
ab
}
};
rv.set(shared_ab.into())
}

pub fn module_resolve_callback<'s>(
Expand Down Expand Up @@ -709,19 +715,17 @@ pub fn module_resolve_callback<'s>(

if req_str == specifier_str {
let id = state.module_resolve_cb(&req_str, referrer_id);
let maybe_info = state.modules.get_info(id);

if maybe_info.is_none() {
let msg = format!(
"Cannot resolve module \"{}\" from \"{}\"",
req_str, referrer_name
);
let msg = v8::String::new(scope, &msg).unwrap();
scope.throw_exception(msg.into());
break;
match state.modules.get_info(id) {
Some(info) => return Some(v8::Local::new(scope, &info.handle)),
None => {
let msg = format!(
r#"Cannot resolve module "{}" from "{}""#,
req_str, referrer_name
);
throw_type_error(scope, msg);
return None;
}
}

return maybe_info.and_then(|i| i.handle.get(scope));
}
}

Expand Down Expand Up @@ -775,3 +779,12 @@ fn get_promise_details(
}
}
}

fn throw_type_error<'s>(
scope: &mut v8::HandleScope<'s>,
message: impl AsRef<str>,
) {
let message = v8::String::new(scope, message.as_ref()).unwrap();
let exception = v8::Exception::type_error(scope, message);
scope.throw_exception(exception);
}
78 changes: 34 additions & 44 deletions core/core_isolate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ pub struct CoreIsolate {
/// embedder slots.
pub struct CoreIsolateState {
pub resource_table: Rc<RefCell<ResourceTable>>,
pub global_context: v8::Global<v8::Context>,
pub(crate) shared_ab: v8::Global<v8::SharedArrayBuffer>,
pub(crate) js_recv_cb: v8::Global<v8::Function>,
pub(crate) js_macrotask_cb: v8::Global<v8::Function>,
pub global_context: Option<v8::Global<v8::Context>>,
pub(crate) shared_ab: Option<v8::Global<v8::SharedArrayBuffer>>,
pub(crate) js_recv_cb: Option<v8::Global<v8::Function>>,
pub(crate) js_macrotask_cb: Option<v8::Global<v8::Function>>,
pub(crate) pending_promise_exceptions: HashMap<i32, v8::Global<v8::Value>>,
pub(crate) js_error_create_fn: Box<JSErrorCreateFn>,
pub(crate) shared: SharedQueue,
Expand Down Expand Up @@ -177,7 +177,7 @@ impl CoreIsolate {
StartupData::None => (None, None),
};

let mut global_context = v8::Global::<v8::Context>::new();
let global_context;
let (mut isolate, maybe_snapshot_creator) = if will_snapshot {
// TODO(ry) Support loading snapshots before snapshotting.
assert!(startup_snapshot.is_none());
Expand All @@ -188,7 +188,7 @@ impl CoreIsolate {
{
let scope = &mut v8::HandleScope::new(&mut isolate);
let context = bindings::initialize_context(scope);
global_context.set(scope, context);
global_context = v8::Global::new(scope, context);
creator.set_default_context(context);
}
(isolate, Some(creator))
Expand Down Expand Up @@ -217,18 +217,18 @@ impl CoreIsolate {
// main source code and source maps.
bindings::initialize_context(scope)
};
global_context.set(scope, context);
global_context = v8::Global::new(scope, context);
}
(isolate, None)
};

isolate.set_slot(Rc::new(RefCell::new(CoreIsolateState {
global_context,
global_context: Some(global_context),
resource_table: Rc::new(RefCell::new(ResourceTable::default())),
pending_promise_exceptions: HashMap::new(),
shared_ab: v8::Global::<v8::SharedArrayBuffer>::new(),
js_recv_cb: v8::Global::<v8::Function>::new(),
js_macrotask_cb: v8::Global::<v8::Function>::new(),
shared_ab: None,
js_recv_cb: None,
js_macrotask_cb: None,
js_error_create_fn: Box::new(JSError::create),
shared: SharedQueue::new(RECOMMENDED_SIZE),
pending_ops: FuturesUnordered::new(),
Expand Down Expand Up @@ -285,9 +285,10 @@ impl CoreIsolate {
let state_rc = Self::state(self);
let state = state_rc.borrow();

let scope = &mut v8::HandleScope::new(self.v8_isolate.as_mut().unwrap());
let context = state.global_context.get(scope).unwrap();
let scope = &mut v8::ContextScope::new(scope, context);
let scope = &mut v8::HandleScope::with_context(
self.v8_isolate.as_mut().unwrap(),
state.global_context.as_ref().unwrap(),
);

drop(state);

Expand Down Expand Up @@ -326,13 +327,8 @@ impl CoreIsolate {
let state = Self::state(self);

// Note: create_blob() method must not be called from within a HandleScope.
// The HandleScope created here is exited at the end of the block.
// TODO(piscisaureus): The rusty_v8 type system should enforce this.
{
let v8_isolate = self.v8_isolate.as_mut().unwrap();
let scope = &mut v8::HandleScope::new(v8_isolate);
state.borrow_mut().global_context.reset(scope);
}
state.borrow_mut().global_context.take();

let snapshot_creator = self.snapshot_creator.as_mut().unwrap();
let snapshot = snapshot_creator
Expand Down Expand Up @@ -372,12 +368,10 @@ impl Future for CoreIsolate {
state.waker.register(cx.waker());
}

let scope = &mut v8::HandleScope::new(&mut **core_isolate);
let context = {
let state = state_rc.borrow();
state.global_context.get(scope).unwrap()
};
let scope = &mut v8::ContextScope::new(scope, context);
let scope = &mut v8::HandleScope::with_context(
&mut **core_isolate,
state_rc.borrow().global_context.as_ref().unwrap(),
);

check_promise_exceptions(scope)?;

Expand Down Expand Up @@ -528,15 +522,12 @@ fn async_op_response<'s>(
) -> Result<(), ErrBox> {
let context = scope.get_current_context();
let global: v8::Local<v8::Value> = context.global(scope).into();

let state_rc = CoreIsolate::state(scope);
let state = state_rc.borrow_mut();

let js_recv_cb = state
let js_recv_cb = CoreIsolate::state(scope)
.borrow()
.js_recv_cb
.get(scope)
.as_ref()
.map(|cb| v8::Local::new(scope, cb))
.expect("Deno.core.recv has not been called.");
drop(state);

let tc_scope = &mut v8::TryCatch::new(scope);

Expand All @@ -561,22 +552,21 @@ fn drain_macrotasks<'s>(scope: &mut v8::HandleScope<'s>) -> Result<(), ErrBox> {
let context = scope.get_current_context();
let global: v8::Local<v8::Value> = context.global(scope).into();

let js_macrotask_cb = {
let state_rc = CoreIsolate::state(scope);
let state = state_rc.borrow_mut();
state.js_macrotask_cb.get(scope)
let js_macrotask_cb = match CoreIsolate::state(scope)
.borrow_mut()
.js_macrotask_cb
.as_ref()
{
Some(cb) => v8::Local::new(scope, cb),
None => return Ok(()),
};
if js_macrotask_cb.is_none() {
return Ok(());
}
let js_macrotask_cb = js_macrotask_cb.unwrap();

// Repeatedly invoke macrotask callback until it returns true (done),
// such that ready microtasks would be automatically run before
// next macrotask is processed.
loop {
let tc_scope = &mut v8::TryCatch::new(scope);
let tc_scope = &mut v8::TryCatch::new(scope);

loop {
let is_done = js_macrotask_cb.call(tc_scope, global, &[]);

if let Some(exception) = tc_scope.exception() {
Expand Down Expand Up @@ -641,7 +631,7 @@ fn check_promise_exceptions<'s>(
if let Some(&key) = state.pending_promise_exceptions.keys().next() {
let handle = state.pending_promise_exceptions.remove(&key).unwrap();
drop(state);
let exception = handle.get(scope).expect("empty error handle");
let exception = v8::Local::new(scope, handle);
exception_to_err_result(scope, exception)
} else {
Ok(())
Expand Down
9 changes: 6 additions & 3 deletions core/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,12 +378,15 @@ impl ErrWithV8Handle {
err: ErrBox,
handle: v8::Local<v8::Value>,
) -> Self {
let handle = v8::Global::new_from(scope, handle);
let handle = v8::Global::new(scope, handle);
Self { err, handle }
}

pub fn get_handle(&self) -> &v8::Global<v8::Value> {
&self.handle
pub fn get_handle<'s>(
&self,
scope: &mut v8::HandleScope<'s>,
) -> v8::Local<'s, v8::Value> {
v8::Local::new(scope, &self.handle)
}
}

Expand Down
Loading

0 comments on commit faa64ed

Please sign in to comment.