aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-10-16 08:05:59 -0600
committerbors-servo <metajack+bors@gmail.com>2015-10-16 08:05:59 -0600
commit7c7dbde0f4372037aac3635b8d81531ca9cdced3 (patch)
tree3d79eaaa41515448e95248343e22fd5232b48ee4 /components/script/dom
parented7ddaa97a962a36c0e2ebab1f256fbd807cca3f (diff)
parent9de42c893541aa87c563ab534e0c5209cca251fd (diff)
downloadservo-7c7dbde0f4372037aac3635b8d81531ca9cdced3.tar.gz
servo-7c7dbde0f4372037aac3635b8d81531ca9cdced3.zip
Auto merge of #8026 - eefriedman:js-rooting, r=nox
Fix uses of JS<T> as a type on the stack `JS<T>` belongs on the heap, and only on the heap. This is a collection of fixes so that code uses either `Root<T>` or `&T` to pass around garbage-collected pointers. Ideally, we could completely ban constructing a `JS<T>` outside of constructor functions, but we aren't quite there yet. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8026) <!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/attr.rs4
-rw-r--r--components/script/dom/bindings/js.rs126
-rw-r--r--components/script/dom/browsercontext.rs2
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs4
-rw-r--r--components/script/dom/document.rs13
-rw-r--r--components/script/dom/event.rs4
-rw-r--r--components/script/dom/filereader.rs6
-rw-r--r--components/script/dom/htmlcanvaselement.rs63
-rw-r--r--components/script/dom/htmlinputelement.rs2
-rw-r--r--components/script/dom/mouseevent.rs2
-rw-r--r--components/script/dom/node.rs46
-rw-r--r--components/script/dom/nodeiterator.rs16
-rw-r--r--components/script/dom/nodelist.rs34
-rw-r--r--components/script/dom/storageevent.rs2
-rw-r--r--components/script/dom/treewalker.rs32
-rw-r--r--components/script/dom/uievent.rs2
-rw-r--r--components/script/dom/webglprogram.rs2
-rw-r--r--components/script/dom/webglrenderingcontext.rs16
18 files changed, 197 insertions, 179 deletions
diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs
index 465ed0f4042..8f545dac744 100644
--- a/components/script/dom/attr.rs
+++ b/components/script/dom/attr.rs
@@ -180,7 +180,7 @@ impl Attr {
name: name,
namespace: namespace,
prefix: prefix,
- owner: MutNullableHeap::new(owner.map(JS::from_ref)),
+ owner: MutNullableHeap::new(owner),
}
}
@@ -315,7 +315,7 @@ impl Attr {
}
(old, new) => assert!(old == new)
}
- self.owner.set(owner.map(JS::from_ref))
+ self.owner.set(owner);
}
pub fn owner(&self) -> Option<Root<Element>> {
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index 16fa12e7189..aea80d88431 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -32,13 +32,19 @@ use js::jsapi::{Heap, JSObject, JSTracer};
use js::jsval::JSVal;
use layout_interface::TrustedNodeAddress;
use script_task::STACK_ROOTS;
-use std::cell::{Cell, UnsafeCell};
+use std::cell::UnsafeCell;
use std::default::Default;
use std::ops::Deref;
+use std::ptr;
use util::mem::HeapSizeOf;
-/// A traced reference to a DOM object. Must only be used as a field in other
-/// DOM objects.
+/// A traced reference to a DOM object
+///
+/// This type is critical to making garbage collection work with the DOM,
+/// but it is very dangerous; if garbage collection happens with a `JS<T>`
+/// on the stack, the `JS<T>` can point to freed memory.
+///
+/// This should only be used as a field in other DOM objects.
#[must_root]
pub struct JS<T> {
ptr: NonZero<*const T>
@@ -54,12 +60,13 @@ impl<T> HeapSizeOf for JS<T> {
impl<T> JS<T> {
/// Returns `LayoutJS<T>` containing the same pointer.
- pub unsafe fn to_layout(self) -> LayoutJS<T> {
+ pub unsafe fn to_layout(&self) -> LayoutJS<T> {
LayoutJS {
ptr: self.ptr.clone()
}
}
}
+
impl<T: Reflectable> JS<T> {
/// Root this JS-owned value to prevent its collection as garbage.
pub fn root(&self) -> Root<T> {
@@ -109,8 +116,6 @@ impl<T: Reflectable> LayoutJS<T> {
}
}
-impl<T> Copy for JS<T> {}
-
impl<T> Copy for LayoutJS<T> {}
impl<T> PartialEq for JS<T> {
@@ -205,73 +210,76 @@ impl MutHeapJSVal {
/// A holder that provides interior mutability for GC-managed values such as
-/// `JS<T>`.
+/// `JS<T>`. Essentially a `Cell<JS<T>>`, but safer.
+///
+/// This should only be used as a field in other DOM objects; see warning
+/// on `JS<T>`.
#[must_root]
#[derive(JSTraceable)]
-#[derive(HeapSizeOf)]
-pub struct MutHeap<T: HeapGCValue + Copy> {
- val: Cell<T>,
+pub struct MutHeap<T: HeapGCValue> {
+ val: UnsafeCell<T>,
}
-impl<T: HeapGCValue + Copy> MutHeap<T> {
+impl<T: Reflectable> MutHeap<JS<T>> {
/// Create a new `MutHeap`.
- pub fn new(initial: T) -> MutHeap<T> {
+ pub fn new(initial: &T) -> MutHeap<JS<T>> {
MutHeap {
- val: Cell::new(initial),
+ val: UnsafeCell::new(JS::from_ref(initial)),
}
}
/// Set this `MutHeap` to the given value.
- pub fn set(&self, val: T) {
- self.val.set(val)
+ pub fn set(&self, val: &T) {
+ unsafe {
+ *self.val.get() = JS::from_ref(val);
+ }
}
/// Set the value in this `MutHeap`.
- pub fn get(&self) -> T {
- self.val.get()
+ pub fn get(&self) -> Root<T> {
+ unsafe {
+ ptr::read(self.val.get()).root()
+ }
+ }
+}
+
+impl<T: HeapGCValue> HeapSizeOf for MutHeap<T> {
+ fn heap_size_of_children(&self) -> usize {
+ // See comment on HeapSizeOf for JS<T>.
+ 0
}
}
-/// A mutable holder for GC-managed values such as `JSval` and `JS<T>`, with
-/// nullability represented by an enclosing Option wrapper. Must be used in
-/// place of traditional internal mutability to ensure that the proper GC
-/// barriers are enforced.
+/// 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.
+///
+/// This should only be used as a field in other DOM objects; see warning
+/// on `JS<T>`.
#[must_root]
-#[derive(JSTraceable, HeapSizeOf)]
-pub struct MutNullableHeap<T: HeapGCValue + Copy> {
- ptr: Cell<Option<T>>
+#[derive(JSTraceable)]
+pub struct MutNullableHeap<T: HeapGCValue> {
+ ptr: UnsafeCell<Option<T>>
}
-impl<T: HeapGCValue + Copy> MutNullableHeap<T> {
+impl<T: Reflectable> MutNullableHeap<JS<T>> {
/// Create a new `MutNullableHeap`.
- pub fn new(initial: Option<T>) -> MutNullableHeap<T> {
+ pub fn new(initial: Option<&T>) -> MutNullableHeap<JS<T>> {
MutNullableHeap {
- ptr: Cell::new(initial)
+ ptr: UnsafeCell::new(initial.map(JS::from_ref))
}
}
- /// Set this `MutNullableHeap` to the given value.
- pub fn set(&self, val: Option<T>) {
- self.ptr.set(val);
- }
-
- /// Retrieve a copy of the current optional inner value.
- pub fn get(&self) -> Option<T> {
- self.ptr.get()
- }
-}
-
-impl<T: Reflectable> MutNullableHeap<JS<T>> {
/// Retrieve a copy of the current inner value. If it is `None`, it is
/// initialized with the result of `cb` first.
pub fn or_init<F>(&self, cb: F) -> Root<T>
where F: FnOnce() -> Root<T>
{
match self.get() {
- Some(inner) => Root::from_rooted(inner),
+ Some(inner) => inner,
None => {
let inner = cb();
- self.set(Some(JS::from_rooted(&inner)));
+ self.set(Some(&inner));
inner
},
}
@@ -280,25 +288,45 @@ 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.
pub unsafe fn get_inner_as_layout(&self) -> Option<LayoutJS<T>> {
- self.ptr.get().map(|js| js.to_layout())
+ ptr::read(self.ptr.get()).map(|js| js.to_layout())
+ }
+
+ /// Get a rooted value out of this object
+ pub fn get(&self) -> Option<Root<T>> {
+ unsafe {
+ ptr::read(self.ptr.get()).map(|o| o.root())
+ }
}
/// Get a rooted value out of this object
- // FIXME(#6684)
pub fn get_rooted(&self) -> Option<Root<T>> {
- self.get().map(|o| o.root())
+ self.get()
+ }
+
+ /// Set this `MutNullableHeap` to the given value.
+ pub fn set(&self, val: Option<&T>) {
+ unsafe {
+ *self.ptr.get() = val.map(|p| JS::from_ref(p));
+ }
}
}
-impl<T: HeapGCValue + Copy> Default for MutNullableHeap<T> {
+impl<T: HeapGCValue> Default for MutNullableHeap<T> {
#[allow(unrooted_must_root)]
fn default() -> MutNullableHeap<T> {
MutNullableHeap {
- ptr: Cell::new(None)
+ ptr: UnsafeCell::new(None)
}
}
}
+impl<T: HeapGCValue> HeapSizeOf for MutNullableHeap<T> {
+ fn heap_size_of_children(&self) -> usize {
+ // See comment on HeapSizeOf for JS<T>.
+ 0
+ }
+}
+
impl<T: Reflectable> LayoutJS<T> {
/// Returns an unsafe pointer to the interior of this JS object. This is
/// the only method that be safely accessed from layout. (The fact that
@@ -435,12 +463,6 @@ impl<T: Reflectable> Root<T> {
pub fn r(&self) -> &T {
&**self
}
-
- /// Generate a new root from a JS<T> reference
- #[allow(unrooted_must_root)]
- pub fn from_rooted(js: JS<T>) -> Root<T> {
- js.root()
- }
}
impl<T: Reflectable> Deref for Root<T> {
diff --git a/components/script/dom/browsercontext.rs b/components/script/dom/browsercontext.rs
index 3df44a5ba9b..af2bfbdc81e 100644
--- a/components/script/dom/browsercontext.rs
+++ b/components/script/dom/browsercontext.rs
@@ -54,7 +54,7 @@ impl BrowsingContext {
}
pub fn frame_element(&self) -> Option<Root<Element>> {
- self.frame_element.map(Root::from_rooted)
+ self.frame_element.as_ref().map(JS::root)
}
pub fn window_proxy(&self) -> *mut JSObject {
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 3664574814e..89d07cf815c 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -763,7 +763,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
serialize(rgba, &mut result).unwrap();
StringOrCanvasGradientOrCanvasPattern::eString(result)
},
- CanvasFillOrStrokeStyle::Gradient(gradient) => {
+ CanvasFillOrStrokeStyle::Gradient(ref gradient) => {
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient.root())
},
}
@@ -803,7 +803,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
serialize(rgba, &mut result).unwrap();
StringOrCanvasGradientOrCanvasPattern::eString(result)
},
- CanvasFillOrStrokeStyle::Gradient(gradient) => {
+ CanvasFillOrStrokeStyle::Gradient(ref gradient) => {
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient.root())
},
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 0419895233b..175cc68ea9d 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -297,7 +297,7 @@ impl Document {
.filter_map(HTMLBaseElementCast::to_root)
.filter(|element| ElementCast::from_ref(&**element).has_attribute(&atom!("href")))
.next();
- self.base_element.set(base.map(|element| JS::from_ref(&*element)));
+ self.base_element.set(base.r());
}
pub fn quirks_mode(&self) -> QuirksMode {
@@ -506,7 +506,7 @@ impl Document {
/// Request that the given element receive focus once the current transaction is complete.
pub fn request_focus(&self, elem: &Element) {
if elem.is_focusable_area() {
- self.possibly_focused.set(Some(JS::from_ref(elem)))
+ self.possibly_focused.set(Some(elem))
}
}
@@ -520,7 +520,7 @@ impl Document {
node.set_focus_state(false);
}
- self.focused.set(self.possibly_focused.get());
+ self.focused.set(self.possibly_focused.get().r());
if let Some(ref elem) = self.focused.get_rooted() {
let node = NodeCast::from_ref(elem.r());
@@ -852,7 +852,7 @@ impl Document {
}
pub fn set_current_script(&self, script: Option<&HTMLScriptElement>) {
- self.current_script.set(script.map(JS::from_ref));
+ self.current_script.set(script);
}
pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) {
@@ -959,7 +959,7 @@ impl Document {
}
pub fn set_current_parser(&self, script: Option<&ServoHTMLParser>) {
- self.current_parser.set(script.map(JS::from_ref));
+ self.current_parser.set(script);
}
pub fn get_current_parser(&self) -> Option<Root<ServoHTMLParser>> {
@@ -1119,8 +1119,7 @@ impl Document {
let new_doc = Document::new(
&*self.window(), None, doctype, None, None,
DocumentSource::NotFromParser, DocumentLoader::new(&self.loader()));
- new_doc.appropriate_template_contents_owner_document.set(
- Some(JS::from_ref(&*new_doc)));
+ new_doc.appropriate_template_contents_owner_document.set(Some(&new_doc));
new_doc
})
}
diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs
index c3a8a52dc55..10118923f56 100644
--- a/components/script/dom/event.rs
+++ b/components/script/dom/event.rs
@@ -106,12 +106,12 @@ impl Event {
#[inline]
pub fn set_current_target(&self, val: &EventTarget) {
- self.current_target.set(Some(JS::from_ref(val)));
+ self.current_target.set(Some(val));
}
#[inline]
pub fn set_target(&self, val: &EventTarget) {
- self.target.set(Some(JS::from_ref(val)));
+ self.target.set(Some(val));
}
#[inline]
diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs
index 3ae20361ab6..a659908f31c 100644
--- a/components/script/dom/filereader.rs
+++ b/components/script/dom/filereader.rs
@@ -116,7 +116,7 @@ impl FileReader {
let global = fr.global.root();
let exception = DOMException::new(global.r(), error);
- fr.error.set(Some(JS::from_rooted(&exception)));
+ fr.error.set(Some(&exception));
fr.dispatch_progress_event("error".to_owned(), 0, None);
return_on_abort!();
@@ -292,7 +292,7 @@ impl FileReaderMethods for FileReader {
let global = self.global.root();
let exception = DOMException::new(global.r(), DOMErrorName::AbortError);
- self.error.set(Some(JS::from_rooted(&exception)));
+ self.error.set(Some(&exception));
self.terminate_ongoing_reading();
// Steps 5 & 6
@@ -346,7 +346,7 @@ impl FileReader {
if blob.IsClosed() {
let global = self.global.root();
let exception = DOMException::new(global.r(), DOMErrorName::InvalidStateError);
- self.error.set(Some(JS::from_rooted(&exception)));
+ self.error.set(Some(&exception));
self.dispatch_progress_event("error".to_owned(), 0, None);
return Ok(());
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index f698f42fe26..2fffe51134f 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -4,13 +4,14 @@
use canvas_traits::{CanvasMsg, FromLayoutMsg};
use dom::attr::Attr;
+use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
use dom::bindings::global::GlobalRef;
-use dom::bindings::js::{HeapGCValue, JS, LayoutJS, MutNullableHeap, Root};
+use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
use dom::bindings::utils::{Reflectable};
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
use dom::document::Document;
@@ -24,7 +25,6 @@ use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{HandleValue, JSContext};
use offscreen_gl_context::GLContextAttributes;
use std::cell::Cell;
-use std::default::Default;
use std::iter::repeat;
use util::str::{DOMString, parse_unsigned_integer};
@@ -32,7 +32,7 @@ const DEFAULT_WIDTH: u32 = 300;
const DEFAULT_HEIGHT: u32 = 150;
#[must_root]
-#[derive(JSTraceable, Clone, Copy, HeapSizeOf)]
+#[derive(JSTraceable, Clone, HeapSizeOf)]
pub enum CanvasContext {
Context2d(JS<CanvasRenderingContext2D>),
WebGL(JS<WebGLRenderingContext>),
@@ -43,7 +43,7 @@ impl HeapGCValue for CanvasContext {}
#[dom_struct]
pub struct HTMLCanvasElement {
htmlelement: HTMLElement,
- context: MutNullableHeap<CanvasContext>,
+ context: DOMRefCell<Option<CanvasContext>>,
width: Cell<u32>,
height: Cell<u32>,
}
@@ -59,9 +59,8 @@ impl HTMLCanvasElement {
prefix: Option<DOMString>,
document: &Document) -> HTMLCanvasElement {
HTMLCanvasElement {
- htmlelement:
- HTMLElement::new_inherited(localName, prefix, document),
- context: Default::default(),
+ htmlelement: HTMLElement::new_inherited(localName, prefix, document),
+ context: DOMRefCell::new(None),
width: Cell::new(DEFAULT_WIDTH),
height: Cell::new(DEFAULT_HEIGHT),
}
@@ -77,10 +76,10 @@ impl HTMLCanvasElement {
fn recreate_contexts(&self) {
let size = self.get_size();
- if let Some(context) = self.context.get() {
- match context {
- CanvasContext::Context2d(context) => context.root().r().recreate(size),
- CanvasContext::WebGL(context) => context.root().r().recreate(size),
+ if let Some(ref context) = *self.context.borrow() {
+ match *context {
+ CanvasContext::Context2d(ref context) => context.root().r().recreate(size),
+ CanvasContext::WebGL(ref context) => context.root().r().recreate(size),
}
}
}
@@ -105,10 +104,10 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
#[allow(unsafe_code)]
unsafe fn get_renderer_id(&self) -> Option<usize> {
let ref canvas = *self.unsafe_get();
- canvas.context.get().map(|context| {
- match context {
- CanvasContext::Context2d(context) => context.to_layout().get_renderer_id(),
- CanvasContext::WebGL(context) => context.to_layout().get_renderer_id(),
+ canvas.context.borrow_for_layout().as_ref().map(|context| {
+ match *context {
+ CanvasContext::Context2d(ref context) => context.to_layout().get_renderer_id(),
+ CanvasContext::WebGL(ref context) => context.to_layout().get_renderer_id(),
}
})
}
@@ -116,10 +115,10 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
#[allow(unsafe_code)]
unsafe fn get_ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
let ref canvas = *self.unsafe_get();
- canvas.context.get().map(|context| {
- match context {
- CanvasContext::Context2d(context) => context.to_layout().get_ipc_renderer(),
- CanvasContext::WebGL(context) => context.to_layout().get_ipc_renderer(),
+ canvas.context.borrow_for_layout().as_ref().map(|context| {
+ match *context {
+ CanvasContext::Context2d(ref context) => context.to_layout().get_ipc_renderer(),
+ CanvasContext::WebGL(ref context) => context.to_layout().get_ipc_renderer(),
}
})
}
@@ -138,24 +137,24 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
impl HTMLCanvasElement {
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
- self.context.get().map(|context| {
- match context {
- CanvasContext::Context2d(context) => context.root().r().ipc_renderer(),
- CanvasContext::WebGL(context) => context.root().r().ipc_renderer(),
+ self.context.borrow().as_ref().map(|context| {
+ match *context {
+ CanvasContext::Context2d(ref context) => context.root().r().ipc_renderer(),
+ CanvasContext::WebGL(ref context) => context.root().r().ipc_renderer(),
}
})
}
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
- if self.context.get().is_none() {
+ if self.context.borrow().is_none() {
let window = window_from_node(self);
let size = self.get_size();
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
- self.context.set(Some(CanvasContext::Context2d(JS::from_rooted(&context))));
+ *self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
}
- match self.context.get().unwrap() {
- CanvasContext::Context2d(context) => Some(context.root()),
+ match *self.context.borrow().as_ref().unwrap() {
+ CanvasContext::Context2d(ref context) => Some(context.root()),
_ => None,
}
}
@@ -163,7 +162,7 @@ impl HTMLCanvasElement {
pub fn get_or_init_webgl_context(&self,
cx: *mut JSContext,
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
- if self.context.get().is_none() {
+ if self.context.borrow().is_none() {
let window = window_from_node(self);
let size = self.get_size();
@@ -180,12 +179,12 @@ impl HTMLCanvasElement {
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
- self.context.set(maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx))));
+ *self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
}
- if let Some(context) = self.context.get() {
- match context {
- CanvasContext::WebGL(context) => Some(context.root()),
+ if let Some(ref context) = *self.context.borrow() {
+ match *context {
+ CanvasContext::WebGL(ref context) => Some(context.root()),
_ => None,
}
} else {
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index cc0aabdc9cb..cdfe8716775 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -758,7 +758,7 @@ impl Activatable for HTMLInputElement {
InputType::InputRadio => {
// We want to restore state only if the element had been changed in the first place
if cache.was_mutable {
- let old_checked: Option<Root<HTMLInputElement>> = cache.checked_radio.map(|t| t.root());
+ let old_checked = cache.checked_radio.as_ref().map(|t| t.root());
let name = self.get_radio_group_name();
match old_checked {
Some(ref o) => {
diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs
index 5f05fc97b77..eb57489c1e4 100644
--- a/components/script/dom/mouseevent.rs
+++ b/components/script/dom/mouseevent.rs
@@ -205,6 +205,6 @@ impl MouseEventMethods for MouseEvent {
self.shift_key.set(shiftKeyArg);
self.meta_key.set(metaKeyArg);
self.button.set(buttonArg);
- self.related_target.set(relatedTargetArg.map(JS::from_ref));
+ self.related_target.set(relatedTargetArg);
}
}
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index d5e7f5c6e83..daacdd09fa0 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -271,32 +271,32 @@ impl Node {
match prev_sibling {
None => {
assert!(Some(*before) == self.first_child.get_rooted().r());
- self.first_child.set(Some(JS::from_ref(new_child)));
+ self.first_child.set(Some(new_child));
},
Some(ref prev_sibling) => {
- prev_sibling.next_sibling.set(Some(JS::from_ref(new_child)));
- new_child.prev_sibling.set(Some(JS::from_ref(prev_sibling.r())));
+ prev_sibling.next_sibling.set(Some(new_child));
+ new_child.prev_sibling.set(Some(prev_sibling.r()));
},
}
- before.prev_sibling.set(Some(JS::from_ref(new_child)));
- new_child.next_sibling.set(Some(JS::from_ref(before)));
+ before.prev_sibling.set(Some(new_child));
+ new_child.next_sibling.set(Some(before));
},
None => {
let last_child = self.GetLastChild();
match last_child {
- None => self.first_child.set(Some(JS::from_ref(new_child))),
+ None => self.first_child.set(Some(new_child)),
Some(ref last_child) => {
assert!(last_child.next_sibling.get().is_none());
- last_child.r().next_sibling.set(Some(JS::from_ref(new_child)));
- new_child.prev_sibling.set(Some(JS::from_rooted(&last_child)));
+ last_child.r().next_sibling.set(Some(new_child));
+ new_child.prev_sibling.set(Some(&last_child));
}
}
- self.last_child.set(Some(JS::from_ref(new_child)));
+ self.last_child.set(Some(new_child));
},
}
- new_child.parent_node.set(Some(JS::from_ref(self)));
+ new_child.parent_node.set(Some(self));
let parent_in_doc = self.is_in_doc();
for node in new_child.traverse_preorder() {
@@ -315,19 +315,19 @@ impl Node {
let prev_sibling = child.GetPreviousSibling();
match prev_sibling {
None => {
- self.first_child.set(child.next_sibling.get());
+ self.first_child.set(child.next_sibling.get().r());
}
Some(ref prev_sibling) => {
- prev_sibling.next_sibling.set(child.next_sibling.get());
+ prev_sibling.next_sibling.set(child.next_sibling.get().r());
}
}
let next_sibling = child.GetNextSibling();
match next_sibling {
None => {
- self.last_child.set(child.prev_sibling.get());
+ self.last_child.set(child.prev_sibling.get().r());
}
Some(ref next_sibling) => {
- next_sibling.prev_sibling.set(child.prev_sibling.get());
+ next_sibling.prev_sibling.set(child.prev_sibling.get().r());
}
}
@@ -591,7 +591,7 @@ impl Node {
match self.parent_node.get() {
None => return,
Some(parent) => parent,
- }.root();
+ };
for sibling in parent.r().children() {
sibling.r().set_has_dirty_siblings(true);
@@ -660,7 +660,7 @@ impl Node {
pub fn is_parent_of(&self, child: &Node) -> bool {
match child.parent_node.get() {
- Some(ref parent) => parent.root().r() == self,
+ Some(ref parent) => parent.r() == self,
None => false,
}
}
@@ -689,7 +689,7 @@ impl Node {
// Step 2.
let parent = match parent.get() {
None => return Ok(()),
- Some(ref parent) => parent.root(),
+ Some(parent) => parent,
};
// Step 3.
@@ -702,7 +702,7 @@ impl Node {
let viable_previous_sibling = match viable_previous_sibling {
Some(ref viable_previous_sibling) => viable_previous_sibling.next_sibling.get(),
None => parent.first_child.get(),
- }.map(|s| s.root());
+ };
// Step 6.
try!(Node::pre_insert(&node, &parent, viable_previous_sibling.r()));
@@ -718,7 +718,7 @@ impl Node {
// Step 2.
let parent = match parent.get() {
None => return Ok(()),
- Some(ref parent) => parent.root(),
+ Some(parent) => parent,
};
// Step 3.
@@ -745,7 +745,7 @@ impl Node {
let doc = self.owner_doc();
let node = try!(doc.r().node_from_nodes_and_strings(nodes));
// Step 3.
- parent_node.root().r().ReplaceChild(node.r(), self).map(|_| ())
+ parent_node.r().ReplaceChild(node.r(), self).map(|_| ())
},
}
}
@@ -823,11 +823,11 @@ impl Node {
}
pub fn owner_doc(&self) -> Root<Document> {
- self.owner_doc.get().unwrap().root()
+ self.owner_doc.get().unwrap()
}
pub fn set_owner_doc(&self, document: &Document) {
- self.owner_doc.set(Some(JS::from_ref(document)));
+ self.owner_doc.set(Some(document));
}
pub fn is_in_html_doc(&self) -> bool {
@@ -1367,7 +1367,7 @@ impl Node {
last_child: Default::default(),
next_sibling: Default::default(),
prev_sibling: Default::default(),
- owner_doc: MutNullableHeap::new(doc.map(JS::from_ref)),
+ owner_doc: MutNullableHeap::new(doc),
child_list: Default::default(),
children_count: Cell::new(0u32),
flags: Cell::new(flags),
diff --git a/components/script/dom/nodeiterator.rs b/components/script/dom/nodeiterator.rs
index 34ec3f6c658..c7152231776 100644
--- a/components/script/dom/nodeiterator.rs
+++ b/components/script/dom/nodeiterator.rs
@@ -36,7 +36,7 @@ impl NodeIterator {
NodeIterator {
reflector_: Reflector::new(),
root_node: JS::from_ref(root_node),
- reference_node: MutHeap::new(JS::from_ref(root_node)),
+ reference_node: MutHeap::new(root_node),
pointer_before_reference_node: Cell::new(true),
what_to_show: what_to_show,
filter: filter
@@ -87,7 +87,7 @@ impl NodeIteratorMethods for NodeIterator {
// https://dom.spec.whatwg.org/#dom-nodeiterator-referencenode
fn ReferenceNode(&self) -> Root<Node> {
- self.reference_node.get().root()
+ self.reference_node.get()
}
// https://dom.spec.whatwg.org/#dom-nodeiterator-pointerbeforereferencenode
@@ -99,7 +99,7 @@ impl NodeIteratorMethods for NodeIterator {
fn NextNode(&self) -> Fallible<Option<Root<Node>>> {
// https://dom.spec.whatwg.org/#concept-NodeIterator-traverse
// Step 1.
- let node = self.reference_node.get().root();
+ let node = self.reference_node.get();
// Step 2.
let mut before_node = self.pointer_before_reference_node.get();
@@ -114,7 +114,7 @@ impl NodeIteratorMethods for NodeIterator {
// Step 3-3.
if result == NodeFilterConstants::FILTER_ACCEPT {
// Step 4.
- self.reference_node.set(JS::from_ref(node.r()));
+ self.reference_node.set(node.r());
self.pointer_before_reference_node.set(before_node);
return Ok(Some(node));
@@ -129,7 +129,7 @@ impl NodeIteratorMethods for NodeIterator {
// Step 3-3.
if result == NodeFilterConstants::FILTER_ACCEPT {
// Step 4.
- self.reference_node.set(JS::from_ref(following_node.r()));
+ self.reference_node.set(following_node.r());
self.pointer_before_reference_node.set(before_node);
return Ok(Some(following_node));
@@ -143,7 +143,7 @@ impl NodeIteratorMethods for NodeIterator {
fn PreviousNode(&self) -> Fallible<Option<Root<Node>>> {
// https://dom.spec.whatwg.org/#concept-NodeIterator-traverse
// Step 1.
- let node = self.reference_node.get().root();
+ let node = self.reference_node.get();
// Step 2.
let mut before_node = self.pointer_before_reference_node.get();
@@ -158,7 +158,7 @@ impl NodeIteratorMethods for NodeIterator {
// Step 3-3.
if result == NodeFilterConstants::FILTER_ACCEPT {
// Step 4.
- self.reference_node.set(JS::from_ref(node.r()));
+ self.reference_node.set(node.r());
self.pointer_before_reference_node.set(before_node);
return Ok(Some(node));
@@ -174,7 +174,7 @@ impl NodeIteratorMethods for NodeIterator {
// Step 3-3.
if result == NodeFilterConstants::FILTER_ACCEPT {
// Step 4.
- self.reference_node.set(JS::from_ref(preceding_node.r()));
+ self.reference_node.set(preceding_node.r());
self.pointer_before_reference_node.set(before_node);
return Ok(Some(preceding_node));
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index d997cad2558..b5db05945ca 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::NodeListBinding;
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use dom::bindings::global::GlobalRef;
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::node::{ChildrenMutation, Node};
use dom::window::Window;
@@ -64,7 +64,7 @@ impl NodeListMethods for NodeList {
fn Item(&self, index: u32) -> Option<Root<Node>> {
match self.list_type {
NodeListType::Simple(ref elems) => {
- elems.get(index as usize).map(|node| Root::from_rooted(*node))
+ elems.get(index as usize).map(|node| node.root())
},
NodeListType::Children(ref list) => list.item(index),
}
@@ -103,8 +103,7 @@ impl ChildrenList {
let last_visited = node.GetFirstChild();
ChildrenList {
node: JS::from_ref(node),
- last_visited:
- MutNullableHeap::new(last_visited.as_ref().map(JS::from_rooted)),
+ last_visited: MutNullableHeap::new(last_visited.r()),
last_index: Cell::new(0u32),
}
}
@@ -127,14 +126,14 @@ impl ChildrenList {
let last_index = self.last_index.get();
if index == last_index {
// Item is last visited child, no need to update last visited.
- return Some(self.last_visited.get().unwrap().root());
+ return Some(self.last_visited.get().unwrap());
}
let last_visited = if index - 1u32 == last_index {
// Item is last visited's next sibling.
- self.last_visited.get().unwrap().root().GetNextSibling().unwrap()
+ self.last_visited.get().unwrap().GetNextSibling().unwrap()
} else if last_index > 0 && index == last_index - 1u32 {
// Item is last visited's previous sibling.
- self.last_visited.get().unwrap().root().GetPreviousSibling().unwrap()
+ self.last_visited.get().unwrap().GetPreviousSibling().unwrap()
} else if index > last_index {
if index == len - 1u32 {
// Item is parent's last child, not worth updating last visited.
@@ -142,7 +141,7 @@ impl ChildrenList {
}
if index <= last_index + (len - last_index) / 2u32 {
// Item is closer to the last visited child and follows it.
- self.last_visited.get().unwrap().root()
+ self.last_visited.get().unwrap()
.inclusively_following_siblings()
.nth((index - last_index) as usize).unwrap()
} else {
@@ -154,7 +153,7 @@ impl ChildrenList {
}
} else if index >= last_index / 2u32 {
// Item is closer to the last visited child and precedes it.
- self.last_visited.get().unwrap().root()
+ self.last_visited.get().unwrap()
.inclusively_preceding_siblings()
.nth((last_index - index) as usize).unwrap()
} else {
@@ -165,7 +164,7 @@ impl ChildrenList {
.nth(index as usize)
.unwrap()
};
- self.last_visited.set(Some(JS::from_rooted(&last_visited)));
+ self.last_visited.set(Some(last_visited.r()));
self.last_index.set(index);
Some(last_visited)
}
@@ -178,7 +177,7 @@ impl ChildrenList {
}
let index = list.last_index.get();
if index < len {
- list.last_visited.set(Some(JS::from_ref(added[index as usize])));
+ list.last_visited.set(Some(added[index as usize]));
} else if index / 2u32 >= len {
// If last index is twice as large as the number of added nodes,
// updating only it means that less nodes will be traversed if
@@ -187,7 +186,7 @@ impl ChildrenList {
} else {
// If last index is not twice as large but still larger,
// it's better to update it to the number of added nodes.
- list.last_visited.set(Some(JS::from_ref(next)));
+ list.last_visited.set(Some(next));
list.last_index.set(len);
}
}
@@ -198,7 +197,7 @@ impl ChildrenList {
added: &[&Node],
next: Option<&Node>) {
let index = list.last_index.get();
- if removed == &*list.last_visited.get().unwrap().root() {
+ if removed == &*list.last_visited.get().unwrap() {
let visited = match (prev, added, next) {
(None, _, None) => {
// Such cases where parent had only one child should
@@ -213,7 +212,7 @@ impl ChildrenList {
prev
},
};
- list.last_visited.set(Some(JS::from_ref(visited)));
+ list.last_visited.set(Some(visited));
} else if added.len() != 1 {
// The replaced child isn't the last visited one, and there are
// 0 or more than 1 nodes to replace it. Special care must be
@@ -250,13 +249,13 @@ impl ChildrenList {
self.last_visited.set(None);
self.last_index.set(0u32);
} else if index < len as u32 {
- self.last_visited.set(Some(JS::from_ref(added[index as usize])));
+ self.last_visited.set(Some(added[index as usize]));
} else {
// Setting last visited to parent's last child serves no purpose,
// so the middle is arbitrarily chosen here in case the caller
// wants random access.
let middle = len / 2;
- self.last_visited.set(Some(JS::from_ref(added[middle])));
+ self.last_visited.set(Some(added[middle]));
self.last_index.set(middle as u32);
}
},
@@ -264,8 +263,7 @@ impl ChildrenList {
}
fn reset(&self) {
- self.last_visited.set(
- self.node.root().GetFirstChild().map(|node| JS::from_rooted(&node)));
+ self.last_visited.set(self.node.root().GetFirstChild().as_ref().map(Root::r));
self.last_index.set(0u32);
}
}
diff --git a/components/script/dom/storageevent.rs b/components/script/dom/storageevent.rs
index 76e697b2861..d9f1f60e395 100644
--- a/components/script/dom/storageevent.rs
+++ b/components/script/dom/storageevent.rs
@@ -37,7 +37,7 @@ impl StorageEvent {
oldValue: oldValue,
newValue: newValue,
url: url,
- storageArea: MutNullableHeap::new(storageArea.map(JS::from_ref))
+ storageArea: MutNullableHeap::new(storageArea)
}
}
diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs
index eb30ab5ff4b..7f4646a1618 100644
--- a/components/script/dom/treewalker.rs
+++ b/components/script/dom/treewalker.rs
@@ -35,7 +35,7 @@ impl TreeWalker {
TreeWalker {
reflector_: Reflector::new(),
root_node: JS::from_ref(root_node),
- current_node: MutHeap::new(JS::from_ref(root_node)),
+ current_node: MutHeap::new(root_node),
what_to_show: what_to_show,
filter: filter
}
@@ -85,18 +85,18 @@ impl TreeWalkerMethods for TreeWalker {
// https://dom.spec.whatwg.org/#dom-treewalker-currentnode
fn CurrentNode(&self) -> Root<Node> {
- self.current_node.get().root()
+ self.current_node.get()
}
// https://dom.spec.whatwg.org/#dom-treewalker-currentnode
fn SetCurrentNode(&self, node: &Node) {
- self.current_node.set(JS::from_ref(node));
+ self.current_node.set(node);
}
// https://dom.spec.whatwg.org/#dom-treewalker-parentnode
fn ParentNode(&self) -> Fallible<Option<Root<Node>>> {
// "1. Let node be the value of the currentNode attribute."
- let mut node = self.current_node.get().root();
+ let mut node = self.current_node.get();
// "2. While node is not null and is not root, run these substeps:"
while !self.is_root_node(node.r()) {
// "1. Let node be node's parent."
@@ -106,7 +106,7 @@ impl TreeWalkerMethods for TreeWalker {
// "2. If node is not null and filtering node returns FILTER_ACCEPT,
// then set the currentNode attribute to node, return node."
if NodeFilterConstants::FILTER_ACCEPT == try!(self.accept_node(node.r())) {
- self.current_node.set(JS::from_rooted(&node));
+ self.current_node.set(&node);
return Ok(Some(node))
}
},
@@ -148,7 +148,7 @@ impl TreeWalkerMethods for TreeWalker {
// https://dom.spec.whatwg.org/#dom-treewalker-previousnode
fn PreviousNode(&self) -> Fallible<Option<Root<Node>>> {
// "1. Let node be the value of the currentNode attribute."
- let mut node = self.current_node.get().root();
+ let mut node = self.current_node.get();
// "2. While node is not root, run these substeps:"
while !self.is_root_node(node.r()) {
// "1. Let sibling be the previous sibling of node."
@@ -170,7 +170,7 @@ impl TreeWalkerMethods for TreeWalker {
_ if node.GetFirstChild().is_some() =>
node = node.GetLastChild().unwrap(),
NodeFilterConstants::FILTER_ACCEPT => {
- self.current_node.set(JS::from_rooted(&node));
+ self.current_node.set(&node);
return Ok(Some(node))
},
_ => break
@@ -194,7 +194,7 @@ impl TreeWalkerMethods for TreeWalker {
// "5. Filter node and if the return value is FILTER_ACCEPT, then
// set the currentNode attribute to node and return node."
if NodeFilterConstants::FILTER_ACCEPT == try!(self.accept_node(node.r())) {
- self.current_node.set(JS::from_rooted(&node));
+ self.current_node.set(&node);
return Ok(Some(node))
}
}
@@ -205,7 +205,7 @@ impl TreeWalkerMethods for TreeWalker {
// https://dom.spec.whatwg.org/#dom-treewalker-nextnode
fn NextNode(&self) -> Fallible<Option<Root<Node>>> {
// "1. Let node be the value of the currentNode attribute."
- let mut node = self.current_node.get().root();
+ let mut node = self.current_node.get();
// "2. Let result be FILTER_ACCEPT."
let mut result = NodeFilterConstants::FILTER_ACCEPT;
// "3. Run these substeps:"
@@ -225,7 +225,7 @@ impl TreeWalkerMethods for TreeWalker {
// "3. If result is FILTER_ACCEPT, then
// set the currentNode attribute to node and return node."
if NodeFilterConstants::FILTER_ACCEPT == result {
- self.current_node.set(JS::from_rooted(&node));
+ self.current_node.set(&node);
return Ok(Some(node))
}
}
@@ -243,7 +243,7 @@ impl TreeWalkerMethods for TreeWalker {
// "4. If result is FILTER_ACCEPT, then
// set the currentNode attribute to node and return node."
if NodeFilterConstants::FILTER_ACCEPT == result {
- self.current_node.set(JS::from_rooted(&node));
+ self.current_node.set(&node);
return Ok(Some(node))
}
}
@@ -267,7 +267,7 @@ impl TreeWalker {
{
// "To **traverse children** of type *type*, run these steps:"
// "1. Let node be the value of the currentNode attribute."
- let cur = self.current_node.get().root();
+ let cur = self.current_node.get();
// "2. Set node to node's first child if type is first, and node's last child if type is last."
// "3. If node is null, return null."
@@ -284,7 +284,7 @@ impl TreeWalker {
// "2. If result is FILTER_ACCEPT, then set the currentNode
// attribute to node and return node."
NodeFilterConstants::FILTER_ACCEPT => {
- self.current_node.set(JS::from_rooted(&node));
+ self.current_node.set(&node);
return Ok(Some(Root::from_ref(node.r())))
},
// "3. If result is FILTER_SKIP, run these subsubsteps:"
@@ -342,7 +342,7 @@ impl TreeWalker {
{
// "To **traverse siblings** of type *type* run these steps:"
// "1. Let node be the value of the currentNode attribute."
- let mut node = self.current_node.get().root();
+ let mut node = self.current_node.get();
// "2. If node is root, return null."
if self.is_root_node(node.r()) {
return Ok(None)
@@ -361,7 +361,7 @@ impl TreeWalker {
// "3. If result is FILTER_ACCEPT, then set the currentNode
// attribute to node and return node."
if NodeFilterConstants::FILTER_ACCEPT == result {
- self.current_node.set(JS::from_rooted(&node));
+ self.current_node.set(&node);
return Ok(Some(node))
}
@@ -447,7 +447,7 @@ impl TreeWalker {
}
fn is_current_node(&self, node: &Node) -> bool {
- JS::from_ref(node) == self.current_node.get()
+ node == &*self.current_node.get()
}
}
diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs
index a28783bc6e4..f01f8476356 100644
--- a/components/script/dom/uievent.rs
+++ b/components/script/dom/uievent.rs
@@ -92,7 +92,7 @@ impl UIEventMethods for UIEvent {
}
event.InitEvent(type_, can_bubble, cancelable);
- self.view.set(view.map(JS::from_ref));
+ self.view.set(view);
self.detail.set(detail);
}
}
diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs
index 37dfc3d7904..997f48c96b4 100644
--- a/components/script/dom/webglprogram.rs
+++ b/components/script/dom/webglprogram.rs
@@ -86,7 +86,7 @@ impl WebGLProgram {
return Err(WebGLError::InvalidOperation);
}
- shader_slot.set(Some(JS::from_ref(shader)));
+ shader_slot.set(Some(shader));
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::AttachShader(self.id, shader.id()))).unwrap();
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index f5a3569da13..0b968b4b42f 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -12,7 +12,7 @@ use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, NodeCast}
use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
use dom::bindings::conversions::ToJSValConvertible;
use dom::bindings::global::{GlobalField, GlobalRef};
-use dom::bindings::js::{JS, LayoutJS, Root};
+use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::event::{EventBubbles, EventCancelable};
use dom::htmlcanvaselement::HTMLCanvasElement;
@@ -78,8 +78,8 @@ pub struct WebGLRenderingContext {
canvas: JS<HTMLCanvasElement>,
last_error: Cell<Option<WebGLError>>,
texture_unpacking_settings: Cell<TextureUnpacking>,
- bound_texture_2d: Cell<Option<JS<WebGLTexture>>>,
- bound_texture_cube_map: Cell<Option<JS<WebGLTexture>>>,
+ bound_texture_2d: MutNullableHeap<JS<WebGLTexture>>,
+ bound_texture_cube_map: MutNullableHeap<JS<WebGLTexture>>,
}
impl WebGLRenderingContext {
@@ -104,8 +104,8 @@ impl WebGLRenderingContext {
canvas: JS::from_ref(canvas),
last_error: Cell::new(None),
texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE),
- bound_texture_2d: Cell::new(None),
- bound_texture_cube_map: Cell::new(None),
+ bound_texture_2d: MutNullableHeap::new(None),
+ bound_texture_cube_map: MutNullableHeap::new(None),
}
})
}
@@ -149,8 +149,8 @@ impl WebGLRenderingContext {
pub fn bound_texture_for(&self, target: u32) -> Option<Root<WebGLTexture>> {
match target {
- constants::TEXTURE_2D => self.bound_texture_2d.get().map(|t| t.root()),
- constants::TEXTURE_CUBE_MAP => self.bound_texture_cube_map.get().map(|t| t.root()),
+ constants::TEXTURE_2D => self.bound_texture_2d.get_rooted(),
+ constants::TEXTURE_CUBE_MAP => self.bound_texture_cube_map.get_rooted(),
_ => unreachable!(),
}
@@ -360,7 +360,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
if let Some(texture) = texture {
match texture.bind(target) {
- Ok(_) => slot.set(Some(JS::from_ref(texture))),
+ Ok(_) => slot.set(Some(texture)),
Err(err) => return self.webgl_error(err),
}
} else {