aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/layout/construct.rs8
-rw-r--r--components/layout/flow.rs5
-rw-r--r--components/layout/layout_task.rs76
-rw-r--r--components/layout/query.rs20
-rw-r--r--components/plugins/lints/unrooted_must_root.rs174
-rw-r--r--components/script/dom/bindings/js.rs35
-rw-r--r--components/script/dom/bindings/utils.rs58
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs1
-rw-r--r--components/script/dom/element.rs5
-rw-r--r--components/script/dom/filelist.rs2
-rw-r--r--components/script/dom/htmlcollection.rs2
-rw-r--r--components/script/dom/nodelist.rs2
-rw-r--r--components/script/dom/webglrenderingcontext.rs1
-rw-r--r--components/script/dom/webidls/Element.webidl2
-rw-r--r--components/servo/Cargo.lock2
15 files changed, 203 insertions, 190 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index ff1ff42a1d2..2ed8f286db0 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -1659,7 +1659,9 @@ impl<'ln> ObjectElement<'ln> for ThreadSafeLayoutNode<'ln> {
}
}
-pub trait FlowConstructionUtils {
+// This must not be public because only the layout constructor can call these
+// methods.
+trait FlowConstructionUtils {
/// Adds a new flow as a child of this flow. Removes the flow from the given leaf set if
/// it's present.
fn add_new_child(&mut self, new_child: FlowRef);
@@ -1675,8 +1677,6 @@ pub trait FlowConstructionUtils {
impl FlowConstructionUtils for FlowRef {
/// Adds a new flow as a child of this flow. Fails if this flow is marked as a leaf.
- ///
- /// This must not be public because only the layout constructor can do this.
fn add_new_child(&mut self, mut new_child: FlowRef) {
{
let kid_base = flow::mut_base(flow_ref::deref_mut(&mut new_child));
@@ -1694,8 +1694,6 @@ impl FlowConstructionUtils for FlowRef {
///
/// All flows must be finished at some point, or they will not have their intrinsic inline-sizes
/// properly computed. (This is not, however, a memory safety problem.)
- ///
- /// This must not be public because only the layout constructor can do this.
fn finish(&mut self) {
if !opts::get().bubble_inline_sizes_separately {
flow_ref::deref_mut(self).bubble_inline_sizes()
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index 96d4b4b159a..5be4533dc6a 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -937,11 +937,6 @@ pub struct BaseFlow {
pub flags: FlowFlags,
}
-#[allow(unsafe_code)]
-unsafe impl Send for BaseFlow {}
-#[allow(unsafe_code)]
-unsafe impl Sync for BaseFlow {}
-
impl fmt::Debug for BaseFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs
index 7dde0fe694c..9c3a3e7ea4c 100644
--- a/components/layout/layout_task.rs
+++ b/components/layout/layout_task.rs
@@ -324,7 +324,6 @@ fn add_font_face_rules(stylesheet: &Stylesheet,
outstanding_web_fonts_counter: &Arc<AtomicUsize>) {
for font_face in stylesheet.effective_rules(&device).font_face() {
for source in &font_face.sources {
- let font_cache_task = (*font_cache_task).clone();
outstanding_web_fonts_counter.fetch_add(1, Ordering::SeqCst);
font_cache_task.add_web_font(font_face.family.clone(),
(*source).clone(),
@@ -878,25 +877,24 @@ impl LayoutTask {
traversal);
}
- fn process_node_geometry_request<'a>(&'a self,
- requested_node: TrustedNodeAddress,
- layout_root: &mut FlowRef,
- rw_data: &mut RWGuard<'a>) {
+ fn process_node_geometry_request(&self,
+ requested_node: TrustedNodeAddress,
+ layout_root: &mut FlowRef)
+ -> Rect<i32> {
let requested_node: OpaqueNode = OpaqueNodeMethods::from_script_node(requested_node);
let mut iterator = FragmentLocatingFragmentIterator::new(requested_node);
sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
- rw_data.client_rect_response = iterator.client_rect;
+ iterator.client_rect
}
- // Compute the resolved value of property for a given (pseudo)element.
- // Stores the result in rw_data.resolved_style_response.
- // https://drafts.csswg.org/cssom/#resolved-value
- fn process_resolved_style_request<'a>(&'a self,
- requested_node: TrustedNodeAddress,
- pseudo: &Option<PseudoElement>,
- property: &Atom,
- layout_root: &mut FlowRef,
- rw_data: &mut RWGuard<'a>) {
+ /// Return the resolved value of property for a given (pseudo)element.
+ /// https://drafts.csswg.org/cssom/#resolved-value
+ fn process_resolved_style_request(&self,
+ requested_node: TrustedNodeAddress,
+ pseudo: &Option<PseudoElement>,
+ property: &Atom,
+ layout_root: &mut FlowRef)
+ -> Option<String> {
// FIXME: Isolate this transmutation into a "bridge" module.
// FIXME(rust#16366): The following line had to be moved because of a
// rustc bug. It should be in the next unsafe block.
@@ -919,8 +917,7 @@ impl LayoutTask {
// The pseudo doesn't exist, return nothing. Chrome seems to query
// the element itself in this case, Firefox uses the resolved value.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=29006
- rw_data.resolved_style_response = None;
- return;
+ return None;
}
Some(layout_node) => layout_node
};
@@ -945,7 +942,7 @@ impl LayoutTask {
// TODO: we will return neither the computed nor used value for margin and padding.
// Firefox returns blank strings for the computed value of shorthands,
// so this should be web-compatible.
- match property.clone() {
+ match *property {
atom!("margin-bottom") | atom!("margin-top") |
atom!("margin-left") | atom!("margin-right") |
atom!("padding-bottom") | atom!("padding-top") |
@@ -971,7 +968,7 @@ impl LayoutTask {
style.writing_mode);
sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root,
&mut iterator);
- rw_data.resolved_style_response = iterator.result.map(|r| r.to_css_string());
+ iterator.result.map(|r| r.to_css_string())
},
atom!("bottom") | atom!("top") | atom!("right") |
@@ -1004,20 +1001,19 @@ impl LayoutTask {
position);
sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root,
&mut iterator);
- rw_data.resolved_style_response = iterator.result.map(|r| r.to_css_string());
+ iterator.result.map(|r| r.to_css_string())
},
// FIXME: implement used value computation for line-height
- property => {
- rw_data.resolved_style_response =
- style.computed_value_to_string(property.as_slice()).ok();
+ ref property => {
+ style.computed_value_to_string(property.as_slice()).ok()
}
- };
+ }
}
- fn process_offset_parent_query<'a>(&'a self,
- requested_node: TrustedNodeAddress,
- layout_root: &mut FlowRef,
- rw_data: &mut RWGuard<'a>) {
+ fn process_offset_parent_query(&self,
+ requested_node: TrustedNodeAddress,
+ layout_root: &mut FlowRef)
+ -> OffsetParentResponse {
let requested_node: OpaqueNode = OpaqueNodeMethods::from_script_node(requested_node);
let mut iterator = ParentOffsetBorderBoxIterator::new(requested_node);
sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
@@ -1027,13 +1023,13 @@ impl LayoutTask {
let parent = iterator.parent_nodes[parent_info_index].as_ref().unwrap();
let origin = iterator.node_border_box.origin - parent.border_box.origin;
let size = iterator.node_border_box.size;
- rw_data.offset_parent_response = OffsetParentResponse {
+ OffsetParentResponse {
node_address: Some(parent.node_address.to_untrusted_node_address()),
rect: Rect::new(origin, size),
- };
+ }
}
None => {
- rw_data.offset_parent_response = OffsetParentResponse::empty();
+ OffsetParentResponse::empty()
}
}
}
@@ -1232,20 +1228,20 @@ impl LayoutTask {
if let Some(mut root_flow) = rw_data.layout_root() {
match data.query_type {
ReflowQueryType::ContentBoxQuery(node) =>
- process_content_box_request(node, &mut root_flow, &mut rw_data),
+ rw_data.content_box_response = process_content_box_request(node, &mut root_flow),
ReflowQueryType::ContentBoxesQuery(node) =>
- process_content_boxes_request(node, &mut root_flow, &mut rw_data),
+ rw_data.content_boxes_response = process_content_boxes_request(node, &mut root_flow),
ReflowQueryType::NodeGeometryQuery(node) =>
- self.process_node_geometry_request(node, &mut root_flow, &mut rw_data),
+ rw_data.client_rect_response = self.process_node_geometry_request(node, &mut root_flow),
ReflowQueryType::ResolvedStyleQuery(node, ref pseudo, ref property) => {
- self.process_resolved_style_request(node,
- pseudo,
- property,
- &mut root_flow,
- &mut rw_data)
+ rw_data.resolved_style_response =
+ self.process_resolved_style_request(node,
+ pseudo,
+ property,
+ &mut root_flow)
}
ReflowQueryType::OffsetParentQuery(node) =>
- self.process_offset_parent_query(node, &mut root_flow, &mut rw_data),
+ rw_data.offset_parent_response = self.process_offset_parent_query(node, &mut root_flow),
ReflowQueryType::NoQuery => {}
}
}
diff --git a/components/layout/query.rs b/components/layout/query.rs
index 024d3022288..d50e150d0ae 100644
--- a/components/layout/query.rs
+++ b/components/layout/query.rs
@@ -10,7 +10,7 @@ use euclid::rect::Rect;
use flow_ref::FlowRef;
use fragment::{Fragment, FragmentBorderBoxIterator};
use gfx::display_list::{DisplayItemMetadata, OpaqueNode};
-use layout_task::{LayoutTaskData, RWGuard};
+use layout_task::LayoutTaskData;
use msg::constellation_msg::ConstellationChan;
use msg::constellation_msg::Msg as ConstellationMsg;
use opaque_node::OpaqueNodeMethods;
@@ -281,27 +281,27 @@ impl FragmentBorderBoxIterator for MarginRetrievingFragmentBorderBoxIterator {
}
}
-pub fn process_content_box_request<'a>(requested_node: TrustedNodeAddress,
- layout_root: &mut FlowRef,
- rw_data: &mut RWGuard<'a>) {
+pub fn process_content_box_request(requested_node: TrustedNodeAddress,
+ layout_root: &mut FlowRef)
+ -> Rect<Au> {
// FIXME(pcwalton): This has not been updated to handle the stacking context relative
// stuff. So the position is wrong in most cases.
let requested_node: OpaqueNode = OpaqueNodeMethods::from_script_node(requested_node);
let mut iterator = UnioningFragmentBorderBoxIterator::new(requested_node);
sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
- rw_data.content_box_response = match iterator.rect {
+ match iterator.rect {
Some(rect) => rect,
None => Rect::zero()
- };
+ }
}
-pub fn process_content_boxes_request<'a>(requested_node: TrustedNodeAddress,
- layout_root: &mut FlowRef,
- rw_data: &mut RWGuard<'a>) {
+pub fn process_content_boxes_request(requested_node: TrustedNodeAddress,
+ layout_root: &mut FlowRef)
+ -> Vec<Rect<Au>> {
// FIXME(pcwalton): This has not been updated to handle the stacking context relative
// stuff. So the position is wrong in most cases.
let requested_node: OpaqueNode = OpaqueNodeMethods::from_script_node(requested_node);
let mut iterator = CollectingFragmentBorderBoxIterator::new(requested_node);
sequential::iterate_through_flow_tree_fragment_border_boxes(layout_root, &mut iterator);
- rw_data.content_boxes_response = iterator.rects;
+ iterator.rects
}
diff --git a/components/plugins/lints/unrooted_must_root.rs b/components/plugins/lints/unrooted_must_root.rs
index bb599e845de..5b6e16c99e9 100644
--- a/components/plugins/lints/unrooted_must_root.rs
+++ b/components/plugins/lints/unrooted_must_root.rs
@@ -8,7 +8,7 @@ use rustc::middle::ty;
use rustc_front::{hir, visit};
use syntax::attr::AttrMetaMethods;
use syntax::{ast, codemap};
-use utils::{match_def_path, unsafe_context, in_derive_expn};
+use utils::{match_def_path, in_derive_expn};
declare_lint!(UNROOTED_MUST_ROOT, Deny,
"Warn and report usage of unrooted jsmanaged objects");
@@ -30,15 +30,11 @@ declare_lint!(UNROOTED_MUST_ROOT, Deny,
/// Structs which have their own mechanism of rooting their unrooted contents (e.g. `ScriptTask`)
/// can be marked as `#[allow(unrooted_must_root)]`. Smart pointers which root their interior type
/// can be marked as `#[allow_unrooted_interior]`
-pub struct UnrootedPass {
- in_new_function: bool
-}
+pub struct UnrootedPass;
impl UnrootedPass {
pub fn new() -> UnrootedPass {
- UnrootedPass {
- in_new_function: true
- }
+ UnrootedPass
}
}
@@ -55,9 +51,11 @@ fn is_unrooted_ty(cx: &LateContext, ty: &ty::TyS, in_new_function: bool) -> bool
} else if cx.tcx.has_attr(did.did, "allow_unrooted_interior") {
false
} else if match_def_path(cx, did.did, &["core", "cell", "Ref"])
- || match_def_path(cx, did.did, &["core", "cell", "RefMut"]) {
- // Ref and RefMut are borrowed pointers, okay to hold unrooted stuff
- // since it will be rooted elsewhere
+ || match_def_path(cx, did.did, &["core", "cell", "RefMut"])
+ || match_def_path(cx, did.did, &["core", "slice", "Iter"])
+ || match_def_path(cx, did.did, &["std", "collections", "hash", "map", "OccupiedEntry"])
+ || match_def_path(cx, did.did, &["std", "collections", "hash", "map", "VacantEntry"]) {
+ // Structures which are semantically similar to an &ptr.
false
} else {
true
@@ -99,6 +97,7 @@ impl LateLintPass for UnrootedPass {
}
}
}
+
/// All enums containing #[must_root] types must be #[must_root] themselves
fn check_variant(&mut self, cx: &LateContext, var: &hir::Variant, _gen: &hir::Generics) {
let ref map = cx.tcx.map;
@@ -121,55 +120,56 @@ impl LateLintPass for UnrootedPass {
}
/// Function arguments that are #[must_root] types are not allowed
fn check_fn(&mut self, cx: &LateContext, kind: visit::FnKind, decl: &hir::FnDecl,
- block: &hir::Block, span: codemap::Span, id: ast::NodeId) {
- match kind {
+ block: &hir::Block, span: codemap::Span, _id: ast::NodeId) {
+ let in_new_function = match kind {
visit::FnKind::ItemFn(n, _, _, _, _, _) |
- visit::FnKind::Method(n, _, _) if n.as_str() == "new"
- || n.as_str().starts_with("new_") => {
- self.in_new_function = true;
- return;
- },
- visit::FnKind::ItemFn(_, _, style, _, _, _) => match style {
- hir::Unsafety::Unsafe => return,
- _ => ()
- },
- _ => ()
- }
- self.in_new_function = false;
+ visit::FnKind::Method(n, _, _) => {
+ n.as_str() == "new" || n.as_str().starts_with("new_")
+ }
+ visit::FnKind::Closure => return,
+ };
- if unsafe_context(&cx.tcx.map, id) {
- return;
+ for arg in &decl.inputs {
+ cx.tcx.ast_ty_to_ty_cache.borrow().get(&arg.ty.id).map(|t| {
+ if is_unrooted_ty(cx, t, false) {
+ if in_derive_expn(cx, span) {
+ return;
+ }
+ cx.span_lint(UNROOTED_MUST_ROOT, arg.ty.span, "Type must be rooted")
+ }
+ });
}
- match block.rules {
- hir::DefaultBlock => {
- for arg in &decl.inputs {
- cx.tcx.ast_ty_to_ty_cache.borrow().get(&arg.ty.id).map(|t| {
- if is_unrooted_ty(cx, t, false) {
- if in_derive_expn(cx, span) {
- return;
- }
- cx.span_lint(UNROOTED_MUST_ROOT, arg.ty.span, "Type must be rooted")
- }
- });
- }
- if let hir::Return(ref ty) = decl.output {
- cx.tcx.ast_ty_to_ty_cache.borrow().get(&ty.id).map(|t| {
- if is_unrooted_ty(cx, t, false) {
- if in_derive_expn(cx, span) {
- return;
- }
- cx.span_lint(UNROOTED_MUST_ROOT, ty.span, "Type must be rooted")
+ if !in_new_function {
+ if let hir::Return(ref ty) = decl.output {
+ cx.tcx.ast_ty_to_ty_cache.borrow().get(&ty.id).map(|t| {
+ if is_unrooted_ty(cx, t, false) {
+ if in_derive_expn(cx, span) {
+ return;
}
- });
- }
+ cx.span_lint(UNROOTED_MUST_ROOT, ty.span, "Type must be rooted")
+ }
+ });
}
- _ => () // fn is `unsafe`
}
+
+ let mut visitor = FnDefVisitor {
+ cx: cx,
+ in_new_function: in_new_function,
+ };
+ visit::walk_block(&mut visitor, block);
}
+}
+
+struct FnDefVisitor<'a, 'b: 'a, 'tcx: 'a+'b> {
+ cx: &'a LateContext<'b, 'tcx>,
+ in_new_function: bool,
+}
+
+impl<'a, 'b: 'a, 'tcx: 'a+'b> visit::Visitor<'a> for FnDefVisitor<'a, 'b, 'tcx> {
+ fn visit_expr(&mut self, expr: &'a hir::Expr) {
+ let cx = self.cx;
- /// Trait casts from #[must_root] types are not allowed
- fn check_expr(&mut self, cx: &LateContext, expr: &hir::Expr) {
fn require_rooted(cx: &LateContext, in_new_function: bool, subexpr: &hir::Expr) {
let ty = cx.tcx.expr_ty(&*subexpr);
if is_unrooted_ty(cx, ty, in_new_function) {
@@ -177,56 +177,52 @@ impl LateLintPass for UnrootedPass {
subexpr.span,
&format!("Expression of type {:?} must be rooted", ty))
}
- };
+ }
match expr.node {
+ /// Trait casts from #[must_root] types are not allowed
hir::ExprCast(ref subexpr, _) => require_rooted(cx, self.in_new_function, &*subexpr),
+ // This catches assignments... the main point of this would be to catch mutable
+ // references to `JS<T>`.
+ // FIXME: Enable this? Triggers on certain kinds of uses of DOMRefCell.
+ // hir::ExprAssign(_, ref rhs) => require_rooted(cx, self.in_new_function, &*rhs),
+ // This catches calls; basically, this enforces the constraint that only constructors
+ // can call other constructors.
+ // FIXME: Enable this? Currently triggers with constructs involving DOMRefCell, and
+ // constructs like Vec<JS<T>> and RootedVec<JS<T>>.
+ // hir::ExprCall(..) if !self.in_new_function => {
+ // require_rooted(cx, self.in_new_function, expr);
+ // }
_ => {
// TODO(pcwalton): Check generics with a whitelist of allowed generics.
}
}
+
+ visit::walk_expr(self, expr);
}
- // Partially copied from rustc::middle::lint::builtin
- // Catches `let` statements and assignments which store a #[must_root] value
- // Expressions which return out of blocks eventually end up in a `let` or assignment
- // statement or a function return (which will be caught when it is used elsewhere)
- fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
- match s.node {
- hir::StmtDecl(_, id) |
- hir::StmtExpr(_, id) |
- hir::StmtSemi(_, id) if unsafe_context(&cx.tcx.map, id) => {
- return
- },
- _ => ()
- };
+ fn visit_pat(&mut self, pat: &'a hir::Pat) {
+ let cx = self.cx;
- let expr = match s.node {
- // Catch a `let` binding
- hir::StmtDecl(ref decl, _) => match decl.node {
- hir::DeclLocal(ref loc) => match loc.init {
- Some(ref e) => &**e,
- _ => return
- },
- _ => return
- },
- hir::StmtExpr(ref expr, _) => match expr.node {
- // This catches deferred `let` statements
- hir::ExprAssign(_, ref e) |
- // Match statements allow you to bind onto the variable later in an arm
- // We need not check arms individually since enum/struct fields are already
- // linted in `check_struct_def` and `check_variant`
- // (so there is no way of destructuring out a `#[must_root]` field)
- hir::ExprMatch(ref e, _, _) => &**e,
- _ => return
- },
- _ => return
- };
+ if let hir::PatIdent(hir::BindByValue(_), _, _) = pat.node {
+ let ty = cx.tcx.pat_ty(pat);
+ if is_unrooted_ty(cx, ty, self.in_new_function) {
+ cx.span_lint(UNROOTED_MUST_ROOT,
+ pat.span,
+ &format!("Expression of type {:?} must be rooted", ty))
+ }
+ }
+
+ visit::walk_pat(self, pat);
+ }
- let ty = cx.tcx.expr_ty(&*expr);
- if is_unrooted_ty(cx, ty, self.in_new_function) {
- cx.span_lint(UNROOTED_MUST_ROOT, expr.span,
- &format!("Expression of type {:?} must be rooted", ty))
+ fn visit_fn(&mut self, kind: visit::FnKind<'a>, decl: &'a hir::FnDecl,
+ block: &'a hir::Block, span: codemap::Span, _id: ast::NodeId) {
+ if kind == visit::FnKind::Closure {
+ visit::walk_fn(self, kind, decl, block, span);
}
}
+
+ fn visit_foreign_item(&mut self, _: &'a hir::ForeignItem) {}
+ fn visit_ty(&mut self, _: &'a hir::Ty) { }
}
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index 6faef9b111b..a2ec90033ba 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -273,6 +273,22 @@ impl<T: HeapGCValue> HeapSizeOf for MutHeap<T> {
}
}
+impl<T: Reflectable> PartialEq for MutHeap<JS<T>> {
+ fn eq(&self, other: &Self) -> bool {
+ unsafe {
+ *self.val.get() == *other.val.get()
+ }
+ }
+}
+
+impl<T: Reflectable + PartialEq> PartialEq<T> for MutHeap<JS<T>> {
+ fn eq(&self, other: &T) -> bool {
+ unsafe {
+ **self.val.get() == *other
+ }
+ }
+}
+
/// A holder that provides interior mutability for GC-managed values such as
/// `JS<T>`, with nullability represented by an enclosing Option wrapper.
/// Essentially a `Cell<Option<JS<T>>>`, but safer.
@@ -310,11 +326,13 @@ impl<T: Reflectable> MutNullableHeap<JS<T>> {
/// Retrieve a copy of the inner optional `JS<T>` as `LayoutJS<T>`.
/// For use by layout, which can't use safe types like Temporary.
+ #[allow(unrooted_must_root)]
pub unsafe fn get_inner_as_layout(&self) -> Option<LayoutJS<T>> {
ptr::read(self.ptr.get()).map(|js| js.to_layout())
}
/// Get a rooted value out of this object
+ #[allow(unrooted_must_root)]
pub fn get(&self) -> Option<Root<T>> {
unsafe {
ptr::read(self.ptr.get()).map(|o| o.root())
@@ -332,6 +350,23 @@ impl<T: Reflectable> MutNullableHeap<JS<T>> {
*self.ptr.get() = val.map(|p| JS::from_ref(p));
}
}
+
+}
+
+impl<T: Reflectable> PartialEq for MutNullableHeap<JS<T>> {
+ fn eq(&self, other: &Self) -> bool {
+ unsafe {
+ *self.ptr.get() == *other.ptr.get()
+ }
+ }
+}
+
+impl<'a, T: Reflectable> PartialEq<Option<&'a T>> for MutNullableHeap<JS<T>> {
+ fn eq(&self, other: &Option<&T>) -> bool {
+ unsafe {
+ *self.ptr.get() == other.map(JS::from_ref)
+ }
+ }
}
impl<T: HeapGCValue> Default for MutNullableHeap<T> {
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index 5dc7f2d6215..27fdb3efa9c 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -28,7 +28,6 @@ use js::jsapi::JS_GetFunctionObject;
use js::jsapi::JS_IsExceptionPending;
use js::jsapi::JS_NewObjectWithUniqueType;
use js::jsapi::JS_ObjectToOuterObject;
-use js::jsapi::PropertyDefinitionBehavior;
use js::jsapi::{CallArgs, GetGlobalForObjectCrossCompartment, JSJitInfo};
use js::jsapi::{CompartmentOptions, OnNewGlobalHookOption};
use js::jsapi::{DOMCallbacks, JSWrapObjectCallbacks};
@@ -38,8 +37,7 @@ use js::jsapi::{JSClass, JSContext, JSObject, JSTracer};
use js::jsapi::{JSFunctionSpec, JSPropertySpec};
use js::jsapi::{JSTraceOp, JS_AlreadyHasOwnProperty, JS_NewFunction};
use js::jsapi::{JSVersion, JS_FireOnNewGlobalObject};
-use js::jsapi::{JS_DefineFunctions, JS_DefineProperty, JS_DefineProperty1};
-use js::jsapi::{JS_DefineProperties, JS_ForwardGetPropertyTo};
+use js::jsapi::{JS_DefineProperty, JS_DefineProperty1, JS_ForwardGetPropertyTo};
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype};
use js::jsapi::{JS_GetProperty, JS_HasProperty, JS_SetProperty};
use js::jsapi::{JS_GetPrototype, JS_HasPropertyById};
@@ -47,7 +45,7 @@ use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JS_InitStandardClasses, JS_NewGlobalObject};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue};
use js::jsval::{PrivateValue, UInt32Value, UndefinedValue};
-use js::rust::{GCMethods, ToString};
+use js::rust::{GCMethods, ToString, define_methods, define_properties};
use js::{JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE, JS_CALLEE};
use js::{JSPROP_PERMANENT, JSPROP_READONLY};
use libc::{self, c_uint};
@@ -305,28 +303,28 @@ fn create_interface_object(cx: *mut JSContext,
ctor_nargs: u32, proto: HandleObject,
members: &'static NativeProperties,
name: *const libc::c_char) {
- let constructor = RootedObject::new(cx, create_constructor(cx, constructor_native, ctor_nargs, name));
- assert!(!constructor.ptr.is_null());
+ unsafe {
+ let constructor = RootedObject::new(cx, create_constructor(cx, constructor_native, ctor_nargs, name));
+ assert!(!constructor.ptr.is_null());
- if let Some(static_methods) = members.static_methods {
- define_methods(cx, constructor.handle(), static_methods);
- }
+ if let Some(static_methods) = members.static_methods {
+ define_methods(cx, constructor.handle(), static_methods).unwrap();
+ }
- if let Some(static_properties) = members.static_attrs {
- define_properties(cx, constructor.handle(), static_properties);
- }
+ if let Some(static_properties) = members.static_attrs {
+ define_properties(cx, constructor.handle(), static_properties).unwrap();
+ }
- if let Some(constants) = members.consts {
- define_constants(cx, constructor.handle(), constants);
- }
+ if let Some(constants) = members.consts {
+ define_constants(cx, constructor.handle(), constants);
+ }
- unsafe {
if !proto.get().is_null() {
assert!(JS_LinkConstructorAndPrototype(cx, constructor.handle(), proto));
}
- }
- define_constructor(cx, receiver, name, constructor.handle());
+ define_constructor(cx, receiver, name, constructor.handle());
+ }
}
/// Defines constants on `obj`.
@@ -344,26 +342,6 @@ fn define_constants(cx: *mut JSContext, obj: HandleObject,
}
}
-/// Defines methods on `obj`. The last entry of `methods` must contain zeroed
-/// memory.
-/// Fails on JSAPI failure.
-fn define_methods(cx: *mut JSContext, obj: HandleObject,
- methods: &'static [JSFunctionSpec]) {
- unsafe {
- assert!(JS_DefineFunctions(cx, obj, methods.as_ptr(), PropertyDefinitionBehavior::DefineAllProperties));
- }
-}
-
-/// Defines attributes on `obj`. The last entry of `properties` must contain
-/// zeroed memory.
-/// Fails on JSAPI failure.
-fn define_properties(cx: *mut JSContext, obj: HandleObject,
- properties: &'static [JSPropertySpec]) {
- unsafe {
- assert!(JS_DefineProperties(cx, obj, properties.as_ptr()));
- }
-}
-
/// Creates the *interface prototype object*.
/// Fails on JSAPI failure.
fn create_interface_prototype_object(cx: *mut JSContext, global: HandleObject,
@@ -375,11 +353,11 @@ fn create_interface_prototype_object(cx: *mut JSContext, global: HandleObject,
assert!(!rval.get().is_null());
if let Some(methods) = members.methods {
- define_methods(cx, rval.handle(), methods);
+ define_methods(cx, rval.handle(), methods).unwrap();
}
if let Some(properties) = members.attrs {
- define_properties(cx, rval.handle(), properties);
+ define_properties(cx, rval.handle(), properties).unwrap();
}
if let Some(constants) = members.consts {
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index f14612d1f2f..aa7936f69f5 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -431,6 +431,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SaveContext)).unwrap();
}
+ #[allow(unrooted_must_root)]
// https://html.spec.whatwg.org/multipage/#dom-context-2d-restore
fn Restore(&self) {
let mut saved_states = self.saved_states.borrow_mut();
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index f0d078fbaf1..1be58932305 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -1461,6 +1461,11 @@ impl ElementMethods for Element {
}
}
+ // https://dom.spec.whatwg.org/#dom-element-webkitmatchesselector
+ fn WebkitMatchesSelector(&self, selectors: DOMString) -> Fallible<bool> {
+ self.Matches(selectors)
+ }
+
// https://dom.spec.whatwg.org/#dom-element-closest
fn Closest(&self, selectors: DOMString) -> Fallible<Option<Root<Element>>> {
match parse_author_origin_selector_list_from_str(&selectors) {
diff --git a/components/script/dom/filelist.rs b/components/script/dom/filelist.rs
index 57542b0a51d..d695ac8f43a 100644
--- a/components/script/dom/filelist.rs
+++ b/components/script/dom/filelist.rs
@@ -18,6 +18,7 @@ pub struct FileList {
}
impl FileList {
+ #[allow(unrooted_must_root)]
fn new_inherited(files: Vec<JS<File>>) -> FileList {
FileList {
reflector_: Reflector::new(),
@@ -25,6 +26,7 @@ impl FileList {
}
}
+ #[allow(unrooted_must_root)]
pub fn new(window: &Window, files: Vec<JS<File>>) -> Root<FileList> {
reflect_dom_object(box FileList::new_inherited(files), GlobalRef::Window(window), FileListBinding::Wrap)
}
diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs
index dda2bd9b3b8..4ddc0fef6dd 100644
--- a/components/script/dom/htmlcollection.rs
+++ b/components/script/dom/htmlcollection.rs
@@ -32,6 +32,7 @@ pub struct HTMLCollection {
}
impl HTMLCollection {
+ #[allow(unrooted_must_root)]
fn new_inherited(collection: Collection) -> HTMLCollection {
HTMLCollection {
reflector_: Reflector::new(),
@@ -39,6 +40,7 @@ impl HTMLCollection {
}
}
+ #[allow(unrooted_must_root)]
pub fn new(window: &Window, collection: Collection) -> Root<HTMLCollection> {
reflect_dom_object(box HTMLCollection::new_inherited(collection),
GlobalRef::Window(window), HTMLCollectionBinding::Wrap)
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index 2ed127dd2dc..490df73bd56 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -27,6 +27,7 @@ pub struct NodeList {
}
impl NodeList {
+ #[allow(unrooted_must_root)]
fn new_inherited(list_type: NodeListType) -> NodeList {
NodeList {
reflector_: Reflector::new(),
@@ -34,6 +35,7 @@ impl NodeList {
}
}
+ #[allow(unrooted_must_root)]
pub fn new(window: &Window,
list_type: NodeListType) -> Root<NodeList> {
reflect_dom_object(box NodeList::new_inherited(list_type),
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index c7011c8e056..749885571eb 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -109,6 +109,7 @@ impl WebGLRenderingContext {
})
}
+ #[allow(unrooted_must_root)]
pub fn new(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>, attrs: GLContextAttributes)
-> Option<Root<WebGLRenderingContext>> {
match WebGLRenderingContext::new_inherited(global, canvas, size, attrs) {
diff --git a/components/script/dom/webidls/Element.webidl b/components/script/dom/webidls/Element.webidl
index b5b35f8e802..2e3deb6adb0 100644
--- a/components/script/dom/webidls/Element.webidl
+++ b/components/script/dom/webidls/Element.webidl
@@ -55,6 +55,8 @@ interface Element : Node {
[Pure, Throws]
boolean matches(DOMString selectors);
+ [Pure, Throws]
+ boolean webkitMatchesSelector(DOMString selectors);
HTMLCollection getElementsByTagName(DOMString localName);
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index a2844fb225a..f112af3d8bd 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -942,7 +942,7 @@ dependencies = [
[[package]]
name = "js"
version = "0.1.0"
-source = "git+https://github.com/servo/rust-mozjs#01ff3cb8cb253a8a634cf6aecf64c10bf9c7d8c4"
+source = "git+https://github.com/servo/rust-mozjs#cb290c48a75852fb26ed67b3ef3e2508c1560b1a"
dependencies = [
"heapsize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",