diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index bef2d7c7e22..03f0b27ceab 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -546,7 +546,8 @@ def addHTMLElement(element, concrete=None): DOMInterfaces[element] = { 'nativeType': 'AbstractNode', 'pointerType': '', - 'concreteType': concrete if concrete else element + 'concreteType': concrete if concrete else element, + 'customTrace': 'trace' } addHTMLElement('Comment') diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 31d2ac1a595..04ac4ebb858 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -3961,10 +3961,9 @@ class CGAbstractClassHook(CGAbstractExternMethod): args) def definition_body_prologue(self): - return "" #XXXjdm we may want to do a proper unwrap here return """ - let this: *%s = &(unwrap::<*rust_box<%s>>(obj).payload); -""" % (self.descriptor.nativeType, self.descriptor.nativeType) + let this: *%s = &(*unwrap::<*rust_box<%s>>(obj)).payload; +""" % (self.descriptor.concreteType, self.descriptor.concreteType) def definition_body(self): return self.definition_body_prologue() + self.generate_code() @@ -3990,6 +3989,18 @@ let _: @mut %s = cast::transmute(RUST_JSVAL_TO_PRIVATE(val)); #return clearWrapper + release return release +class CGClassTraceHook(CGAbstractClassHook): + """ + A hook to trace through our native object; used for GC and CC + """ + def __init__(self, descriptor): + args = [Argument('*mut JSTracer', 'trc'), Argument('*JSObject', 'obj')] + CGAbstractClassHook.__init__(self, descriptor, TRACE_HOOK_NAME, 'void', + args) + + def generate_code(self): + return " (*this).trace(%s);" % self.args[0].name + class CGClassConstructHook(CGAbstractExternMethod): """ JS-visible constructor for our objects @@ -4154,7 +4165,7 @@ class CGDescriptor(CGThing): # Only generate a trace hook if the class wants a custom hook. if (descriptor.customTrace): - #cgThings.append(CGClassTraceHook(descriptor)) + cgThings.append(CGClassTraceHook(descriptor)) pass if descriptor.interface.hasInterfaceObject(): diff --git a/src/components/script/dom/bindings/element.rs b/src/components/script/dom/bindings/element.rs index 9c925a22d9a..f0904bee503 100644 --- a/src/components/script/dom/bindings/element.rs +++ b/src/components/script/dom/bindings/element.rs @@ -4,12 +4,12 @@ use dom::types::*; use dom::bindings::codegen::*; -use dom::bindings::utils::{BindingObject, WrapperCache, CacheableWrapper}; +use dom::bindings::utils::{BindingObject, WrapperCache, CacheableWrapper, Traceable}; use dom::node::ScriptView; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::{JSContext, JSObject, JSTracer}; -pub macro_rules! generate_cacheable_wrapper( +macro_rules! generate_cacheable_wrapper( ($name: path, $wrap: path) => ( impl CacheableWrapper for $name { fn get_wrappercache(&mut self) -> &mut WrapperCache { @@ -24,7 +24,7 @@ pub macro_rules! generate_cacheable_wrapper( ) ) -pub macro_rules! generate_binding_object( +macro_rules! generate_binding_object( ($name: path) => ( impl BindingObject for $name { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> { @@ -34,139 +34,221 @@ pub macro_rules! generate_binding_object( ) ) +macro_rules! generate_traceable( + ($name: path) => ( + impl Traceable for $name { + fn trace(&self, trc: *mut JSTracer) { + self.parent.trace(trc); + } + } + ) +) + generate_cacheable_wrapper!(Comment, CommentBinding::Wrap) generate_binding_object!(Comment) +generate_traceable!(Comment) generate_cacheable_wrapper!(DocumentType, DocumentTypeBinding::Wrap) generate_binding_object!(DocumentType) +generate_traceable!(DocumentType) generate_cacheable_wrapper!(Text, TextBinding::Wrap) generate_binding_object!(Text) +generate_traceable!(Text) generate_cacheable_wrapper!(HTMLHeadElement, HTMLHeadElementBinding::Wrap) generate_binding_object!(HTMLHeadElement) +generate_traceable!(HTMLHeadElement) generate_cacheable_wrapper!(HTMLAnchorElement, HTMLAnchorElementBinding::Wrap) generate_binding_object!(HTMLAnchorElement) +generate_traceable!(HTMLAnchorElement) generate_cacheable_wrapper!(HTMLAppletElement, HTMLAppletElementBinding::Wrap) generate_binding_object!(HTMLAppletElement) +generate_traceable!(HTMLAppletElement) generate_cacheable_wrapper!(HTMLAreaElement, HTMLAreaElementBinding::Wrap) generate_binding_object!(HTMLAreaElement) +generate_traceable!(HTMLAreaElement) generate_cacheable_wrapper!(HTMLAudioElement, HTMLAudioElementBinding::Wrap) generate_binding_object!(HTMLAudioElement) +generate_traceable!(HTMLAudioElement) generate_cacheable_wrapper!(HTMLBaseElement, HTMLBaseElementBinding::Wrap) generate_binding_object!(HTMLBaseElement) +generate_traceable!(HTMLBaseElement) generate_cacheable_wrapper!(HTMLBodyElement, HTMLBodyElementBinding::Wrap) generate_binding_object!(HTMLBodyElement) +generate_traceable!(HTMLBodyElement) generate_cacheable_wrapper!(HTMLButtonElement, HTMLButtonElementBinding::Wrap) generate_binding_object!(HTMLButtonElement) +generate_traceable!(HTMLButtonElement) generate_cacheable_wrapper!(HTMLCanvasElement, HTMLCanvasElementBinding::Wrap) generate_binding_object!(HTMLCanvasElement) +generate_traceable!(HTMLCanvasElement) generate_cacheable_wrapper!(HTMLDataListElement, HTMLDataListElementBinding::Wrap) generate_binding_object!(HTMLDataListElement) +generate_traceable!(HTMLDataListElement) generate_cacheable_wrapper!(HTMLDListElement, HTMLDListElementBinding::Wrap) generate_binding_object!(HTMLDListElement) +generate_traceable!(HTMLDListElement) generate_cacheable_wrapper!(HTMLFormElement, HTMLFormElementBinding::Wrap) generate_binding_object!(HTMLFormElement) +generate_traceable!(HTMLFormElement) generate_cacheable_wrapper!(HTMLFrameElement, HTMLFrameElementBinding::Wrap) generate_binding_object!(HTMLFrameElement) +generate_traceable!(HTMLFrameElement) generate_cacheable_wrapper!(HTMLFrameSetElement, HTMLFrameSetElementBinding::Wrap) generate_binding_object!(HTMLFrameSetElement) +generate_traceable!(HTMLFrameSetElement) generate_cacheable_wrapper!(HTMLBRElement, HTMLBRElementBinding::Wrap) generate_binding_object!(HTMLBRElement) +generate_traceable!(HTMLBRElement) generate_cacheable_wrapper!(HTMLHRElement, HTMLHRElementBinding::Wrap) generate_binding_object!(HTMLHRElement) +generate_traceable!(HTMLHRElement) generate_cacheable_wrapper!(HTMLHtmlElement, HTMLHtmlElementBinding::Wrap) generate_binding_object!(HTMLHtmlElement) +generate_traceable!(HTMLHtmlElement) generate_cacheable_wrapper!(HTMLDataElement, HTMLDataElementBinding::Wrap) generate_binding_object!(HTMLDataElement) +generate_traceable!(HTMLDataElement) generate_cacheable_wrapper!(HTMLDirectoryElement, HTMLDirectoryElementBinding::Wrap) generate_binding_object!(HTMLDirectoryElement) +generate_traceable!(HTMLDirectoryElement) generate_cacheable_wrapper!(HTMLDivElement, HTMLDivElementBinding::Wrap) generate_binding_object!(HTMLDivElement) +generate_traceable!(HTMLDivElement) generate_cacheable_wrapper!(HTMLEmbedElement, HTMLEmbedElementBinding::Wrap) generate_binding_object!(HTMLEmbedElement) +generate_traceable!(HTMLEmbedElement) generate_cacheable_wrapper!(HTMLFieldSetElement, HTMLFieldSetElementBinding::Wrap) generate_binding_object!(HTMLFieldSetElement) +generate_traceable!(HTMLFieldSetElement) generate_cacheable_wrapper!(HTMLFontElement, HTMLFontElementBinding::Wrap) generate_binding_object!(HTMLFontElement) +generate_traceable!(HTMLFontElement) generate_cacheable_wrapper!(HTMLHeadingElement, HTMLHeadingElementBinding::Wrap) generate_binding_object!(HTMLHeadingElement) +generate_traceable!(HTMLHeadingElement) generate_cacheable_wrapper!(HTMLIFrameElement, HTMLIFrameElementBinding::Wrap) generate_binding_object!(HTMLIFrameElement) +generate_traceable!(HTMLIFrameElement) generate_cacheable_wrapper!(HTMLImageElement, HTMLImageElementBinding::Wrap) generate_binding_object!(HTMLImageElement) +generate_traceable!(HTMLImageElement) generate_cacheable_wrapper!(HTMLInputElement, HTMLInputElementBinding::Wrap) generate_binding_object!(HTMLInputElement) +generate_traceable!(HTMLInputElement) generate_cacheable_wrapper!(HTMLLabelElement, HTMLLabelElementBinding::Wrap) generate_binding_object!(HTMLLabelElement) +generate_traceable!(HTMLLabelElement) generate_cacheable_wrapper!(HTMLLegendElement, HTMLLegendElementBinding::Wrap) generate_binding_object!(HTMLLegendElement) +generate_traceable!(HTMLLegendElement) generate_cacheable_wrapper!(HTMLLIElement, HTMLLIElementBinding::Wrap) generate_binding_object!(HTMLLIElement) +generate_traceable!(HTMLLIElement) generate_cacheable_wrapper!(HTMLLinkElement, HTMLLinkElementBinding::Wrap) generate_binding_object!(HTMLLinkElement) +generate_traceable!(HTMLLinkElement) generate_cacheable_wrapper!(HTMLMapElement, HTMLMapElementBinding::Wrap) generate_binding_object!(HTMLMapElement) +generate_traceable!(HTMLMapElement) generate_cacheable_wrapper!(HTMLMediaElement, HTMLMediaElementBinding::Wrap) generate_binding_object!(HTMLMediaElement) +generate_traceable!(HTMLMediaElement) generate_cacheable_wrapper!(HTMLMetaElement, HTMLMetaElementBinding::Wrap) generate_binding_object!(HTMLMetaElement) +generate_traceable!(HTMLMetaElement) generate_cacheable_wrapper!(HTMLMeterElement, HTMLMeterElementBinding::Wrap) generate_binding_object!(HTMLMeterElement) +generate_traceable!(HTMLMeterElement) generate_cacheable_wrapper!(HTMLModElement, HTMLModElementBinding::Wrap) generate_binding_object!(HTMLModElement) +generate_traceable!(HTMLModElement) generate_cacheable_wrapper!(HTMLObjectElement, HTMLObjectElementBinding::Wrap) generate_binding_object!(HTMLObjectElement) +generate_traceable!(HTMLObjectElement) generate_cacheable_wrapper!(HTMLOListElement, HTMLOListElementBinding::Wrap) generate_binding_object!(HTMLOListElement) +generate_traceable!(HTMLOListElement) generate_cacheable_wrapper!(HTMLOptGroupElement, HTMLOptGroupElementBinding::Wrap) generate_binding_object!(HTMLOptGroupElement) +generate_traceable!(HTMLOptGroupElement) generate_cacheable_wrapper!(HTMLOptionElement, HTMLOptionElementBinding::Wrap) generate_binding_object!(HTMLOptionElement) +generate_traceable!(HTMLOptionElement) generate_cacheable_wrapper!(HTMLOutputElement, HTMLOutputElementBinding::Wrap) generate_binding_object!(HTMLOutputElement) +generate_traceable!(HTMLOutputElement) generate_cacheable_wrapper!(HTMLParagraphElement, HTMLParagraphElementBinding::Wrap) generate_binding_object!(HTMLParagraphElement) +generate_traceable!(HTMLParagraphElement) generate_cacheable_wrapper!(HTMLParamElement, HTMLParamElementBinding::Wrap) generate_binding_object!(HTMLParamElement) +generate_traceable!(HTMLParamElement) generate_cacheable_wrapper!(HTMLPreElement, HTMLPreElementBinding::Wrap) generate_binding_object!(HTMLPreElement) +generate_traceable!(HTMLPreElement) generate_cacheable_wrapper!(HTMLProgressElement, HTMLProgressElementBinding::Wrap) generate_binding_object!(HTMLProgressElement) +generate_traceable!(HTMLProgressElement) generate_cacheable_wrapper!(HTMLQuoteElement, HTMLQuoteElementBinding::Wrap) generate_binding_object!(HTMLQuoteElement) +generate_traceable!(HTMLQuoteElement) generate_cacheable_wrapper!(HTMLScriptElement, HTMLScriptElementBinding::Wrap) generate_binding_object!(HTMLScriptElement) +generate_traceable!(HTMLScriptElement) generate_cacheable_wrapper!(HTMLSelectElement, HTMLSelectElementBinding::Wrap) generate_binding_object!(HTMLSelectElement) +generate_traceable!(HTMLSelectElement) generate_cacheable_wrapper!(HTMLSourceElement, HTMLSourceElementBinding::Wrap) generate_binding_object!(HTMLSourceElement) +generate_traceable!(HTMLSourceElement) generate_cacheable_wrapper!(HTMLSpanElement, HTMLSpanElementBinding::Wrap) generate_binding_object!(HTMLSpanElement) +generate_traceable!(HTMLSpanElement) generate_cacheable_wrapper!(HTMLStyleElement, HTMLStyleElementBinding::Wrap) generate_binding_object!(HTMLStyleElement) +generate_traceable!(HTMLStyleElement) generate_cacheable_wrapper!(HTMLTableElement, HTMLTableElementBinding::Wrap) generate_binding_object!(HTMLTableElement) +generate_traceable!(HTMLTableElement) generate_cacheable_wrapper!(HTMLTableCaptionElement, HTMLTableCaptionElementBinding::Wrap) generate_binding_object!(HTMLTableCaptionElement) +generate_traceable!(HTMLTableCaptionElement) generate_cacheable_wrapper!(HTMLTableCellElement, HTMLTableCellElementBinding::Wrap) generate_binding_object!(HTMLTableCellElement) +generate_traceable!(HTMLTableCellElement) generate_cacheable_wrapper!(HTMLTableColElement, HTMLTableColElementBinding::Wrap) generate_binding_object!(HTMLTableColElement) +generate_traceable!(HTMLTableColElement) generate_cacheable_wrapper!(HTMLTableRowElement, HTMLTableRowElementBinding::Wrap) generate_binding_object!(HTMLTableRowElement) +generate_traceable!(HTMLTableRowElement) generate_cacheable_wrapper!(HTMLTableSectionElement, HTMLTableSectionElementBinding::Wrap) generate_binding_object!(HTMLTableSectionElement) +generate_traceable!(HTMLTableSectionElement) generate_cacheable_wrapper!(HTMLTemplateElement, HTMLTemplateElementBinding::Wrap) generate_binding_object!(HTMLTemplateElement) +generate_traceable!(HTMLTemplateElement) generate_cacheable_wrapper!(HTMLTextAreaElement, HTMLTextAreaElementBinding::Wrap) generate_binding_object!(HTMLTextAreaElement) +generate_traceable!(HTMLTextAreaElement) generate_cacheable_wrapper!(HTMLTitleElement, HTMLTitleElementBinding::Wrap) generate_binding_object!(HTMLTitleElement) +generate_traceable!(HTMLTitleElement) generate_cacheable_wrapper!(HTMLTimeElement, HTMLTimeElementBinding::Wrap) generate_binding_object!(HTMLTimeElement) +generate_traceable!(HTMLTimeElement) generate_cacheable_wrapper!(HTMLTrackElement, HTMLTrackElementBinding::Wrap) generate_binding_object!(HTMLTrackElement) +generate_traceable!(HTMLTrackElement) generate_cacheable_wrapper!(HTMLUListElement, HTMLUListElementBinding::Wrap) generate_binding_object!(HTMLUListElement) -generate_cacheable_wrapper!(HTMLVideoElement, HTMLVideoElementBinding::Wrap) -generate_binding_object!(HTMLVideoElement) +generate_traceable!(HTMLUListElement) generate_cacheable_wrapper!(HTMLUnknownElement, HTMLUnknownElementBinding::Wrap) generate_binding_object!(HTMLUnknownElement) +generate_traceable!(HTMLUnknownElement) +generate_cacheable_wrapper!(HTMLVideoElement, HTMLVideoElementBinding::Wrap) +generate_binding_object!(HTMLVideoElement) +generate_traceable!(HTMLVideoElement) + +generate_traceable!(HTMLElement) +generate_traceable!(Element) +generate_traceable!(CharacterData) diff --git a/src/components/script/dom/bindings/node.rs b/src/components/script/dom/bindings/node.rs index 059cbe0061c..05aff3793ca 100644 --- a/src/components/script/dom/bindings/node.rs +++ b/src/components/script/dom/bindings/node.rs @@ -2,15 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::utils::{CacheableWrapper, WrapperCache}; +use dom::bindings::utils::{CacheableWrapper, WrapperCache, Traceable}; use dom::element::*; use dom::types::*; use dom::node::{AbstractNode, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId}; use dom::node::{DoctypeNodeTypeId, ScriptView}; use std::cast; +use std::libc; use std::ptr; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::{JSContext, JSObject, JSTracer, JSTRACE_OBJECT, JS_CallTracer}; use servo_util::tree::TreeNodeRef; macro_rules! generate_element( @@ -107,3 +108,33 @@ impl CacheableWrapper for AbstractNode { fail!(~"need to implement wrapping"); } } + +impl Traceable for Node { + fn trace(&self, tracer: *mut JSTracer) { + #[fixed_stack_segment] + fn trace_node(tracer: *mut JSTracer, node: Option>, name: &str) { + if node.is_none() { + return; + } + debug!("tracing %s", name); + let mut node = node.unwrap(); + let cache = node.get_wrappercache(); + let wrapper = cache.get_wrapper(); + assert!(wrapper.is_not_null()); + unsafe { + (*tracer).debugPrinter = ptr::null(); + (*tracer).debugPrintIndex = -1; + do name.to_c_str().with_ref |name| { + (*tracer).debugPrintArg = name as *libc::c_void; + JS_CallTracer(cast::transmute(tracer), wrapper, JSTRACE_OBJECT as u32); + } + } + } + error!("tracing %p?:", self.wrapper.get_wrapper()); + trace_node(tracer, self.parent_node, "parent"); + trace_node(tracer, self.first_child, "first child"); + trace_node(tracer, self.last_child, "last child"); + trace_node(tracer, self.next_sibling, "next sibling"); + trace_node(tracer, self.prev_sibling, "prev sibling"); + } +} diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index be8259be454..f1151c6a8d7 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -27,7 +27,7 @@ use js::jsapi::{JS_GetFunctionPrototype, JS_InternString, JS_GetFunctionObject}; use js::jsapi::{JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject}; use js::jsapi::{JS_NewStringCopyN, JS_DefineFunctions, JS_DefineProperty}; use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot}; -use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative}; +use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative, JSTracer}; use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor}; use js::jsapi::{JSPropertyOp, JSStrictPropertyOp}; use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; @@ -546,6 +546,10 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: c_uint, _vp: *mut JSVa return 0; } +pub trait Traceable { + fn trace(&self, trc: *mut JSTracer); +} + #[fixed_stack_segment] pub fn initialize_global(global: *JSObject) { let protoArray = @mut ([0 as *JSObject, ..PrototypeList::id::_ID_Count as uint]);