1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

Upgrade to rusty_v8 v0.1.1 (#3741)

This commit is contained in:
Bert Belder 2020-01-21 20:24:31 +01:00
parent fa7f34eb8c
commit 8c3cd634a8
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
6 changed files with 149 additions and 152 deletions

6
Cargo.lock generated
View file

@ -303,7 +303,7 @@ dependencies = [
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rusty_v8 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rusty_v8 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1155,7 +1155,7 @@ dependencies = [
[[package]]
name = "rusty_v8"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1906,7 +1906,7 @@ dependencies = [
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e"
"checksum rustls-native-certs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51ffebdbb48c14f84eba0b715197d673aff1dd22cc1007ca647e28483bbcc307"
"checksum rusty_v8 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0acbe68bf184bc575f1f33294e74d37d5cd6d28e5857cb7b5501c17575decda"
"checksum rusty_v8 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d0a2e0cf49117db64379701eb50d12ab9ec3ca8292047f140c13c5174599441"
"checksum rustyline 5.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a23cb19702a8d6afb6edb3c842386e680d4883760e0df74e6848e23c2a87a635"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021"

View file

@ -21,7 +21,7 @@ libc = "0.2.66"
log = "0.4.8"
serde_json = "1.0.44"
url = "2.1.0"
rusty_v8 = "=0.1.0"
rusty_v8 = "0.1.1"
[[example]]
name = "deno_core_http_bench"

View file

@ -6,10 +6,8 @@ use crate::isolate::PinnedBuf;
use crate::isolate::SHARED_RESPONSE_BUF_SIZE;
use rusty_v8 as v8;
use v8::InIsolate;
use v8::MapFnTo;
use libc::c_void;
use std::convert::TryFrom;
use std::option::Option;
use std::ptr;
@ -95,16 +93,19 @@ pub fn module_origin<'a>(
)
}
pub fn initialize_context<'a>(
scope: &mut impl v8::ToLocal<'a>,
mut context: v8::Local<v8::Context>,
) {
context.enter();
pub fn initialize_context<'s>(
scope: &mut impl v8::ToLocal<'s>,
) -> v8::Local<'s, v8::Context> {
let mut hs = v8::EscapableHandleScope::new(scope);
let scope = hs.enter();
let context = v8::Context::new(scope);
let global = context.global(scope);
let deno_val = v8::Object::new(scope);
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let deno_val = v8::Object::new(scope);
global.set(
context,
v8::String::new(scope, "Deno").unwrap().into(),
@ -112,7 +113,6 @@ pub fn initialize_context<'a>(
);
let mut core_val = v8::Object::new(scope);
deno_val.set(
context,
v8::String::new(scope, "core").unwrap().into(),
@ -178,7 +178,7 @@ pub fn initialize_context<'a>(
queue_microtask_val.into(),
);
context.exit();
scope.escape(context)
}
pub unsafe fn slice_to_uint8array<'sc>(
@ -221,7 +221,7 @@ pub extern "C" fn host_import_module_dynamically_callback(
referrer: v8::Local<v8::ScriptOrModule>,
specifier: v8::Local<v8::String>,
) -> *mut v8::Promise {
let mut cbs = v8::CallbackScope::new(context);
let mut cbs = v8::CallbackScope::new_escapable(context);
let mut hs = v8::EscapableHandleScope::new(cbs.enter());
let scope = hs.enter();
let isolate = scope.isolate();
@ -307,7 +307,7 @@ pub extern "C" fn message_callback(
// TerminateExecution was called
if scope.isolate().is_execution_terminating() {
let u = v8::new_undefined(scope);
let u = v8::undefined(scope);
deno_isolate.handle_exception(scope, context, u.into());
return;
}
@ -324,8 +324,9 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
let deno_isolate: &mut Isolate =
unsafe { &mut *(scope.isolate().get_data(0) as *mut Isolate) };
let mut context = deno_isolate.global_context.get(scope).unwrap();
context.enter();
let context = deno_isolate.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let promise = message.get_promise();
let promise_id = promise.get_identity_hash();
@ -351,8 +352,6 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
// Should not warn. See #1272
}
};
context.exit();
}
fn print(
@ -465,7 +464,7 @@ fn eval_context(
Ok(s) => s,
Err(_) => {
let msg = v8::String::new(scope, "Invalid argument").unwrap();
let exception = v8::type_error(scope, msg);
let exception = v8::Exception::type_error(scope, msg);
scope.isolate().throw_exception(exception);
return;
}
@ -494,7 +493,7 @@ fn eval_context(
output.set(
context,
v8::Integer::new(scope, 0).into(),
v8::new_null(scope).into(),
v8::null(scope).into(),
);
let errinfo_obj = v8::Object::new(scope);
@ -535,7 +534,7 @@ fn eval_context(
output.set(
context,
v8::Integer::new(scope, 0).into(),
v8::new_null(scope).into(),
v8::null(scope).into(),
);
let errinfo_obj = v8::Object::new(scope);
@ -577,7 +576,7 @@ fn eval_context(
output.set(
context,
v8::Integer::new(scope, 1).into(),
v8::new_null(scope).into(),
v8::null(scope).into(),
);
rv.set(output.into());
}
@ -591,11 +590,7 @@ fn error_to_json(
unsafe { &mut *(scope.isolate().get_data(0) as *mut Isolate) };
let context = deno_isolate.global_context.get(scope).unwrap();
// TODO(piscisaureus): This is transmute necessary because of a bug in
// rusty_v8's implementation of `v8::create_message()`, which needs to be
// fixed.
let exception = unsafe { std::mem::transmute(args.get(0)) };
let message = v8::create_message(scope, exception);
let message = v8::Exception::create_message(scope, args.get(0));
let json_obj = encode_message_as_object(scope, context, message);
let json_string = v8::json::stringify(context, json_obj.into()).unwrap();
@ -611,7 +606,7 @@ fn queue_microtask(
Ok(f) => scope.isolate().enqueue_microtask(f),
Err(_) => {
let msg = v8::String::new(scope, "Invalid argument").unwrap();
let exception = v8::type_error(scope, msg);
let exception = v8::Exception::type_error(scope, msg);
scope.isolate().throw_exception(exception);
}
};
@ -628,15 +623,10 @@ fn shared_getter(
// Lazily initialize the persistent external ArrayBuffer.
if deno_isolate.shared_ab.is_empty() {
let data_ptr = deno_isolate.shared.bytes.as_ptr();
let data_len = deno_isolate.shared.bytes.len();
let ab = unsafe {
v8::SharedArrayBuffer::new_DEPRECATED(
scope,
data_ptr as *mut c_void,
data_len,
)
};
let ab = v8::SharedArrayBuffer::new_with_backing_store(
scope,
deno_isolate.shared.get_backing_store(),
);
deno_isolate.shared_ab.set(scope, ab);
}
@ -649,7 +639,7 @@ pub fn module_resolve_callback<'s>(
specifier: v8::Local<'s, v8::String>,
referrer: v8::Local<'s, v8::Module>,
) -> Option<v8::Local<'s, v8::Module>> {
let mut scope = v8::CallbackScope::new(context);
let mut scope = v8::CallbackScope::new_escapable(context);
let mut scope = v8::EscapableHandleScope::new(scope.enter());
let scope = scope.enter();

View file

@ -87,7 +87,7 @@ impl Drop for EsIsolate {
// Clear persistent handles we own.
{
let mut locker = v8::Locker::new(&isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
for module in self.modules.info.values_mut() {
module.handle.reset(scope);
@ -142,11 +142,12 @@ impl EsIsolate {
let isolate = self.core_isolate.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(&isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
assert!(!self.core_isolate.global_context.is_empty());
let mut context = self.core_isolate.global_context.get(scope).unwrap();
context.enter();
let context = self.core_isolate.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let name_str = v8::String::new(scope, name).unwrap();
let source_str = v8::String::new(scope, source).unwrap();
@ -166,7 +167,6 @@ impl EsIsolate {
context,
tc.exception().unwrap(),
);
context.exit();
return 0;
}
let module = maybe_module.unwrap();
@ -183,7 +183,6 @@ impl EsIsolate {
self
.modules
.register(id, name, main, handle, import_specifiers);
context.exit();
id
}
@ -203,18 +202,17 @@ impl EsIsolate {
fn mod_instantiate2(&mut self, id: ModuleId) {
let isolate = self.core_isolate.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
assert!(!self.core_isolate.global_context.is_empty());
let mut context = self.core_isolate.global_context.get(scope).unwrap();
context.enter();
let mut try_catch = v8::TryCatch::new(scope);
let context = self.core_isolate.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let mut try_catch = v8::TryCatch::new(cs.enter());
let tc = try_catch.enter();
let maybe_info = self.modules.get_info(id);
if maybe_info.is_none() {
context.exit();
return;
}
@ -222,7 +220,6 @@ impl EsIsolate {
let mut module = module_handle.get(scope).unwrap();
if module.get_status() == v8::ModuleStatus::Errored {
context.exit();
return;
}
@ -237,8 +234,6 @@ impl EsIsolate {
tc.exception().unwrap(),
);
}
context.exit();
}
/// Instanciates a ES module
@ -254,11 +249,12 @@ impl EsIsolate {
fn mod_evaluate2(&mut self, id: ModuleId) {
let isolate = self.core_isolate.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
assert!(!self.core_isolate.global_context.is_empty());
let mut context = self.core_isolate.global_context.get(scope).unwrap();
context.enter();
let context = self.core_isolate.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let info = self.modules.get_info(id).expect("ModuleInfo not found");
let mut module = info.handle.get(scope).expect("Empty module handle");
@ -292,8 +288,6 @@ impl EsIsolate {
}
other => panic!("Unexpected module status {:?}", other),
};
context.exit();
}
/// Evaluates an already instantiated ES module.
@ -353,11 +347,13 @@ impl EsIsolate {
);
let isolate = self.core_isolate.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
assert!(!self.core_isolate.global_context.is_empty());
let mut context = self.core_isolate.global_context.get(scope).unwrap();
context.enter();
let context = self.core_isolate.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let mut resolver_handle = self
.dyn_import_map
.remove(&id)
@ -367,7 +363,7 @@ impl EsIsolate {
// Resolution error.
if let Some(error_str) = error {
let msg = v8::String::new(scope, &error_str).unwrap();
let e = v8::type_error(scope, msg);
let e = v8::Exception::type_error(scope, msg);
resolver.reject(context, e).unwrap();
} else {
let e = self.core_isolate.last_exception_handle.get(scope).unwrap();
@ -375,8 +371,8 @@ impl EsIsolate {
self.core_isolate.last_exception.take();
resolver.reject(context, e).unwrap();
}
isolate.run_microtasks();
context.exit();
scope.isolate().run_microtasks();
self.core_isolate.check_last_exception()
}
@ -389,11 +385,13 @@ impl EsIsolate {
assert!(mod_id != 0);
let isolate = self.core_isolate.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
assert!(!self.core_isolate.global_context.is_empty());
let mut context = self.core_isolate.global_context.get(scope).unwrap();
context.enter();
let context = self.core_isolate.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let mut resolver_handle = self
.dyn_import_map
.remove(&id)
@ -409,8 +407,7 @@ impl EsIsolate {
assert_eq!(module.get_status(), v8::ModuleStatus::Evaluated);
let module_namespace = module.get_module_namespace();
resolver.resolve(context, module_namespace).unwrap();
isolate.run_microtasks();
context.exit();
scope.isolate().run_microtasks();
self.core_isolate.check_last_exception()
}

View file

@ -200,7 +200,7 @@ impl Drop for Isolate {
// Clear persistent handles we own.
{
let mut locker = v8::Locker::new(&isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
// </Boilerplate>
self.global_context.reset(scope);
@ -232,7 +232,7 @@ static DENO_INIT: Once = Once::new();
#[allow(clippy::missing_safety_doc)]
pub unsafe fn v8_init() {
let platform = v8::platform::new_default_platform();
let platform = v8::new_default_platform();
v8::V8::initialize_platform(platform);
v8::V8::initialize();
// TODO(ry) This makes WASM compile synchronously. Eventually we should
@ -282,16 +282,14 @@ impl Isolate {
let isolate = Isolate::setup_isolate(isolate);
let mut locker = v8::Locker::new(&isolate);
{
let mut hs = v8::HandleScope::new(&mut locker);
let scope = hs.enter();
let context = v8::Context::new(scope);
// context.enter();
global_context.set(scope, context);
creator.set_default_context(context);
bindings::initialize_context(scope, context);
// context.exit();
}
let scope = locker.enter();
let mut hs = v8::HandleScope::new(scope);
let scope = hs.enter();
let context = bindings::initialize_context(scope);
global_context.set(scope, context);
creator.set_default_context(context);
(isolate, Some(creator))
} else {
@ -302,23 +300,25 @@ impl Isolate {
params.set_snapshot_blob(snapshot);
}
let load_snapshot_is_null = load_snapshot.is_none();
let isolate = v8::Isolate::new(params);
let isolate = Isolate::setup_isolate(isolate);
{
let mut locker = v8::Locker::new(&isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let scope = hs.enter();
let context = v8::Context::new(scope);
let mut locker = v8::Locker::new(&isolate);
let scope = locker.enter();
if load_snapshot_is_null {
let mut hs = v8::HandleScope::new(scope);
let scope = hs.enter();
let context = match load_snapshot {
Some(_) => v8::Context::new(scope),
None => {
// If no snapshot is provided, we initialize the context with empty
// main source code and source maps.
bindings::initialize_context(scope, context);
bindings::initialize_context(scope)
}
global_context.set(scope, context);
}
};
global_context.set(scope, context);
(isolate, None)
};
@ -374,7 +374,7 @@ impl Isolate {
pub fn clear_exception(&mut self) {
let isolate = self.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
self.last_exception_handle.reset(scope);
self.last_exception.take();
@ -395,7 +395,7 @@ impl Isolate {
let exception = if exception.is_null_or_undefined() {
let exception_str =
v8::String::new(scope, "execution terminated").unwrap();
v8::error(scope, exception_str)
v8::Exception::error(scope, exception_str)
} else {
exception
};
@ -419,7 +419,7 @@ impl Isolate {
context: v8::Local<'a, v8::Context>,
exception: v8::Local<'a, v8::Value>,
) -> String {
let message = v8::create_message(scope, exception);
let message = v8::Exception::create_message(scope, exception);
self.encode_message_as_json(scope, context, message)
}
@ -434,15 +434,6 @@ impl Isolate {
json_string.to_rust_string_lossy(s)
}
#[allow(dead_code)]
pub fn run_microtasks(&mut self) {
let isolate = self.v8_isolate.as_mut().unwrap();
let _locker = v8::Locker::new(isolate);
isolate.enter();
isolate.run_microtasks();
isolate.exit();
}
// TODO(bartlomieju): `error_handler` should be removed
#[allow(dead_code)]
pub fn set_error_handler(&mut self, handler: Box<IsolateErrorHandleFn>) {
@ -545,24 +536,25 @@ impl Isolate {
let isolate = self.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(isolate);
assert!(!self.global_context.is_empty());
let mut hs = v8::HandleScope::new(&mut locker);
let s = hs.enter();
let mut context = self.global_context.get(s).unwrap();
context.enter();
let source = v8::String::new(s, js_source).unwrap();
let name = v8::String::new(s, js_filename).unwrap();
let mut try_catch = v8::TryCatch::new(s);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
let context = self.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let source = v8::String::new(scope, js_source).unwrap();
let name = v8::String::new(scope, js_filename).unwrap();
let mut try_catch = v8::TryCatch::new(scope);
let tc = try_catch.enter();
let origin = bindings::script_origin(s, name);
let origin = bindings::script_origin(scope, name);
let mut script =
v8::Script::compile(s, context, source, Some(&origin)).unwrap();
let result = script.run(s, context);
v8::Script::compile(scope, context, source, Some(&origin)).unwrap();
let result = script.run(scope, context);
if result.is_none() {
assert!(tc.has_caught());
let exception = tc.exception().unwrap();
self.handle_exception(s, context, exception);
self.handle_exception(scope, context, exception);
}
context.exit();
self.check_last_exception()
}
@ -596,10 +588,11 @@ impl Isolate {
let mut locker = v8::Locker::new(isolate);
assert!(!self.global_context.is_empty());
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
let mut context = self.global_context.get(scope).unwrap();
context.enter();
let context = self.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let pending_promises: Vec<(i32, v8::Global<v8::Value>)> =
self.pending_promise_map.drain().collect();
@ -608,17 +601,15 @@ impl Isolate {
self.handle_exception(scope, context, error);
handle.reset(scope);
}
context.exit();
}
fn throw_exception(&mut self, text: &str) {
let isolate = self.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
let msg = v8::String::new(scope, text).unwrap();
isolate.throw_exception(msg.into());
scope.isolate().throw_exception(msg.into());
}
fn async_op_response2(&mut self, op_id: OpId, buf: Box<[u8]>) {
@ -626,10 +617,11 @@ impl Isolate {
// println!("deno_execute -> Isolate ptr {:?}", isolate);
let mut locker = v8::Locker::new(isolate);
assert!(!self.global_context.is_empty());
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
let mut context = self.global_context.get(scope).unwrap();
context.enter();
let context = self.global_context.get(scope).unwrap();
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let mut try_catch = v8::TryCatch::new(scope);
let tc = try_catch.enter();
@ -642,28 +634,24 @@ impl Isolate {
return;
}
let mut argc = 0;
let mut args: Vec<v8::Local<v8::Value>> = vec![];
let global: v8::Local<v8::Value> = context.global(scope).into();
if !buf.is_empty() {
argc = 2;
let op_id = v8::Integer::new(scope, op_id as i32);
args.push(op_id.into());
let buf = unsafe { bindings::slice_to_uint8array(self, scope, &buf) };
args.push(buf.into());
}
let global = context.global(scope);
let maybe_value =
let maybe_value = if !buf.is_empty() {
let op_id: v8::Local<v8::Value> =
v8::Integer::new(scope, op_id as i32).into();
let buf: v8::Local<v8::Value> =
unsafe { bindings::slice_to_uint8array(self, scope, &buf) }.into();
js_recv_cb
.unwrap()
.call(scope, context, global.into(), argc, args);
.call(scope, context, global, &[op_id, buf])
} else {
js_recv_cb.unwrap().call(scope, context, global, &[])
};
if tc.has_caught() {
assert!(maybe_value.is_none());
self.handle_exception(scope, context, tc.exception().unwrap());
}
context.exit();
}
fn async_op_response(
@ -689,7 +677,7 @@ impl Isolate {
let isolate = self.v8_isolate.as_ref().unwrap();
let mut locker = v8::Locker::new(isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let mut hs = v8::HandleScope::new(locker.enter());
let scope = hs.enter();
self.global_context.reset(scope);

View file

@ -17,6 +17,7 @@ SharedQueue Binary Layout
*/
use crate::ops::OpId;
use rusty_v8 as v8;
const MAX_RECORDS: usize = 100;
/// Total number of records added.
@ -34,18 +35,39 @@ const HEAD_INIT: usize = 4 * INDEX_RECORDS;
pub const RECOMMENDED_SIZE: usize = 128 * MAX_RECORDS;
pub struct SharedQueue {
pub bytes: Vec<u8>,
buf: v8::SharedRef<v8::BackingStore>,
}
impl SharedQueue {
pub fn new(len: usize) -> Self {
let mut bytes = Vec::new();
bytes.resize(HEAD_INIT + len, 0);
let mut q = Self { bytes };
let mut buf = Vec::new();
buf.resize(HEAD_INIT + len, 0);
let buf = buf.into_boxed_slice();
let buf =
unsafe { v8::SharedArrayBuffer::new_backing_store_from_boxed_slice(buf) };
let mut q = Self { buf };
q.reset();
q
}
pub fn get_backing_store(&mut self) -> &mut v8::SharedRef<v8::BackingStore> {
&mut self.buf
}
pub fn bytes(&self) -> &[u8] {
unsafe {
// This is quite bad. The rusty_v8 issue that makes it necessitates it
// just barely missed the rusty_v8 v0.1.1 release cutoff.
#[allow(clippy::cast_ref_to_mut)]
let self_mut = &mut *(self as *const _ as *mut Self);
self_mut.bytes_mut()
}
}
pub fn bytes_mut(&mut self) -> &mut [u8] {
self.buf.data_bytes()
}
fn reset(&mut self) {
debug!("rust:shared_queue:reset");
let s: &mut [u32] = self.as_u32_slice_mut();
@ -55,21 +77,21 @@ impl SharedQueue {
}
fn as_u32_slice(&self) -> &[u32] {
let p = self.bytes.as_ptr();
let p = self.bytes().as_ptr();
// Assert pointer is 32 bit aligned before casting.
assert_eq!((p as usize) % std::mem::align_of::<u32>(), 0);
#[allow(clippy::cast_ptr_alignment)]
let p32 = p as *const u32;
unsafe { std::slice::from_raw_parts(p32, self.bytes.len() / 4) }
unsafe { std::slice::from_raw_parts(p32, self.bytes().len() / 4) }
}
fn as_u32_slice_mut(&mut self) -> &mut [u32] {
let p = self.bytes.as_mut_ptr();
let p = self.bytes_mut().as_mut_ptr();
// Assert pointer is 32 bit aligned before casting.
assert_eq!((p as usize) % std::mem::align_of::<u32>(), 0);
#[allow(clippy::cast_ptr_alignment)]
let p32 = p as *mut u32;
unsafe { std::slice::from_raw_parts_mut(p32, self.bytes.len() / 4) }
unsafe { std::slice::from_raw_parts_mut(p32, self.bytes().len() / 4) }
}
pub fn size(&self) -> usize {
@ -149,7 +171,7 @@ impl SharedQueue {
self.num_shifted_off(),
self.head()
);
Some((op_id, &self.bytes[off..end]))
Some((op_id, &self.bytes()[off..end]))
}
/// Because JS-side may cast `record` to Int32Array it is required
@ -166,13 +188,13 @@ impl SharedQueue {
);
assert_eq!(record.len() % 4, 0);
let index = self.num_records();
if end > self.bytes.len() || index >= MAX_RECORDS {
if end > self.bytes().len() || index >= MAX_RECORDS {
debug!("WARNING the sharedQueue overflowed");
return false;
}
self.set_meta(index, end, op_id);
assert_eq!(end - off, record.len());
self.bytes[off..end].copy_from_slice(record);
self.bytes_mut()[off..end].copy_from_slice(record);
let u32_slice = self.as_u32_slice_mut();
u32_slice[INDEX_NUM_RECORDS] += 1;
u32_slice[INDEX_HEAD] = end as u32;