From e9cc7676fa239264598570f1cd800475d61bca36 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 19 Jul 2012 11:28:54 +0200 Subject: [PATCH] mshtml: Make node object's dynamic IDispatchEx-based properties cycle collectable. --- dlls/mshtml/dispex.c | 32 ++++++++++++++++++++++++++++++++ dlls/mshtml/htmlnode.c | 3 +++ dlls/mshtml/mshtml_private.h | 2 ++ 3 files changed, 37 insertions(+) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index bbe6098eaf0..b2024d4b3d1 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1377,6 +1377,38 @@ BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv) return TRUE; } +void dispex_traverse(DispatchEx *This, nsCycleCollectionTraversalCallback *cb) +{ + dynamic_prop_t *prop; + + if(!This->dynamic_data) + return; + + for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) { + if(V_VT(&prop->var) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&prop->var), "dispex_data", cb); + } + + /* FIXME: Traverse func_disps */ +} + +void dispex_unlink(DispatchEx *This) +{ + dynamic_prop_t *prop; + + if(!This->dynamic_data) + return; + + for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) { + if(V_VT(&prop->var) == VT_DISPATCH) { + V_VT(&prop->var) = VT_EMPTY; + IDispatch_Release(V_DISPATCH(&prop->var)); + }else { + VariantClear(&prop->var); + } + } +} + void release_dispex(DispatchEx *This) { dynamic_prop_t *prop; diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index f33df64df2e..2afcb231bee 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -1123,6 +1123,7 @@ static nsresult NSAPI HTMLDOMNode_traverse(void *ccp, void *p, nsCycleCollection if(This->nsnode) note_cc_edge((nsISupports*)This->nsnode, "This->nsnode", cb); + dispex_traverse(&This->dispex, cb); return NS_OK; } @@ -1133,6 +1134,8 @@ static nsresult NSAPI HTMLDOMNode_unlink(void *p) TRACE("%p\n", This); + dispex_unlink(&This->dispex); + if(This->nsnode) { nsIDOMNode *nsnode = This->nsnode; This->nsnode = NULL; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index efa6f52984d..803d2147c7d 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -258,6 +258,8 @@ HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**) DECLSPEC_H HRESULT get_dispids(tid_t,DWORD*,DISPID**) DECLSPEC_HIDDEN; HRESULT remove_prop(DispatchEx*,BSTR,VARIANT_BOOL*) DECLSPEC_HIDDEN; HRESULT dispex_get_dynid(DispatchEx*,const WCHAR*,DISPID*) DECLSPEC_HIDDEN; +void dispex_traverse(DispatchEx*,nsCycleCollectionTraversalCallback*) DECLSPEC_HIDDEN; +void dispex_unlink(DispatchEx*) DECLSPEC_HIDDEN; void release_typelib(void) DECLSPEC_HIDDEN; HRESULT get_htmldoc_classinfo(ITypeInfo **typeinfo) DECLSPEC_HIDDEN;