Make Promise::resolve_native actually sound

We shouldn't have to pass a raw JSContext pointer, and to enter the
promise's context's compartment by hand.
This commit is contained in:
Anthony Ramine 2017-09-21 16:00:48 +02:00
parent 658dc8a501
commit 5addc2dfa3
17 changed files with 42 additions and 53 deletions

View file

@ -79,10 +79,10 @@ pub fn consume_body_with_promise<T: BodyOperations + DomObject>(object: &T,
match pkg_data_results {
Ok(results) => {
match results {
FetchedData::Text(s) => promise.resolve_native(cx, &USVString(s)),
FetchedData::Json(j) => promise.resolve_native(cx, &j),
FetchedData::BlobData(b) => promise.resolve_native(cx, &b),
FetchedData::FormData(f) => promise.resolve_native(cx, &f),
FetchedData::Text(s) => promise.resolve_native(&USVString(s)),
FetchedData::Json(j) => promise.resolve_native(&j),
FetchedData::BlobData(b) => promise.resolve_native(&b),
FetchedData::FormData(f) => promise.resolve_native(&f),
};
},
Err(err) => promise.reject_error(cx, err),

View file

@ -142,10 +142,7 @@ impl TrustedPromise {
let this = self;
task!(resolve_promise: move || {
debug!("Resolving promise.");
let this = this.root();
let cx = this.global().get_cx();
let _ac = JSAutoCompartment::new(cx, this.reflector().get_jsobject().get());
this.resolve_native(cx, &value);
this.root().resolve_native(&value);
})
}
}

View file

@ -514,7 +514,7 @@ impl AsyncBluetoothListener for Bluetooth {
BluetoothResponse::RequestDevice(device) => {
let mut device_instance_map = self.device_instance_map.borrow_mut();
if let Some(existing_device) = device_instance_map.get(&device.id.clone()) {
return promise.resolve_native(promise_cx, &**existing_device);
return promise.resolve_native(&**existing_device);
}
let bt_device = BluetoothDevice::new(&self.global(),
DOMString::from(device.id.clone()),
@ -530,12 +530,12 @@ impl AsyncBluetoothListener for Bluetooth {
);
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
// Step 5.
promise.resolve_native(promise_cx, &bt_device);
promise.resolve_native(&bt_device);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability
// Step 2 - 3.
BluetoothResponse::GetAvailability(is_available) => {
promise.resolve_native(promise_cx, &is_available);
promise.resolve_native(&is_available);
}
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
}
@ -573,7 +573,7 @@ impl PermissionAlgorithm for Bluetooth {
// Step 3.
if let PermissionState::Denied = status.get_state() {
status.set_devices(Vec::new());
return promise.resolve_native(cx, status);
return promise.resolve_native(status);
}
// Step 4.
@ -637,7 +637,7 @@ impl PermissionAlgorithm for Bluetooth {
// https://w3c.github.io/permissions/#dom-permissions-query
// Step 7.
promise.resolve_native(cx, status);
promise.resolve_native(status);
}
// https://webbluetoothcg.github.io/web-bluetooth/#request-the-bluetooth-permission

View file

@ -273,7 +273,7 @@ impl AsyncBluetoothListener for BluetoothDevice {
// Step 3.1.
self.watching_advertisements.set(true);
// Step 3.2.
promise.resolve_native(promise_cx, &());
promise.resolve_native(&());
},
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
}

View file

@ -98,7 +98,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult {
// https://w3c.github.io/permissions/#dom-permissions-request
// Step 8.
return promise.resolve_native(promise_cx, self);
return promise.resolve_native(self);
}
let bt_device = BluetoothDevice::new(&self.global(),
DOMString::from(device.id.clone()),
@ -117,7 +117,7 @@ impl AsyncBluetoothListener for BluetoothPermissionResult {
// https://w3c.github.io/permissions/#dom-permissions-request
// Step 8.
promise.resolve_native(promise_cx, self);
promise.resolve_native(self);
},
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
}

View file

@ -262,7 +262,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
// Step 7.
BluetoothResponse::GetDescriptors(descriptors_vec, single) => {
if single {
promise.resolve_native(promise_cx, &device.get_or_create_descriptor(&descriptors_vec[0], &self));
promise.resolve_native(&device.get_or_create_descriptor(&descriptors_vec[0], &self));
return;
}
let mut descriptors = vec!();
@ -270,7 +270,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
let bt_descriptor = device.get_or_create_descriptor(&descriptor, &self);
descriptors.push(bt_descriptor);
}
promise.resolve_native(promise_cx, &descriptors);
promise.resolve_native(&descriptors);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
BluetoothResponse::ReadValue(result) => {
@ -285,7 +285,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
self.upcast::<EventTarget>().fire_bubbling_event(atom!("characteristicvaluechanged"));
// Step 5.5.4.
promise.resolve_native(promise_cx, &value);
promise.resolve_native(&value);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
BluetoothResponse::WriteValue(result) => {
@ -296,7 +296,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
*self.value.borrow_mut() = Some(ByteString::new(result));
// Step 7.5.3.
promise.resolve_native(promise_cx, &());
promise.resolve_native(&());
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications
@ -306,7 +306,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
// (StartNotification) Step 11.
// (StopNotification) Step 5.
promise.resolve_native(promise_cx, self);
promise.resolve_native(self);
},
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
}

View file

@ -159,7 +159,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor {
*self.value.borrow_mut() = Some(value.clone());
// Step 5.4.3.
promise.resolve_native(promise_cx, &value);
promise.resolve_native(&value);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue
BluetoothResponse::WriteValue(result) => {
@ -171,7 +171,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTDescriptor {
// Step 7.4.3.
// TODO: Resolve promise with undefined instead of a value.
promise.resolve_native(promise_cx, &());
promise.resolve_native(&());
},
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
}

View file

@ -136,14 +136,14 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer {
self.connected.set(connected);
// Step 5.2.5.
promise.resolve_native(promise_cx, self);
promise.resolve_native(self);
},
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
BluetoothResponse::GetPrimaryServices(services_vec, single) => {
let device = self.Device();
if single {
promise.resolve_native(promise_cx, &device.get_or_create_service(&services_vec[0], &self));
promise.resolve_native(&device.get_or_create_service(&services_vec[0], &self));
return;
}
let mut services = vec!();
@ -151,7 +151,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTServer {
let bt_service = device.get_or_create_service(&service, &self);
services.push(bt_service);
}
promise.resolve_native(promise_cx, &services);
promise.resolve_native(&services);
},
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
}

View file

@ -135,8 +135,7 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService {
// Step 7.
BluetoothResponse::GetCharacteristics(characteristics_vec, single) => {
if single {
promise.resolve_native(promise_cx,
&device.get_or_create_characteristic(&characteristics_vec[0], &self));
promise.resolve_native(&device.get_or_create_characteristic(&characteristics_vec[0], &self));
return;
}
let mut characteristics = vec!();
@ -144,21 +143,20 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTService {
let bt_characteristic = device.get_or_create_characteristic(&characteristic, &self);
characteristics.push(bt_characteristic);
}
promise.resolve_native(promise_cx, &characteristics);
promise.resolve_native(&characteristics);
},
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
BluetoothResponse::GetIncludedServices(services_vec, single) => {
if single {
return promise.resolve_native(promise_cx,
&device.get_or_create_service(&services_vec[0], &device.get_gatt()));
return promise.resolve_native(&device.get_or_create_service(&services_vec[0], &device.get_gatt()));
}
let mut services = vec!();
for service in services_vec {
let bt_service = device.get_or_create_service(&service, &device.get_gatt());
services.push(bt_service);
}
promise.resolve_native(promise_cx, &services);
promise.resolve_native(&services);
},
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
}

View file

@ -316,10 +316,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
// Step 16, 16.3
if let Some(promise) = self.when_defined.borrow_mut().remove(&name) {
// 16.1
let cx = promise.global().get_cx();
// 16.2
promise.resolve_native(cx, &UndefinedValue());
promise.resolve_native(&UndefinedValue());
}
Ok(())
}
@ -353,7 +350,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
// Step 2
if self.definitions.borrow().contains_key(&name) {
let promise = Promise::new(global_scope);
promise.resolve_native(global_scope.get_cx(), &UndefinedValue());
promise.resolve_native(&UndefinedValue());
return promise
}

View file

@ -140,14 +140,14 @@ impl Permissions {
// (Request) Step 7. The default algorithm always resolve
// (Request) Step 8.
p.resolve_native(cx, &status);
p.resolve_native(&status);
},
&Operation::Query => {
// (Query) Step 6.
Permissions::permission_query(cx, &p, &root_desc, &status);
// (Query) Step 7.
p.resolve_native(cx, &status);
p.resolve_native(&status);
},
&Operation::Revoke => {

View file

@ -142,7 +142,9 @@ impl Promise {
}
#[allow(unsafe_code)]
pub fn resolve_native<T>(&self, cx: *mut JSContext, val: &T) where T: ToJSValConvertible {
pub fn resolve_native<T>(&self, val: &T) where T: ToJSValConvertible {
let cx = self.global().get_cx();
let _ac = JSAutoCompartment::new(cx, self.reflector().get_jsobject().get());
rooted!(in(cx) let mut v = UndefinedValue());
unsafe {
val.to_jsval(cx, v.handle_mut());

View file

@ -35,7 +35,7 @@ use dom::promise::Promise;
use dom::promisenativehandler::{PromiseNativeHandler, Callback};
use dom::url::URL;
use dom_struct::dom_struct;
use js::jsapi::{HandleObject, HandleValue, Heap, JSContext, JSObject, JSAutoCompartment};
use js::jsapi::{HandleObject, HandleValue, Heap, JSContext, JSObject};
use js::jsapi::{JS_NewPlainObject, JS_NewUint8ClampedArray};
use js::jsval::{JSVal, NullValue};
use script_traits::MsDuration;
@ -814,9 +814,6 @@ pub struct TestBindingCallback {
impl TestBindingCallback {
#[allow(unrooted_must_root)]
pub fn invoke(self) {
let p = self.promise.root();
let cx = p.global().get_cx();
let _ac = JSAutoCompartment::new(cx, p.reflector().get_jsobject().get());
p.resolve_native(cx, &self.value);
self.promise.root().resolve_native(&self.value);
}
}

View file

@ -87,7 +87,7 @@ impl VRMethods for VR {
let displays: Vec<Root<VRDisplay>> = self.displays.borrow().iter()
.map(|d| Root::from_ref(&**d))
.collect();
promise.resolve_native(promise.global().get_cx(), &displays);
promise.resolve_native(&displays);
promise
}

View file

@ -320,7 +320,7 @@ impl VRDisplayMethods for VRDisplay {
if self.presenting.get() {
*self.layer.borrow_mut() = layer_bounds;
self.layer_ctx.set(Some(&layer_ctx));
promise.resolve_native(promise.global().get_cx(), &());
promise.resolve_native(&());
return promise;
}
@ -335,7 +335,7 @@ impl VRDisplayMethods for VRDisplay {
*self.layer.borrow_mut() = layer_bounds;
self.layer_ctx.set(Some(&layer_ctx));
self.init_present();
promise.resolve_native(promise.global().get_cx(), &());
promise.resolve_native(&());
},
Err(e) => {
promise.reject_native(promise.global().get_cx(), &e);
@ -366,7 +366,7 @@ impl VRDisplayMethods for VRDisplay {
match receiver.recv().unwrap() {
Ok(()) => {
self.stop_present();
promise.resolve_native(promise.global().get_cx(), &());
promise.resolve_native(&());
},
Err(e) => {
promise.reject_native(promise.global().get_cx(), &e);

View file

@ -167,9 +167,7 @@ impl FetchResponseListener for FetchContext {
}
}
// Step 4.3
promise.resolve_native(
promise_cx,
&self.response_object.root());
promise.resolve_native(&self.response_object.root());
self.fetch_promise = Some(TrustedPromise::new(promise));
}

View file

@ -264,7 +264,7 @@ impl JobQueue {
fn settle_job_promise(global: &GlobalScope, promise: &Promise, settle: SettleType) {
let _ac = JSAutoCompartment::new(global.get_cx(), promise.reflector().get_jsobject().get());
match settle {
SettleType::Resolve(reg) => promise.resolve_native(global.get_cx(), &*reg.root()),
SettleType::Resolve(reg) => promise.resolve_native(&*reg.root()),
SettleType::Reject(err) => promise.reject_error(global.get_cx(), err),
};
}