use a structured clone holder to store rooted clones

This commit is contained in:
Gregory Terzian 2018-07-20 13:02:02 +08:00
parent aab335e543
commit a5d7cd1a7f

View file

@ -104,14 +104,17 @@ impl StructuredCloneReader {
} }
unsafe fn read_blob(cx: *mut JSContext, unsafe fn read_blob(cx: *mut JSContext,
r: *mut JSStructuredCloneReader) r: *mut JSStructuredCloneReader,
sc_holder: &mut StructuredCloneHolder)
-> *mut JSObject { -> *mut JSObject {
let structured_reader = StructuredCloneReader { r: r }; let structured_reader = StructuredCloneReader { r: r };
let blob_buffer = structured_reader.read_bytes(); let blob_buffer = structured_reader.read_bytes();
let type_str = structured_reader.read_str(); let type_str = structured_reader.read_str();
let target_global = GlobalScope::from_context(cx); let target_global = GlobalScope::from_context(cx);
let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str); let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str);
return blob.reflector().get_jsobject().get() let js_object = blob.reflector().get_jsobject().get();
sc_holder.blob = Some(blob);
js_object
} }
unsafe fn write_blob(blob: DomRoot<Blob>, unsafe fn write_blob(blob: DomRoot<Blob>,
@ -129,12 +132,12 @@ unsafe extern "C" fn read_callback(cx: *mut JSContext,
r: *mut JSStructuredCloneReader, r: *mut JSStructuredCloneReader,
tag: u32, tag: u32,
_data: u32, _data: u32,
_closure: *mut raw::c_void) closure: *mut raw::c_void)
-> *mut JSObject { -> *mut JSObject {
assert!(tag < StructuredCloneTags::Max as u32, "tag should be lower than StructuredCloneTags::Max"); assert!(tag < StructuredCloneTags::Max as u32, "tag should be lower than StructuredCloneTags::Max");
assert!(tag > StructuredCloneTags::Min as u32, "tag should be higher than StructuredCloneTags::Min"); assert!(tag > StructuredCloneTags::Min as u32, "tag should be higher than StructuredCloneTags::Min");
if tag == StructuredCloneTags::DomBlob as u32 { if tag == StructuredCloneTags::DomBlob as u32 {
return read_blob(cx, r) return read_blob(cx, r, &mut *(closure as *mut StructuredCloneHolder))
} }
return ptr::null_mut() return ptr::null_mut()
} }
@ -191,6 +194,10 @@ static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredClon
freeTransfer: Some(free_transfer_callback), freeTransfer: Some(free_transfer_callback),
}; };
struct StructuredCloneHolder {
blob: Option<DomRoot<Blob>>
}
/// A buffer for a structured clone. /// A buffer for a structured clone.
pub enum StructuredCloneData { pub enum StructuredCloneData {
/// A non-serializable (default) variant /// A non-serializable (default) variant
@ -244,6 +251,8 @@ impl StructuredCloneData {
let cx = global.get_cx(); let cx = global.get_cx();
let globalhandle = global.reflector().get_jsobject(); let globalhandle = global.reflector().get_jsobject();
let _ac = JSAutoCompartment::new(cx, globalhandle.get()); let _ac = JSAutoCompartment::new(cx, globalhandle.get());
let mut sc_holder = StructuredCloneHolder { blob: None };
let sc_holder_ptr = &mut sc_holder as *mut _;
unsafe { unsafe {
assert!(JS_ReadStructuredClone(cx, assert!(JS_ReadStructuredClone(cx,
data, data,
@ -251,7 +260,7 @@ impl StructuredCloneData {
JS_STRUCTURED_CLONE_VERSION, JS_STRUCTURED_CLONE_VERSION,
rval, rval,
&STRUCTURED_CLONE_CALLBACKS, &STRUCTURED_CLONE_CALLBACKS,
ptr::null_mut())); sc_holder_ptr as *mut raw::c_void));
} }
} }