diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-06-19 16:46:55 -0600 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-06-19 16:46:55 -0600 |
commit | e7808c526c348fea5e3b48af70b7f1a066652097 (patch) | |
tree | 640b22869e8a7eb7d5657df3074f0b0ccd528c29 /components/script/dom/bindings/proxyhandler.rs | |
parent | a256f39796270cd3a5f40f33eaa4e407117b0cc6 (diff) | |
parent | 675267b7822d2d6c30c0e36fc22e0191b741b973 (diff) | |
download | servo-e7808c526c348fea5e3b48af70b7f1a066652097.tar.gz servo-e7808c526c348fea5e3b48af70b7f1a066652097.zip |
Auto merge of #6150 - servo:smupgrade3, r=mbrubeck
Upgrade to Spidermonkey 39
> Here it is.
>
> ~~There's two major things that are unfinished here:~~
> - ~~Dealing with the unroot_must_root lint. I'm not sure about the value of this lint with the new rooting API.~~ Done.
> - ~~Updating the Cargo.locks to point to the new SM and SM binding.~~ Done.
>
> I also included my fixes for the rust update, but these will disappear in a rebase. A rust update is necessary to support calling `Drop` on `Heap<T>` correctly when `Heap<T>` is inside a `Rc<T>`. Otherwise `&self` points to the wrong location.
>
> Incremental GC is disabled here. I'm not sure how to deal with the incremental barriers so that's left for later.
>
> Generational GC works. SM doesn't work without it.
>
> The biggest change here is to the rooting API. `Root` was made movable, and `Temporary` and `JSRef` was removed. Movable `Root`s means there's no need for `Temporary`, and `JSRef`s aren't needed generally since it can be assumed that being able to obtain a reference to a dom object means it's already rooted. References have their lifetime bound to the Roots that provided them. DOM objects that haven't passed through `reflect_dom_object` don't need to be rooted, and DOM objects that have passed through `reflect_dom_object` can't be obtained without being rooted through `native_from_reflector_jsmanaged` or `JS::<T>::root()`.
>
> Support for `Heap<T>` ended up messier than I expected. It's split into two commits, but only because it's a bit difficult to fold them together. Supporting `Heap<T>` properly requires that that `Heap::<T>::set()` be called on something that won't move. I removed the Copy and Clone trait from `Heap<T>` so `Cell` can't hold `Heap<T>` - only `UnsafeCell` can hold it.
>
> `CallbackObject` is a bit tricky - I moved all callbacks into `Rc<T>` in order to make sure that the pointer inside to a `*mut JSObject` doesn't move. This is necessary for supporting `Heap<T>`.
>
> `RootedCollectionSet` is very general purpose now. Anything with `JSTraceable` can be rooted by `RootedCollectionSet`/`RootedTraceable`. Right now, `RootedTraceable` is only used to hold down dom objects before they're fully attached to their reflector. I had to make a custom mechanism to dispatch the trace call - couldn't figure out how to get trait objects working for this case.
>
> This has been tested with the following zeal settings:
>
> GC after every allocation
> JS_GC_ZEAL=2,1
>
> GC after every 100 allocations (important for catching use-after-free bugs)
> JS_GC_ZEAL=2,100
>
> Verify pre barriers
> JS_GC_ZEAL=4,1
>
> Verify post barriers
> JS_GC_ZEAL=11,1
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6150)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom/bindings/proxyhandler.rs')
-rw-r--r-- | components/script/dom/bindings/proxyhandler.rs | 139 |
1 files changed, 71 insertions, 68 deletions
diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs index 4441bdf2335..b7800ddc83e 100644 --- a/components/script/dom/bindings/proxyhandler.rs +++ b/components/script/dom/bindings/proxyhandler.rs @@ -8,18 +8,19 @@ use dom::bindings::conversions::is_dom_proxy; use dom::bindings::utils::delete_property_by_id; -use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString}; +use js::jsapi::{JSContext, JSPropertyDescriptor, JSObject, JSString}; use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewStringCopyN}; -use js::jsapi::{JS_DefinePropertyById, JS_NewObjectWithGivenProto}; -use js::jsapi::{JS_ReportErrorFlagsAndNumber, JS_StrictPropertyStub}; -use js::jsapi::{JSREPORT_WARNING, JSREPORT_STRICT, JSREPORT_STRICT_MODE_ERROR}; +use js::jsapi::{JS_DefinePropertyById6, JS_NewObjectWithGivenProto}; +use js::jsapi::{JS_StrictPropertyStub, JSErrNum}; +use js::jsapi::{Handle, HandleObject, HandleId, MutableHandle, RootedObject, ObjectOpResult}; +use js::jsapi::AutoIdVector; +use js::jsapi::GetObjectProto; use js::jsval::ObjectValue; use js::glue::GetProxyExtra; -use js::glue::{GetObjectProto, GetObjectParent, SetProxyExtra, GetProxyHandler}; +use js::glue::{SetProxyExtra, GetProxyHandler}; use js::glue::InvokeGetOwnPropertyDescriptor; -use js::glue::RUST_js_GetErrorMessage; -use js::glue::AutoIdVector; -use js::{JSPROP_GETTER, JSPROP_ENUMERATE, JSPROP_READONLY, JSRESOLVE_QUALIFIED}; +use js::{JSPROP_GETTER, JSPROP_ENUMERATE, JSPROP_READONLY}; +use js::{JSTrue, JSFalse}; use libc; use std::mem; @@ -32,60 +33,78 @@ static JSPROXYSLOT_EXPANDO: u32 = 0; /// Otherwise, walk along the prototype chain to find a property with that /// name. pub unsafe extern fn get_property_descriptor(cx: *mut JSContext, - proxy: *mut JSObject, - id: jsid, set: bool, - desc: *mut JSPropertyDescriptor) - -> bool { - let handler = GetProxyHandler(proxy); - if !InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, set, desc) { - return false; + proxy: HandleObject, + id: HandleId, + desc: MutableHandle<JSPropertyDescriptor>) + -> u8 { + let handler = GetProxyHandler(proxy.get()); + if InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, desc) == 0 { + return JSFalse; } - if !(*desc).obj.is_null() { - return true; + if !desc.get().obj.is_null() { + return JSTrue; } - //let proto = JS_GetPrototype(proxy); - let proto = GetObjectProto(proxy); - if proto.is_null() { - (*desc).obj = ptr::null_mut(); - return true; + let mut proto = RootedObject::new(cx, ptr::null_mut()); + if GetObjectProto(cx, proxy, proto.handle_mut()) == 0 { + desc.get().obj = ptr::null_mut(); + return JSTrue; } - JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc) != 0 + JS_GetPropertyDescriptorById(cx, proto.handle(), id, desc) } /// Defines an expando on the given `proxy`. -pub unsafe extern fn define_property(cx: *mut JSContext, proxy: *mut JSObject, - id: jsid, desc: *mut JSPropertyDescriptor) - -> bool { - static JSMSG_GETTER_ONLY: libc::c_uint = 160; - +pub unsafe extern fn define_property(cx: *mut JSContext, proxy: HandleObject, + id: HandleId, desc: Handle<JSPropertyDescriptor>, + result: *mut ObjectOpResult) + -> u8 { //FIXME: Workaround for https://github.com/mozilla/rust/issues/13385 - let setter: *const libc::c_void = mem::transmute((*desc).setter); + let setter: *const libc::c_void = mem::transmute(desc.get().setter); let setter_stub: *const libc::c_void = mem::transmute(JS_StrictPropertyStub); - if ((*desc).attrs & JSPROP_GETTER) != 0 && setter == setter_stub { - return JS_ReportErrorFlagsAndNumber(cx, - JSREPORT_WARNING | JSREPORT_STRICT | - JSREPORT_STRICT_MODE_ERROR, - Some(RUST_js_GetErrorMessage), ptr::null_mut(), - JSMSG_GETTER_ONLY) != 0; + if (desc.get().attrs & JSPROP_GETTER) != 0 && setter == setter_stub { + (*result).code_ = JSErrNum::JSMSG_GETTER_ONLY as u32; + return JSTrue; } - let expando = ensure_expando_object(cx, proxy); - return JS_DefinePropertyById(cx, expando, id, (*desc).value, (*desc).getter, - (*desc).setter, (*desc).attrs) != 0; + let expando = RootedObject::new(cx, ensure_expando_object(cx, proxy)); + JS_DefinePropertyById6(cx, expando.handle(), id, desc, result) } /// Deletes an expando off the given `proxy`. -pub unsafe extern fn delete(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, - bp: *mut bool) -> bool { - let expando = get_expando_object(proxy); - if expando.is_null() { - *bp = true; - return true; +pub unsafe extern fn delete(cx: *mut JSContext, proxy: HandleObject, id: HandleId, + bp: *mut ObjectOpResult) -> u8 { + let expando = RootedObject::new(cx, get_expando_object(proxy)); + if expando.ptr.is_null() { + (*bp).code_ = 0 /* OkCode */; + return JSTrue; } - return delete_property_by_id(cx, expando, id, &mut *bp); + delete_property_by_id(cx, expando.handle(), id, bp) +} + +/// Stub for ownPropertyKeys +pub unsafe extern fn own_property_keys(cx: *mut JSContext, + proxy: HandleObject, + props: *mut AutoIdVector) -> u8 { + // FIXME: implement this + // https://github.com/servo/servo/issues/6390 + JSTrue +} + +/// Controls whether the Extensible bit can be changed +pub unsafe extern fn prevent_extensions(_cx: *mut JSContext, + _proxy: HandleObject, + result: *mut ObjectOpResult) -> u8 { + (*result).code_ = JSErrNum::JSMSG_CANT_PREVENT_EXTENSIONS as u32; + return JSTrue; +} + +/// Reports whether the object is Extensible +pub unsafe extern fn is_extensible(_cx: *mut JSContext, _proxy: HandleObject, + succeeded: *mut u8) -> u8 { + *succeeded = JSTrue; + return JSTrue; } /// Returns the stringification of an object with class `name`. @@ -103,10 +122,10 @@ pub fn object_to_string(cx: *mut JSContext, name: &str) -> *mut JSString { } /// Get the expando object, or null if there is none. -pub fn get_expando_object(obj: *mut JSObject) -> *mut JSObject { +pub fn get_expando_object(obj: HandleObject) -> *mut JSObject { unsafe { - assert!(is_dom_proxy(obj)); - let val = GetProxyExtra(obj, JSPROXYSLOT_EXPANDO); + assert!(is_dom_proxy(obj.get())); + let val = GetProxyExtra(obj.get(), JSPROXYSLOT_EXPANDO); if val.is_undefined() { ptr::null_mut() } else { @@ -117,18 +136,16 @@ pub fn get_expando_object(obj: *mut JSObject) -> *mut JSObject { /// Get the expando object, or create it if it doesn't exist yet. /// Fails on JSAPI failure. -pub fn ensure_expando_object(cx: *mut JSContext, obj: *mut JSObject) +pub fn ensure_expando_object(cx: *mut JSContext, obj: HandleObject) -> *mut JSObject { unsafe { - assert!(is_dom_proxy(obj)); + assert!(is_dom_proxy(obj.get())); let mut expando = get_expando_object(obj); if expando.is_null() { - expando = JS_NewObjectWithGivenProto(cx, ptr::null_mut(), - ptr::null_mut(), - GetObjectParent(obj)); + expando = JS_NewObjectWithGivenProto(cx, ptr::null_mut(), HandleObject::null()); assert!(!expando.is_null()); - SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(&*expando)); + SetProxyExtra(obj.get(), JSPROXYSLOT_EXPANDO, ObjectValue(&*expando)); } return expando; } @@ -142,18 +159,4 @@ pub fn fill_property_descriptor(desc: &mut JSPropertyDescriptor, desc.attrs = if readonly { JSPROP_READONLY } else { 0 } | JSPROP_ENUMERATE; desc.getter = None; desc.setter = None; - desc.shortid = 0; -} - -/// No-op required hook. -pub unsafe extern fn get_own_property_names(_cx: *mut JSContext, - _obj: *mut JSObject, - _v: *mut AutoIdVector) -> bool { - true -} - -/// No-op required hook. -pub unsafe extern fn enumerate(_cx: *mut JSContext, _obj: *mut JSObject, - _v: *mut AutoIdVector) -> bool { - true } |