diff options
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r-- | components/script/dom/bindings/refcounted.rs | 39 | ||||
-rw-r--r-- | components/script/dom/bindings/structuredclone.rs | 52 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 4 |
3 files changed, 79 insertions, 16 deletions
diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs index dcf11626543..f22074d5fef 100644 --- a/components/script/dom/bindings/refcounted.rs +++ b/components/script/dom/bindings/refcounted.rs @@ -23,12 +23,17 @@ //! as JS roots. use core::nonzero::NonZero; +use dom::bindings::conversions::ToJSValConvertible; +use dom::bindings::error::Error; use dom::bindings::js::Root; use dom::bindings::reflector::{DomObject, Reflector}; use dom::bindings::trace::trace_reflector; use dom::promise::Promise; +use js::jsapi::JSAutoCompartment; use js::jsapi::JSTracer; use libc; +use script_thread::Runnable; +use script_thread::ScriptThread; use std::cell::RefCell; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::HashMap; @@ -115,6 +120,40 @@ impl TrustedPromise { promise }) } + + /// A runnable which will reject the promise. + #[allow(unrooted_must_root)] + pub fn reject_runnable(self, error: Error) -> impl Runnable + Send { + struct RejectPromise(TrustedPromise, Error); + impl Runnable for RejectPromise { + fn main_thread_handler(self: Box<Self>, script_thread: &ScriptThread) { + let this = *self; + let cx = script_thread.get_cx(); + let promise = this.0.root(); + let _ac = JSAutoCompartment::new(cx, promise.reflector().get_jsobject().get()); + promise.reject_error(cx, this.1); + } + } + RejectPromise(self, error) + } + + /// A runnable which will resolve the promise. + #[allow(unrooted_must_root)] + pub fn resolve_runnable<T>(self, value: T) -> impl Runnable + Send where + T: ToJSValConvertible + Send + { + struct ResolvePromise<T>(TrustedPromise, T); + impl<T: ToJSValConvertible> Runnable for ResolvePromise<T> { + fn main_thread_handler(self: Box<Self>, script_thread: &ScriptThread) { + let this = *self; + let cx = script_thread.get_cx(); + let promise = this.0.root(); + let _ac = JSAutoCompartment::new(cx, promise.reflector().get_jsobject().get()); + promise.resolve_native(cx, &this.1); + } + } + ResolvePromise(self, value) + } } /// A safe wrapper around a raw pointer to a DOM object that can be diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index b3a9df32695..53f3b63e085 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -67,16 +67,44 @@ unsafe fn read_length(r: *mut JSStructuredCloneReader) return length as usize; } +struct StructuredCloneWriter { + w: *mut JSStructuredCloneWriter, +} + +impl StructuredCloneWriter { + unsafe fn write_slice(&self, v: &[u8]) { + let type_length = v.len(); + write_length(self.w, type_length); + assert!(JS_WriteBytes(self.w, v.as_ptr() as *const raw::c_void, type_length)); + } + unsafe fn write_str(&self, s: &str) { + self.write_slice(s.as_bytes()); + } +} + +struct StructuredCloneReader { + r: *mut JSStructuredCloneReader, +} + +impl StructuredCloneReader { + unsafe fn read_bytes(&self) -> Vec<u8> { + let mut bytes = vec![0u8; read_length(self.r)]; + let blob_length = bytes.len(); + assert!(JS_ReadBytes(self.r, bytes.as_mut_ptr() as *mut raw::c_void, blob_length)); + return bytes; + } + unsafe fn read_str(&self) -> String { + let str_buffer = self.read_bytes(); + return String::from_utf8_unchecked(str_buffer); + } +} + unsafe fn read_blob(cx: *mut JSContext, r: *mut JSStructuredCloneReader) -> *mut JSObject { - let blob_length = read_length(r); - let type_str_length = read_length(r); - let mut blob_buffer = vec![0u8; blob_length]; - assert!(JS_ReadBytes(r, blob_buffer.as_mut_ptr() as *mut raw::c_void, blob_length)); - let mut type_str_buffer = vec![0u8; type_str_length]; - assert!(JS_ReadBytes(r, type_str_buffer.as_mut_ptr() as *mut raw::c_void, type_str_length)); - let type_str = String::from_utf8_unchecked(type_str_buffer); + let structured_reader = StructuredCloneReader { r: r }; + let blob_buffer = structured_reader.read_bytes(); + let type_str = structured_reader.read_str(); let target_global = GlobalScope::from_context(cx); let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str); return blob.reflector().get_jsobject().get() @@ -85,15 +113,11 @@ unsafe fn read_blob(cx: *mut JSContext, unsafe fn write_blob(blob: Root<Blob>, w: *mut JSStructuredCloneWriter) -> Result<(), ()> { + let structured_writer = StructuredCloneWriter { w: w }; let blob_vec = try!(blob.get_bytes()); - let blob_length = blob_vec.len(); - let type_string_bytes = blob.type_string().as_bytes().to_vec(); - let type_string_length = type_string_bytes.len(); assert!(JS_WriteUint32Pair(w, StructuredCloneTags::DomBlob as u32, 0)); - write_length(w, blob_length); - write_length(w, type_string_length); - assert!(JS_WriteBytes(w, blob_vec.as_ptr() as *const raw::c_void, blob_length)); - assert!(JS_WriteBytes(w, type_string_bytes.as_ptr() as *const raw::c_void, type_string_length)); + structured_writer.write_slice(&blob_vec); + structured_writer.write_str(&blob.type_string()); return Ok(()) } diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index a0f26d12c23..2b3bfceceb2 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -58,7 +58,7 @@ use js::glue::{CallObjectTracer, CallValueTracer}; use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind}; use js::jsval::JSVal; use js::rust::Runtime; -use msg::constellation_msg::{FrameId, FrameType, PipelineId}; +use msg::constellation_msg::{BrowsingContextId, FrameType, PipelineId}; use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; use net_traits::filemanager_thread::RelativePos; use net_traits::image::base::{Image, ImageMetadata}; @@ -336,7 +336,7 @@ unsafe_no_jsmanaged_fields!(TrustedPromise); unsafe_no_jsmanaged_fields!(PropertyDeclarationBlock); // These three are interdependent, if you plan to put jsmanaged data // in one of these make sure it is propagated properly to containing structs -unsafe_no_jsmanaged_fields!(DocumentActivity, FrameId, FrameType, WindowSizeData, WindowSizeType, PipelineId); +unsafe_no_jsmanaged_fields!(DocumentActivity, BrowsingContextId, FrameType, WindowSizeData, WindowSizeType, PipelineId); unsafe_no_jsmanaged_fields!(TimerEventId, TimerSource); unsafe_no_jsmanaged_fields!(TimelineMarkerType); unsafe_no_jsmanaged_fields!(WorkerId); |