aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/promise.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2016-08-12 11:44:56 -0400
committerJosh Matthews <josh@joshmatthews.net>2016-09-22 16:16:52 -0400
commitab168204ed9b6068c312a98253ab32bcaa5e2239 (patch)
tree79d1bfd85843fd0995c33c5220bfec042e69b915 /components/script/dom/promise.rs
parent7ba3172ce0d9d9d6a003b27d66450fea876bd563 (diff)
downloadservo-ab168204ed9b6068c312a98253ab32bcaa5e2239.tar.gz
servo-ab168204ed9b6068c312a98253ab32bcaa5e2239.zip
Support native promise callbacks.
Diffstat (limited to 'components/script/dom/promise.rs')
-rw-r--r--components/script/dom/promise.rs76
1 files changed, 74 insertions, 2 deletions
diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs
index c99ae69792c..79490e0bc13 100644
--- a/components/script/dom/promise.rs
+++ b/components/script/dom/promise.rs
@@ -4,6 +4,7 @@
use dom::bindings::callback::CallbackContainer;
use dom::bindings::codegen::Bindings::PromiseBinding::AnyCallback;
+use dom::bindings::conversions::root_from_object;
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::reflector::{Reflectable, MutReflectable, Reflector};
@@ -82,7 +83,7 @@ impl Promise {
pub fn maybe_resolve_native<T>(&self, cx: *mut JSContext, val: &T) where T: ToJSValConvertible {
rooted!(in(cx) let mut v = UndefinedValue());
unsafe {
- val.to_jsval(cx, m.handle_mut());
+ val.to_jsval(cx, v.handle_mut());
}
self.maybe_resolve(cx, v.handle());
}
@@ -102,7 +103,7 @@ impl Promise {
pub fn maybe_reject_native<T>(&self, cx: *mut JSContext, val: &T) where T: ToJSValConvertible {
rooted!(in(cx) let mut v = UndefinedValue());
unsafe {
- val.to_jsval(cx, m.handle_mut());
+ val.to_jsval(cx, v.handle_mut());
}
self.maybe_reject(cx, v.handle());
}
@@ -143,6 +144,29 @@ impl Promise {
}
obj
}
+
+ #[allow(unsafe_code)]
+ pub fn append_native_handler(&self, handler: &PromiseNativeHandler) {
+ let global = self.global();
+ let cx = global.r().get_cx();
+ rooted!(in(cx) let resolve_func =
+ create_native_handler_function(cx,
+ handler.reflector().get_jsobject(),
+ NativeHandlerTask::Resolve));
+
+ rooted!(in(cx) let reject_func =
+ create_native_handler_function(cx,
+ handler.reflector().get_jsobject(),
+ NativeHandlerTask::Reject));
+
+ unsafe {
+ let ok = AddPromiseReactions(cx,
+ self.promise_obj(),
+ resolve_func.handle(),
+ reject_func.handle());
+ assert!(ok);
+ }
+ }
}
#[allow(unsafe_code)]
@@ -151,3 +175,51 @@ unsafe extern fn do_nothing_promise_executor(_cx: *mut JSContext, argc: u32, vp:
*args.rval() = UndefinedValue();
true
}
+
+const SLOT_NATIVEHANDLER: usize = 0;
+const SLOT_NATIVEHANDLER_TASK: usize = 1;
+
+#[derive(PartialEq)]
+enum NativeHandlerTask {
+ Resolve = 0,
+ Reject = 1,
+}
+
+#[allow(unsafe_code)]
+unsafe extern fn native_handler_callback(cx: *mut JSContext, argc: u32, vp: *mut JSVal) -> bool {
+ let args = CallArgs::from_vp(vp, argc);
+ rooted!(in(cx) let v = *GetFunctionNativeReserved(args.callee(), SLOT_NATIVEHANDLER));
+ assert!(v.get().is_object());
+
+ let handler = root_from_object::<PromiseNativeHandler>(v.to_object())
+ .ok().expect("unexpected value for native handler in promise native handler callback");
+
+ rooted!(in(cx) let v = *GetFunctionNativeReserved(args.callee(), SLOT_NATIVEHANDLER_TASK));
+ match v.to_int32() {
+ v if v == NativeHandlerTask::Resolve as i32 => handler.resolved_callback(cx, args.get(0)),
+ v if v == NativeHandlerTask::Reject as i32 => handler.rejected_callback(cx, args.get(0)),
+ _ => panic!("unexpected native handler task value"),
+ };
+
+ true
+}
+
+#[allow(unsafe_code)]
+fn create_native_handler_function(cx: *mut JSContext,
+ holder: HandleObject,
+ task: NativeHandlerTask) -> *mut JSObject {
+ unsafe {
+ let func = NewFunctionWithReserved(cx, Some(native_handler_callback), 1, 0, ptr::null());
+ assert!(!func.is_null());
+
+ rooted!(in(cx) let obj = JS_GetFunctionObject(func));
+ assert!(!obj.is_null());
+ SetFunctionNativeReserved(obj.get(),
+ SLOT_NATIVEHANDLER,
+ &ObjectValue(&**holder));
+ SetFunctionNativeReserved(obj.get(),
+ SLOT_NATIVEHANDLER_TASK,
+ &Int32Value(task as i32));
+ obj.get()
+ }
+}