From 94060b99c939413d9425f4c196e36066644421b4 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 19 Jul 2012 11:29:13 +0200 Subject: [PATCH] mshtml: Make nsIDOMHTMLDocument reference cycle collectable. --- dlls/mshtml/htmldoc.c | 43 ++++++++++++++++++++++++++++++++---- dlls/mshtml/htmlnode.c | 6 +++++ dlls/mshtml/mshtml_private.h | 2 ++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 8d5330e12b4..d78767cd041 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -2085,8 +2085,10 @@ static void HTMLDocumentNode_destructor(HTMLDOMNode *iface) while(!list_empty(&This->plugin_hosts)) detach_plugin_host(LIST_ENTRY(list_head(&This->plugin_hosts), PluginHost, entry)); - if(This->nsdoc) + if(This->nsdoc) { release_document_mutation(This); + nsIDOMHTMLDocument_Release(This->nsdoc); + } heap_free(This->event_vector); destroy_htmldoc(&This->basedoc); @@ -2099,10 +2101,44 @@ static HRESULT HTMLDocumentNode_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HT return E_NOTIMPL; } +static void HTMLDocumentNode_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface); + + if(This->nsdoc) + note_cc_edge((nsISupports*)This->nsdoc, "This->nsdoc", cb); +} + +static void HTMLDocumentNode_unlink(HTMLDOMNode *iface) +{ + HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface); + + if(This->nsdoc) { + nsIDOMHTMLDocument *nsdoc = This->nsdoc; + + release_document_mutation(This); + This->nsdoc = NULL; + nsIDOMHTMLDocument_Release(nsdoc); + } +} + static const NodeImplVtbl HTMLDocumentNodeImplVtbl = { HTMLDocumentNode_QI, HTMLDocumentNode_destructor, - HTMLDocumentNode_clone + HTMLDocumentNode_clone, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + HTMLDocumentNode_traverse, + HTMLDocumentNode_unlink }; static HRESULT HTMLDocumentFragment_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret) @@ -2236,8 +2272,7 @@ HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_ob HTMLDOMNode_Init(doc, &doc->node, (nsIDOMNode*)nsdoc); - /* No AddRef, share the reference with nsnode */ - assert((nsIDOMNode*)nsdoc == doc->node.nsnode); + nsIDOMHTMLDocument_AddRef(nsdoc); doc->nsdoc = nsdoc; init_document_mutation(doc); diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 2afcb231bee..a9e5d3fe79c 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -1125,6 +1125,9 @@ static nsresult NSAPI HTMLDOMNode_traverse(void *ccp, void *p, nsCycleCollection note_cc_edge((nsISupports*)This->nsnode, "This->nsnode", cb); dispex_traverse(&This->dispex, cb); + if(This->vtbl->traverse) + This->vtbl->traverse(This, cb); + return NS_OK; } @@ -1134,6 +1137,9 @@ static nsresult NSAPI HTMLDOMNode_unlink(void *p) TRACE("%p\n", This); + if(This->vtbl->unlink) + This->vtbl->unlink(This); + dispex_unlink(&This->dispex); if(This->nsnode) { diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 803d2147c7d..af165bf6ea6 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -587,6 +587,8 @@ typedef struct { HRESULT (*get_dispid)(HTMLDOMNode*,BSTR,DWORD,DISPID*); HRESULT (*invoke)(HTMLDOMNode*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*); HRESULT (*bind_to_tree)(HTMLDOMNode*); + void (*traverse)(HTMLDOMNode*,nsCycleCollectionTraversalCallback*); + void (*unlink)(HTMLDOMNode*); } NodeImplVtbl; struct HTMLDOMNode {