rusty_v8
rusty_v8 copied to clipboard
`BackingStore` should not be `Sync`
SharedRef<T> implements Send if T implements Sync, so BackingStore implementing Sync means the following is possible:
let buffer: v8::Local<v8::ArrayBuffer> = run_script(
scope,
r#"
let arrayBuffer = new ArrayBuffer(1024);
globalThis.buffer = new Uint8Array(arrayBuffer);
arrayBuffer
"#,
);
let backing_store = buffer.get_backing_store();
std::thread::spawn(move || {
// We can dereference the sent `backing_store` into a slice of `Cell<u8>`,
// which allows us to mutate the backing store's bytes from this thread,
// without any unsafe code, even though the isolate in the main thread
// still has access to the `ArrayBuffer` object.
let cell_slice: &[Cell<u8>] = &backing_store;
cell_slice[0].set(42);
});
let value: v8::Local<v8::Number> = run_script(scope, "globalThis.buffer[0]");
println!("Read value: {}", value.value());
Users of BackingStore might then want to unsafely implement Send and/or Sync if they have made sure that the backing store is shared. (Though dereferencing it would still be unsound for the time being due to #711.)
This was discovered when investigating denoland/serde_v8#47.