From: Gabriel Ivăncescu gabrielopcode@gmail.com
This implements support for the Cycle Collection via the dispex, using the CC ref count mechanism. After releasing its dynamic props, the dispex calls the destructor for the parent object, which is *required* in the dispex vtbl. This destructor should, at least, free the object itself (we can't free it from the dispex, because we don't know the dispex's offset in the object).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 72 ++++-- dlls/mshtml/htmlattr.c | 34 ++- dlls/mshtml/htmldoc.c | 12 +- dlls/mshtml/htmlelem.c | 144 +++++++----- dlls/mshtml/htmlelemcol.c | 33 +-- dlls/mshtml/htmlevent.c | 90 +++++--- dlls/mshtml/htmlevent.h | 2 +- dlls/mshtml/htmlimg.c | 18 +- dlls/mshtml/htmllocation.c | 30 ++- dlls/mshtml/htmlnode.c | 37 ++-- dlls/mshtml/htmlselect.c | 18 +- dlls/mshtml/htmlstorage.c | 28 +-- dlls/mshtml/htmlstyle.c | 22 +- dlls/mshtml/htmlstyle.h | 2 +- dlls/mshtml/htmlstylesheet.c | 116 ++++++---- dlls/mshtml/htmltextnode.c | 10 +- dlls/mshtml/htmlwindow.c | 132 +++++------ dlls/mshtml/mshtml_private.h | 36 ++- dlls/mshtml/nsembed.c | 1 + dlls/mshtml/omnavigator.c | 411 +++++++++++++++++++++++------------ dlls/mshtml/range.c | 72 +++--- dlls/mshtml/selection.c | 38 ++-- dlls/mshtml/xmlhttprequest.c | 56 +++-- 23 files changed, 875 insertions(+), 539 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index fecc7f6690c..d23c37650c1 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,16 +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) { - assert(!This->obj); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -846,6 +842,13 @@ static inline func_disp_t *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, func_disp_t, dispex); }
+static void function_destructor(DispatchEx *dispex) +{ + func_disp_t *This = impl_from_DispatchEx(dispex); + assert(!This->obj); + free(This); +} + static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { @@ -902,6 +905,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_value, NULL, NULL, @@ -926,8 +930,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;
@@ -1975,7 +1979,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; @@ -1991,12 +2001,13 @@ 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;
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) @@ -2014,14 +2025,17 @@ 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) +nsresult NSAPI dispex_unlink(void *p) { + DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop;
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++) { VariantClear(&prop->var); @@ -2042,19 +2056,17 @@ void dispex_unlink(DispatchEx *This) free(This->dynamic_data->func_disps); This->dynamic_data->func_disps = NULL; } -}
-const void *dispex_get_vtbl(DispatchEx *dispex) -{ - return dispex->info->desc->vtbl; + 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->dynamic_data) - return; + goto destructor;
for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) { VariantClear(&prop->var); @@ -2078,6 +2090,24 @@ void release_dispex(DispatchEx *This) }
free(This->dynamic_data); + +destructor: + 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 b7e40a23d55..000e178046e 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,18 +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) { - assert(!This->elem); - release_dispex(&This->dispex); - VariantClear(&This->value); - free(This->name); - free(This); - } - return ref; }
@@ -480,6 +472,24 @@ static const IHTMLDOMAttribute2Vtbl HTMLDOMAttribute2Vtbl = { HTMLDOMAttribute2_cloneNode };
+static inline HTMLDOMAttribute *impl_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLDOMAttribute, dispex); +} + +static void HTMLDOMAttribute_destructor(DispatchEx *dispex) +{ + HTMLDOMAttribute *This = impl_from_DispatchEx(dispex); + assert(!This->elem); + VariantClear(&This->value); + free(This->name); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLDOMAttribute_dispex_vtbl = { + HTMLDOMAttribute_destructor, +}; + static const tid_t HTMLDOMAttribute_iface_tids[] = { IHTMLDOMAttribute_tid, IHTMLDOMAttribute2_tid, @@ -487,7 +497,7 @@ static const tid_t HTMLDOMAttribute_iface_tids[] = { }; static dispex_static_data_t HTMLDOMAttribute_dispex = { L"Attr", - NULL, + &HTMLDOMAttribute_dispex_vtbl, DispHTMLDOMAttribute_tid, HTMLDOMAttribute_iface_tids }; @@ -509,9 +519,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 049b5c3559e..d40d3c4e799 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -295,6 +295,10 @@ static inline DocumentType *DocumentType_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, DocumentType, node.event_target.dispex); }
+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 +371,7 @@ static IHTMLEventObj *DocumentType_set_current_event(DispatchEx *dispex, IHTMLEv
static event_target_vtbl_t DocumentType_event_target_vtbl = { { - NULL, + DocumentType_dispex_destructor, }, DocumentType_get_gecko_target, NULL, @@ -5925,6 +5929,10 @@ static inline HTMLDocumentNode *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDocumentNode, node.event_target.dispex); }
+static void HTMLDocumentNode_dispex_destructor(DispatchEx *dispex) +{ +} + static HRESULT HTMLDocumentNode_get_name(DispatchEx *dispex, DISPID id, BSTR *name) { HTMLDocumentNode *This = impl_from_DispatchEx(dispex); @@ -6096,6 +6104,7 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI
static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { { + HTMLDocumentNode_dispex_destructor, NULL, NULL, HTMLDocumentNode_get_name, @@ -6203,7 +6212,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 53c418ab333..5545d8b91a5 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,17 +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) { - if(This->nsrect) - nsIDOMClientRect_Release(This->nsrect); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -841,19 +834,36 @@ static const IHTMLRect2Vtbl HTMLRect2Vtbl = { HTMLRect2_get_height, };
+static inline HTMLRect *HTMLRect_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLRect, dispex); +} + +static void HTMLRect_destructor(DispatchEx *dispex) +{ + HTMLRect *This = HTMLRect_from_DispatchEx(dispex); + if(This->nsrect) + nsIDOMClientRect_Release(This->nsrect); + free(This); +} + void HTMLRect_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { if (mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLRect2_tid, NULL); }
+static const dispex_static_data_vtbl_t HTMLRect_dispex_vtbl = { + HTMLRect_destructor, +}; + static const tid_t HTMLRect_iface_tids[] = { IHTMLRect_tid, 0 }; static dispex_static_data_t HTMLRect_dispex = { L"ClientRect", - NULL, + &HTMLRect_dispex_vtbl, IHTMLRect_tid, HTMLRect_iface_tids, HTMLRect_init_dispex_info @@ -869,7 +879,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);
@@ -884,7 +894,7 @@ typedef struct { DispatchEx dispex; IHTMLRectCollection IHTMLRectCollection_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
nsIDOMClientRectList *rect_list; } HTMLRectCollection; @@ -1052,7 +1062,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);
@@ -1062,17 +1072,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) { - if(This->rect_list) - nsIDOMClientRectList_Release(This->rect_list); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -1194,6 +1197,14 @@ static inline HTMLRectCollection *HTMLRectCollection_from_DispatchEx(DispatchEx return CONTAINING_RECORD(iface, HTMLRectCollection, dispex); }
+static void HTMLRectCollection_destructor(DispatchEx *dispex) +{ + HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); + if(This->rect_list) + nsIDOMClientRectList_Release(This->rect_list); + free(This); +} + static HRESULT HTMLRectCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) { HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); @@ -1269,6 +1280,7 @@ static HRESULT HTMLRectCollection_invoke(DispatchEx *dispex, DISPID id, LCID lci }
static const dispex_static_data_vtbl_t HTMLRectCollection_dispex_vtbl = { + HTMLRectCollection_destructor, NULL, HTMLRectCollection_get_dispid, HTMLRectCollection_get_name, @@ -3299,8 +3311,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));
@@ -6933,6 +6945,10 @@ static inline HTMLElement *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLElement, node.event_target.dispex); }
+static void HTMLElement_dispex_destructor(DispatchEx *dispex) +{ +} + static HRESULT HTMLElement_get_dispid(DispatchEx *dispex, BSTR name, DWORD grfdex, DISPID *pid) { @@ -7328,6 +7344,7 @@ static const tid_t HTMLElement_iface_tids[] = {
const event_target_vtbl_t HTMLElement_event_target_vtbl = { { + HTMLElement_dispex_destructor, NULL, HTMLElement_get_dispid, HTMLElement_get_name, @@ -7350,7 +7367,7 @@ struct token_list { IWineDOMTokenList IWineDOMTokenList_iface; IHTMLElement *element;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref; };
static inline struct token_list *impl_from_IWineDOMTokenList(IWineDOMTokenList *iface) @@ -7383,7 +7400,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);
@@ -7393,16 +7410,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) { - IHTMLElement_Release(token_list->element); - release_dispex(&token_list->dispex); - free(token_list); - } - return ref; }
@@ -7720,6 +7731,13 @@ static inline struct token_list *token_list_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, struct token_list, dispex); }
+static void token_list_destructor(DispatchEx *dispex) +{ + struct token_list *token_list = token_list_from_DispatchEx(dispex); + IHTMLElement_Release(token_list->element); + free(token_list); +} + static HRESULT token_list_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { @@ -7795,6 +7813,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_value, token_list_get_dispid, token_list_get_name, @@ -7824,7 +7843,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; @@ -8079,7 +8098,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);
@@ -8089,15 +8108,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) - { - free(This); - } - return ref; }
@@ -8172,6 +8186,17 @@ static const IHTMLFiltersCollectionVtbl HTMLFiltersCollectionVtbl = { HTMLFiltersCollection_item };
+static inline HTMLFiltersCollection *HTMLFiltersCollection_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLFiltersCollection, dispex); +} + +static void HTMLFiltersCollection_destructor(DispatchEx *dispex) +{ + HTMLFiltersCollection *This = HTMLFiltersCollection_from_DispatchEx(dispex); + free(This); +} + static HRESULT HTMLFiltersCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) { WCHAR *ptr; @@ -8211,6 +8236,7 @@ static HRESULT HTMLFiltersCollection_invoke(DispatchEx *dispex, DISPID id, LCID }
static const dispex_static_data_vtbl_t HTMLFiltersCollection_dispex_vtbl = { + HTMLFiltersCollection_destructor, NULL, HTMLFiltersCollection_get_dispid, HTMLFiltersCollection_get_name, @@ -8237,7 +8263,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)); @@ -8528,7 +8554,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);
@@ -8538,22 +8564,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) { - while(!list_empty(&This->attrs)) { - HTMLDOMAttribute *attr = LIST_ENTRY(list_head(&This->attrs), HTMLDOMAttribute, entry); - - list_remove(&attr->entry); - attr->elem = NULL; - IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface); - } - - free(This); - } - return ref; }
@@ -8901,6 +8915,21 @@ static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex); }
+static void HTMLAttributeCollection_destructor(DispatchEx *dispex) +{ + HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); + + while(!list_empty(&This->attrs)) { + HTMLDOMAttribute *attr = LIST_ENTRY(list_head(&This->attrs), HTMLDOMAttribute, entry); + + list_remove(&attr->entry); + attr->elem = NULL; + IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface); + } + + free(This); +} + static HRESULT HTMLAttributeCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) { HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); @@ -8967,6 +8996,7 @@ static HRESULT HTMLAttributeCollection_invoke(DispatchEx *dispex, DISPID id, LCI }
static const dispex_static_data_vtbl_t HTMLAttributeCollection_dispex_vtbl = { + HTMLAttributeCollection_destructor, NULL, HTMLAttributeCollection_get_dispid, HTMLAttributeCollection_get_name, @@ -9005,7 +9035,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 75ee079e3c7..ef610536536 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,21 +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) { - unsigned i; - - for(i=0; i < This->len; i++) - node_release(&This->elems[i]->node); - free(This->elems); - - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -550,6 +539,17 @@ static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); }
+static void HTMLElementCollection_destructor(DispatchEx *dispex) +{ + HTMLElementCollection *This = impl_from_DispatchEx(dispex); + unsigned i; + + for(i = 0; i < This->len; i++) + node_release(&This->elems[i]->node); + free(This->elems); + free(This); +} + #define DISPID_ELEMCOL_0 MSHTML_DISPID_CUSTOM_MIN
static HRESULT HTMLElementCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) @@ -622,6 +622,7 @@ static HRESULT HTMLElementCollection_invoke(DispatchEx *dispex, DISPID id, LCID }
static const dispex_static_data_vtbl_t HTMLElementColection_dispex_vtbl = { + HTMLElementCollection_destructor, NULL, HTMLElementCollection_get_dispid, HTMLElementCollection_get_name, @@ -853,7 +854,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 ccea4e16567..5d38188d289 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,17 +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) { - if(This->event) - IDOMEvent_Release(&This->event->IDOMEvent_iface); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -872,6 +865,23 @@ static inline HTMLEventObj *unsafe_impl_from_IHTMLEventObj(IHTMLEventObj *iface) return iface->lpVtbl == &HTMLEventObjVtbl ? impl_from_IHTMLEventObj(iface) : NULL; }
+static inline HTMLEventObj *HTMLEventObj_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLEventObj, dispex); +} + +static void HTMLEventObj_destructor(DispatchEx *dispex) +{ + HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); + if(This->event) + IDOMEvent_Release(&This->event->IDOMEvent_iface); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLEventObj_dispex_vtbl = { + HTMLEventObj_destructor, +}; + static const tid_t HTMLEventObj_iface_tids[] = { IHTMLEventObj_tid, 0 @@ -879,7 +889,7 @@ static const tid_t HTMLEventObj_iface_tids[] = {
static dispex_static_data_t HTMLEventObj_dispex = { L"MSEventObj", - NULL, + &HTMLEventObj_dispex_vtbl, DispCEventObj_tid, HTMLEventObj_iface_tids }; @@ -893,7 +903,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); @@ -951,7 +961,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);
@@ -961,21 +971,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) { - if(This->destroy) - This->destroy(This); - if(This->target) - IEventTarget_Release(&This->target->IEventTarget_iface); - nsIDOMEvent_Release(This->nsevent); - release_dispex(&This->dispex); - free(This->type); - free(This); - } - return ref; }
@@ -1234,6 +1233,23 @@ static const IDOMEventVtbl DOMEventVtbl = { DOMEvent_get_srcElement };
+static inline DOMEvent *DOMEvent_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, DOMEvent, dispex); +} + +static void DOMEvent_destructor(DispatchEx *dispex) +{ + DOMEvent *This = DOMEvent_from_DispatchEx(dispex); + if(This->destroy) + This->destroy(This); + if(This->target) + IEventTarget_Release(&This->target->IEventTarget_iface); + nsIDOMEvent_Release(This->nsevent); + free(This->type); + free(This); +} + static inline DOMUIEvent *impl_from_IDOMUIEvent(IDOMUIEvent *iface) { return CONTAINING_RECORD(iface, DOMUIEvent, IDOMUIEvent_iface); @@ -2908,6 +2924,10 @@ static void DOMStorageEvent_destroy(DOMEvent *event) SysFreeString(storage_event->url); }
+static const dispex_static_data_vtbl_t DOMEvent_dispex_vtbl = { + DOMEvent_destructor, +}; + static const tid_t DOMEvent_iface_tids[] = { IDOMEvent_tid, 0 @@ -2915,7 +2935,7 @@ static const tid_t DOMEvent_iface_tids[] = {
static dispex_static_data_t DOMEvent_dispex = { L"Event", - NULL, + &DOMEvent_dispex_vtbl, DispDOMEvent_tid, DOMEvent_iface_tids }; @@ -2928,7 +2948,7 @@ static const tid_t DOMUIEvent_iface_tids[] = {
static dispex_static_data_t DOMUIEvent_dispex = { L"UIEvent", - NULL, + &DOMEvent_dispex_vtbl, DispDOMUIEvent_tid, DOMUIEvent_iface_tids }; @@ -2942,7 +2962,7 @@ static const tid_t DOMMouseEvent_iface_tids[] = {
static dispex_static_data_t DOMMouseEvent_dispex = { L"MouseEvent", - NULL, + &DOMEvent_dispex_vtbl, DispDOMMouseEvent_tid, DOMMouseEvent_iface_tids }; @@ -2956,7 +2976,7 @@ static const tid_t DOMKeyboardEvent_iface_tids[] = {
static dispex_static_data_t DOMKeyboardEvent_dispex = { L"KeyboardEvent", - NULL, + &DOMEvent_dispex_vtbl, DispDOMKeyboardEvent_tid, DOMKeyboardEvent_iface_tids }; @@ -2969,7 +2989,7 @@ static void DOMPageTransitionEvent_init_dispex_info(dispex_data_t *info, compat_
dispex_static_data_t DOMPageTransitionEvent_dispex = { L"PageTransitionEvent", - NULL, + &DOMEvent_dispex_vtbl, DispDOMEvent_tid, DOMEvent_iface_tids, DOMPageTransitionEvent_init_dispex_info @@ -2983,7 +3003,7 @@ static const tid_t DOMCustomEvent_iface_tids[] = {
static dispex_static_data_t DOMCustomEvent_dispex = { L"CustomEvent", - NULL, + &DOMEvent_dispex_vtbl, DispDOMCustomEvent_tid, DOMCustomEvent_iface_tids }; @@ -2995,7 +3015,7 @@ static const tid_t DOMMessageEvent_iface_tids[] = {
dispex_static_data_t DOMMessageEvent_dispex = { L"MessageEvent", - NULL, + &DOMEvent_dispex_vtbl, DispDOMMessageEvent_tid, DOMMessageEvent_iface_tids, DOMMessageEvent_init_dispex_info @@ -3009,7 +3029,7 @@ static const tid_t DOMProgressEvent_iface_tids[] = {
dispex_static_data_t DOMProgressEvent_dispex = { L"ProgressEvent", - NULL, + &DOMEvent_dispex_vtbl, DispDOMProgressEvent_tid, DOMProgressEvent_iface_tids }; @@ -3022,7 +3042,7 @@ static const tid_t DOMStorageEvent_iface_tids[] = {
dispex_static_data_t DOMStorageEvent_dispex = { L"StorageEvent", - NULL, + &DOMEvent_dispex_vtbl, DispDOMStorageEvent_tid, DOMStorageEvent_iface_tids }; @@ -3037,7 +3057,6 @@ static void *event_ctor(unsigned size, dispex_static_data_t *dispex_data, void * event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; event->query_interface = query_interface; event->destroy = destroy; - event->ref = 1; event->event_id = event_id; if(event_id != EVENTID_LAST) { event->type = wcsdup(event_info[event_id].name); @@ -3048,6 +3067,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(); diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 5e2c7a0a054..8b8c06999a1 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); void (*destroy)(struct DOMEvent*);
diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index 47fc2be8d5d..00859733286 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -800,7 +800,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);
@@ -810,15 +810,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); - free(This); - } - return ref; }
@@ -947,6 +942,12 @@ static inline HTMLImageElementFactory *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLImageElementFactory, dispex); }
+static void HTMLImageElementFactory_destructor(DispatchEx *dispex) +{ + HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); + free(This); +} + static HRESULT HTMLImageElementFactory_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) @@ -981,6 +982,7 @@ static const tid_t HTMLImageElementFactory_iface_tids[] = { };
static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = { + HTMLImageElementFactory_destructor, HTMLImageElementFactory_value, NULL, NULL, @@ -1003,7 +1005,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 c361df7d85e..9149251f62d 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,16 +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) { - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -616,13 +610,29 @@ static const IHTMLLocationVtbl HTMLLocationVtbl = { HTMLLocation_toString };
+static inline HTMLLocation *impl_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLLocation, dispex); +} + +static void HTMLLocation_destructor(DispatchEx *dispex) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLLocation_dispex_vtbl = { + HTMLLocation_destructor, +}; + static const tid_t HTMLLocation_iface_tids[] = { IHTMLLocation_tid, 0 }; static dispex_static_data_t HTMLLocation_dispex = { L"Location", - NULL, + &HTMLLocation_dispex_vtbl, DispHTMLLocation_tid, HTMLLocation_iface_tids }; @@ -635,7 +645,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 b29383ad9ff..354a4719601 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,15 +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) { - nsIDOMNodeList_Release(This->nslist); - free(This); - } - return ref; }
@@ -364,6 +359,13 @@ static inline HTMLDOMChildrenCollection *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, dispex); }
+static void HTMLDOMChildrenCollection_destructor(DispatchEx *dispex) +{ + HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); + nsIDOMNodeList_Release(This->nslist); + free(This); +} + #define DISPID_CHILDCOL_0 MSHTML_DISPID_CUSTOM_MIN
static HRESULT HTMLDOMChildrenCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) @@ -433,6 +435,7 @@ static HRESULT HTMLDOMChildrenCollection_invoke(DispatchEx *dispex, DISPID id, L }
static const dispex_static_data_vtbl_t HTMLDOMChildrenCollection_dispex_vtbl = { + HTMLDOMChildrenCollection_destructor, NULL, HTMLDOMChildrenCollection_get_dispid, HTMLDOMChildrenCollection_get_name, @@ -461,7 +464,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; @@ -1413,6 +1416,10 @@ static const IHTMLDOMNode3Vtbl HTMLDOMNode3Vtbl = { HTMLDOMNode3_isSupported };
+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); @@ -1495,13 +1502,17 @@ 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, +}; + 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 @@ -1579,7 +1590,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); @@ -1596,7 +1607,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);
if(This->nsnode) { nsIDOMNode *nsnode = This->nsnode; @@ -1624,7 +1635,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 dd1c784c28d..4fc46f5d09b 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -479,7 +479,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);
@@ -489,15 +489,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); - free(This); - } - return ref; }
@@ -597,6 +592,12 @@ static inline HTMLOptionElementFactory *HTMLOptionElementFactory_from_DispatchEx return CONTAINING_RECORD(iface, HTMLOptionElementFactory, dispex); }
+static void HTMLOptionElementFactory_destructor(DispatchEx *dispex) +{ + HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); + free(This); +} + static HRESULT HTMLOptionElementFactory_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) @@ -635,6 +636,7 @@ static const tid_t HTMLOptionElementFactory_iface_tids[] = { };
static const dispex_static_data_vtbl_t HTMLOptionElementFactory_dispex_vtbl = { + HTMLOptionElementFactory_destructor, HTMLOptionElementFactory_value, NULL, NULL, @@ -657,7 +659,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 24eec4ba078..5d7f2603ac8 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,19 +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_session_map_entry(This->session_storage); - release_dispex(&This->dispex); - free(This->filename); - CloseHandle(This->mutex); - release_props(This); - free(This); - } - return ref; }
@@ -1063,6 +1054,16 @@ static inline HTMLStorage *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLStorage, dispex); }
+static void HTMLStorage_destructor(DispatchEx *dispex) +{ + HTMLStorage *This = impl_from_DispatchEx(dispex); + release_session_map_entry(This->session_storage); + free(This->filename); + CloseHandle(This->mutex); + release_props(This); + free(This); +} + static HRESULT check_item(HTMLStorage *This, const WCHAR *key) { struct session_entry *session_entry; @@ -1308,6 +1309,7 @@ static HRESULT HTMLStorage_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pi }
static const dispex_static_data_vtbl_t HTMLStorage_dispex_vtbl = { + HTMLStorage_destructor, NULL, HTMLStorage_get_dispid, HTMLStorage_get_name, @@ -1475,7 +1477,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 c8dc69bb2af..f653f3c38b2 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,17 +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) { - if(This->nsstyle) - nsIDOMCSSStyleDeclaration_Release(This->nsstyle); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -9969,6 +9962,14 @@ static inline CSSStyle *impl_from_DispatchEx(DispatchEx *dispex) return CONTAINING_RECORD(dispex, CSSStyle, dispex); }
+static void CSSStyle_destructor(DispatchEx *dispex) +{ + CSSStyle *This = impl_from_DispatchEx(dispex); + if(This->nsstyle) + nsIDOMCSSStyleDeclaration_Release(This->nsstyle); + free(This); +} + static HRESULT CSSStyle_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) { CSSStyle *This = impl_from_DispatchEx(dispex); @@ -9997,6 +9998,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, NULL, CSSStyle_get_dispid, NULL, @@ -10063,10 +10065,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 59680d720e2..e78ebe6592d 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,17 +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); - if(This->nsstylesheetrule) - nsIDOMCSSRule_Release(This->nsstylesheetrule); - free(This); - } - return ref; }
@@ -206,13 +199,30 @@ static const IHTMLStyleSheetRuleVtbl HTMLStyleSheetRuleVtbl = { HTMLStyleSheetRule_get_readOnly };
+static inline HTMLStyleSheetRule *HTMLStyleSheetRule_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLStyleSheetRule, dispex); +} + +static void HTMLStyleSheetRule_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); + if(This->nsstylesheetrule) + nsIDOMCSSRule_Release(This->nsstylesheetrule); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLStyleSheetRule_dispex_vtbl = { + HTMLStyleSheetRule_destructor, +}; + static const tid_t HTMLStyleSheetRule_iface_tids[] = { IHTMLStyleSheetRule_tid, 0 }; static dispex_static_data_t HTMLStyleSheetRule_dispex = { L"CSSStyleRule", - NULL, + &HTMLStyleSheetRule_dispex_vtbl, DispHTMLStyleSheetRule_tid, HTMLStyleSheetRule_iface_tids }; @@ -227,8 +237,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); @@ -276,7 +286,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);
@@ -286,17 +296,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); - if(This->nslist) - nsIDOMCSSRuleList_Release(This->nslist); - free(This); - } - return ref; }
@@ -389,6 +392,14 @@ static inline HTMLStyleSheetRulesCollection *HTMLStyleSheetRulesCollection_from_ return CONTAINING_RECORD(iface, HTMLStyleSheetRulesCollection, dispex); }
+static void HTMLStyleSheetRulesCollection_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); + if(This->nslist) + nsIDOMCSSRuleList_Release(This->nslist); + free(This); +} + static HRESULT HTMLStyleSheetRulesCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) { HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); @@ -466,6 +477,7 @@ static HRESULT HTMLStyleSheetRulesCollection_invoke(DispatchEx *dispex, DISPID i }
static const dispex_static_data_vtbl_t HTMLStyleSheetRulesCollection_dispex_vtbl = { + HTMLStyleSheetRulesCollection_destructor, NULL, HTMLStyleSheetRulesCollection_get_dispid, HTMLStyleSheetRulesCollection_get_name, @@ -491,8 +503,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); @@ -661,7 +673,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);
@@ -671,17 +683,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); - if(This->nslist) - nsIDOMStyleSheetList_Release(This->nslist); - free(This); - } - return ref; }
@@ -816,6 +821,14 @@ static inline HTMLStyleSheetsCollection *HTMLStyleSheetsCollection_from_Dispatch return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, dispex); }
+static void HTMLStyleSheetsCollection_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); + if(This->nslist) + nsIDOMStyleSheetList_Release(This->nslist); + free(This); +} + static HRESULT HTMLStyleSheetsCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) { HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); @@ -893,6 +906,7 @@ static HRESULT HTMLStyleSheetsCollection_invoke(DispatchEx *dispex, DISPID id, L }
static const dispex_static_data_vtbl_t HTMLStyleSheetsCollection_dispex_vtbl = { + HTMLStyleSheetsCollection_destructor, NULL, HTMLStyleSheetsCollection_get_dispid, HTMLStyleSheetsCollection_get_name, @@ -918,7 +932,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); @@ -965,7 +979,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);
@@ -975,17 +989,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); - if(This->nsstylesheet) - nsIDOMCSSStyleSheet_Release(This->nsstylesheet); - free(This); - } - return ref; }
@@ -1462,19 +1469,36 @@ static const IHTMLStyleSheet4Vtbl HTMLStyleSheet4Vtbl = { HTMLStyleSheet4_deleteRule, };
+static inline HTMLStyleSheet *HTMLStyleSheet_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLStyleSheet, dispex); +} + +static void HTMLStyleSheet_destructor(DispatchEx *dispex) +{ + HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); + if(This->nsstylesheet) + nsIDOMCSSStyleSheet_Release(This->nsstylesheet); + free(This); +} + static void HTMLStyleSheet_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { if(mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLStyleSheet4_tid, NULL); }
+static const dispex_static_data_vtbl_t HTMLStyleSheet_dispex_vtbl = { + HTMLStyleSheet_destructor, +}; + static const tid_t HTMLStyleSheet_iface_tids[] = { IHTMLStyleSheet_tid, 0 }; static dispex_static_data_t HTMLStyleSheet_dispex = { L"CSSStyleSheet", - NULL, + &HTMLStyleSheet_dispex_vtbl, DispHTMLStyleSheet_tid, HTMLStyleSheet_iface_tids, HTMLStyleSheet_init_dispex_info @@ -1490,8 +1514,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..76515aa6d95 100644 --- a/dlls/mshtml/htmltextnode.c +++ b/dlls/mshtml/htmltextnode.c @@ -319,6 +319,10 @@ static const IHTMLDOMTextNode2Vtbl HTMLDOMTextNode2Vtbl = { HTMLDOMTextNode2_replaceData };
+static void HTMLDOMTextNode_destructor(DispatchEx *dispex) +{ +} + static inline HTMLDOMTextNode *impl_from_HTMLDOMNode(HTMLDOMNode *iface) { return CONTAINING_RECORD(iface, HTMLDOMTextNode, node); @@ -358,6 +362,10 @@ static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = { HTMLDOMTextNode_clone };
+static const dispex_static_data_vtbl_t HTMLDOMTextNode_dispex_vtbl = { + HTMLDOMTextNode_destructor, +}; + static const tid_t HTMLDOMTextNode_iface_tids[] = { IHTMLDOMNode_tid, IHTMLDOMNode2_tid, @@ -367,7 +375,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 55a2488155e..6a0607700bf 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_unlink(&outer_window->location->dispex.IDispatchEx_iface);
abort_window_bindings(window); remove_target_tasks(window->task_magic); @@ -224,68 +224,6 @@ static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface) return ref; }
-static void release_inner_window(HTMLInnerWindow *This) -{ - unsigned i; - - TRACE("%p\n", This); - - detach_inner_window(This); - - if(This->doc) { - This->doc->window = NULL; - IHTMLDOMNode_Release(&This->doc->node.IHTMLDOMNode_iface); - } - - release_event_target(&This->event_target); - release_dispex(&This->event_target.dispex); - - for(i=0; i < This->global_prop_cnt; i++) - free(This->global_props[i].name); - free(This->global_props); - - if(This->image_factory) { - This->image_factory->window = NULL; - IHTMLImageElementFactory_Release(&This->image_factory->IHTMLImageElementFactory_iface); - } - - if(This->option_factory) { - This->option_factory->window = NULL; - IHTMLOptionElementFactory_Release(&This->option_factory->IHTMLOptionElementFactory_iface); - } - - if(This->xhr_factory) { - This->xhr_factory->window = NULL; - IHTMLXMLHttpRequestFactory_Release(&This->xhr_factory->IHTMLXMLHttpRequestFactory_iface); - } - - if(This->screen) - IHTMLScreen_Release(This->screen); - - if(This->history) { - This->history->window = NULL; - IOmHistory_Release(&This->history->IOmHistory_iface); - } - - if(This->navigator) - IOmNavigator_Release(This->navigator); - if(This->session_storage) { - detach_html_storage(This->session_storage); - IHTMLStorage_Release(This->session_storage); - } - if(This->local_storage) { - detach_html_storage(This->local_storage); - IHTMLStorage_Release(This->local_storage); - } - - VariantClear(&This->performance); - - if(This->mon) - IMoniker_Release(This->mon); - - free(This); -} - static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface) { HTMLWindow *This = impl_from_IHTMLWindow2(iface); @@ -3729,6 +3667,71 @@ static inline HTMLInnerWindow *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLInnerWindow, event_target.dispex); }
+static void HTMLWindow_destructor(DispatchEx *dispex) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + unsigned i; + + TRACE("%p\n", This); + + if(This->base.console) + IWineMSHTMLConsole_Release(This->base.console); + + detach_inner_window(This); + + if(This->doc) { + This->doc->window = NULL; + IHTMLDOMNode_Release(&This->doc->node.IHTMLDOMNode_iface); + } + + release_event_target(&This->event_target); + + for(i=0; i < This->global_prop_cnt; i++) + free(This->global_props[i].name); + free(This->global_props); + + if(This->image_factory) { + This->image_factory->window = NULL; + IHTMLImageElementFactory_Release(&This->image_factory->IHTMLImageElementFactory_iface); + } + + if(This->option_factory) { + This->option_factory->window = NULL; + IHTMLOptionElementFactory_Release(&This->option_factory->IHTMLOptionElementFactory_iface); + } + + if(This->xhr_factory) { + This->xhr_factory->window = NULL; + IHTMLXMLHttpRequestFactory_Release(&This->xhr_factory->IHTMLXMLHttpRequestFactory_iface); + } + + if(This->screen) + IHTMLScreen_Release(This->screen); + + if(This->history) { + This->history->window = NULL; + IOmHistory_Release(&This->history->IOmHistory_iface); + } + + if(This->navigator) + IOmNavigator_Release(This->navigator); + if(This->session_storage) { + detach_html_storage(This->session_storage); + IHTMLStorage_Release(This->session_storage); + } + if(This->local_storage) { + detach_html_storage(This->local_storage); + IHTMLStorage_Release(This->local_storage); + } + + VariantClear(&This->performance); + + if(This->mon) + IMoniker_Release(This->mon); + + free(This); +} + static HRESULT HTMLWindow_get_name(DispatchEx *dispex, DISPID id, BSTR *name) { HTMLInnerWindow *This = impl_from_DispatchEx(dispex); @@ -3967,6 +3970,7 @@ static IHTMLEventObj *HTMLWindow_set_current_event(DispatchEx *dispex, IHTMLEven
static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { { + HTMLWindow_destructor, NULL, NULL, HTMLWindow_get_name, @@ -4089,7 +4093,7 @@ static void NSAPI window_delete_cycle_collectable(void *p) window_unlink(p);
if(!is_outer_window(This)) { - release_inner_window(This->inner_window); + 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 3a05528d97c..119568386fd 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -338,6 +338,7 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t; typedef struct DispatchEx DispatchEx;
typedef struct { + void (*destructor)(DispatchEx*); HRESULT (*value)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*); HRESULT (*get_dispid)(DispatchEx*,BSTR,DWORD,DISPID*); HRESULT (*get_name)(DispatchEx*,DISPID,BSTR*); @@ -403,16 +404,28 @@ 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**); +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*); @@ -465,7 +478,7 @@ typedef struct { DispatchEx dispex; IHTMLOptionElementFactory IHTMLOptionElementFactory_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
HTMLInnerWindow *window; } HTMLOptionElementFactory; @@ -474,7 +487,7 @@ typedef struct { DispatchEx dispex; IHTMLImageElementFactory IHTMLImageElementFactory_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
HTMLInnerWindow *window; } HTMLImageElementFactory; @@ -483,7 +496,7 @@ typedef struct { DispatchEx dispex; IHTMLXMLHttpRequestFactory IHTMLXMLHttpRequestFactory_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
HTMLInnerWindow *window; } HTMLXMLHttpRequestFactory; @@ -492,7 +505,7 @@ struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
HTMLOuterWindow *window; }; @@ -501,7 +514,7 @@ typedef struct { DispatchEx dispex; IOmHistory IOmHistory_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
HTMLInnerWindow *window; } OmHistory; @@ -932,8 +945,6 @@ struct HTMLDocumentNode {
nsIDocumentObserver nsIDocumentObserver_iface;
- LONG ref; - ConnectionPointContainer cp_container; HTMLOuterWindow *outer_window; HTMLInnerWindow *window; @@ -1047,6 +1058,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);
@@ -1133,7 +1145,7 @@ struct HTMLAttributeCollection { IHTMLAttributeCollection2 IHTMLAttributeCollection2_iface; IHTMLAttributeCollection3 IHTMLAttributeCollection3_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
HTMLElement *elem; struct list attrs; @@ -1144,7 +1156,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/nsembed.c b/dlls/mshtml/nsembed.c index 3e300d4e3e8..ad39c827f51 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 7615b114d3e..9b0cf027dd5 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,18 +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) { - assert(!This->browser); - if(This->implementation) - nsIDOMDOMImplementation_Release(This->implementation); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -294,6 +286,24 @@ static const IHTMLDOMImplementation2Vtbl HTMLDOMImplementation2Vtbl = { HTMLDOMImplementation2_hasFeature };
+static inline HTMLDOMImplementation *HTMLDOMImplementation_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLDOMImplementation, dispex); +} + +static void HTMLDOMImplementation_destructor(DispatchEx *dispex) +{ + HTMLDOMImplementation *This = HTMLDOMImplementation_from_DispatchEx(dispex); + assert(!This->browser); + if(This->implementation) + nsIDOMDOMImplementation_Release(This->implementation); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLDOMImplementation_dispex_vtbl = { + HTMLDOMImplementation_destructor, +}; + static void HTMLDOMImplementation_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) { if(compat_mode >= COMPAT_MODE_IE9) @@ -306,7 +316,7 @@ static const tid_t HTMLDOMImplementation_iface_tids[] = { }; static dispex_static_data_t HTMLDOMImplementation_dispex = { L"DOMImplementation", - NULL, + &HTMLDOMImplementation_dispex_vtbl, DispHTMLDOMImplementation_tid, HTMLDOMImplementation_iface_tids, HTMLDOMImplementation_init_dispex_info @@ -326,8 +336,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); @@ -353,7 +363,7 @@ typedef struct { DispatchEx dispex; IHTMLScreen IHTMLScreen_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref; } HTMLScreen;
static inline HTMLScreen *impl_from_IHTMLScreen(IHTMLScreen *iface) @@ -386,7 +396,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);
@@ -396,15 +406,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); - free(This); - } - return ref; }
@@ -553,13 +558,28 @@ static const IHTMLScreenVtbl HTMLSreenVtbl = { HTMLScreen_get_fontSmoothingEnabled };
+static inline HTMLScreen *HTMLScreen_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLScreen, dispex); +} + +static void HTMLScreen_destructor(DispatchEx *dispex) +{ + HTMLScreen *This = HTMLScreen_from_DispatchEx(dispex); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLScreen_dispex_vtbl = { + HTMLScreen_destructor, +}; + static const tid_t HTMLScreen_iface_tids[] = { IHTMLScreen_tid, 0 }; static dispex_static_data_t HTMLScreen_dispex = { L"Screen", - NULL, + &HTMLScreen_dispex_vtbl, DispHTMLScreen_tid, HTMLScreen_iface_tids }; @@ -573,7 +593,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);
@@ -611,7 +631,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);
@@ -621,15 +641,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); - free(This); - } - return ref; }
@@ -717,13 +732,28 @@ static const IOmHistoryVtbl OmHistoryVtbl = { OmHistory_go };
+static inline OmHistory *OmHistory_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, OmHistory, dispex); +} + +static void OmHistory_destructor(DispatchEx *dispex) +{ + OmHistory *This = OmHistory_from_DispatchEx(dispex); + free(This); +} + +static const dispex_static_data_vtbl_t OmHistory_dispex_vtbl = { + OmHistory_destructor, +}; + static const tid_t OmHistory_iface_tids[] = { IOmHistory_tid, 0 }; static dispex_static_data_t OmHistory_dispex = { L"History", - NULL, + &OmHistory_dispex_vtbl, DispHTMLHistory_tid, OmHistory_iface_tids }; @@ -740,7 +770,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;
@@ -752,7 +782,7 @@ struct HTMLPluginsCollection { DispatchEx dispex; IHTMLPluginsCollection IHTMLPluginsCollection_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
OmNavigator *navigator; }; @@ -787,7 +817,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);
@@ -797,17 +827,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) { - if(This->navigator) - This->navigator->plugins = NULL; - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -874,13 +897,30 @@ static const IHTMLPluginsCollectionVtbl HTMLPluginsCollectionVtbl = { HTMLPluginsCollection_refresh };
+static inline HTMLPluginsCollection *HTMLPluginsCollection_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLPluginsCollection, dispex); +} + +static void HTMLPluginsCollection_destructor(DispatchEx *dispex) +{ + HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); + if(This->navigator) + This->navigator->plugins = NULL; + free(This); +} + +static const dispex_static_data_vtbl_t HTMLPluginsCollection_dispex_vtbl = { + HTMLPluginsCollection_destructor, +}; + static const tid_t HTMLPluginsCollection_iface_tids[] = { IHTMLPluginsCollection_tid, 0 }; static dispex_static_data_t HTMLPluginsCollection_dispex = { L"PluginArray", - NULL, + &HTMLPluginsCollection_dispex_vtbl, DispCPlugins_tid, HTMLPluginsCollection_iface_tids }; @@ -894,8 +934,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)); @@ -908,7 +948,7 @@ struct HTMLMimeTypesCollection { DispatchEx dispex; IHTMLMimeTypesCollection IHTMLMimeTypesCollection_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
OmNavigator *navigator; }; @@ -943,7 +983,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);
@@ -953,17 +993,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) { - if(This->navigator) - This->navigator->mime_types = NULL; - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -1019,13 +1052,30 @@ static const IHTMLMimeTypesCollectionVtbl HTMLMimeTypesCollectionVtbl = { HTMLMimeTypesCollection_get_length };
+static inline HTMLMimeTypesCollection *HTMLMimeTypesCollection_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLMimeTypesCollection, dispex); +} + +static void HTMLMimeTypesCollection_destructor(DispatchEx *dispex) +{ + HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); + if(This->navigator) + This->navigator->mime_types = NULL; + free(This); +} + +static const dispex_static_data_vtbl_t HTMLMimeTypesCollection_dispex_vtbl = { + HTMLMimeTypesCollection_destructor, +}; + static const tid_t HTMLMimeTypesCollection_iface_tids[] = { IHTMLMimeTypesCollection_tid, 0 }; static dispex_static_data_t HTMLMimeTypesCollection_dispex = { L"MimeTypeArray", - NULL, + &HTMLMimeTypesCollection_dispex_vtbl, IHTMLMimeTypesCollection_tid, HTMLMimeTypesCollection_iface_tids }; @@ -1039,8 +1089,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)); @@ -1079,7 +1129,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);
@@ -1089,19 +1139,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) { - if(This->plugins) - This->plugins->navigator = NULL; - if(This->mime_types) - This->mime_types->navigator = NULL; - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -1447,13 +1488,32 @@ static const IOmNavigatorVtbl OmNavigatorVtbl = { OmNavigator_get_userProfile };
+static inline OmNavigator *OmNavigator_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, OmNavigator, dispex); +} + +static void OmNavigator_destructor(DispatchEx *dispex) +{ + OmNavigator *This = OmNavigator_from_DispatchEx(dispex); + if(This->plugins) + This->plugins->navigator = NULL; + if(This->mime_types) + This->mime_types->navigator = NULL; + free(This); +} + +static const dispex_static_data_vtbl_t OmNavigator_dispex_vtbl = { + OmNavigator_destructor, +}; + static const tid_t OmNavigator_iface_tids[] = { IOmNavigator_tid, 0 }; static dispex_static_data_t OmNavigator_dispex = { L"Navigator", - NULL, + &OmNavigator_dispex_vtbl, DispHTMLNavigator_tid, OmNavigator_iface_tids }; @@ -1467,7 +1527,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);
@@ -1479,7 +1539,7 @@ typedef struct { DispatchEx dispex; IHTMLPerformanceTiming IHTMLPerformanceTiming_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; } HTMLPerformanceTiming;
@@ -1513,7 +1573,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);
@@ -1523,16 +1583,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) { - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -1857,13 +1911,29 @@ static const IHTMLPerformanceTimingVtbl HTMLPerformanceTimingVtbl = { HTMLPerformanceTiming_toJSON };
+static inline HTMLPerformanceTiming *HTMLPerformanceTiming_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLPerformanceTiming, 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, +}; + static const tid_t HTMLPerformanceTiming_iface_tids[] = { IHTMLPerformanceTiming_tid, 0 }; static dispex_static_data_t HTMLPerformanceTiming_dispex = { L"PerformanceTiming", - NULL, + &HTMLPerformanceTiming_dispex_vtbl, IHTMLPerformanceTiming_tid, HTMLPerformanceTiming_iface_tids }; @@ -1872,7 +1942,7 @@ typedef struct { DispatchEx dispex; IHTMLPerformanceNavigation IHTMLPerformanceNavigation_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref; HTMLInnerWindow *window; } HTMLPerformanceNavigation;
@@ -1906,7 +1976,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);
@@ -1916,16 +1986,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) { - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -2014,13 +2078,29 @@ static const IHTMLPerformanceNavigationVtbl HTMLPerformanceNavigationVtbl = { HTMLPerformanceNavigation_toJSON };
+static inline HTMLPerformanceNavigation *HTMLPerformanceNavigation_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLPerformanceNavigation, dispex); +} + +static void HTMLPerformanceNavigation_destructor(DispatchEx *dispex) +{ + HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLPerformanceNavigation_dispex_vtbl = { + HTMLPerformanceNavigation_destructor, +}; + static const tid_t HTMLPerformanceNavigation_iface_tids[] = { IHTMLPerformanceNavigation_tid, 0 }; static dispex_static_data_t HTMLPerformanceNavigation_dispex = { L"PerformanceNavigation", - NULL, + &HTMLPerformanceNavigation_dispex_vtbl, IHTMLPerformanceNavigation_tid, HTMLPerformanceNavigation_iface_tids }; @@ -2029,7 +2109,7 @@ typedef struct { DispatchEx dispex; IHTMLPerformance IHTMLPerformance_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
HTMLInnerWindow *window; IHTMLPerformanceNavigation *navigation; @@ -2066,7 +2146,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);
@@ -2076,20 +2156,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) { - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); - if(This->navigation) - IHTMLPerformanceNavigation_Release(This->navigation); - if(This->timing) - IHTMLPerformanceTiming_Release(This->timing); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -2143,9 +2213,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)); @@ -2171,9 +2241,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)); @@ -2215,13 +2285,33 @@ static const IHTMLPerformanceVtbl HTMLPerformanceVtbl = { HTMLPerformance_toJSON };
+static inline HTMLPerformance *HTMLPerformance_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLPerformance, dispex); +} + +static void HTMLPerformance_destructor(DispatchEx *dispex) +{ + HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + if(This->navigation) + IHTMLPerformanceNavigation_Release(This->navigation); + if(This->timing) + IHTMLPerformanceTiming_Release(This->timing); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLPerformance_dispex_vtbl = { + HTMLPerformance_destructor, +}; + static const tid_t HTMLPerformance_iface_tids[] = { IHTMLPerformance_tid, 0 }; static dispex_static_data_t HTMLPerformance_dispex = { L"Performance", - NULL, + &HTMLPerformance_dispex_vtbl, IHTMLPerformance_tid, HTMLPerformance_iface_tids }; @@ -2236,9 +2326,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); @@ -2251,7 +2341,7 @@ typedef struct { DispatchEx dispex; IHTMLNamespaceCollection IHTMLNamespaceCollection_iface;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref; } HTMLNamespaceCollection;
static inline HTMLNamespaceCollection *impl_from_IHTMLNamespaceCollection(IHTMLNamespaceCollection *iface) @@ -2284,7 +2374,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);
@@ -2294,15 +2384,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); - free(This); - } - return ref; }
@@ -2377,13 +2462,28 @@ static const IHTMLNamespaceCollectionVtbl HTMLNamespaceCollectionVtbl = { HTMLNamespaceCollection_add };
+static inline HTMLNamespaceCollection *HTMLNamespaceCollection_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLNamespaceCollection, dispex); +} + +static void HTMLNamespaceCollection_destructor(DispatchEx *dispex) +{ + HTMLNamespaceCollection *This = HTMLNamespaceCollection_from_DispatchEx(dispex); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLNamespaceCollection_dispex_vtbl = { + HTMLNamespaceCollection_destructor, +}; + static const tid_t HTMLNamespaceCollection_iface_tids[] = { IHTMLNamespaceCollection_tid, 0 }; static dispex_static_data_t HTMLNamespaceCollection_dispex = { L"MSNamespaceInfoCollection", - NULL, + &HTMLNamespaceCollection_dispex_vtbl, DispHTMLNamespaceCollection_tid, HTMLNamespaceCollection_iface_tids }; @@ -2396,7 +2496,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; @@ -2406,7 +2506,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) @@ -2439,7 +2539,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);
@@ -2449,15 +2549,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); - free(console); - } - return ref; }
@@ -2633,13 +2728,28 @@ static const IWineMSHTMLConsoleVtbl WineMSHTMLConsoleVtbl = { console_warn, };
+static inline struct console *console_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct console, dispex); +} + +static void console_destructor(DispatchEx *dispex) +{ + struct console *console = console_from_DispatchEx(dispex); + free(console); +} + +static const dispex_static_data_vtbl_t console_dispex_vtbl = { + console_destructor, +}; + static const tid_t console_iface_tids[] = { IWineMSHTMLConsole_tid, 0 }; static dispex_static_data_t console_dispex = { L"Console", - NULL, + &console_dispex_vtbl, IWineMSHTMLConsole_tid, console_iface_tids }; @@ -2656,7 +2766,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; @@ -2671,7 +2781,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; @@ -2710,7 +2820,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);
@@ -2720,23 +2830,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); - struct media_query_list_listener *listener, *listener2; + LONG ref = dispex_ccref_decr(&media_query_list->ccref, &media_query_list->dispex);
TRACE("(%p) ref=%ld\n", media_query_list, ref);
- if(!ref) { - media_query_list->callback->media_query_list = NULL; - LIST_FOR_EACH_ENTRY_SAFE(listener, listener2, &media_query_list->listeners, struct media_query_list_listener, entry) { - IDispatch_Release(listener->function); - free(listener); - } - nsIDOMMediaQueryListListener_Release(&media_query_list->callback->nsIDOMMediaQueryListListener_iface); - nsIDOMMediaQueryList_Release(media_query_list->nsquerylist); - release_dispex(&media_query_list->dispex); - free(media_query_list); - } - return ref; }
@@ -2956,13 +3053,37 @@ static const nsIDOMMediaQueryListListenerVtbl media_query_list_callback_vtbl = { media_query_list_callback_HandleChange };
+static inline struct media_query_list *media_query_list_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct media_query_list, dispex); +} + +static void media_query_list_destructor(DispatchEx *dispex) +{ + struct media_query_list *media_query_list = media_query_list_from_DispatchEx(dispex); + struct media_query_list_listener *listener, *listener2; + + media_query_list->callback->media_query_list = NULL; + LIST_FOR_EACH_ENTRY_SAFE(listener, listener2, &media_query_list->listeners, struct media_query_list_listener, entry) { + IDispatch_Release(listener->function); + free(listener); + } + nsIDOMMediaQueryListListener_Release(&media_query_list->callback->nsIDOMMediaQueryListListener_iface); + nsIDOMMediaQueryList_Release(media_query_list->nsquerylist); + free(media_query_list); +} + +static const dispex_static_data_vtbl_t media_query_list_dispex_vtbl = { + media_query_list_destructor, +}; + static const tid_t media_query_list_iface_tids[] = { IWineMSHTMLMediaQueryList_tid, 0 }; static dispex_static_data_t media_query_list_dispex = { L"MediaQueryList", - NULL, + &media_query_list_dispex_vtbl, IWineMSHTMLMediaQueryList_tid, media_query_list_iface_tids }; @@ -3004,8 +3125,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 1f062f5022a..20730b5e0f2 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,19 +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) { - if(This->nsrange) - nsIDOMRange_Release(This->nsrange); - if(This->doc) - list_remove(&This->entry); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -1718,13 +1709,32 @@ static const IOleCommandTargetVtbl OleCommandTargetVtbl = { RangeCommandTarget_Exec };
+static inline HTMLTxtRange *HTMLTxtRange_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLTxtRange, dispex); +} + +static void HTMLTxtRange_destructor(DispatchEx *dispex) +{ + HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); + if(This->nsrange) + nsIDOMRange_Release(This->nsrange); + if(This->doc) + list_remove(&This->entry); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLTxtRange_dispex_vtbl = { + HTMLTxtRange_destructor, +}; + static const tid_t HTMLTxtRange_iface_tids[] = { IHTMLTxtRange_tid, 0 }; static dispex_static_data_t HTMLTxtRange_dispex = { L"TextRange", - NULL, + &HTMLTxtRange_dispex_vtbl, IHTMLTxtRange_tid, HTMLTxtRange_iface_tids }; @@ -1742,7 +1752,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); @@ -1785,7 +1795,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);
@@ -1795,17 +1805,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) { - if(This->nsrange) - nsIDOMRange_Release(This->nsrange); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -2063,6 +2066,23 @@ static const IHTMLDOMRangeVtbl HTMLDOMRangeVtbl = { HTMLDOMRange_getBoundingClientRect, };
+static inline HTMLDOMRange *HTMLDOMRange_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLDOMRange, dispex); +} + +static void HTMLDOMRange_destructor(DispatchEx *dispex) +{ + HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); + if(This->nsrange) + nsIDOMRange_Release(This->nsrange); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLDOMRange_dispex_vtbl = { + HTMLDOMRange_destructor, +}; + static const tid_t HTMLDOMRange_iface_tids[] = { IHTMLDOMRange_tid, 0 @@ -2070,7 +2090,7 @@ static const tid_t HTMLDOMRange_iface_tids[] = {
static dispex_static_data_t HTMLDOMRange_dispex = { L"Range", - NULL, + &HTMLDOMRange_dispex_vtbl, DispHTMLDOMRange_tid, HTMLDOMRange_iface_tids }; @@ -2086,7 +2106,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 03a330d3f30..639ab0ce391 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,19 +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) { - if(This->nsselection) - nsISelection_Release(This->nsselection); - if(This->doc) - list_remove(&This->entry); - release_dispex(&This->dispex); - free(This); - } - return ref; }
@@ -329,6 +320,25 @@ static const IHTMLSelectionObject2Vtbl HTMLSelectionObject2Vtbl = { HTMLSelectionObject2_get_typeDetail };
+static inline HTMLSelectionObject *impl_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLSelectionObject, dispex); +} + +static void HTMLSelectionObject_destructor(DispatchEx *dispex) +{ + HTMLSelectionObject *This = impl_from_DispatchEx(dispex); + if(This->nsselection) + nsISelection_Release(This->nsselection); + if(This->doc) + list_remove(&This->entry); + free(This); +} + +static const dispex_static_data_vtbl_t HTMLSelectionObject_dispex_vtbl = { + HTMLSelectionObject_destructor, +}; + static const tid_t HTMLSelectionObject_iface_tids[] = { IHTMLSelectionObject_tid, IHTMLSelectionObject2_tid, @@ -336,7 +346,7 @@ static const tid_t HTMLSelectionObject_iface_tids[] = { }; static dispex_static_data_t HTMLSelectionObject_dispex = { L"MSSelection", - NULL, + &HTMLSelectionObject_dispex_vtbl, IHTMLSelectionObject_tid, /* FIXME: We have a test for that, but it doesn't expose IHTMLSelectionObject2 iface. */ HTMLSelectionObject_iface_tids }; @@ -354,8 +364,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 17f29396b8f..2f7544ae191 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,21 +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);
- if(!ref) { - remove_target_tasks(This->task_magic); - detach_xhr_event_listener(This->event_listener); - if(This->pending_progress_event) - IDOMEvent_Release(&This->pending_progress_event->IDOMEvent_iface); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); - release_event_target(&This->event_target); - release_dispex(&This->event_target.dispex); - nsIXMLHttpRequest_Release(This->nsxhr); - free(This); - } + /* 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) + This->magic++;
return ref; } @@ -1530,6 +1523,19 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex); }
+static void HTMLXMLHttpRequest_destructor(DispatchEx *dispex) +{ + HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); + remove_target_tasks(This->task_magic); + detach_xhr_event_listener(This->event_listener); + if(This->pending_progress_event) + IDOMEvent_Release(&This->pending_progress_event->IDOMEvent_iface); + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + release_event_target(&This->event_target); + nsIXMLHttpRequest_Release(This->nsxhr); + free(This); +} + static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex) { HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); @@ -1574,7 +1580,7 @@ static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode
static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = { { - NULL, + HTMLXMLHttpRequest_destructor, }, HTMLXMLHttpRequest_get_gecko_target, HTMLXMLHttpRequest_bind_event @@ -1626,7 +1632,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);
@@ -1636,15 +1642,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); - free(This); - } - return ref; }
@@ -1718,9 +1719,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; @@ -1766,6 +1767,12 @@ static inline HTMLXMLHttpRequestFactory *factory_from_DispatchEx(DispatchEx *ifa return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, dispex); }
+static void HTMLXMLHttpRequestFactory_destructor(DispatchEx *dispex) +{ + HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + free(This); +} + static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { @@ -1790,6 +1797,7 @@ static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WOR }
static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = { + HTMLXMLHttpRequestFactory_destructor, HTMLXMLHttpRequestFactory_value };
@@ -1813,7 +1821,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,