servo: Merge #12830 - Implement promise bindings (from jdm:promises); r=Ms2ger

This implements support for using Promises in WebIDL, executing promise callbacks in batches (equivalent to running all enqueued jobs from a setTimeout(0)), and attaching native callbacks to promise objects. This is the combined work of myself, @dati91, and @mmatyas based on the following prior work in Gecko:
* Codegen.py
* Promise.webidl
* Promise.cpp/Promise.h
* PromiseNativeHandler.h

This does not implement microtasks per #4283. This allows us to make progress on testing code that requires the use of Promises right now; the microtasks work is more complicated, but also largely orthogonal to implement.

Requires https://github.com/servo/mozjs/pull/89, https://github.com/servo/rust-mozjs/pull/287, and https://github.com/servo/rust-mozjs/pull/294.

---
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #4282
- [X] There are tests for these changes

Source-Repo: https://github.com/servo/servo
Source-Revision: 2b1a39c2ae14b78e437551d05f0e691a13e5d183
This commit is contained in:
Josh Matthews
2016-09-22 15:23:23 -05:00
parent 6037711550
commit 8a62caabc3
20 changed files with 901 additions and 43 deletions

View File

@@ -27,7 +27,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen
use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior};
use dom::bindings::global::GlobalRef;
use dom::bindings::global::{GlobalRef, GlobalRoot};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root, RootCollection};
use dom::bindings::js::{RootCollectionPtr, RootedReference};
@@ -77,8 +77,8 @@ use parse::xml::{self, parse_xml};
use profile_traits::mem::{self, OpaqueSender, Report, ReportKind, ReportsChan};
use profile_traits::time::{self, ProfilerCategory, profile};
use script_layout_interface::message::{self, NewLayoutThreadInfo, ReflowQueryType};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory};
use script_runtime::{ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory, EnqueuedPromiseCallback};
use script_runtime::{ScriptPort, StackRootTLS, get_reports, new_rt_and_cx, PromiseJobQueue};
use script_traits::{CompositorEvent, ConstellationControlMsg, EventResult};
use script_traits::{InitialScriptState, MouseButton, MouseEventType, MozBrowserEvent};
use script_traits::{NewLayoutInfo, ScriptMsg as ConstellationMsg};
@@ -394,6 +394,8 @@ pub struct ScriptThread {
timer_event_port: Receiver<TimerEvent>,
content_process_shutdown_chan: IpcSender<()>,
promise_job_queue: PromiseJobQueue,
}
/// In the event of thread panic, all data on the stack runs its destructor. However, there
@@ -599,6 +601,8 @@ impl ScriptThread {
timer_event_port: timer_event_port,
content_process_shutdown_chan: state.content_process_shutdown_chan,
promise_job_queue: PromiseJobQueue::new(),
}
}
@@ -2174,6 +2178,33 @@ impl ScriptThread {
location.Reload();
}
}
pub fn enqueue_promise_job(job: EnqueuedPromiseCallback, global: GlobalRef) {
SCRIPT_THREAD_ROOT.with(|root| {
let script_thread = unsafe { &*root.get().unwrap() };
script_thread.promise_job_queue.enqueue(job, global);
});
}
pub fn flush_promise_jobs(global: GlobalRef) {
SCRIPT_THREAD_ROOT.with(|root| {
let script_thread = unsafe { &*root.get().unwrap() };
let _ = script_thread.dom_manipulation_task_source.queue(box FlushPromiseJobs, global);
})
}
fn do_flush_promise_jobs(&self) {
self.promise_job_queue.flush_promise_jobs(|id| {
self.find_child_context(id).map(|context| GlobalRoot::Window(context.active_window()))
});
}
}
struct FlushPromiseJobs;
impl Runnable for FlushPromiseJobs {
fn main_thread_handler(self: Box<FlushPromiseJobs>, script_thread: &ScriptThread) {
script_thread.do_flush_promise_jobs();
}
}
impl Drop for ScriptThread {