From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> Traverse currently only describes the nodes, without actually traversing the edges. This method is required, but DOM Nodes don't make use of it yet, so they are special case no-ops as temporary exceptions, because they still use their own mechanism which will change in the future. Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> --- dlls/mshtml/dispex.c | 72 +++++++++--- dlls/mshtml/htmlattr.c | 16 ++- dlls/mshtml/htmldoc.c | 23 +++- dlls/mshtml/htmlelem.c | 99 ++++++++++------ dlls/mshtml/htmlelemcol.c | 20 ++-- dlls/mshtml/htmlevent.c | 86 +++++++++++--- dlls/mshtml/htmlevent.h | 2 +- dlls/mshtml/htmlimg.c | 16 ++- dlls/mshtml/htmllocation.c | 16 ++- dlls/mshtml/htmlnode.c | 39 +++++-- dlls/mshtml/htmlselect.c | 16 ++- dlls/mshtml/htmlstorage.c | 18 +-- dlls/mshtml/htmlstyle.c | 16 ++- dlls/mshtml/htmlstyle.h | 2 +- dlls/mshtml/htmlstylesheet.c | 72 +++++++----- dlls/mshtml/htmltextnode.c | 15 ++- dlls/mshtml/htmlwindow.c | 25 ++-- dlls/mshtml/mshtml_private.h | 44 ++++--- dlls/mshtml/mutation.c | 36 +++--- dlls/mshtml/nsembed.c | 1 + dlls/mshtml/omnavigator.c | 215 +++++++++++++++++++++-------------- dlls/mshtml/range.c | 36 +++--- dlls/mshtml/selection.c | 18 +-- dlls/mshtml/xmlhttprequest.c | 35 ++++-- 24 files changed, 627 insertions(+), 311 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 6bd2c9cf6cb..66862992fd8 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -33,6 +33,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define MAX_ARGS 16 +ExternalCycleCollectionParticipant dispex_ccp; + static CRITICAL_SECTION cs_dispex_static_data; static CRITICAL_SECTION_DEBUG cs_dispex_static_data_dbg = { @@ -88,7 +90,7 @@ typedef struct { typedef struct { DispatchEx dispex; IUnknown IUnknown_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; DispatchEx *obj; func_info_t *info; } func_disp_t; @@ -812,7 +814,7 @@ static HRESULT WINAPI Function_QueryInterface(IUnknown *iface, REFIID riid, void static ULONG WINAPI Function_AddRef(IUnknown *iface) { func_disp_t *This = impl_from_IUnknown(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -822,13 +824,10 @@ static ULONG WINAPI Function_AddRef(IUnknown *iface) static ULONG WINAPI Function_Release(IUnknown *iface) { func_disp_t *This = impl_from_IUnknown(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -843,6 +842,12 @@ static inline func_disp_t *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, func_disp_t, dispex); } +static void function_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + func_disp_t *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "func_disp", cb); +} + static void function_destructor(DispatchEx *dispex) { func_disp_t *This = impl_from_DispatchEx(dispex); @@ -907,6 +912,7 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR static const dispex_static_data_vtbl_t function_dispex_vtbl = { function_destructor, + function_traverse, NULL, function_value, NULL, @@ -932,8 +938,8 @@ static func_disp_t *create_func_disp(DispatchEx *obj, func_info_t *info) return NULL; ret->IUnknown_iface.lpVtbl = &FunctionUnkVtbl; + ccref_init(&ret->ccref, 1); init_dispatch(&ret->dispex, &ret->IUnknown_iface, &function_dispex, dispex_compat_mode(obj)); - ret->ref = 1; ret->obj = obj; ret->info = info; @@ -1981,7 +1987,13 @@ BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv) *ppv = &This->IDispatchEx_iface; else if(IsEqualGUID(&IID_IDispatchEx, riid)) *ppv = &This->IDispatchEx_iface; - else if(IsEqualGUID(&IID_IDispatchJS, riid)) + else if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) { + *ppv = &dispex_ccp; + return TRUE; + }else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) { + *ppv = &This->IDispatchEx_iface; + return TRUE; + }else if(IsEqualGUID(&IID_IDispatchJS, riid)) *ppv = NULL; else if(IsEqualGUID(&IID_UndocumentedScriptIface, riid)) *ppv = NULL; @@ -1997,12 +2009,15 @@ BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv) return TRUE; } -void dispex_traverse(DispatchEx *This, nsCycleCollectionTraversalCallback *cb) +nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb) { + DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop; + This->info->desc->vtbl->traverse(This, cb); + if(!This->dynamic_data) - return; + return NS_OK; for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) { if(V_VT(&prop->var) == VT_DISPATCH) @@ -2020,9 +2035,11 @@ void dispex_traverse(DispatchEx *This, nsCycleCollectionTraversalCallback *cb) note_cc_edge((nsISupports*)V_DISPATCH(&iter->val), "func_val", cb); } } + + return NS_OK; } -void dispex_unlink(DispatchEx *This) +void dispex_props_unlink(DispatchEx *This) { dynamic_prop_t *prop; @@ -2050,16 +2067,23 @@ void dispex_unlink(DispatchEx *This) } } -const void *dispex_get_vtbl(DispatchEx *dispex) +nsresult NSAPI dispex_unlink(void *p) { - return dispex->info->desc->vtbl; + DispatchEx *This = impl_from_IDispatchEx(p); + + if(This->info->desc->vtbl->unlink) + This->info->desc->vtbl->unlink(This); + + dispex_props_unlink(This); + return NS_OK; } -void release_dispex(DispatchEx *This) +void NSAPI dispex_delete_cycle_collectable(void *p) { + DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop; - if(This->info->desc->vtbl && This->info->desc->vtbl->unlink) + if(This->info->desc->vtbl->unlink) This->info->desc->vtbl->unlink(This); if(!This->dynamic_data) @@ -2089,8 +2113,22 @@ void release_dispex(DispatchEx *This) free(This->dynamic_data); destructor: - if(This->info->desc->vtbl && This->info->desc->vtbl->destructor) - This->info->desc->vtbl->destructor(This); + This->info->desc->vtbl->destructor(This); +} + +void init_dispex_cc(void) +{ + static const CCObjCallback dispex_ccp_callback = { + dispex_traverse, + dispex_unlink, + dispex_delete_cycle_collectable + }; + ccp_init(&dispex_ccp, &dispex_ccp_callback); +} + +const void *dispex_get_vtbl(DispatchEx *dispex) +{ + return dispex->info->desc->vtbl; } void init_dispatch(DispatchEx *dispex, IUnknown *outer, dispex_static_data_t *data, compat_mode_t compat_mode) diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c index c99e39a47bd..db3604b1823 100644 --- a/dlls/mshtml/htmlattr.c +++ b/dlls/mshtml/htmlattr.c @@ -65,7 +65,7 @@ static HRESULT WINAPI HTMLDOMAttribute_QueryInterface(IHTMLDOMAttribute *iface, static ULONG WINAPI HTMLDOMAttribute_AddRef(IHTMLDOMAttribute *iface) { HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -75,13 +75,10 @@ static ULONG WINAPI HTMLDOMAttribute_AddRef(IHTMLDOMAttribute *iface) static ULONG WINAPI HTMLDOMAttribute_Release(IHTMLDOMAttribute *iface) { HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -480,6 +477,12 @@ static inline HTMLDOMAttribute *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMAttribute, dispex); } +static void HTMLDOMAttribute_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMAttribute *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMAttribute", cb); +} + static void HTMLDOMAttribute_unlink(DispatchEx *dispex) { HTMLDOMAttribute *This = impl_from_DispatchEx(dispex); @@ -497,6 +500,7 @@ static void HTMLDOMAttribute_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLDOMAttribute_dispex_vtbl = { HTMLDOMAttribute_destructor, + HTMLDOMAttribute_traverse, HTMLDOMAttribute_unlink }; @@ -529,9 +533,9 @@ HRESULT HTMLDOMAttribute_Create(const WCHAR *name, HTMLElement *elem, DISPID dis ret->IHTMLDOMAttribute_iface.lpVtbl = &HTMLDOMAttributeVtbl; ret->IHTMLDOMAttribute2_iface.lpVtbl = &HTMLDOMAttribute2Vtbl; - ret->ref = 1; ret->dispid = dispid; ret->elem = elem; + ccref_init(&ret->ccref, 1); init_dispatch(&ret->dispex, (IUnknown*)&ret->IHTMLDOMAttribute_iface, &HTMLDOMAttribute_dispex, compat_mode); diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 23b0064c9a6..550b8511240 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -295,6 +295,14 @@ static inline DocumentType *DocumentType_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, DocumentType, node.event_target.dispex); } +static void DocumentType_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void DocumentType_dispex_destructor(DispatchEx *dispex) +{ +} + static HRESULT DocumentType_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) { DocumentType *This = DocumentType_from_HTMLDOMNode(iface); @@ -367,7 +375,8 @@ static IHTMLEventObj *DocumentType_set_current_event(DispatchEx *dispex, IHTMLEv static event_target_vtbl_t DocumentType_event_target_vtbl = { { - NULL, + DocumentType_dispex_destructor, + DocumentType_traverse, }, DocumentType_get_gecko_target, NULL, @@ -5915,6 +5924,14 @@ static inline HTMLDocumentNode *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDocumentNode, node.event_target.dispex); } +static void HTMLDocumentNode_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDocumentNode_dispex_destructor(DispatchEx *dispex) +{ +} + static HRESULT HTMLDocumentNode_get_name(DispatchEx *dispex, DISPID id, BSTR *name) { HTMLDocumentNode *This = impl_from_DispatchEx(dispex); @@ -6086,7 +6103,8 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { { - NULL, + HTMLDocumentNode_dispex_destructor, + HTMLDocumentNode_traverse, NULL, NULL, NULL, @@ -6195,7 +6213,6 @@ static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLInnerWindo if(!doc) return NULL; - doc->ref = 1; doc->IDispatchEx_iface.lpVtbl = &DocDispatchExVtbl; doc->IHTMLDocument2_iface.lpVtbl = &HTMLDocumentVtbl; doc->IHTMLDocument3_iface.lpVtbl = &HTMLDocument3Vtbl; diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 91316a8f237..bc6db95d00f 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -340,7 +340,7 @@ typedef struct DispatchEx dispex; IHTMLFiltersCollection IHTMLFiltersCollection_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; } HTMLFiltersCollection; static inline HTMLFiltersCollection *impl_from_IHTMLFiltersCollection(IHTMLFiltersCollection *iface) @@ -531,7 +531,7 @@ typedef struct { IHTMLRect IHTMLRect_iface; IHTMLRect2 IHTMLRect2_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMClientRect *nsrect; } HTMLRect; @@ -568,7 +568,7 @@ static HRESULT WINAPI HTMLRect_QueryInterface(IHTMLRect *iface, REFIID riid, voi static ULONG WINAPI HTMLRect_AddRef(IHTMLRect *iface) { HTMLRect *This = impl_from_IHTMLRect(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -578,13 +578,10 @@ static ULONG WINAPI HTMLRect_AddRef(IHTMLRect *iface) static ULONG WINAPI HTMLRect_Release(IHTMLRect *iface) { HTMLRect *This = impl_from_IHTMLRect(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -842,6 +839,12 @@ static inline HTMLRect *HTMLRect_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLRect, dispex); } +static void HTMLRect_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLRect *This = HTMLRect_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ClientRect", cb); +} + static void HTMLRect_unlink(DispatchEx *dispex) { HTMLRect *This = HTMLRect_from_DispatchEx(dispex); @@ -862,6 +865,7 @@ void HTMLRect_init_dispex_info(dispex_data_t *info, compat_mode_t mode) static const dispex_static_data_vtbl_t HTMLRect_dispex_vtbl = { HTMLRect_destructor, + HTMLRect_traverse, HTMLRect_unlink }; @@ -887,7 +891,7 @@ static HRESULT create_html_rect(nsIDOMClientRect *nsrect, compat_mode_t compat_m rect->IHTMLRect_iface.lpVtbl = &HTMLRectVtbl; rect->IHTMLRect2_iface.lpVtbl = &HTMLRect2Vtbl; - rect->ref = 1; + ccref_init(&rect->ccref, 1); init_dispatch(&rect->dispex, (IUnknown*)&rect->IHTMLRect_iface, &HTMLRect_dispex, compat_mode); @@ -902,7 +906,7 @@ typedef struct { DispatchEx dispex; IHTMLRectCollection IHTMLRectCollection_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMClientRectList *rect_list; } HTMLRectCollection; @@ -1070,7 +1074,7 @@ static HRESULT WINAPI HTMLRectCollection_QueryInterface(IHTMLRectCollection *ifa static ULONG WINAPI HTMLRectCollection_AddRef(IHTMLRectCollection *iface) { HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1080,13 +1084,10 @@ static ULONG WINAPI HTMLRectCollection_AddRef(IHTMLRectCollection *iface) static ULONG WINAPI HTMLRectCollection_Release(IHTMLRectCollection *iface) { HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1208,6 +1209,12 @@ static inline HTMLRectCollection *HTMLRectCollection_from_DispatchEx(DispatchEx return CONTAINING_RECORD(iface, HTMLRectCollection, dispex); } +static void HTMLRectCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ClientRectCollection", cb); +} + static void HTMLRectCollection_unlink(DispatchEx *dispex) { HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); @@ -1296,6 +1303,7 @@ static HRESULT HTMLRectCollection_invoke(DispatchEx *dispex, DISPID id, LCID lci static const dispex_static_data_vtbl_t HTMLRectCollection_dispex_vtbl = { HTMLRectCollection_destructor, + HTMLRectCollection_traverse, HTMLRectCollection_unlink, NULL, HTMLRectCollection_get_dispid, @@ -3327,8 +3335,8 @@ static HRESULT WINAPI HTMLElement2_getClientRects(IHTMLElement2 *iface, IHTMLRec } rects->IHTMLRectCollection_iface.lpVtbl = &HTMLRectCollectionVtbl; - rects->ref = 1; rects->rect_list = rect_list; + ccref_init(&rects->ccref, 1); init_dispatch(&rects->dispex, (IUnknown*)&rects->IHTMLRectCollection_iface, &HTMLRectCollection_dispex, dispex_compat_mode(&This->node.event_target.dispex)); @@ -6961,6 +6969,14 @@ static inline HTMLElement *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLElement, node.event_target.dispex); } +static void HTMLElement_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLElement_dispex_destructor(DispatchEx *dispex) +{ +} + static HRESULT HTMLElement_get_dispid(DispatchEx *dispex, BSTR name, DWORD grfdex, DISPID *pid) { @@ -7356,7 +7372,8 @@ static const tid_t HTMLElement_iface_tids[] = { const event_target_vtbl_t HTMLElement_event_target_vtbl = { { - NULL, + HTMLElement_dispex_destructor, + HTMLElement_traverse, NULL, NULL, HTMLElement_get_dispid, @@ -7380,7 +7397,7 @@ struct token_list { IWineDOMTokenList IWineDOMTokenList_iface; IHTMLElement *element; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; }; static inline struct token_list *impl_from_IWineDOMTokenList(IWineDOMTokenList *iface) @@ -7413,7 +7430,7 @@ static HRESULT WINAPI token_list_QueryInterface(IWineDOMTokenList *iface, REFIID static ULONG WINAPI token_list_AddRef(IWineDOMTokenList *iface) { struct token_list *token_list = impl_from_IWineDOMTokenList(iface); - LONG ref = InterlockedIncrement(&token_list->ref); + LONG ref = dispex_ccref_incr(&token_list->ccref, &token_list->dispex); TRACE("(%p) ref=%ld\n", token_list, ref); @@ -7423,13 +7440,10 @@ static ULONG WINAPI token_list_AddRef(IWineDOMTokenList *iface) static ULONG WINAPI token_list_Release(IWineDOMTokenList *iface) { struct token_list *token_list = impl_from_IWineDOMTokenList(iface); - LONG ref = InterlockedDecrement(&token_list->ref); + LONG ref = dispex_ccref_decr(&token_list->ccref, &token_list->dispex); TRACE("(%p) ref=%ld\n", token_list, ref); - if(!ref) - release_dispex(&token_list->dispex); - return ref; } @@ -7747,6 +7761,12 @@ static inline struct token_list *token_list_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, struct token_list, dispex); } +static void token_list_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct token_list *token_list = token_list_from_DispatchEx(dispex); + describe_cc_node(&token_list->ccref, "DOMTokenList", cb); +} + static void token_list_unlink(DispatchEx *dispex) { struct token_list *token_list = token_list_from_DispatchEx(dispex); @@ -7835,6 +7855,7 @@ static HRESULT token_list_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD static const dispex_static_data_vtbl_t token_list_dispex_vtbl = { token_list_destructor, + token_list_traverse, token_list_unlink, token_list_value, token_list_get_dispid, @@ -7865,7 +7886,7 @@ static HRESULT create_token_list(compat_mode_t compat_mode, IHTMLElement *elemen } obj->IWineDOMTokenList_iface.lpVtbl = &WineDOMTokenListVtbl; - obj->ref = 1; + ccref_init(&obj->ccref, 1); init_dispatch(&obj->dispex, (IUnknown*)&obj->IWineDOMTokenList_iface, &token_list_dispex, compat_mode); IHTMLElement_AddRef(element); obj->element = element; @@ -8120,7 +8141,7 @@ static HRESULT WINAPI HTMLFiltersCollection_QueryInterface(IHTMLFiltersCollectio static ULONG WINAPI HTMLFiltersCollection_AddRef(IHTMLFiltersCollection *iface) { HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -8130,13 +8151,10 @@ static ULONG WINAPI HTMLFiltersCollection_AddRef(IHTMLFiltersCollection *iface) static ULONG WINAPI HTMLFiltersCollection_Release(IHTMLFiltersCollection *iface) { HTMLFiltersCollection *This = impl_from_IHTMLFiltersCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -8216,6 +8234,12 @@ static inline HTMLFiltersCollection *HTMLFiltersCollection_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLFiltersCollection, dispex); } +static void HTMLFiltersCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLFiltersCollection *This = HTMLFiltersCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "FiltersCollection", cb); +} + static void HTMLFiltersCollection_destructor(DispatchEx *dispex) { HTMLFiltersCollection *This = HTMLFiltersCollection_from_DispatchEx(dispex); @@ -8262,6 +8286,7 @@ static HRESULT HTMLFiltersCollection_invoke(DispatchEx *dispex, DISPID id, LCID static const dispex_static_data_vtbl_t HTMLFiltersCollection_dispex_vtbl = { HTMLFiltersCollection_destructor, + HTMLFiltersCollection_traverse, NULL, NULL, HTMLFiltersCollection_get_dispid, @@ -8289,7 +8314,7 @@ static HRESULT create_filters_collection(compat_mode_t compat_mode, IHTMLFilters return E_OUTOFMEMORY; collection->IHTMLFiltersCollection_iface.lpVtbl = &HTMLFiltersCollectionVtbl; - collection->ref = 1; + ccref_init(&collection->ccref, 1); init_dispatch(&collection->dispex, (IUnknown*)&collection->IHTMLFiltersCollection_iface, &HTMLFiltersCollection_dispex, min(compat_mode, COMPAT_MODE_IE8)); @@ -8580,7 +8605,7 @@ static HRESULT WINAPI HTMLAttributeCollection_QueryInterface(IHTMLAttributeColle static ULONG WINAPI HTMLAttributeCollection_AddRef(IHTMLAttributeCollection *iface) { HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -8590,13 +8615,10 @@ static ULONG WINAPI HTMLAttributeCollection_AddRef(IHTMLAttributeCollection *ifa static ULONG WINAPI HTMLAttributeCollection_Release(IHTMLAttributeCollection *iface) { HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -8944,6 +8966,12 @@ static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex); } +static void HTMLAttributeCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "AttributeCollection", cb); +} + static void HTMLAttributeCollection_unlink(DispatchEx *dispex) { HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); @@ -9029,6 +9057,7 @@ static HRESULT HTMLAttributeCollection_invoke(DispatchEx *dispex, DISPID id, LCI static const dispex_static_data_vtbl_t HTMLAttributeCollection_dispex_vtbl = { HTMLAttributeCollection_destructor, + HTMLAttributeCollection_traverse, HTMLAttributeCollection_unlink, NULL, HTMLAttributeCollection_get_dispid, @@ -9068,7 +9097,7 @@ HRESULT HTMLElement_get_attr_col(HTMLDOMNode *iface, HTMLAttributeCollection **a This->attrs->IHTMLAttributeCollection_iface.lpVtbl = &HTMLAttributeCollectionVtbl; This->attrs->IHTMLAttributeCollection2_iface.lpVtbl = &HTMLAttributeCollection2Vtbl; This->attrs->IHTMLAttributeCollection3_iface.lpVtbl = &HTMLAttributeCollection3Vtbl; - This->attrs->ref = 2; + ccref_init(&This->attrs->ccref, 2); This->attrs->elem = This; list_init(&This->attrs->attrs); diff --git a/dlls/mshtml/htmlelemcol.c b/dlls/mshtml/htmlelemcol.c index 178ccde9b4d..4cab3abd99b 100644 --- a/dlls/mshtml/htmlelemcol.c +++ b/dlls/mshtml/htmlelemcol.c @@ -35,10 +35,10 @@ typedef struct { DispatchEx dispex; IHTMLElementCollection IHTMLElementCollection_iface; + nsCycleCollectingAutoRefCnt ccref; + HTMLElement **elems; DWORD len; - - LONG ref; } HTMLElementCollection; typedef struct { @@ -238,7 +238,7 @@ static HRESULT WINAPI HTMLElementCollection_QueryInterface(IHTMLElementCollectio static ULONG WINAPI HTMLElementCollection_AddRef(IHTMLElementCollection *iface) { HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -248,13 +248,10 @@ static ULONG WINAPI HTMLElementCollection_AddRef(IHTMLElementCollection *iface) static ULONG WINAPI HTMLElementCollection_Release(IHTMLElementCollection *iface) { HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -542,6 +539,12 @@ static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); } +static void HTMLElementCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLElementCollection *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ElementCollection", cb); +} + static void HTMLElementCollection_unlink(DispatchEx *dispex) { HTMLElementCollection *This = impl_from_DispatchEx(dispex); @@ -634,6 +637,7 @@ static HRESULT HTMLElementCollection_invoke(DispatchEx *dispex, DISPID id, LCID static const dispex_static_data_vtbl_t HTMLElementColection_dispex_vtbl = { HTMLElementCollection_destructor, + HTMLElementCollection_traverse, HTMLElementCollection_unlink, NULL, HTMLElementCollection_get_dispid, @@ -866,7 +870,7 @@ static IHTMLElementCollection *HTMLElementCollection_Create(HTMLElement **elems, return NULL; ret->IHTMLElementCollection_iface.lpVtbl = &HTMLElementCollectionVtbl; - ret->ref = 1; + ccref_init(&ret->ccref, 1); ret->elems = elems; ret->len = len; diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 6b5ea716a75..494a339216e 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -335,7 +335,7 @@ typedef struct { DispatchEx dispex; IHTMLEventObj IHTMLEventObj_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; DOMEvent *event; VARIANT return_value; @@ -371,7 +371,7 @@ static HRESULT WINAPI HTMLEventObj_QueryInterface(IHTMLEventObj *iface, REFIID r static ULONG WINAPI HTMLEventObj_AddRef(IHTMLEventObj *iface) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -381,13 +381,10 @@ static ULONG WINAPI HTMLEventObj_AddRef(IHTMLEventObj *iface) static ULONG WINAPI HTMLEventObj_Release(IHTMLEventObj *iface) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -873,6 +870,12 @@ static inline HTMLEventObj *HTMLEventObj_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLEventObj, dispex); } +static void HTMLEventObj_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "EventObj", cb); +} + static void HTMLEventObj_unlink(DispatchEx *dispex) { HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); @@ -891,6 +894,7 @@ static void HTMLEventObj_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLEventObj_dispex_vtbl = { HTMLEventObj_destructor, + HTMLEventObj_traverse, HTMLEventObj_unlink }; @@ -915,7 +919,7 @@ static HTMLEventObj *alloc_event_obj(DOMEvent *event, compat_mode_t compat_mode) return NULL; event_obj->IHTMLEventObj_iface.lpVtbl = &HTMLEventObjVtbl; - event_obj->ref = 1; + ccref_init(&event_obj->ccref, 1); event_obj->event = event; if(event) IDOMEvent_AddRef(&event->IDOMEvent_iface); @@ -973,7 +977,7 @@ static HRESULT WINAPI DOMEvent_QueryInterface(IDOMEvent *iface, REFIID riid, voi static ULONG WINAPI DOMEvent_AddRef(IDOMEvent *iface) { DOMEvent *This = impl_from_IDOMEvent(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%lu\n", This, ref); @@ -983,13 +987,10 @@ static ULONG WINAPI DOMEvent_AddRef(IDOMEvent *iface) static ULONG WINAPI DOMEvent_Release(IDOMEvent *iface) { DOMEvent *This = impl_from_IDOMEvent(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%lu\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1253,6 +1254,12 @@ static inline DOMEvent *DOMEvent_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, DOMEvent, dispex); } +static void DOMEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMEvent *This = DOMEvent_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMEvent", cb); +} + static void DOMEvent_unlink(DispatchEx *dispex) { DOMEvent *This = DOMEvent_from_DispatchEx(dispex); @@ -1419,6 +1426,12 @@ static void *DOMUIEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; } +static void DOMUIEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->event.ccref, "DOMUIEvent", cb); +} + static void DOMUIEvent_unlink(DispatchEx *dispex) { DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -1951,6 +1964,12 @@ static void *DOMMouseEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; } +static void DOMMouseEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->ui_event.event.ccref, "DOMMouseEvent", cb); +} + static void DOMMouseEvent_unlink(DispatchEx *dispex) { DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -2250,6 +2269,12 @@ static void *DOMKeyboardEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; } +static void DOMKeyboardEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->ui_event.event.ccref, "DOMKeyboardEvent", cb); +} + static void DOMKeyboardEvent_unlink(DispatchEx *dispex) { DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -2458,6 +2483,12 @@ static void *DOMCustomEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; } +static void DOMCustomEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&custom_event->event.ccref, "DOMCustomEvent", cb); +} + static void DOMCustomEvent_unlink(DispatchEx *dispex) { DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -2610,6 +2641,12 @@ static void *DOMMessageEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; } +static void DOMMessageEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&message_event->event.ccref, "DOMMessageEvent", cb); +} + static void DOMMessageEvent_unlink(DispatchEx *dispex) { DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -2791,6 +2828,12 @@ static void *DOMProgressEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; } +static void DOMProgressEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->event.ccref, "DOMProgressEvent", cb); +} + static void DOMProgressEvent_unlink(DispatchEx *dispex) { DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -2954,6 +2997,12 @@ static void *DOMStorageEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; } +static void DOMStorageEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&storage_event->event.ccref, "DOMStorageEvent", cb); +} + static void DOMStorageEvent_destructor(DispatchEx *dispex) { DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -2966,6 +3015,7 @@ static void DOMStorageEvent_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t DOMEvent_dispex_vtbl = { DOMEvent_destructor, + DOMEvent_traverse, DOMEvent_unlink }; @@ -2983,6 +3033,7 @@ static dispex_static_data_t DOMEvent_dispex = { static const dispex_static_data_vtbl_t DOMUIEvent_dispex_vtbl = { DOMEvent_destructor, + DOMUIEvent_traverse, DOMUIEvent_unlink }; @@ -3001,6 +3052,7 @@ static dispex_static_data_t DOMUIEvent_dispex = { static const dispex_static_data_vtbl_t DOMMouseEvent_dispex_vtbl = { DOMEvent_destructor, + DOMMouseEvent_traverse, DOMMouseEvent_unlink }; @@ -3020,6 +3072,7 @@ static dispex_static_data_t DOMMouseEvent_dispex = { static const dispex_static_data_vtbl_t DOMKeyboardEvent_dispex_vtbl = { DOMEvent_destructor, + DOMKeyboardEvent_traverse, DOMKeyboardEvent_unlink }; @@ -3053,6 +3106,7 @@ static dispex_static_data_t DOMPageTransitionEvent_dispex = { static const dispex_static_data_vtbl_t DOMCustomEvent_dispex_vtbl = { DOMCustomEvent_destructor, + DOMCustomEvent_traverse, DOMCustomEvent_unlink }; @@ -3071,6 +3125,7 @@ static dispex_static_data_t DOMCustomEvent_dispex = { static const dispex_static_data_vtbl_t DOMMessageEvent_dispex_vtbl = { DOMMessageEvent_destructor, + DOMMessageEvent_traverse, DOMMessageEvent_unlink }; @@ -3089,6 +3144,7 @@ static dispex_static_data_t DOMMessageEvent_dispex = { static const dispex_static_data_vtbl_t DOMProgressEvent_dispex_vtbl = { DOMEvent_destructor, + DOMProgressEvent_traverse, DOMProgressEvent_unlink }; @@ -3107,6 +3163,7 @@ static dispex_static_data_t DOMProgressEvent_dispex = { static const dispex_static_data_vtbl_t DOMStorageEvent_dispex_vtbl = { DOMStorageEvent_destructor, + DOMStorageEvent_traverse, DOMEvent_unlink }; @@ -3132,7 +3189,6 @@ static void *event_ctor(unsigned size, dispex_static_data_t *dispex_data, void * return NULL; event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; event->query_interface = query_interface; - event->ref = 1; event->event_id = event_id; if(event_id != EVENTID_LAST) { event->type = wcsdup(event_info[event_id].name); @@ -3143,6 +3199,7 @@ static void *event_ctor(unsigned size, dispex_static_data_t *dispex_data, void * event->bubbles = (event_info[event_id].flags & EVENT_BUBBLES) != 0; event->cancelable = (event_info[event_id].flags & EVENT_CANCELABLE) != 0; } + ccref_init(&event->ccref, 1); nsIDOMEvent_AddRef(event->nsevent = nsevent); event->time_stamp = get_time_stamp(); @@ -4531,11 +4588,12 @@ void release_event_target(EventTarget *event_target) WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter, iter2, &event_target->handler_map, listener_container_t, entry) { while(!list_empty(&iter->listeners)) { event_listener_t *listener = LIST_ENTRY(list_head(&iter->listeners), event_listener_t, entry); + list_remove(&listener->entry); if(listener->function) IDispatch_Release(listener->function); - list_remove(&listener->entry); free(listener); } free(iter); } + rb_destroy(&event_target->handler_map, NULL, NULL); } diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index f6c7cbc381b..d3a35c883dd 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -76,7 +76,7 @@ typedef struct DOMEvent { DispatchEx dispex; IDOMEvent IDOMEvent_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; void *(*query_interface)(struct DOMEvent*,REFIID); nsIDOMEvent *nsevent; diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index cc091429500..b2f2ef869ed 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -794,7 +794,7 @@ static HRESULT WINAPI HTMLImageElementFactory_QueryInterface(IHTMLImageElementFa static ULONG WINAPI HTMLImageElementFactory_AddRef(IHTMLImageElementFactory *iface) { HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -804,13 +804,10 @@ static ULONG WINAPI HTMLImageElementFactory_AddRef(IHTMLImageElementFactory *ifa static ULONG WINAPI HTMLImageElementFactory_Release(IHTMLImageElementFactory *iface) { HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -939,6 +936,12 @@ static inline HTMLImageElementFactory *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLImageElementFactory, dispex); } +static void HTMLImageElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ImageElementFactory", cb); +} + static void HTMLImageElementFactory_destructor(DispatchEx *dispex) { HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); @@ -980,6 +983,7 @@ static const tid_t HTMLImageElementFactory_iface_tids[] = { static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = { HTMLImageElementFactory_destructor, + HTMLImageElementFactory_traverse, NULL, HTMLImageElementFactory_value, NULL, @@ -1003,7 +1007,7 @@ HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow *window, HTMLImageElement return E_OUTOFMEMORY; ret->IHTMLImageElementFactory_iface.lpVtbl = &HTMLImageElementFactoryVtbl; - ret->ref = 1; + ccref_init(&ret->ccref, 1); ret->window = window; init_dispatch(&ret->dispex, (IUnknown*)&ret->IHTMLImageElementFactory_iface, diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index bcb19b0e1c0..20fb0e3ccbe 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -88,7 +88,7 @@ static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID r static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -98,13 +98,10 @@ static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface) static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -618,6 +615,12 @@ static inline HTMLLocation *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLLocation, dispex); } +static void HTMLLocation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Location", cb); +} + static void HTMLLocation_unlink(DispatchEx *dispex) { HTMLLocation *This = impl_from_DispatchEx(dispex); @@ -636,6 +639,7 @@ static void HTMLLocation_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLLocation_dispex_vtbl = { HTMLLocation_destructor, + HTMLLocation_traverse, HTMLLocation_unlink }; @@ -658,7 +662,7 @@ HRESULT create_location(HTMLOuterWindow *window, HTMLLocation **ret) return E_OUTOFMEMORY; location->IHTMLLocation_iface.lpVtbl = &HTMLLocationVtbl; - location->ref = 1; + ccref_init(&location->ccref, 1); location->window = window; IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index d412b570aec..eb62ff5b6e3 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -41,7 +41,7 @@ typedef struct { DispatchEx dispex; IHTMLDOMChildrenCollection IHTMLDOMChildrenCollection_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMNodeList *nslist; } HTMLDOMChildrenCollection; @@ -225,7 +225,7 @@ static HRESULT WINAPI HTMLDOMChildrenCollection_QueryInterface(IHTMLDOMChildrenC static ULONG WINAPI HTMLDOMChildrenCollection_AddRef(IHTMLDOMChildrenCollection *iface) { HTMLDOMChildrenCollection *This = impl_from_IHTMLDOMChildrenCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -235,13 +235,10 @@ static ULONG WINAPI HTMLDOMChildrenCollection_AddRef(IHTMLDOMChildrenCollection static ULONG WINAPI HTMLDOMChildrenCollection_Release(IHTMLDOMChildrenCollection *iface) { HTMLDOMChildrenCollection *This = impl_from_IHTMLDOMChildrenCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -362,6 +359,12 @@ static inline HTMLDOMChildrenCollection *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, dispex); } +static void HTMLDOMChildrenCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMChildrenCollection", cb); +} + static void HTMLDOMChildrenCollection_unlink(DispatchEx *dispex) { HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); @@ -444,6 +447,7 @@ static HRESULT HTMLDOMChildrenCollection_invoke(DispatchEx *dispex, DISPID id, L static const dispex_static_data_vtbl_t HTMLDOMChildrenCollection_dispex_vtbl = { HTMLDOMChildrenCollection_destructor, + HTMLDOMChildrenCollection_traverse, HTMLDOMChildrenCollection_unlink, NULL, HTMLDOMChildrenCollection_get_dispid, @@ -473,7 +477,7 @@ HRESULT create_child_collection(nsIDOMNodeList *nslist, compat_mode_t compat_mod return E_OUTOFMEMORY; collection->IHTMLDOMChildrenCollection_iface.lpVtbl = &HTMLDOMChildrenCollectionVtbl; - collection->ref = 1; + ccref_init(&collection->ccref, 1); nsIDOMNodeList_AddRef(nslist); collection->nslist = nslist; @@ -1425,6 +1429,14 @@ static const IHTMLDOMNode3Vtbl HTMLDOMNode3Vtbl = { HTMLDOMNode3_isSupported }; +static void HTMLDOMNode_dispex_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDOMNode_dispex_destructor(DispatchEx *dispex) +{ +} + HRESULT HTMLDOMNode_QI(HTMLDOMNode *This, REFIID riid, void **ppv) { TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); @@ -1507,13 +1519,18 @@ void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsno assert(nsres == NS_OK); } +static const dispex_static_data_vtbl_t HTMLDOMNode_dispex_vtbl = { + HTMLDOMNode_dispex_destructor, + HTMLDOMNode_dispex_traverse, +}; + static const tid_t HTMLDOMNode_iface_tids[] = { IHTMLDOMNode_tid, 0 }; static dispex_static_data_t HTMLDOMNode_dispex = { L"Node", - NULL, + &HTMLDOMNode_dispex_vtbl, IHTMLDOMNode_tid, HTMLDOMNode_iface_tids, HTMLDOMNode_init_dispex_info @@ -1591,7 +1608,7 @@ static nsresult NSAPI HTMLDOMNode_traverse(void *ccp, void *p, nsCycleCollection note_cc_edge((nsISupports*)This->nsnode, "This->nsnode", cb); if(This->doc && &This->doc->node != This) note_cc_edge((nsISupports*)&This->doc->node.IHTMLDOMNode_iface, "This->doc", cb); - dispex_traverse(&This->event_target.dispex, cb); + dispex_traverse(&dispex_ccp, &This->event_target.dispex.IDispatchEx_iface, cb); if(This->vtbl->traverse) This->vtbl->traverse(This, cb); @@ -1608,7 +1625,7 @@ static nsresult NSAPI HTMLDOMNode_unlink(void *p) if(This->vtbl->unlink) This->vtbl->unlink(This); - dispex_unlink(&This->event_target.dispex); + dispex_unlink(&This->event_target.dispex.IDispatchEx_iface); unlink_ref(&This->nsnode); if(This->doc && &This->doc->node != This) { @@ -1631,7 +1648,7 @@ static void NSAPI HTMLDOMNode_delete_cycle_collectable(void *p) if(This->vtbl->unlink) This->vtbl->unlink(This); This->vtbl->destructor(This); - release_dispex(&This->event_target.dispex); + dispex_delete_cycle_collectable(&This->event_target.dispex.IDispatchEx_iface); free(This); } diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index b48805de64d..231303aabaa 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -473,7 +473,7 @@ static HRESULT WINAPI HTMLOptionElementFactory_QueryInterface(IHTMLOptionElement static ULONG WINAPI HTMLOptionElementFactory_AddRef(IHTMLOptionElementFactory *iface) { HTMLOptionElementFactory *This = impl_from_IHTMLOptionElementFactory(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -483,13 +483,10 @@ static ULONG WINAPI HTMLOptionElementFactory_AddRef(IHTMLOptionElementFactory *i static ULONG WINAPI HTMLOptionElementFactory_Release(IHTMLOptionElementFactory *iface) { HTMLOptionElementFactory *This = impl_from_IHTMLOptionElementFactory(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -589,6 +586,12 @@ static inline HTMLOptionElementFactory *HTMLOptionElementFactory_from_DispatchEx return CONTAINING_RECORD(iface, HTMLOptionElementFactory, dispex); } +static void HTMLOptionElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "OptionElementFactory", cb); +} + static void HTMLOptionElementFactory_destructor(DispatchEx *dispex) { HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); @@ -634,6 +637,7 @@ static const tid_t HTMLOptionElementFactory_iface_tids[] = { static const dispex_static_data_vtbl_t HTMLOptionElementFactory_dispex_vtbl = { HTMLOptionElementFactory_destructor, + HTMLOptionElementFactory_traverse, NULL, HTMLOptionElementFactory_value, NULL, @@ -657,7 +661,7 @@ HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow *window, HTMLOptionEleme return E_OUTOFMEMORY; ret->IHTMLOptionElementFactory_iface.lpVtbl = &HTMLOptionElementFactoryVtbl; - ret->ref = 1; + ccref_init(&ret->ccref, 1); ret->window = window; init_dispatch(&ret->dispex, (IUnknown*)&ret->IHTMLOptionElementFactory_iface, diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index cad2b2dbd32..4ea611590d1 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -39,7 +39,7 @@ enum { MAX_QUOTA = 5000000 }; typedef struct { DispatchEx dispex; IHTMLStorage IHTMLStorage_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; unsigned num_props; BSTR *props; HTMLInnerWindow *window; @@ -383,7 +383,7 @@ static HRESULT WINAPI HTMLStorage_QueryInterface(IHTMLStorage *iface, REFIID rii static ULONG WINAPI HTMLStorage_AddRef(IHTMLStorage *iface) { HTMLStorage *This = impl_from_IHTMLStorage(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -393,13 +393,10 @@ static ULONG WINAPI HTMLStorage_AddRef(IHTMLStorage *iface) static ULONG WINAPI HTMLStorage_Release(IHTMLStorage *iface) { HTMLStorage *This = impl_from_IHTMLStorage(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1057,6 +1054,12 @@ static inline HTMLStorage *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLStorage, dispex); } +static void HTMLStorage_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLStorage *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Storage", cb); +} + static void HTMLStorage_destructor(DispatchEx *dispex) { HTMLStorage *This = impl_from_DispatchEx(dispex); @@ -1313,6 +1316,7 @@ static HRESULT HTMLStorage_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pi static const dispex_static_data_vtbl_t HTMLStorage_dispex_vtbl = { HTMLStorage_destructor, + HTMLStorage_traverse, NULL, NULL, HTMLStorage_get_dispid, @@ -1481,7 +1485,7 @@ HRESULT create_html_storage(HTMLInnerWindow *window, BOOL local, IHTMLStorage ** } storage->IHTMLStorage_iface.lpVtbl = &HTMLStorageVtbl; - storage->ref = 1; + ccref_init(&storage->ccref, 1); storage->window = window; init_dispatch(&storage->dispex, (IUnknown*)&storage->IHTMLStorage_iface, &HTMLStorage_dispex, diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index b696a155fc2..94dfe1b2d21 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -4758,7 +4758,7 @@ static HRESULT WINAPI HTMLCSSStyleDeclaration_QueryInterface(IHTMLCSSStyleDeclar static ULONG WINAPI HTMLCSSStyleDeclaration_AddRef(IHTMLCSSStyleDeclaration *iface) { CSSStyle *This = impl_from_IHTMLCSSStyleDeclaration(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -4768,13 +4768,10 @@ static ULONG WINAPI HTMLCSSStyleDeclaration_AddRef(IHTMLCSSStyleDeclaration *ifa static ULONG WINAPI HTMLCSSStyleDeclaration_Release(IHTMLCSSStyleDeclaration *iface) { CSSStyle *This = impl_from_IHTMLCSSStyleDeclaration(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -9965,6 +9962,12 @@ static inline CSSStyle *impl_from_DispatchEx(DispatchEx *dispex) return CONTAINING_RECORD(dispex, CSSStyle, dispex); } +static void CSSStyle_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + CSSStyle *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "CSSStyle", cb); +} + static void CSSStyle_unlink(DispatchEx *dispex) { CSSStyle *This = impl_from_DispatchEx(dispex); @@ -10006,6 +10009,7 @@ void CSSStyle_init_dispex_info(dispex_data_t *info, compat_mode_t mode) const dispex_static_data_vtbl_t CSSStyle_dispex_vtbl = { CSSStyle_destructor, + CSSStyle_traverse, CSSStyle_unlink, NULL, CSSStyle_get_dispid, @@ -10073,10 +10077,10 @@ void init_css_style(CSSStyle *style, nsIDOMCSSStyleDeclaration *nsstyle, style_q { style->IHTMLCSSStyleDeclaration_iface.lpVtbl = &HTMLCSSStyleDeclarationVtbl; style->IHTMLCSSStyleDeclaration2_iface.lpVtbl = &HTMLCSSStyleDeclaration2Vtbl; - style->ref = 1; style->qi = qi; style->nsstyle = nsstyle; nsIDOMCSSStyleDeclaration_AddRef(nsstyle); + ccref_init(&style->ccref, 1); init_dispatch(&style->dispex, (IUnknown*)&style->IHTMLCSSStyleDeclaration_iface, dispex_info, compat_mode); diff --git a/dlls/mshtml/htmlstyle.h b/dlls/mshtml/htmlstyle.h index 73d54128120..81161671665 100644 --- a/dlls/mshtml/htmlstyle.h +++ b/dlls/mshtml/htmlstyle.h @@ -24,7 +24,7 @@ struct CSSStyle { IHTMLCSSStyleDeclaration IHTMLCSSStyleDeclaration_iface; IHTMLCSSStyleDeclaration2 IHTMLCSSStyleDeclaration2_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; style_qi_t qi; nsIDOMCSSStyleDeclaration *nsstyle; diff --git a/dlls/mshtml/htmlstylesheet.c b/dlls/mshtml/htmlstylesheet.c index 010f3ef3f8c..79bcb55b9af 100644 --- a/dlls/mshtml/htmlstylesheet.c +++ b/dlls/mshtml/htmlstylesheet.c @@ -36,7 +36,7 @@ struct HTMLStyleSheet { IHTMLStyleSheet IHTMLStyleSheet_iface; IHTMLStyleSheet4 IHTMLStyleSheet4_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMCSSStyleSheet *nsstylesheet; }; @@ -45,7 +45,7 @@ struct HTMLStyleSheetsCollection { DispatchEx dispex; IHTMLStyleSheetsCollection IHTMLStyleSheetsCollection_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMStyleSheetList *nslist; }; @@ -63,7 +63,7 @@ struct HTMLStyleSheetRulesCollection { DispatchEx dispex; IHTMLStyleSheetRulesCollection IHTMLStyleSheetRulesCollection_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMCSSRuleList *nslist; }; @@ -72,7 +72,7 @@ struct HTMLStyleSheetRule { DispatchEx dispex; IHTMLStyleSheetRule IHTMLStyleSheetRule_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMCSSRule *nsstylesheetrule; }; @@ -109,7 +109,7 @@ static HRESULT WINAPI HTMLStyleSheetRule_QueryInterface(IHTMLStyleSheetRule *ifa static ULONG WINAPI HTMLStyleSheetRule_AddRef(IHTMLStyleSheetRule *iface) { HTMLStyleSheetRule *This = impl_from_IHTMLStyleSheetRule(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -119,13 +119,10 @@ static ULONG WINAPI HTMLStyleSheetRule_AddRef(IHTMLStyleSheetRule *iface) static ULONG WINAPI HTMLStyleSheetRule_Release(IHTMLStyleSheetRule *iface) { HTMLStyleSheetRule *This = impl_from_IHTMLStyleSheetRule(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -207,6 +204,12 @@ static inline HTMLStyleSheetRule *HTMLStyleSheetRule_from_DispatchEx(DispatchEx return CONTAINING_RECORD(iface, HTMLStyleSheetRule, dispex); } +static void HTMLStyleSheetRule_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetRule", cb); +} + static void HTMLStyleSheetRule_unlink(DispatchEx *dispex) { HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); @@ -221,6 +224,7 @@ static void HTMLStyleSheetRule_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLStyleSheetRule_dispex_vtbl = { HTMLStyleSheetRule_destructor, + HTMLStyleSheetRule_traverse, HTMLStyleSheetRule_unlink }; @@ -245,8 +249,8 @@ static HRESULT create_style_sheet_rule(nsIDOMCSSRule *nsstylesheetrule, compat_m return E_OUTOFMEMORY; rule->IHTMLStyleSheetRule_iface.lpVtbl = &HTMLStyleSheetRuleVtbl; - rule->ref = 1; rule->nsstylesheetrule = NULL; + ccref_init(&rule->ccref, 1); init_dispatch(&rule->dispex, (IUnknown *)&rule->IHTMLStyleSheetRule_iface, &HTMLStyleSheetRule_dispex, compat_mode); @@ -294,7 +298,7 @@ static HRESULT WINAPI HTMLStyleSheetRulesCollection_QueryInterface(IHTMLStyleShe static ULONG WINAPI HTMLStyleSheetRulesCollection_AddRef(IHTMLStyleSheetRulesCollection *iface) { HTMLStyleSheetRulesCollection *This = impl_from_IHTMLStyleSheetRulesCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -304,13 +308,10 @@ static ULONG WINAPI HTMLStyleSheetRulesCollection_AddRef(IHTMLStyleSheetRulesCol static ULONG WINAPI HTMLStyleSheetRulesCollection_Release(IHTMLStyleSheetRulesCollection *iface) { HTMLStyleSheetRulesCollection *This = impl_from_IHTMLStyleSheetRulesCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -403,6 +404,12 @@ static inline HTMLStyleSheetRulesCollection *HTMLStyleSheetRulesCollection_from_ return CONTAINING_RECORD(iface, HTMLStyleSheetRulesCollection, dispex); } +static void HTMLStyleSheetRulesCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetRulesCollection", cb); +} + static void HTMLStyleSheetRulesCollection_unlink(DispatchEx *dispex) { HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); @@ -493,6 +500,7 @@ static HRESULT HTMLStyleSheetRulesCollection_invoke(DispatchEx *dispex, DISPID i static const dispex_static_data_vtbl_t HTMLStyleSheetRulesCollection_dispex_vtbl = { HTMLStyleSheetRulesCollection_destructor, + HTMLStyleSheetRulesCollection_traverse, HTMLStyleSheetRulesCollection_unlink, NULL, HTMLStyleSheetRulesCollection_get_dispid, @@ -519,8 +527,8 @@ static HRESULT create_style_sheet_rules_collection(nsIDOMCSSRuleList *nslist, co return E_OUTOFMEMORY; collection->IHTMLStyleSheetRulesCollection_iface.lpVtbl = &HTMLStyleSheetRulesCollectionVtbl; - collection->ref = 1; collection->nslist = nslist; + ccref_init(&collection->ccref, 1); init_dispatch(&collection->dispex, (IUnknown*)&collection->IHTMLStyleSheetRulesCollection_iface, &HTMLStyleSheetRulesCollection_dispex, compat_mode); @@ -689,7 +697,7 @@ static HRESULT WINAPI HTMLStyleSheetsCollection_QueryInterface(IHTMLStyleSheetsC static ULONG WINAPI HTMLStyleSheetsCollection_AddRef(IHTMLStyleSheetsCollection *iface) { HTMLStyleSheetsCollection *This = impl_from_IHTMLStyleSheetsCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -699,13 +707,10 @@ static ULONG WINAPI HTMLStyleSheetsCollection_AddRef(IHTMLStyleSheetsCollection static ULONG WINAPI HTMLStyleSheetsCollection_Release(IHTMLStyleSheetsCollection *iface) { HTMLStyleSheetsCollection *This = impl_from_IHTMLStyleSheetsCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -840,6 +845,12 @@ static inline HTMLStyleSheetsCollection *HTMLStyleSheetsCollection_from_Dispatch return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, dispex); } +static void HTMLStyleSheetsCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetsCollection", cb); +} + static void HTMLStyleSheetsCollection_unlink(DispatchEx *dispex) { HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); @@ -930,6 +941,7 @@ static HRESULT HTMLStyleSheetsCollection_invoke(DispatchEx *dispex, DISPID id, L static const dispex_static_data_vtbl_t HTMLStyleSheetsCollection_dispex_vtbl = { HTMLStyleSheetsCollection_destructor, + HTMLStyleSheetsCollection_traverse, HTMLStyleSheetsCollection_unlink, NULL, HTMLStyleSheetsCollection_get_dispid, @@ -956,7 +968,7 @@ HRESULT create_style_sheet_collection(nsIDOMStyleSheetList *nslist, compat_mode_ return E_OUTOFMEMORY; collection->IHTMLStyleSheetsCollection_iface.lpVtbl = &HTMLStyleSheetsCollectionVtbl; - collection->ref = 1; + ccref_init(&collection->ccref, 1); if(nslist) nsIDOMStyleSheetList_AddRef(nslist); @@ -1003,7 +1015,7 @@ static HRESULT WINAPI HTMLStyleSheet_QueryInterface(IHTMLStyleSheet *iface, REFI static ULONG WINAPI HTMLStyleSheet_AddRef(IHTMLStyleSheet *iface) { HTMLStyleSheet *This = impl_from_IHTMLStyleSheet(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1013,13 +1025,10 @@ static ULONG WINAPI HTMLStyleSheet_AddRef(IHTMLStyleSheet *iface) static ULONG WINAPI HTMLStyleSheet_Release(IHTMLStyleSheet *iface) { HTMLStyleSheet *This = impl_from_IHTMLStyleSheet(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1501,6 +1510,12 @@ static inline HTMLStyleSheet *HTMLStyleSheet_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLStyleSheet, dispex); } +static void HTMLStyleSheet_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheet", cb); +} + static void HTMLStyleSheet_unlink(DispatchEx *dispex) { HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); @@ -1521,6 +1536,7 @@ static void HTMLStyleSheet_init_dispex_info(dispex_data_t *info, compat_mode_t m static const dispex_static_data_vtbl_t HTMLStyleSheet_dispex_vtbl = { HTMLStyleSheet_destructor, + HTMLStyleSheet_traverse, HTMLStyleSheet_unlink }; @@ -1546,8 +1562,8 @@ HRESULT create_style_sheet(nsIDOMStyleSheet *nsstylesheet, compat_mode_t compat_ style_sheet->IHTMLStyleSheet_iface.lpVtbl = &HTMLStyleSheetVtbl; style_sheet->IHTMLStyleSheet4_iface.lpVtbl = &HTMLStyleSheet4Vtbl; - style_sheet->ref = 1; style_sheet->nsstylesheet = NULL; + ccref_init(&style_sheet->ccref, 1); init_dispatch(&style_sheet->dispex, (IUnknown*)&style_sheet->IHTMLStyleSheet_iface, &HTMLStyleSheet_dispex, compat_mode); diff --git a/dlls/mshtml/htmltextnode.c b/dlls/mshtml/htmltextnode.c index a09c0758452..75ce7b6f5ce 100644 --- a/dlls/mshtml/htmltextnode.c +++ b/dlls/mshtml/htmltextnode.c @@ -319,6 +319,14 @@ static const IHTMLDOMTextNode2Vtbl HTMLDOMTextNode2Vtbl = { HTMLDOMTextNode2_replaceData }; +static void HTMLDOMTextNode_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDOMTextNode_destructor(DispatchEx *dispex) +{ +} + static inline HTMLDOMTextNode *impl_from_HTMLDOMNode(HTMLDOMNode *iface) { return CONTAINING_RECORD(iface, HTMLDOMTextNode, node); @@ -358,6 +366,11 @@ static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = { HTMLDOMTextNode_clone }; +static const dispex_static_data_vtbl_t HTMLDOMTextNode_dispex_vtbl = { + HTMLDOMTextNode_destructor, + HTMLDOMTextNode_traverse, +}; + static const tid_t HTMLDOMTextNode_iface_tids[] = { IHTMLDOMNode_tid, IHTMLDOMNode2_tid, @@ -367,7 +380,7 @@ static const tid_t HTMLDOMTextNode_iface_tids[] = { }; static dispex_static_data_t HTMLDOMTextNode_dispex = { L"Text", - NULL, + &HTMLDOMTextNode_dispex_vtbl, DispHTMLDOMTextNode_tid, HTMLDOMTextNode_iface_tids, HTMLDOMNode_init_dispex_info diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 01fd0744e34..d63de01b658 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -134,7 +134,7 @@ static void detach_inner_window(HTMLInnerWindow *window) detach_document_node(doc); if(outer_window && outer_window->location) - dispex_unlink(&outer_window->location->dispex); + dispex_props_unlink(&outer_window->location->dispex); abort_window_bindings(window); remove_target_tasks(window->task_magic); @@ -3688,6 +3688,12 @@ static inline HTMLInnerWindow *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLInnerWindow, event_target.dispex); } +static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->base.ccref, "InnerWindow", cb); +} + static void HTMLWindow_unlink(DispatchEx *dispex) { HTMLInnerWindow *This = impl_from_DispatchEx(dispex); @@ -4011,6 +4017,7 @@ static IHTMLEventObj *HTMLWindow_set_current_event(DispatchEx *dispex, IHTMLEven static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { { HTMLWindow_destructor, + HTMLWindow_traverse, HTMLWindow_unlink, NULL, NULL, @@ -4047,10 +4054,9 @@ static nsresult NSAPI window_traverse(void *ccp, void *p, nsCycleCollectionTrave HTMLWindow *This = impl_from_IHTMLWindow2(p); HTMLOuterWindow *window; - if(!is_outer_window(This)) { - /* FIXME: Traverse inner window and its dispex */ - return NS_OK; - } + if(!is_outer_window(This)) + return dispex_traverse(&window_ccp, &This->inner_window->event_target.dispex.IDispatchEx_iface, cb); + window = This->outer_window; describe_cc_node(&window->base.ccref, "OuterWindow", cb); @@ -4075,10 +4081,9 @@ static nsresult NSAPI window_unlink(void *p) HTMLWindow *This = impl_from_IHTMLWindow2(p); HTMLOuterWindow *window; - if(!is_outer_window(This)) { - /* FIXME: Unlink inner window and its dispex */ - return NS_OK; - } + if(!is_outer_window(This)) + return dispex_unlink(&This->inner_window->event_target.dispex.IDispatchEx_iface); + window = This->outer_window; remove_target_tasks(window->task_magic); @@ -4123,7 +4128,7 @@ static void NSAPI window_delete_cycle_collectable(void *p) window_unlink(p); if(!is_outer_window(This)) { - release_dispex(&This->inner_window->event_target.dispex); + dispex_delete_cycle_collectable(&This->inner_window->event_target.dispex.IDispatchEx_iface); return; } diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c44441ce3d9..806ab8f978f 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -337,6 +337,7 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t; #define MSHTML_CUSTOM_DISPID_CNT (MSHTML_DISPID_CUSTOM_MAX-MSHTML_DISPID_CUSTOM_MIN) typedef struct DispatchEx DispatchEx; +typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback; /* dispex is our base IDispatchEx implementation for all mshtml objects, and the vtbl allows @@ -347,8 +348,11 @@ typedef struct DispatchEx DispatchEx; - dynamic props: These props are generally allocated by external code (e.g. 'document.wine = 42' creates 'wine' dynamic prop on document) */ typedef struct { - /* Unlike delete_cycle_collectable, unlink is called before the destructor (if available). */ + /* Used to implement Cycle Collection callbacks; destructor and traverse are not optional! + Note that traverse *must* describe the node first before doing any traversal (if any). + Unlike delete_cycle_collectable, unlink is called before the destructor (if available). */ void (*destructor)(DispatchEx*); + void (*traverse)(DispatchEx*,nsCycleCollectionTraversalCallback*); void (*unlink)(DispatchEx*); /* Called when the object wants to handle DISPID_VALUE invocations */ @@ -408,8 +412,6 @@ typedef struct { void *callbacks; } ExternalCycleCollectionParticipant; -typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback; - typedef struct { nsresult (NSAPI *traverse)(void*,void*,nsCycleCollectionTraversalCallback*); nsresult (NSAPI *unlink)(void*); @@ -425,16 +427,29 @@ extern void (__cdecl *ccp_init)(ExternalCycleCollectionParticipant*,const CCObjC extern void (__cdecl *describe_cc_node)(nsCycleCollectingAutoRefCnt*,const char*,nsCycleCollectionTraversalCallback*); extern void (__cdecl *note_cc_edge)(nsISupports*,const char*,nsCycleCollectionTraversalCallback*); +extern ExternalCycleCollectionParticipant dispex_ccp; + +static inline LONG dispex_ccref_incr(nsCycleCollectingAutoRefCnt *ccref, DispatchEx *dispex) +{ + return ccref_incr(ccref, (nsISupports*)&dispex->IDispatchEx_iface); +} + +static inline LONG dispex_ccref_decr(nsCycleCollectingAutoRefCnt *ccref, DispatchEx *dispex) +{ + return ccref_decr(ccref, (nsISupports*)&dispex->IDispatchEx_iface, &dispex_ccp); +} + void init_dispatch(DispatchEx*,IUnknown*,dispex_static_data_t*,compat_mode_t); -void release_dispex(DispatchEx*); BOOL dispex_query_interface(DispatchEx*,REFIID,void**); +void dispex_props_unlink(DispatchEx*); +nsresult NSAPI dispex_traverse(void*,void*,nsCycleCollectionTraversalCallback*); +nsresult NSAPI dispex_unlink(void*); +void NSAPI dispex_delete_cycle_collectable(void*); HRESULT change_type(VARIANT*,VARIANT*,VARTYPE,IServiceProvider*); HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**); HRESULT get_dispids(tid_t,DWORD*,DISPID**); HRESULT remove_attribute(DispatchEx*,DISPID,VARIANT_BOOL*); HRESULT dispex_get_dynid(DispatchEx*,const WCHAR*,BOOL,DISPID*); -void dispex_traverse(DispatchEx*,nsCycleCollectionTraversalCallback*); -void dispex_unlink(DispatchEx*); void release_typelib(void); HRESULT get_class_typeinfo(const CLSID*,ITypeInfo**); const void *dispex_get_vtbl(DispatchEx*); @@ -487,7 +502,7 @@ typedef struct { DispatchEx dispex; IHTMLOptionElementFactory IHTMLOptionElementFactory_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; } HTMLOptionElementFactory; @@ -496,7 +511,7 @@ typedef struct { DispatchEx dispex; IHTMLImageElementFactory IHTMLImageElementFactory_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; } HTMLImageElementFactory; @@ -505,7 +520,7 @@ typedef struct { DispatchEx dispex; IHTMLXMLHttpRequestFactory IHTMLXMLHttpRequestFactory_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; } HTMLXMLHttpRequestFactory; @@ -514,7 +529,7 @@ struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLOuterWindow *window; }; @@ -523,7 +538,7 @@ typedef struct { DispatchEx dispex; IOmHistory IOmHistory_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; } OmHistory; @@ -955,8 +970,6 @@ struct HTMLDocumentNode { nsIDocumentObserver nsIDocumentObserver_iface; - LONG ref; - ConnectionPointContainer cp_container; HTMLOuterWindow *outer_window; HTMLInnerWindow *window; @@ -1070,6 +1083,7 @@ BOOL is_gecko_path(const char*); void set_viewer_zoom(GeckoBrowser*,float); float get_viewer_zoom(GeckoBrowser*); +void init_dispex_cc(void); void init_window_cc(void); void init_node_cc(void); @@ -1156,7 +1170,7 @@ struct HTMLAttributeCollection { IHTMLAttributeCollection2 IHTMLAttributeCollection2_iface; IHTMLAttributeCollection3 IHTMLAttributeCollection3_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLElement *elem; struct list attrs; @@ -1167,7 +1181,7 @@ typedef struct { IHTMLDOMAttribute IHTMLDOMAttribute_iface; IHTMLDOMAttribute2 IHTMLDOMAttribute2_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; /* value is valid only for detached attributes (when elem == NULL). */ VARIANT value; diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 6fdb5093066..ba74e3f6a7a 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -1080,7 +1080,7 @@ void init_mutation(nsIComponentManager *component_manager) struct mutation_observer { IWineMSHTMLMutationObserver IWineMSHTMLMutationObserver_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; DispatchEx dispex; IDispatch *callback; }; @@ -1113,7 +1113,7 @@ static HRESULT WINAPI MutationObserver_QueryInterface(IWineMSHTMLMutationObserve static ULONG WINAPI MutationObserver_AddRef(IWineMSHTMLMutationObserver *iface) { struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1123,13 +1123,10 @@ static ULONG WINAPI MutationObserver_AddRef(IWineMSHTMLMutationObserver *iface) static ULONG WINAPI MutationObserver_Release(IWineMSHTMLMutationObserver *iface) { struct mutation_observer *This = impl_from_IWineMSHTMLMutationObserver(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1215,6 +1212,12 @@ static inline struct mutation_observer *mutation_observer_from_DispatchEx(Dispat return CONTAINING_RECORD(iface, struct mutation_observer, dispex); } +static void mutation_observer_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct mutation_observer *This = mutation_observer_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "MutationObserver", cb); +} + static void mutation_observer_unlink(DispatchEx *dispex) { struct mutation_observer *This = mutation_observer_from_DispatchEx(dispex); @@ -1229,6 +1232,7 @@ static void mutation_observer_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t mutation_observer_dispex_vtbl = { mutation_observer_destructor, + mutation_observer_traverse, mutation_observer_unlink }; @@ -1258,7 +1262,7 @@ static HRESULT create_mutation_observer(compat_mode_t compat_mode, IDispatch *ca } obj->IWineMSHTMLMutationObserver_iface.lpVtbl = &WineMSHTMLMutationObserverVtbl; - obj->ref = 1; + ccref_init(&obj->ccref, 1); init_dispatch(&obj->dispex, (IUnknown*)&obj->IWineMSHTMLMutationObserver_iface, &mutation_observer_dispex, compat_mode); @@ -1272,7 +1276,7 @@ struct mutation_observer_ctor { IUnknown IUnknown_iface; DispatchEx dispex; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; }; static inline struct mutation_observer_ctor *mutation_observer_ctor_from_IUnknown(IUnknown *iface) @@ -1308,7 +1312,7 @@ static HRESULT WINAPI mutation_observer_ctor_QueryInterface(IUnknown *iface, REF static ULONG WINAPI mutation_observer_ctor_AddRef(IUnknown *iface) { struct mutation_observer_ctor *This = mutation_observer_ctor_from_IUnknown(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1318,13 +1322,10 @@ static ULONG WINAPI mutation_observer_ctor_AddRef(IUnknown *iface) static ULONG WINAPI mutation_observer_ctor_Release(IUnknown *iface) { struct mutation_observer_ctor *This = mutation_observer_ctor_from_IUnknown(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1334,6 +1335,12 @@ static const IUnknownVtbl mutation_observer_ctor_vtbl = { mutation_observer_ctor_Release, }; +static void mutation_observer_ctor_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct mutation_observer_ctor *This = mutation_observer_ctor_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "MutationObserver Constructor", cb); +} + static void mutation_observer_ctor_destructor(DispatchEx *dispex) { struct mutation_observer_ctor *This = mutation_observer_ctor_from_DispatchEx(dispex); @@ -1389,6 +1396,7 @@ static HRESULT mutation_observer_ctor_value(DispatchEx *dispex, LCID lcid, static dispex_static_data_vtbl_t mutation_observer_ctor_dispex_vtbl = { mutation_observer_ctor_destructor, + mutation_observer_ctor_traverse, NULL, mutation_observer_ctor_value }; @@ -1418,7 +1426,7 @@ HRESULT create_mutation_observer_ctor(compat_mode_t compat_mode, IDispatch **ret } obj->IUnknown_iface.lpVtbl = &mutation_observer_ctor_vtbl; - obj->ref = 1; + ccref_init(&obj->ccref, 1); init_dispatch(&obj->dispex, (IUnknown*)&obj->IUnknown_iface, &mutation_observer_ctor_dispex, compat_mode); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 61d4ec335b4..00295242f4a 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -596,6 +596,7 @@ static BOOL init_xpcom(const PRUnichar *gre_path) ERR("NS_GetComponentRegistrar failed: %08lx\n", nsres); } + init_dispex_cc(); init_window_cc(); init_node_cc(); diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 0594a46f4ee..397ea83c120 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -38,7 +38,7 @@ typedef struct { DispatchEx dispex; IOmNavigator IOmNavigator_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLPluginsCollection *plugins; HTMLMimeTypesCollection *mime_types; @@ -49,7 +49,7 @@ typedef struct { IHTMLDOMImplementation IHTMLDOMImplementation_iface; IHTMLDOMImplementation2 IHTMLDOMImplementation2_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMDOMImplementation *implementation; GeckoBrowser *browser; @@ -85,7 +85,7 @@ static HRESULT WINAPI HTMLDOMImplementation_QueryInterface(IHTMLDOMImplementatio static ULONG WINAPI HTMLDOMImplementation_AddRef(IHTMLDOMImplementation *iface) { HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -95,13 +95,10 @@ static ULONG WINAPI HTMLDOMImplementation_AddRef(IHTMLDOMImplementation *iface) static ULONG WINAPI HTMLDOMImplementation_Release(IHTMLDOMImplementation *iface) { HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -294,6 +291,12 @@ static inline HTMLDOMImplementation *HTMLDOMImplementation_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLDOMImplementation, dispex); } +static void HTMLDOMImplementation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMImplementation *This = HTMLDOMImplementation_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMImplementation", cb); +} + static void HTMLDOMImplementation_unlink(DispatchEx *dispex) { HTMLDOMImplementation *This = HTMLDOMImplementation_from_DispatchEx(dispex); @@ -309,6 +312,7 @@ static void HTMLDOMImplementation_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLDOMImplementation_dispex_vtbl = { HTMLDOMImplementation_destructor, + HTMLDOMImplementation_traverse, HTMLDOMImplementation_unlink }; @@ -344,8 +348,8 @@ HRESULT create_dom_implementation(HTMLDocumentNode *doc_node, IHTMLDOMImplementa dom_implementation->IHTMLDOMImplementation_iface.lpVtbl = &HTMLDOMImplementationVtbl; dom_implementation->IHTMLDOMImplementation2_iface.lpVtbl = &HTMLDOMImplementation2Vtbl; - dom_implementation->ref = 1; dom_implementation->browser = doc_node->browser; + ccref_init(&dom_implementation->ccref, 1); init_dispatch(&dom_implementation->dispex, (IUnknown*)&dom_implementation->IHTMLDOMImplementation_iface, &HTMLDOMImplementation_dispex, doc_node->document_mode); @@ -371,7 +375,7 @@ typedef struct { DispatchEx dispex; IHTMLScreen IHTMLScreen_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; } HTMLScreen; static inline HTMLScreen *impl_from_IHTMLScreen(IHTMLScreen *iface) @@ -404,7 +408,7 @@ static HRESULT WINAPI HTMLScreen_QueryInterface(IHTMLScreen *iface, REFIID riid, static ULONG WINAPI HTMLScreen_AddRef(IHTMLScreen *iface) { HTMLScreen *This = impl_from_IHTMLScreen(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -414,13 +418,10 @@ static ULONG WINAPI HTMLScreen_AddRef(IHTMLScreen *iface) static ULONG WINAPI HTMLScreen_Release(IHTMLScreen *iface) { HTMLScreen *This = impl_from_IHTMLScreen(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -574,6 +575,12 @@ static inline HTMLScreen *HTMLScreen_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLScreen, dispex); } +static void HTMLScreen_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLScreen *This = HTMLScreen_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Screen", cb); +} + static void HTMLScreen_destructor(DispatchEx *dispex) { HTMLScreen *This = HTMLScreen_from_DispatchEx(dispex); @@ -582,6 +589,7 @@ static void HTMLScreen_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLScreen_dispex_vtbl = { HTMLScreen_destructor, + HTMLScreen_traverse }; static const tid_t HTMLScreen_iface_tids[] = { @@ -604,7 +612,7 @@ HRESULT create_html_screen(compat_mode_t compat_mode, IHTMLScreen **ret) return E_OUTOFMEMORY; screen->IHTMLScreen_iface.lpVtbl = &HTMLSreenVtbl; - screen->ref = 1; + ccref_init(&screen->ccref, 1); init_dispatch(&screen->dispex, (IUnknown*)&screen->IHTMLScreen_iface, &HTMLScreen_dispex, compat_mode); @@ -642,7 +650,7 @@ static HRESULT WINAPI OmHistory_QueryInterface(IOmHistory *iface, REFIID riid, v static ULONG WINAPI OmHistory_AddRef(IOmHistory *iface) { OmHistory *This = impl_from_IOmHistory(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -652,13 +660,10 @@ static ULONG WINAPI OmHistory_AddRef(IOmHistory *iface) static ULONG WINAPI OmHistory_Release(IOmHistory *iface) { OmHistory *This = impl_from_IOmHistory(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -751,6 +756,12 @@ static inline OmHistory *OmHistory_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, OmHistory, dispex); } +static void OmHistory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + OmHistory *This = OmHistory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "History", cb); +} + static void OmHistory_destructor(DispatchEx *dispex) { OmHistory *This = OmHistory_from_DispatchEx(dispex); @@ -759,6 +770,7 @@ static void OmHistory_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t OmHistory_dispex_vtbl = { OmHistory_destructor, + OmHistory_traverse }; static const tid_t OmHistory_iface_tids[] = { @@ -784,7 +796,7 @@ HRESULT create_history(HTMLInnerWindow *window, OmHistory **ret) init_dispatch(&history->dispex, (IUnknown*)&history->IOmHistory_iface, &OmHistory_dispex, dispex_compat_mode(&window->event_target.dispex)); history->IOmHistory_iface.lpVtbl = &OmHistoryVtbl; - history->ref = 1; + ccref_init(&history->ccref, 1); history->window = window; @@ -796,7 +808,7 @@ struct HTMLPluginsCollection { DispatchEx dispex; IHTMLPluginsCollection IHTMLPluginsCollection_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; OmNavigator *navigator; }; @@ -831,7 +843,7 @@ static HRESULT WINAPI HTMLPluginsCollection_QueryInterface(IHTMLPluginsCollectio static ULONG WINAPI HTMLPluginsCollection_AddRef(IHTMLPluginsCollection *iface) { HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -841,13 +853,10 @@ static ULONG WINAPI HTMLPluginsCollection_AddRef(IHTMLPluginsCollection *iface) static ULONG WINAPI HTMLPluginsCollection_Release(IHTMLPluginsCollection *iface) { HTMLPluginsCollection *This = impl_from_IHTMLPluginsCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -919,6 +928,12 @@ static inline HTMLPluginsCollection *HTMLPluginsCollection_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLPluginsCollection, dispex); } +static void HTMLPluginsCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PluginsCollection", cb); +} + static void HTMLPluginsCollection_unlink(DispatchEx *dispex) { HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); @@ -936,6 +951,7 @@ static void HTMLPluginsCollection_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLPluginsCollection_dispex_vtbl = { HTMLPluginsCollection_destructor, + HTMLPluginsCollection_traverse, HTMLPluginsCollection_unlink }; @@ -959,8 +975,8 @@ static HRESULT create_plugins_collection(OmNavigator *navigator, HTMLPluginsColl return E_OUTOFMEMORY; col->IHTMLPluginsCollection_iface.lpVtbl = &HTMLPluginsCollectionVtbl; - col->ref = 1; col->navigator = navigator; + ccref_init(&col->ccref, 1); init_dispatch(&col->dispex, (IUnknown*)&col->IHTMLPluginsCollection_iface, &HTMLPluginsCollection_dispex, dispex_compat_mode(&navigator->dispex)); @@ -973,7 +989,7 @@ struct HTMLMimeTypesCollection { DispatchEx dispex; IHTMLMimeTypesCollection IHTMLMimeTypesCollection_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; OmNavigator *navigator; }; @@ -1008,7 +1024,7 @@ static HRESULT WINAPI HTMLMimeTypesCollection_QueryInterface(IHTMLMimeTypesColle static ULONG WINAPI HTMLMimeTypesCollection_AddRef(IHTMLMimeTypesCollection *iface) { HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1018,13 +1034,10 @@ static ULONG WINAPI HTMLMimeTypesCollection_AddRef(IHTMLMimeTypesCollection *ifa static ULONG WINAPI HTMLMimeTypesCollection_Release(IHTMLMimeTypesCollection *iface) { HTMLMimeTypesCollection *This = impl_from_IHTMLMimeTypesCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1085,6 +1098,12 @@ static inline HTMLMimeTypesCollection *HTMLMimeTypesCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLMimeTypesCollection, dispex); } +static void HTMLMimeTypesCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "MimeTypesCollection", cb); +} + static void HTMLMimeTypesCollection_unlink(DispatchEx *dispex) { HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); @@ -1102,6 +1121,7 @@ static void HTMLMimeTypesCollection_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLMimeTypesCollection_dispex_vtbl = { HTMLMimeTypesCollection_destructor, + HTMLMimeTypesCollection_traverse, HTMLMimeTypesCollection_unlink }; @@ -1125,8 +1145,8 @@ static HRESULT create_mime_types_collection(OmNavigator *navigator, HTMLMimeType return E_OUTOFMEMORY; col->IHTMLMimeTypesCollection_iface.lpVtbl = &HTMLMimeTypesCollectionVtbl; - col->ref = 1; col->navigator = navigator; + ccref_init(&col->ccref, 1); init_dispatch(&col->dispex, (IUnknown*)&col->IHTMLMimeTypesCollection_iface, &HTMLMimeTypesCollection_dispex, dispex_compat_mode(&navigator->dispex)); @@ -1165,7 +1185,7 @@ static HRESULT WINAPI OmNavigator_QueryInterface(IOmNavigator *iface, REFIID rii static ULONG WINAPI OmNavigator_AddRef(IOmNavigator *iface) { OmNavigator *This = impl_from_IOmNavigator(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1175,13 +1195,10 @@ static ULONG WINAPI OmNavigator_AddRef(IOmNavigator *iface) static ULONG WINAPI OmNavigator_Release(IOmNavigator *iface) { OmNavigator *This = impl_from_IOmNavigator(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1532,6 +1549,12 @@ static inline OmNavigator *OmNavigator_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, OmNavigator, dispex); } +static void OmNavigator_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + OmNavigator *This = OmNavigator_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Navigator", cb); +} + static void OmNavigator_unlink(DispatchEx *dispex) { OmNavigator *This = OmNavigator_from_DispatchEx(dispex); @@ -1553,6 +1576,7 @@ static void OmNavigator_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t OmNavigator_dispex_vtbl = { OmNavigator_destructor, + OmNavigator_traverse, OmNavigator_unlink }; @@ -1576,7 +1600,7 @@ HRESULT create_navigator(compat_mode_t compat_mode, IOmNavigator **navigator) return E_OUTOFMEMORY; ret->IOmNavigator_iface.lpVtbl = &OmNavigatorVtbl; - ret->ref = 1; + ccref_init(&ret->ccref, 1); init_dispatch(&ret->dispex, (IUnknown*)&ret->IOmNavigator_iface, &OmNavigator_dispex, compat_mode); @@ -1588,7 +1612,7 @@ typedef struct { DispatchEx dispex; IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; } HTMLPerformanceTiming; @@ -1622,7 +1646,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_QueryInterface(IHTMLPerformanceTimin static ULONG WINAPI HTMLPerformanceTiming_AddRef(IHTMLPerformanceTiming *iface) { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1632,13 +1656,10 @@ static ULONG WINAPI HTMLPerformanceTiming_AddRef(IHTMLPerformanceTiming *iface) static ULONG WINAPI HTMLPerformanceTiming_Release(IHTMLPerformanceTiming *iface) { HTMLPerformanceTiming *This = impl_from_IHTMLPerformanceTiming(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1968,6 +1989,12 @@ static inline HTMLPerformanceTiming *HTMLPerformanceTiming_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLPerformanceTiming, dispex); } +static void HTMLPerformanceTiming_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PerformanceTiming", cb); +} + static void HTMLPerformanceTiming_unlink(DispatchEx *dispex) { HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); @@ -1981,12 +2008,12 @@ static void HTMLPerformanceTiming_unlink(DispatchEx *dispex) static void HTMLPerformanceTiming_destructor(DispatchEx *dispex) { HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); free(This); } static const dispex_static_data_vtbl_t HTMLPerformanceTiming_dispex_vtbl = { HTMLPerformanceTiming_destructor, + HTMLPerformanceTiming_traverse, HTMLPerformanceTiming_unlink }; @@ -2005,7 +2032,7 @@ typedef struct { DispatchEx dispex; IHTMLPerformanceNavigation IHTMLPerformanceNavigation_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; } HTMLPerformanceNavigation; @@ -2039,7 +2066,7 @@ static HRESULT WINAPI HTMLPerformanceNavigation_QueryInterface(IHTMLPerformanceN static ULONG WINAPI HTMLPerformanceNavigation_AddRef(IHTMLPerformanceNavigation *iface) { HTMLPerformanceNavigation *This = impl_from_IHTMLPerformanceNavigation(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -2049,13 +2076,10 @@ static ULONG WINAPI HTMLPerformanceNavigation_AddRef(IHTMLPerformanceNavigation static ULONG WINAPI HTMLPerformanceNavigation_Release(IHTMLPerformanceNavigation *iface) { HTMLPerformanceNavigation *This = impl_from_IHTMLPerformanceNavigation(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -2149,6 +2173,12 @@ static inline HTMLPerformanceNavigation *HTMLPerformanceNavigation_from_Dispatch return CONTAINING_RECORD(iface, HTMLPerformanceNavigation, dispex); } +static void HTMLPerformanceNavigation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PerformanceNavigation", cb); +} + static void HTMLPerformanceNavigation_unlink(DispatchEx *dispex) { HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); @@ -2167,6 +2197,7 @@ static void HTMLPerformanceNavigation_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLPerformanceNavigation_dispex_vtbl = { HTMLPerformanceNavigation_destructor, + HTMLPerformanceNavigation_traverse, HTMLPerformanceNavigation_unlink }; @@ -2185,7 +2216,7 @@ typedef struct { DispatchEx dispex; IHTMLPerformance IHTMLPerformance_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; IHTMLPerformanceNavigation *navigation; @@ -2222,7 +2253,7 @@ static HRESULT WINAPI HTMLPerformance_QueryInterface(IHTMLPerformance *iface, RE static ULONG WINAPI HTMLPerformance_AddRef(IHTMLPerformance *iface) { HTMLPerformance *This = impl_from_IHTMLPerformance(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -2232,13 +2263,10 @@ static ULONG WINAPI HTMLPerformance_AddRef(IHTMLPerformance *iface) static ULONG WINAPI HTMLPerformance_Release(IHTMLPerformance *iface) { HTMLPerformance *This = impl_from_IHTMLPerformance(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -2292,9 +2320,9 @@ static HRESULT WINAPI HTMLPerformance_get_navigation(IHTMLPerformance *iface, return E_OUTOFMEMORY; navigation->IHTMLPerformanceNavigation_iface.lpVtbl = &HTMLPerformanceNavigationVtbl; - navigation->ref = 1; navigation->window = This->window; IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface); + ccref_init(&navigation->ccref, 1); init_dispatch(&navigation->dispex, (IUnknown*)&navigation->IHTMLPerformanceNavigation_iface, &HTMLPerformanceNavigation_dispex, dispex_compat_mode(&This->dispex)); @@ -2320,9 +2348,9 @@ static HRESULT WINAPI HTMLPerformance_get_timing(IHTMLPerformance *iface, IHTMLP return E_OUTOFMEMORY; timing->IHTMLPerformanceTiming_iface.lpVtbl = &HTMLPerformanceTimingVtbl; - timing->ref = 1; timing->window = This->window; IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface); + ccref_init(&timing->ccref, 1); init_dispatch(&timing->dispex, (IUnknown*)&timing->IHTMLPerformanceTiming_iface, &HTMLPerformanceTiming_dispex, dispex_compat_mode(&This->dispex)); @@ -2369,6 +2397,12 @@ static inline HTMLPerformance *HTMLPerformance_from_DispatchEx(DispatchEx *iface return CONTAINING_RECORD(iface, HTMLPerformance, dispex); } +static void HTMLPerformance_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Performance", cb); +} + static void HTMLPerformance_unlink(DispatchEx *dispex) { HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); @@ -2389,6 +2423,7 @@ static void HTMLPerformance_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLPerformance_dispex_vtbl = { HTMLPerformance_destructor, + HTMLPerformance_traverse, HTMLPerformance_unlink }; @@ -2413,9 +2448,9 @@ HRESULT create_performance(HTMLInnerWindow *window, IHTMLPerformance **ret) return E_OUTOFMEMORY; performance->IHTMLPerformance_iface.lpVtbl = &HTMLPerformanceVtbl; - performance->ref = 1; performance->window = window; IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); + ccref_init(&performance->ccref, 1); init_dispatch(&performance->dispex, (IUnknown*)&performance->IHTMLPerformance_iface, &HTMLPerformance_dispex, compat_mode); @@ -2428,7 +2463,7 @@ typedef struct { DispatchEx dispex; IHTMLNamespaceCollection IHTMLNamespaceCollection_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; } HTMLNamespaceCollection; static inline HTMLNamespaceCollection *impl_from_IHTMLNamespaceCollection(IHTMLNamespaceCollection *iface) @@ -2461,7 +2496,7 @@ static HRESULT WINAPI HTMLNamespaceCollection_QueryInterface(IHTMLNamespaceColle static ULONG WINAPI HTMLNamespaceCollection_AddRef(IHTMLNamespaceCollection *iface) { HTMLNamespaceCollection *This = impl_from_IHTMLNamespaceCollection(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -2471,13 +2506,10 @@ static ULONG WINAPI HTMLNamespaceCollection_AddRef(IHTMLNamespaceCollection *ifa static ULONG WINAPI HTMLNamespaceCollection_Release(IHTMLNamespaceCollection *iface) { HTMLNamespaceCollection *This = impl_from_IHTMLNamespaceCollection(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -2557,6 +2589,12 @@ static inline HTMLNamespaceCollection *HTMLNamespaceCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLNamespaceCollection, dispex); } +static void HTMLNamespaceCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLNamespaceCollection *This = HTMLNamespaceCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "NamespaceCollection", cb); +} + static void HTMLNamespaceCollection_destructor(DispatchEx *dispex) { HTMLNamespaceCollection *This = HTMLNamespaceCollection_from_DispatchEx(dispex); @@ -2565,6 +2603,7 @@ static void HTMLNamespaceCollection_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLNamespaceCollection_dispex_vtbl = { HTMLNamespaceCollection_destructor, + HTMLNamespaceCollection_traverse }; static const tid_t HTMLNamespaceCollection_iface_tids[] = { @@ -2586,7 +2625,7 @@ HRESULT create_namespace_collection(compat_mode_t compat_mode, IHTMLNamespaceCol return E_OUTOFMEMORY; namespaces->IHTMLNamespaceCollection_iface.lpVtbl = &HTMLNamespaceCollectionVtbl; - namespaces->ref = 1; + ccref_init(&namespaces->ccref, 1); init_dispatch(&namespaces->dispex, (IUnknown*)&namespaces->IHTMLNamespaceCollection_iface, &HTMLNamespaceCollection_dispex, compat_mode); *ret = &namespaces->IHTMLNamespaceCollection_iface; @@ -2596,7 +2635,7 @@ HRESULT create_namespace_collection(compat_mode_t compat_mode, IHTMLNamespaceCol struct console { DispatchEx dispex; IWineMSHTMLConsole IWineMSHTMLConsole_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; }; static inline struct console *impl_from_IWineMSHTMLConsole(IWineMSHTMLConsole *iface) @@ -2629,7 +2668,7 @@ static HRESULT WINAPI console_QueryInterface(IWineMSHTMLConsole *iface, REFIID r static ULONG WINAPI console_AddRef(IWineMSHTMLConsole *iface) { struct console *console = impl_from_IWineMSHTMLConsole(iface); - LONG ref = InterlockedIncrement(&console->ref); + LONG ref = dispex_ccref_incr(&console->ccref, &console->dispex); TRACE("(%p) ref=%ld\n", console, ref); @@ -2639,13 +2678,10 @@ static ULONG WINAPI console_AddRef(IWineMSHTMLConsole *iface) static ULONG WINAPI console_Release(IWineMSHTMLConsole *iface) { struct console *console = impl_from_IWineMSHTMLConsole(iface); - LONG ref = InterlockedDecrement(&console->ref); + LONG ref = dispex_ccref_decr(&console->ccref, &console->dispex); TRACE("(%p) ref=%ld\n", console, ref); - if(!ref) - release_dispex(&console->dispex); - return ref; } @@ -2826,6 +2862,12 @@ static inline struct console *console_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, struct console, dispex); } +static void console_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct console *console = console_from_DispatchEx(dispex); + describe_cc_node(&console->ccref, "Console", cb); +} + static void console_destructor(DispatchEx *dispex) { struct console *console = console_from_DispatchEx(dispex); @@ -2834,6 +2876,7 @@ static void console_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t console_dispex_vtbl = { console_destructor, + console_traverse }; static const tid_t console_iface_tids[] = { @@ -2859,7 +2902,7 @@ void create_console(compat_mode_t compat_mode, IWineMSHTMLConsole **ret) } obj->IWineMSHTMLConsole_iface.lpVtbl = &WineMSHTMLConsoleVtbl; - obj->ref = 1; + ccref_init(&obj->ccref, 1); init_dispatch(&obj->dispex, (IUnknown*)&obj->IWineMSHTMLConsole_iface, &console_dispex, compat_mode); *ret = &obj->IWineMSHTMLConsole_iface; @@ -2874,7 +2917,7 @@ struct media_query_list_callback; struct media_query_list { DispatchEx dispex; IWineMSHTMLMediaQueryList IWineMSHTMLMediaQueryList_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMMediaQueryList *nsquerylist; struct media_query_list_callback *callback; struct list listeners; @@ -2913,7 +2956,7 @@ static HRESULT WINAPI media_query_list_QueryInterface(IWineMSHTMLMediaQueryList static ULONG WINAPI media_query_list_AddRef(IWineMSHTMLMediaQueryList *iface) { struct media_query_list *media_query_list = impl_from_IWineMSHTMLMediaQueryList(iface); - LONG ref = InterlockedIncrement(&media_query_list->ref); + LONG ref = dispex_ccref_incr(&media_query_list->ccref, &media_query_list->dispex); TRACE("(%p) ref=%ld\n", media_query_list, ref); @@ -2923,13 +2966,10 @@ static ULONG WINAPI media_query_list_AddRef(IWineMSHTMLMediaQueryList *iface) static ULONG WINAPI media_query_list_Release(IWineMSHTMLMediaQueryList *iface) { struct media_query_list *media_query_list = impl_from_IWineMSHTMLMediaQueryList(iface); - LONG ref = InterlockedDecrement(&media_query_list->ref); + LONG ref = dispex_ccref_decr(&media_query_list->ccref, &media_query_list->dispex); TRACE("(%p) ref=%ld\n", media_query_list, ref); - if(!ref) - release_dispex(&media_query_list->dispex); - return ref; } @@ -3154,6 +3194,12 @@ static inline struct media_query_list *media_query_list_from_DispatchEx(Dispatch return CONTAINING_RECORD(iface, struct media_query_list, dispex); } +static void media_query_list_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct media_query_list *media_query_list = media_query_list_from_DispatchEx(dispex); + describe_cc_node(&media_query_list->ccref, "MediaQueryList", cb); +} + static void media_query_list_unlink(DispatchEx *dispex) { struct media_query_list *media_query_list = media_query_list_from_DispatchEx(dispex); @@ -3177,6 +3223,7 @@ static void media_query_list_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t media_query_list_dispex_vtbl = { media_query_list_destructor, + media_query_list_traverse, media_query_list_unlink }; @@ -3228,8 +3275,8 @@ HRESULT create_media_query_list(HTMLWindow *window, BSTR media_query, IDispatch assert(NS_SUCCEEDED(nsres)); media_query_list->IWineMSHTMLMediaQueryList_iface.lpVtbl = &media_query_list_vtbl; - media_query_list->ref = 1; list_init(&media_query_list->listeners); + ccref_init(&media_query_list->ccref, 1); init_dispatch(&media_query_list->dispex, (IUnknown*)&media_query_list->IWineMSHTMLMediaQueryList_iface, &media_query_list_dispex, dispex_compat_mode(&window->inner_window->event_target.dispex)); diff --git a/dlls/mshtml/range.c b/dlls/mshtml/range.c index 562dbf35b49..3dc7e2a5d95 100644 --- a/dlls/mshtml/range.c +++ b/dlls/mshtml/range.c @@ -37,7 +37,7 @@ typedef struct { IHTMLTxtRange IHTMLTxtRange_iface; IOleCommandTarget IOleCommandTarget_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMRange *nsrange; HTMLDocumentNode *doc; @@ -49,7 +49,7 @@ typedef struct { DispatchEx dispex; IHTMLDOMRange IHTMLDOMRange_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsIDOMRange *nsrange; } HTMLDOMRange; @@ -841,7 +841,7 @@ static HRESULT WINAPI HTMLTxtRange_QueryInterface(IHTMLTxtRange *iface, REFIID r static ULONG WINAPI HTMLTxtRange_AddRef(IHTMLTxtRange *iface) { HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -851,13 +851,10 @@ static ULONG WINAPI HTMLTxtRange_AddRef(IHTMLTxtRange *iface) static ULONG WINAPI HTMLTxtRange_Release(IHTMLTxtRange *iface) { HTMLTxtRange *This = impl_from_IHTMLTxtRange(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1717,6 +1714,12 @@ static inline HTMLTxtRange *HTMLTxtRange_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLTxtRange, dispex); } +static void HTMLTxtRange_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "TextRange", cb); +} + static void HTMLTxtRange_unlink(DispatchEx *dispex) { HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); @@ -1735,6 +1738,7 @@ static void HTMLTxtRange_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLTxtRange_dispex_vtbl = { HTMLTxtRange_destructor, + HTMLTxtRange_traverse, HTMLTxtRange_unlink }; @@ -1762,7 +1766,7 @@ HRESULT HTMLTxtRange_Create(HTMLDocumentNode *doc, nsIDOMRange *nsrange, IHTMLTx ret->IHTMLTxtRange_iface.lpVtbl = &HTMLTxtRangeVtbl; ret->IOleCommandTarget_iface.lpVtbl = &OleCommandTargetVtbl; - ret->ref = 1; + ccref_init(&ret->ccref, 1); if(nsrange) nsIDOMRange_AddRef(nsrange); @@ -1805,7 +1809,7 @@ static HRESULT WINAPI HTMLDOMRange_QueryInterface(IHTMLDOMRange *iface, REFIID r static ULONG WINAPI HTMLDOMRange_AddRef(IHTMLDOMRange *iface) { HTMLDOMRange *This = impl_from_IHTMLDOMRange(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1815,13 +1819,10 @@ static ULONG WINAPI HTMLDOMRange_AddRef(IHTMLDOMRange *iface) static ULONG WINAPI HTMLDOMRange_Release(IHTMLDOMRange *iface) { HTMLDOMRange *This = impl_from_IHTMLDOMRange(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -2084,6 +2085,12 @@ static inline HTMLDOMRange *HTMLDOMRange_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMRange, dispex); } +static void HTMLDOMRange_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMRange", cb); +} + static void HTMLDOMRange_unlink(DispatchEx *dispex) { HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); @@ -2098,6 +2105,7 @@ static void HTMLDOMRange_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLDOMRange_dispex_vtbl = { HTMLDOMRange_destructor, + HTMLDOMRange_traverse, HTMLDOMRange_unlink }; @@ -2124,7 +2132,7 @@ HRESULT create_dom_range(nsIDOMRange *nsrange, compat_mode_t compat_mode, IHTMLD init_dispatch(&ret->dispex, (IUnknown*)&ret->IHTMLDOMRange_iface, &HTMLDOMRange_dispex, compat_mode); ret->IHTMLDOMRange_iface.lpVtbl = &HTMLDOMRangeVtbl; - ret->ref = 1; + ccref_init(&ret->ccref, 1); if(nsrange) nsIDOMRange_AddRef(nsrange); diff --git a/dlls/mshtml/selection.c b/dlls/mshtml/selection.c index cc9c0acece6..ac092124b70 100644 --- a/dlls/mshtml/selection.c +++ b/dlls/mshtml/selection.c @@ -36,7 +36,7 @@ typedef struct { IHTMLSelectionObject IHTMLSelectionObject_iface; IHTMLSelectionObject2 IHTMLSelectionObject2_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; nsISelection *nsselection; HTMLDocumentNode *doc; @@ -79,7 +79,7 @@ static HRESULT WINAPI HTMLSelectionObject_QueryInterface(IHTMLSelectionObject *i static ULONG WINAPI HTMLSelectionObject_AddRef(IHTMLSelectionObject *iface) { HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -89,13 +89,10 @@ static ULONG WINAPI HTMLSelectionObject_AddRef(IHTMLSelectionObject *iface) static ULONG WINAPI HTMLSelectionObject_Release(IHTMLSelectionObject *iface) { HTMLSelectionObject *This = impl_from_IHTMLSelectionObject(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -328,6 +325,12 @@ static inline HTMLSelectionObject *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLSelectionObject, dispex); } +static void HTMLSelectionObject_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLSelectionObject *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "SelectionObject", cb); +} + static void HTMLSelectionObject_unlink(DispatchEx *dispex) { HTMLSelectionObject *This = impl_from_DispatchEx(dispex); @@ -346,6 +349,7 @@ static void HTMLSelectionObject_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t HTMLSelectionObject_dispex_vtbl = { HTMLSelectionObject_destructor, + HTMLSelectionObject_traverse, HTMLSelectionObject_unlink }; @@ -374,8 +378,8 @@ HRESULT HTMLSelectionObject_Create(HTMLDocumentNode *doc, nsISelection *nsselect selection->IHTMLSelectionObject_iface.lpVtbl = &HTMLSelectionObjectVtbl; selection->IHTMLSelectionObject2_iface.lpVtbl = &HTMLSelectionObject2Vtbl; - selection->ref = 1; selection->nsselection = nsselection; /* We shouldn't call AddRef here */ + ccref_init(&selection->ccref, 1); selection->doc = doc; list_add_head(&doc->selection_list, &selection->entry); diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 75f52fb6c8e..2c971d54dc6 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -136,7 +136,7 @@ struct HTMLXMLHttpRequest { IHTMLXMLHttpRequest2 IHTMLXMLHttpRequest2_iface; IWineXMLHttpRequestPrivate IWineXMLHttpRequestPrivate_iface; IProvideClassInfo2 IProvideClassInfo2_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; LONG task_magic; LONG ready_state; response_type_t response_type; @@ -536,7 +536,7 @@ static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *ifa static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface) { HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->event_target.dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -546,12 +546,14 @@ static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface) static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface) { HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->event_target.dispex); TRACE("(%p) ref=%ld\n", This, ref); + /* The Cycle Collector might delay the unlink or destruction after ref reaches 0, + but we don't want a task to possibly grab ref to us and send events anymore. */ if(!ref) - release_dispex(&This->event_target.dispex); + This->magic++; return ref; } @@ -1521,6 +1523,12 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex); } +static void HTMLXMLHttpRequest_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "XMLHttpRequest", cb); +} + static void HTMLXMLHttpRequest_unlink(DispatchEx *dispex) { HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); @@ -1595,6 +1603,7 @@ static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = { { HTMLXMLHttpRequest_destructor, + HTMLXMLHttpRequest_traverse, HTMLXMLHttpRequest_unlink }, HTMLXMLHttpRequest_get_gecko_target, @@ -1647,7 +1656,7 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpReque static ULONG WINAPI HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory *iface) { HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = dispex_ccref_incr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); @@ -1657,13 +1666,10 @@ static ULONG WINAPI HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory static ULONG WINAPI HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory *iface) { HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = dispex_ccref_decr(&This->ccref, &This->dispex); TRACE("(%p) ref=%ld\n", This, ref); - if(!ref) - release_dispex(&This->dispex); - return ref; } @@ -1737,9 +1743,9 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor ret->IHTMLXMLHttpRequest2_iface.lpVtbl = &HTMLXMLHttpRequest2Vtbl; ret->IWineXMLHttpRequestPrivate_iface.lpVtbl = &WineXMLHttpRequestPrivateVtbl; ret->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl; + ccref_init(&ret->ccref, 1); EventTarget_Init(&ret->event_target, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface, &HTMLXMLHttpRequest_dispex, This->window->doc->document_mode); - ret->ref = 1; /* Always register the handlers because we need them to track state */ event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl; @@ -1785,6 +1791,12 @@ static inline HTMLXMLHttpRequestFactory *factory_from_DispatchEx(DispatchEx *ifa return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, dispex); } +static void HTMLXMLHttpRequestFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "XMLHttpRequestFactory", cb); +} + static void HTMLXMLHttpRequestFactory_destructor(DispatchEx *dispex) { HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); @@ -1816,6 +1828,7 @@ static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WOR static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = { HTMLXMLHttpRequestFactory_destructor, + HTMLXMLHttpRequestFactory_traverse, NULL, HTMLXMLHttpRequestFactory_value }; @@ -1840,7 +1853,7 @@ HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpReq return E_OUTOFMEMORY; ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl; - ret->ref = 1; + ccref_init(&ret->ccref, 1); ret->window = window; init_dispatch(&ret->dispex, (IUnknown*)&ret->IHTMLXMLHttpRequestFactory_iface, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3542