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

Make SharedRef<T> deref to UnsafeCell<T> instead of T (#242)

Closes: #240
This commit is contained in:
Bert Belder 2020-01-22 22:29:03 +01:00
parent bf128554fc
commit dcb94533f8
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
2 changed files with 62 additions and 45 deletions

View file

@ -1,3 +1,4 @@
use std::cell::UnsafeCell;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem::replace; use std::mem::replace;
use std::mem::size_of; use std::mem::size_of;
@ -209,9 +210,9 @@ where
T: Shared, T: Shared,
{ {
// TODO: Maybe this should deref to UnsafeCell<T>? // TODO: Maybe this should deref to UnsafeCell<T>?
type Target = T; type Target = UnsafeCell<T>;
fn deref(&self) -> &T { fn deref(&self) -> &Self::Target {
unsafe { &*<T as Shared>::deref(self) } unsafe { &*(<T as Shared>::deref(self) as *const UnsafeCell<T>) }
} }
} }
@ -219,8 +220,8 @@ impl<T> DerefMut for SharedRef<T>
where where
T: Shared, T: Shared,
{ {
fn deref_mut(&mut self) -> &mut T { fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *<T as Shared>::deref(self) } unsafe { &mut *(<T as Shared>::deref(self) as *mut UnsafeCell<T>) }
} }
} }

View file

@ -281,17 +281,23 @@ fn array_buffer() {
assert_eq!(unique_bs[0], 0); assert_eq!(unique_bs[0], 0);
assert_eq!(unique_bs[9], 9); assert_eq!(unique_bs[9], 9);
let mut shared_bs = unique_bs.make_shared(); let mut shared_bs_1 = unique_bs.make_shared();
assert_eq!(10, shared_bs.byte_length()); {
assert_eq!(false, shared_bs.is_shared()); let bs = unsafe { &mut *shared_bs_1.get() };
assert_eq!(shared_bs[0], 0); assert_eq!(10, bs.byte_length());
assert_eq!(shared_bs[9], 9); assert_eq!(false, bs.is_shared());
assert_eq!(bs[0], 0);
assert_eq!(bs[9], 9);
}
let ab = v8::ArrayBuffer::with_backing_store(scope, &mut shared_bs); let ab = v8::ArrayBuffer::with_backing_store(scope, &mut shared_bs_1);
let bs = ab.get_backing_store(); let shared_bs_2 = ab.get_backing_store();
assert_eq!(10, ab.byte_length()); {
assert_eq!(bs[0], 0); let bs = unsafe { &mut *shared_bs_2.get() };
assert_eq!(bs[9], 9); assert_eq!(10, ab.byte_length());
assert_eq!(bs[0], 0);
assert_eq!(bs[9], 9);
}
} }
} }
@ -315,16 +321,16 @@ fn array_buffer_with_shared_backing_store() {
assert_eq!(42, ab1.byte_length()); assert_eq!(42, ab1.byte_length());
let bs1 = ab1.get_backing_store(); let bs1 = ab1.get_backing_store();
assert_eq!(ab1.byte_length(), bs1.byte_length()); assert_eq!(ab1.byte_length(), unsafe { (*bs1.get()).byte_length() });
assert_eq!(2, v8::SharedRef::use_count(&bs1)); assert_eq!(2, v8::SharedRef::use_count(&bs1));
let bs2 = ab1.get_backing_store(); let bs2 = ab1.get_backing_store();
assert_eq!(ab1.byte_length(), bs2.byte_length()); assert_eq!(ab1.byte_length(), unsafe { (*bs2.get()).byte_length() });
assert_eq!(3, v8::SharedRef::use_count(&bs1)); assert_eq!(3, v8::SharedRef::use_count(&bs1));
assert_eq!(3, v8::SharedRef::use_count(&bs2)); assert_eq!(3, v8::SharedRef::use_count(&bs2));
let mut bs3 = ab1.get_backing_store(); let mut bs3 = ab1.get_backing_store();
assert_eq!(ab1.byte_length(), bs3.byte_length()); assert_eq!(ab1.byte_length(), unsafe { (*bs3.get()).byte_length() });
assert_eq!(4, v8::SharedRef::use_count(&bs1)); assert_eq!(4, v8::SharedRef::use_count(&bs1));
assert_eq!(4, v8::SharedRef::use_count(&bs2)); assert_eq!(4, v8::SharedRef::use_count(&bs2));
assert_eq!(4, v8::SharedRef::use_count(&bs3)); assert_eq!(4, v8::SharedRef::use_count(&bs3));
@ -341,7 +347,7 @@ fn array_buffer_with_shared_backing_store() {
assert_eq!(3, v8::SharedRef::use_count(&bs3)); assert_eq!(3, v8::SharedRef::use_count(&bs3));
let bs4 = ab2.get_backing_store(); let bs4 = ab2.get_backing_store();
assert_eq!(ab2.byte_length(), bs4.byte_length()); assert_eq!(ab1.byte_length(), unsafe { (*bs4.get()).byte_length() });
assert_eq!(4, v8::SharedRef::use_count(&bs3)); assert_eq!(4, v8::SharedRef::use_count(&bs3));
assert_eq!(4, v8::SharedRef::use_count(&bs4)); assert_eq!(4, v8::SharedRef::use_count(&bs4));
@ -1877,21 +1883,22 @@ fn shared_array_buffer() {
let context = v8::Context::new(scope); let context = v8::Context::new(scope);
let mut cs = v8::ContextScope::new(scope, context); let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter(); let scope = cs.enter();
let maybe_sab = v8::SharedArrayBuffer::new(scope, 16);
assert!(maybe_sab.is_some()); let sab = v8::SharedArrayBuffer::new(scope, 16).unwrap();
let sab = maybe_sab.unwrap(); let shared_bs_1 = sab.get_backing_store();
let mut backing_store = sab.get_backing_store(); {
backing_store[5] = 12; let bs = unsafe { &mut *shared_bs_1.get() };
backing_store[12] = 52; bs[5] = 12;
bs[12] = 52;
}
let global = context.global(scope); let global = context.global(scope);
assert_eq!( let r = global.create_data_property(
global.create_data_property( context,
context, v8_str(scope, "shared").into(),
v8_str(scope, "shared").into(), sab.into(),
sab.into(),
),
v8::MaybeBool::JustTrue
); );
assert_eq!(r, v8::MaybeBool::JustTrue);
let source = v8::String::new( let source = v8::String::new(
scope, scope,
r"sharedBytes = new Uint8Array(shared); r"sharedBytes = new Uint8Array(shared);
@ -1901,29 +1908,38 @@ fn shared_array_buffer() {
) )
.unwrap(); .unwrap();
let mut script = v8::Script::compile(scope, context, source, None).unwrap(); let mut script = v8::Script::compile(scope, context, source, None).unwrap();
source.to_rust_string_lossy(scope);
let result: v8::Local<v8::Integer> = let result: v8::Local<v8::Integer> =
script.run(scope, context).unwrap().try_into().unwrap(); script.run(scope, context).unwrap().try_into().unwrap();
assert_eq!(result.value(), 64); assert_eq!(result.value(), 64);
assert_eq!(backing_store[2], 16); {
assert_eq!(backing_store[14], 62); let bs = unsafe { &*shared_bs_1.get() };
assert_eq!(bs[2], 16);
assert_eq!(bs[14], 62);
}
let data: Box<[u8]> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9].into_boxed_slice(); let data: Box<[u8]> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9].into_boxed_slice();
let bs = unsafe { let bs = unsafe {
v8::SharedArrayBuffer::new_backing_store_from_boxed_slice(data) v8::SharedArrayBuffer::new_backing_store_from_boxed_slice(data)
}; };
assert_eq!(10, bs.byte_length()); assert_eq!(bs.byte_length(), 10);
assert_eq!(true, bs.is_shared()); assert_eq!(bs.is_shared(), true);
let mut bs = bs.make_shared(); let mut shared_bs_2 = bs.make_shared();
assert_eq!(10, bs.byte_length()); {
assert_eq!(true, bs.is_shared()); let bs = unsafe { &*shared_bs_2.get() };
assert_eq!(bs.byte_length(), 10);
assert_eq!(bs.is_shared(), true);
}
let ab = v8::SharedArrayBuffer::with_backing_store(scope, &mut bs); let ab = v8::SharedArrayBuffer::with_backing_store(scope, &mut shared_bs_2);
let bs = ab.get_backing_store(); let shared_bs_3 = ab.get_backing_store();
assert_eq!(10, ab.byte_length()); {
assert_eq!(bs[0], 0); let bs = unsafe { &*shared_bs_3.get() };
assert_eq!(bs[9], 9); assert_eq!(bs.byte_length(), 10);
assert_eq!(bs[0], 0);
assert_eq!(bs[9], 9);
}
} }
} }