mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Support native promise callbacks.
This commit is contained in:
parent
7ba3172ce0
commit
ab168204ed
5 changed files with 138 additions and 3 deletions
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue