This is first part in a series that implements Cycle Collection for every mshtml object (dispex) and cleans up rest of the code based on it, which is obviously needed due to dynamic props and other extra object-specific refs.
In an effort to split it up as much as possible, since it already has quite a lot of restructuring and changes, some of the earlier patches will introduce temporary leaks or cyclic refs, but that's because we'll later handle them properly with the dispex CC. These shouldn't affect behavior, though, so it shouldn't pose problems for functionality.
Nodes are, initially, not changed much (other than to make it compatible with the dispex) to keep changes as small as possible. They still use their own CC mechanism and refcounting, which is hackish but that is solved in a follow-up MR, so it's temporary only.
Eventually, every object (including nodes) will use the dispex's vtbl to do its Cycle Collection, except for stuff like outer window (which is a special case).
In this first part, the objects that are using the node CC will have no-op dispex CC methods since they are using the node's, but this is temporary only.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Rather than filling it during initialization, which was a bit confusing, even more later on when dispex will handle Cycle Collection.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlanchor.c | 2 +- dlls/mshtml/htmlarea.c | 2 +- dlls/mshtml/htmlbody.c | 2 +- dlls/mshtml/htmlcomment.c | 3 ++- dlls/mshtml/htmlelem.c | 5 +---- dlls/mshtml/htmlevent.h | 1 + dlls/mshtml/htmlform.c | 2 +- dlls/mshtml/htmlframe.c | 4 ++-- dlls/mshtml/htmlgeneric.c | 3 ++- dlls/mshtml/htmlhead.c | 9 +++++---- dlls/mshtml/htmlimg.c | 2 +- dlls/mshtml/htmlinput.c | 6 +++--- dlls/mshtml/htmllink.c | 2 +- dlls/mshtml/htmlobject.c | 5 +++-- dlls/mshtml/htmlscript.c | 2 +- dlls/mshtml/htmlselect.c | 4 ++-- dlls/mshtml/htmlstyleelem.c | 3 ++- dlls/mshtml/htmltable.c | 7 ++++--- dlls/mshtml/htmltextarea.c | 3 ++- 19 files changed, 36 insertions(+), 31 deletions(-)
diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c index 1e783ce007e..7620bc45d81 100644 --- a/dlls/mshtml/htmlanchor.c +++ b/dlls/mshtml/htmlanchor.c @@ -902,7 +902,7 @@ static const tid_t HTMLAnchorElement_iface_tids[] = {
static dispex_static_data_t HTMLAnchorElement_dispex = { L"HTMLAnchorElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLAnchorElement_tid, HTMLAnchorElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlarea.c b/dlls/mshtml/htmlarea.c index c518432519d..b6dbd0b28d5 100644 --- a/dlls/mshtml/htmlarea.c +++ b/dlls/mshtml/htmlarea.c @@ -509,7 +509,7 @@ static const tid_t HTMLAreaElement_iface_tids[] = { }; static dispex_static_data_t HTMLAreaElement_dispex = { L"HTMLAreaElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLAreaElement_tid, HTMLAreaElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlbody.c b/dlls/mshtml/htmlbody.c index 6338e7e907b..5ee2555e421 100644 --- a/dlls/mshtml/htmlbody.c +++ b/dlls/mshtml/htmlbody.c @@ -1010,7 +1010,7 @@ static const tid_t HTMLBodyElement_iface_tids[] = {
static dispex_static_data_t HTMLBodyElement_dispex = { L"HTMLBodyElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLBody_tid, HTMLBodyElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlcomment.c b/dlls/mshtml/htmlcomment.c index cc3bec32959..705d84f4367 100644 --- a/dlls/mshtml/htmlcomment.c +++ b/dlls/mshtml/htmlcomment.c @@ -27,6 +27,7 @@ #include "ole2.h"
#include "mshtml_private.h" +#include "htmlevent.h"
#include "wine/debug.h"
@@ -200,7 +201,7 @@ static const tid_t HTMLCommentElement_iface_tids[] = { }; static dispex_static_data_t HTMLCommentElement_dispex = { L"Comment", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLCommentElement_tid, HTMLCommentElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index ad5bda63665..53c418ab333 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -7326,7 +7326,7 @@ static const tid_t HTMLElement_iface_tids[] = { 0 };
-static event_target_vtbl_t HTMLElement_event_target_vtbl = { +const event_target_vtbl_t HTMLElement_event_target_vtbl = { { NULL, HTMLElement_get_dispid, @@ -7946,9 +7946,6 @@ void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMElement *n This->IProvideMultipleClassInfo_iface.lpVtbl = &ProvideMultipleClassInfoVtbl; This->IWineHTMLElementPrivate_iface.lpVtbl = &WineHTMLElementPrivateVtbl;
- if(dispex_data && !dispex_data->vtbl) - dispex_data->vtbl = &HTMLElement_event_target_vtbl.dispex_vtbl; - if(nselem) { nsIDOMHTMLElement *html_element; nsresult nsres; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 5a46b855a30..5e2c7a0a054 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -138,6 +138,7 @@ typedef struct { IHTMLEventObj *(*set_current_event)(DispatchEx*,IHTMLEventObj*); } event_target_vtbl_t;
+extern const event_target_vtbl_t HTMLElement_event_target_vtbl; IHTMLEventObj *default_set_current_event(HTMLInnerWindow*,IHTMLEventObj*);
static inline EventTarget *get_node_event_prop_target(HTMLDOMNode *node, eventid_t eid) diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c index 3e7ca112311..385cc6f9834 100644 --- a/dlls/mshtml/htmlform.c +++ b/dlls/mshtml/htmlform.c @@ -1007,7 +1007,7 @@ static const tid_t HTMLFormElement_iface_tids[] = {
static dispex_static_data_t HTMLFormElement_dispex = { L"HTMLFormElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLFormElement_tid, HTMLFormElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlframe.c b/dlls/mshtml/htmlframe.c index 9be69c29f9a..acc5dbad8ca 100644 --- a/dlls/mshtml/htmlframe.c +++ b/dlls/mshtml/htmlframe.c @@ -1043,7 +1043,7 @@ static const tid_t HTMLFrameElement_iface_tids[] = {
static dispex_static_data_t HTMLFrameElement_dispex = { L"HTMLFrameElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLFrameElement_tid, HTMLFrameElement_iface_tids, HTMLElement_init_dispex_info @@ -1638,7 +1638,7 @@ static const tid_t HTMLIFrame_iface_tids[] = {
static dispex_static_data_t HTMLIFrame_dispex = { L"HTMLIFrameElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLIFrame_tid, HTMLIFrame_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlgeneric.c b/dlls/mshtml/htmlgeneric.c index 9244ba017fb..4666348fddb 100644 --- a/dlls/mshtml/htmlgeneric.c +++ b/dlls/mshtml/htmlgeneric.c @@ -29,6 +29,7 @@ #include "wine/debug.h"
#include "mshtml_private.h" +#include "htmlevent.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
@@ -169,7 +170,7 @@ static const tid_t HTMLGenericElement_iface_tids[] = {
static dispex_static_data_t HTMLGenericElement_dispex = { L"HTMLUnknownElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLGenericElement_tid, HTMLGenericElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlhead.c b/dlls/mshtml/htmlhead.c index 072efd967b9..1ef183338c7 100644 --- a/dlls/mshtml/htmlhead.c +++ b/dlls/mshtml/htmlhead.c @@ -29,6 +29,7 @@ #include "wine/debug.h"
#include "mshtml_private.h" +#include "htmlevent.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
@@ -184,7 +185,7 @@ static const tid_t HTMLTitleElement_iface_tids[] = { }; static dispex_static_data_t HTMLTitleElement_dispex = { L"HTMLTitleElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLTitleElement_tid, HTMLTitleElement_iface_tids, HTMLElement_init_dispex_info @@ -369,7 +370,7 @@ static const tid_t HTMLHtmlElement_iface_tids[] = { }; static dispex_static_data_t HTMLHtmlElement_dispex = { L"HTMLHtmlElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLHtmlElement_tid, HTMLHtmlElement_iface_tids, HTMLElement_init_dispex_info @@ -606,7 +607,7 @@ static const tid_t HTMLMetaElement_iface_tids[] = {
static dispex_static_data_t HTMLMetaElement_dispex = { L"HTMLMetaElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLMetaElement_tid, HTMLMetaElement_iface_tids, HTMLElement_init_dispex_info @@ -770,7 +771,7 @@ static const tid_t HTMLHeadElement_iface_tids[] = { }; static dispex_static_data_t HTMLHeadElement_dispex = { L"HTMLHeadElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLHeadElement_tid, HTMLHeadElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index 50fa3531464..47fc2be8d5d 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -742,7 +742,7 @@ static void HTMLImgElement_init_dispex_info(dispex_data_t *info, compat_mode_t m
static dispex_static_data_t HTMLImgElement_dispex = { L"HTMLImageElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLImg_tid, HTMLImgElement_iface_tids, HTMLImgElement_init_dispex_info diff --git a/dlls/mshtml/htmlinput.c b/dlls/mshtml/htmlinput.c index c220a2495c7..4d59cf4f158 100644 --- a/dlls/mshtml/htmlinput.c +++ b/dlls/mshtml/htmlinput.c @@ -1456,7 +1456,7 @@ static const tid_t HTMLInputElement_iface_tids[] = { }; static dispex_static_data_t HTMLInputElement_dispex = { L"HTMLInputElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLInputElement_tid, HTMLInputElement_iface_tids, HTMLElement_init_dispex_info @@ -1653,7 +1653,7 @@ static const tid_t HTMLLabelElement_iface_tids[] = {
static dispex_static_data_t HTMLLabelElement_dispex = { L"HTMLLabelElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLLabelElement_tid, HTMLLabelElement_iface_tids, HTMLElement_init_dispex_info @@ -2001,7 +2001,7 @@ static const tid_t HTMLButtonElement_iface_tids[] = {
static dispex_static_data_t HTMLButtonElement_dispex = { L"HTMLButtonElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLButtonElement_tid, HTMLButtonElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmllink.c b/dlls/mshtml/htmllink.c index 124507a2fc9..d5ae5932e0e 100644 --- a/dlls/mshtml/htmllink.c +++ b/dlls/mshtml/htmllink.c @@ -448,7 +448,7 @@ static const tid_t HTMLLinkElement_iface_tids[] = { }; static dispex_static_data_t HTMLLinkElement_dispex = { L"HTMLLinkElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLLinkElement_tid, HTMLLinkElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlobject.c b/dlls/mshtml/htmlobject.c index 9e30b5426fb..6e29ccd640c 100644 --- a/dlls/mshtml/htmlobject.c +++ b/dlls/mshtml/htmlobject.c @@ -29,6 +29,7 @@ #include "wine/debug.h"
#include "mshtml_private.h" +#include "htmlevent.h" #include "pluginhost.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml); @@ -777,7 +778,7 @@ static const tid_t HTMLObjectElement_iface_tids[] = { }; static dispex_static_data_t HTMLObjectElement_dispex = { L"HTMLObjectElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLObjectElement_tid, HTMLObjectElement_iface_tids, HTMLElement_init_dispex_info @@ -1040,7 +1041,7 @@ static const tid_t HTMLEmbedElement_iface_tids[] = { }; static dispex_static_data_t HTMLEmbedElement_dispex = { L"HTMLEmbedElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLEmbed_tid, HTMLEmbedElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c index 2ef21fbfb0a..42cf63c47bd 100644 --- a/dlls/mshtml/htmlscript.c +++ b/dlls/mshtml/htmlscript.c @@ -481,7 +481,7 @@ static const tid_t HTMLScriptElement_iface_tids[] = {
static dispex_static_data_t HTMLScriptElement_dispex = { L"HTMLScriptElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLScriptElement_tid, HTMLScriptElement_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index bbe6fadebba..dd1c784c28d 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -419,7 +419,7 @@ static const tid_t HTMLOptionElement_iface_tids[] = { }; static dispex_static_data_t HTMLOptionElement_dispex = { L"HTMLOptionElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLOptionElement_tid, HTMLOptionElement_iface_tids, HTMLElement_init_dispex_info @@ -1496,7 +1496,7 @@ static const tid_t HTMLSelectElement_tids[] = {
static dispex_static_data_t HTMLSelectElement_dispex = { L"HTMLSelectElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLSelectElement_tid, HTMLSelectElement_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmlstyleelem.c b/dlls/mshtml/htmlstyleelem.c index abd720cc18f..434afcd46e3 100644 --- a/dlls/mshtml/htmlstyleelem.c +++ b/dlls/mshtml/htmlstyleelem.c @@ -29,6 +29,7 @@ #include "wine/debug.h"
#include "mshtml_private.h" +#include "htmlevent.h" #include "mshtmdid.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml); @@ -464,7 +465,7 @@ static const tid_t HTMLStyleElement_iface_tids[] = { }; static dispex_static_data_t HTMLStyleElement_dispex = { L"HTMLStyleElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLStyleElement_tid, HTMLStyleElement_iface_tids, HTMLStyleElement_init_dispex_info diff --git a/dlls/mshtml/htmltable.c b/dlls/mshtml/htmltable.c index 1afb32ea6ec..3cadc75b90d 100644 --- a/dlls/mshtml/htmltable.c +++ b/dlls/mshtml/htmltable.c @@ -28,6 +28,7 @@ #include "wine/debug.h"
#include "mshtml_private.h" +#include "htmlevent.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
@@ -522,7 +523,7 @@ static const tid_t HTMLTableCell_iface_tids[] = {
static dispex_static_data_t HTMLTableCell_dispex = { L"HTMLTableDataCellElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLTableCell_tid, HTMLTableCell_iface_tids, HTMLElement_init_dispex_info @@ -968,7 +969,7 @@ static const tid_t HTMLTableRow_iface_tids[] = {
static dispex_static_data_t HTMLTableRow_dispex = { L"HTMLTableRowElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLTableRow_tid, HTMLTableRow_iface_tids, HTMLElement_init_dispex_info @@ -2002,7 +2003,7 @@ static const tid_t HTMLTable_iface_tids[] = {
static dispex_static_data_t HTMLTable_dispex = { L"HTMLTableElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLTable_tid, HTMLTable_iface_tids, HTMLElement_init_dispex_info diff --git a/dlls/mshtml/htmltextarea.c b/dlls/mshtml/htmltextarea.c index 5820c0c7291..98468685eab 100644 --- a/dlls/mshtml/htmltextarea.c +++ b/dlls/mshtml/htmltextarea.c @@ -28,6 +28,7 @@ #include "wine/debug.h"
#include "mshtml_private.h" +#include "htmlevent.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
@@ -481,7 +482,7 @@ static const tid_t HTMLTextAreaElement_iface_tids[] = {
static dispex_static_data_t HTMLTextAreaElement_dispex = { L"HTMLTextAreaElement", - NULL, + &HTMLElement_event_target_vtbl.dispex_vtbl, DispHTMLTextAreaElement_tid, HTMLTextAreaElement_iface_tids, HTMLElement_init_dispex_info
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 6 +++--- dlls/mshtml/navigate.c | 6 +++--- dlls/mshtml/omnavigator.c | 17 ++++++++++------- 3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 59d652a828b..827b3289849 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -508,9 +508,6 @@ typedef struct {
LONG ref;
- ULONG navigation_type; - ULONG redirect_count; - ULONGLONG navigation_start_time; ULONGLONG unload_event_start_time; ULONGLONG unload_event_end_time; @@ -621,6 +618,9 @@ struct HTMLInnerWindow { IMoniker *mon; nsChannelBSC *bscallback; struct list bindings; + + ULONG navigation_type; + ULONG redirect_count; };
typedef enum { diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 112b63ba4b1..8b9d97d19f1 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1358,9 +1358,9 @@ static HRESULT nsChannelBSC_start_binding(BSCallback *bsc) DWORD flags = This->bsc.window->base.outer_window->load_flags;
if(flags & BINDING_FROMHIST) - This->bsc.window->performance_timing->navigation_type = 2; /* TYPE_BACK_FORWARD */ + This->bsc.window->navigation_type = 2; /* TYPE_BACK_FORWARD */ if(flags & BINDING_REFRESH) - This->bsc.window->performance_timing->navigation_type = 1; /* TYPE_RELOAD */ + This->bsc.window->navigation_type = 1; /* TYPE_RELOAD */
This->bsc.window->base.outer_window->base.inner_window->doc->skip_mutation_notif = FALSE; This->bsc.window->performance_timing->navigation_start_time = get_time_stamp(); @@ -1733,7 +1733,7 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG t break; case BINDSTATUS_REDIRECTING: if(This->is_doc_channel) { - This->bsc.window->performance_timing->redirect_count++; + This->bsc.window->redirect_count++; if(!This->bsc.window->performance_timing->redirect_time) This->bsc.window->performance_timing->redirect_time = get_time_stamp(); } diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 298d99f86eb..5a8fee0ea36 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1879,7 +1879,7 @@ typedef struct { IHTMLPerformanceNavigation IHTMLPerformanceNavigation_iface;
LONG ref; - HTMLPerformanceTiming *timing; + HTMLInnerWindow *window; } HTMLPerformanceNavigation;
static inline HTMLPerformanceNavigation *impl_from_IHTMLPerformanceNavigation(IHTMLPerformanceNavigation *iface) @@ -1927,7 +1927,7 @@ static ULONG WINAPI HTMLPerformanceNavigation_Release(IHTMLPerformanceNavigation TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) { - IHTMLPerformanceTiming_Release(&This->timing->IHTMLPerformanceTiming_iface); + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); release_dispex(&This->dispex); free(This); } @@ -1976,7 +1976,7 @@ static HRESULT WINAPI HTMLPerformanceNavigation_get_type(IHTMLPerformanceNavigat
TRACE("(%p)->(%p)\n", This, p);
- *p = This->timing->navigation_type; + *p = This->window->navigation_type; return S_OK; }
@@ -1986,7 +1986,7 @@ static HRESULT WINAPI HTMLPerformanceNavigation_get_redirectCount(IHTMLPerforman
TRACE("(%p)->(%p)\n", This, p);
- *p = This->timing->redirect_count; + *p = This->window->redirect_count; return S_OK; }
@@ -2037,6 +2037,7 @@ typedef struct {
LONG ref;
+ HTMLInnerWindow *window; IHTMLPerformanceNavigation *navigation; HTMLPerformanceTiming *timing; } HTMLPerformance; @@ -2086,7 +2087,7 @@ static ULONG WINAPI HTMLPerformance_Release(IHTMLPerformance *iface) TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) { - IHTMLPerformanceTiming_Release(&This->timing->IHTMLPerformanceTiming_iface); + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); if(This->navigation) IHTMLPerformanceNavigation_Release(This->navigation); release_dispex(&This->dispex); @@ -2147,8 +2148,8 @@ static HRESULT WINAPI HTMLPerformance_get_navigation(IHTMLPerformance *iface,
navigation->IHTMLPerformanceNavigation_iface.lpVtbl = &HTMLPerformanceNavigationVtbl; navigation->ref = 1; - navigation->timing = This->timing; - IHTMLPerformanceTiming_AddRef(&This->timing->IHTMLPerformanceTiming_iface); + navigation->window = This->window; + IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface);
init_dispatch(&navigation->dispex, (IUnknown*)&navigation->IHTMLPerformanceNavigation_iface, &HTMLPerformanceNavigation_dispex, dispex_compat_mode(&This->dispex)); @@ -2222,6 +2223,8 @@ HRESULT create_performance(HTMLInnerWindow *window, IHTMLPerformance **ret)
performance->IHTMLPerformance_iface.lpVtbl = &HTMLPerformanceVtbl; performance->ref = 1; + performance->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&performance->dispex, (IUnknown*)&performance->IHTMLPerformance_iface, &HTMLPerformance_dispex, compat_mode);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 8 --- dlls/mshtml/mshtml_private.h | 43 +++++------ dlls/mshtml/mutation.c | 2 +- dlls/mshtml/navigate.c | 20 +++--- dlls/mshtml/nsevents.c | 25 +++---- dlls/mshtml/omnavigator.c | 134 +++++++++++++++++++---------------- dlls/mshtml/view.c | 4 +- 7 files changed, 112 insertions(+), 124 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c6072c7e9fa..c2e5b10b90a 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -303,7 +303,6 @@ static void release_inner_window(HTMLInnerWindow *This) IHTMLStorage_Release(This->local_storage); }
- IHTMLPerformanceTiming_Release(&This->performance_timing->IHTMLPerformanceTiming_iface); VariantClear(&This->performance);
if(This->mon) @@ -4057,18 +4056,11 @@ static void *alloc_window(size_t size) static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, HTMLInnerWindow **ret) { HTMLInnerWindow *window; - HRESULT hres;
window = alloc_window(sizeof(HTMLInnerWindow)); if(!window) return E_OUTOFMEMORY;
- hres = create_performance_timing(&window->performance_timing); - if(FAILED(hres)) { - free(window); - return hres; - } - list_init(&window->children); list_init(&window->script_hosts); list_init(&window->bindings); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 827b3289849..87c3c062483 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -502,30 +502,6 @@ typedef struct { HTMLInnerWindow *window; } OmHistory;
-typedef struct { - DispatchEx dispex; - IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; - - LONG ref; - - ULONGLONG navigation_start_time; - ULONGLONG unload_event_start_time; - ULONGLONG unload_event_end_time; - ULONGLONG redirect_time; - ULONGLONG dns_lookup_time; - ULONGLONG connect_time; - ULONGLONG request_time; - ULONGLONG response_start_time; - ULONGLONG response_end_time; - ULONGLONG dom_interactive_time; - ULONGLONG dom_complete_time; - ULONGLONG dom_content_loaded_event_start_time; - ULONGLONG dom_content_loaded_event_end_time; - ULONGLONG load_event_start_time; - ULONGLONG load_event_end_time; - ULONGLONG first_paint_time; -} HTMLPerformanceTiming; - typedef struct nsChannelBSC nsChannelBSC;
struct HTMLWindow { @@ -603,7 +579,6 @@ struct HTMLInnerWindow {
BOOL performance_initialized; VARIANT performance; - HTMLPerformanceTiming *performance_timing;
unsigned blocking_depth; unsigned parser_callback_cnt; @@ -621,6 +596,23 @@ struct HTMLInnerWindow {
ULONG navigation_type; ULONG redirect_count; + + ULONGLONG navigation_start_time; + ULONGLONG unload_event_start_time; + ULONGLONG unload_event_end_time; + ULONGLONG redirect_time; + ULONGLONG dns_lookup_time; + ULONGLONG connect_time; + ULONGLONG request_time; + ULONGLONG response_start_time; + ULONGLONG response_end_time; + ULONGLONG dom_interactive_time; + ULONGLONG dom_complete_time; + ULONGLONG dom_content_loaded_event_start_time; + ULONGLONG dom_content_loaded_event_end_time; + ULONGLONG load_event_start_time; + ULONGLONG load_event_end_time; + ULONGLONG first_paint_time; };
typedef enum { @@ -994,7 +986,6 @@ void HTMLLocation_Init(HTMLLocation*); HRESULT create_navigator(compat_mode_t,IOmNavigator**); HRESULT create_html_screen(compat_mode_t,IHTMLScreen**); HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**); -HRESULT create_performance_timing(HTMLPerformanceTiming**); HRESULT create_history(HTMLInnerWindow*,OmHistory**); HRESULT create_namespace_collection(compat_mode_t,IHTMLNamespaceCollection**); HRESULT create_dom_implementation(HTMLDocumentNode*,IHTMLDOMImplementation**); diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 83ab623aea8..63aa4478453 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -313,7 +313,7 @@ static nsresult run_end_load(HTMLDocumentNode *This, nsISupports *arg1, nsISuppo bind_event_scripts(This);
if(This->window == window) { - window->performance_timing->dom_interactive_time = get_time_stamp(); + window->dom_interactive_time = get_time_stamp(); set_ready_state(This->outer_window, READYSTATE_INTERACTIVE); } IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 8b9d97d19f1..ccd99bb7b95 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1102,7 +1102,7 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) IWinInetHttpInfo *wininet_info;
if(This->is_doc_channel) - This->bsc.window->performance_timing->response_start_time = get_time_stamp(); + This->bsc.window->response_start_time = get_time_stamp();
This->response_processed = TRUE; if(This->bsc.binding) { @@ -1363,7 +1363,7 @@ static HRESULT nsChannelBSC_start_binding(BSCallback *bsc) This->bsc.window->navigation_type = 1; /* TYPE_RELOAD */
This->bsc.window->base.outer_window->base.inner_window->doc->skip_mutation_notif = FALSE; - This->bsc.window->performance_timing->navigation_start_time = get_time_stamp(); + This->bsc.window->navigation_start_time = get_time_stamp(); }
return S_OK; @@ -1531,7 +1531,7 @@ static HRESULT nsChannelBSC_stop_binding(BSCallback *bsc, HRESULT result) nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc);
if(This->is_doc_channel && This->bsc.window) { - This->bsc.window->performance_timing->response_end_time = get_time_stamp(); + This->bsc.window->response_end_time = get_time_stamp(); if(result != E_ABORT) { if(FAILED(result)) handle_navigation_error(This, result); @@ -1734,21 +1734,21 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG t case BINDSTATUS_REDIRECTING: if(This->is_doc_channel) { This->bsc.window->redirect_count++; - if(!This->bsc.window->performance_timing->redirect_time) - This->bsc.window->performance_timing->redirect_time = get_time_stamp(); + if(!This->bsc.window->redirect_time) + This->bsc.window->redirect_time = get_time_stamp(); } return handle_redirect(This, status_text); case BINDSTATUS_FINDINGRESOURCE: - if(This->is_doc_channel && !This->bsc.window->performance_timing->dns_lookup_time) - This->bsc.window->performance_timing->dns_lookup_time = get_time_stamp(); + if(This->is_doc_channel && !This->bsc.window->dns_lookup_time) + This->bsc.window->dns_lookup_time = get_time_stamp(); break; case BINDSTATUS_CONNECTING: if(This->is_doc_channel) - This->bsc.window->performance_timing->connect_time = get_time_stamp(); + This->bsc.window->connect_time = get_time_stamp(); break; case BINDSTATUS_SENDINGREQUEST: if(This->is_doc_channel) - This->bsc.window->performance_timing->request_time = get_time_stamp(); + This->bsc.window->request_time = get_time_stamp(); break; case BINDSTATUS_BEGINDOWNLOADDATA: { IWinInetHttpInfo *http_info; @@ -1805,7 +1805,7 @@ static HRESULT nsChannelBSC_on_response(BSCallback *bsc, DWORD response_code, HRESULT hres;
if(This->is_doc_channel) - This->bsc.window->performance_timing->response_start_time = get_time_stamp(); + This->bsc.window->response_start_time = get_time_stamp();
This->response_processed = TRUE; This->nschannel->response_status = response_code; diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 90d4bc9e9bd..be888084961 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -238,7 +238,7 @@ static nsresult handle_dom_content_loaded(HTMLDocumentNode *doc, nsIDOMEvent *ns HRESULT hres;
if(doc->window) - doc->window->performance_timing->dom_content_loaded_event_start_time = get_time_stamp(); + doc->window->dom_content_loaded_event_start_time = get_time_stamp();
hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&doc->node.event_target.dispex), &event); if(SUCCEEDED(hres)) { @@ -247,7 +247,7 @@ static nsresult handle_dom_content_loaded(HTMLDocumentNode *doc, nsIDOMEvent *ns }
if(doc->window) - doc->window->performance_timing->dom_content_loaded_event_end_time = get_time_stamp(); + doc->window->dom_content_loaded_event_end_time = get_time_stamp();
return NS_OK; } @@ -348,7 +348,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) if(doc_obj) handle_docobj_load(doc_obj);
- doc->window->performance_timing->dom_complete_time = get_time_stamp(); + doc->window->dom_complete_time = get_time_stamp(); set_ready_state(doc->outer_window, READYSTATE_COMPLETE);
if(doc_obj) { @@ -366,7 +366,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) IUnknown_Release(doc_obj->outer_unk); }
- doc->window->performance_timing->load_event_start_time = get_time_stamp(); + doc->window->load_event_start_time = get_time_stamp();
if(doc->dom_document) { hres = create_document_event(doc, EVENTID_LOAD, &load_event); @@ -384,7 +384,7 @@ static nsresult handle_load(HTMLDocumentNode *doc, nsIDOMEvent *event) IDOMEvent_Release(&load_event->IDOMEvent_iface); }
- doc->window->performance_timing->load_event_end_time = get_time_stamp(); + doc->window->load_event_end_time = get_time_stamp(); return NS_OK; }
@@ -409,8 +409,7 @@ static nsresult handle_beforeunload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent)
static nsresult handle_unload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent) { - HTMLPerformanceTiming *timing = NULL; - HTMLInnerWindow *window; + HTMLInnerWindow *window, *pending_window; DOMEvent *event; HRESULT hres;
@@ -418,11 +417,9 @@ static nsresult handle_unload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent) return NS_OK; doc->unload_sent = TRUE;
- if(window->base.outer_window->pending_window) - timing = window->base.outer_window->pending_window->performance_timing; - - if(timing) - timing->unload_event_start_time = get_time_stamp(); + pending_window = window->base.outer_window->pending_window; + if(pending_window) + pending_window->unload_event_start_time = get_time_stamp();
hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&doc->node.event_target.dispex), &event); if(SUCCEEDED(hres)) { @@ -430,8 +427,8 @@ static nsresult handle_unload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent) IDOMEvent_Release(&event->IDOMEvent_iface); }
- if(timing) - timing->unload_event_end_time = get_time_stamp(); + if(pending_window) + pending_window->unload_event_end_time = get_time_stamp();
return NS_OK; } diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 5a8fee0ea36..7615b114d3e 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1475,6 +1475,14 @@ HRESULT create_navigator(compat_mode_t compat_mode, IOmNavigator **navigator) return S_OK; }
+typedef struct { + DispatchEx dispex; + IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; + + LONG ref; + HTMLInnerWindow *window; +} HTMLPerformanceTiming; + static inline HTMLPerformanceTiming *impl_from_IHTMLPerformanceTiming(IHTMLPerformanceTiming *iface) { return CONTAINING_RECORD(iface, HTMLPerformanceTiming, IHTMLPerformanceTiming_iface); @@ -1520,8 +1528,8 @@ static ULONG WINAPI HTMLPerformanceTiming_Release(IHTMLPerformanceTiming *iface) TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) { - if(This->dispex.outer) - release_dispex(&This->dispex); + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + release_dispex(&This->dispex); free(This); }
@@ -1565,20 +1573,22 @@ static HRESULT WINAPI HTMLPerformanceTiming_Invoke(IHTMLPerformanceTiming *iface
static ULONGLONG get_fetch_time(HTMLPerformanceTiming *This) { + HTMLInnerWindow *window = This->window; + /* If there's no prior doc unloaded and no redirects, fetch time == navigationStart time */ - if(!This->unload_event_end_time && !This->redirect_time) - return This->navigation_start_time; + if(!window->unload_event_end_time && !window->redirect_time) + return window->navigation_start_time;
- if(This->dns_lookup_time) - return This->dns_lookup_time; - if(This->connect_time) - return This->connect_time; - if(This->request_time) - return This->request_time; - if(This->unload_event_end_time) - return This->unload_event_end_time; + if(window->dns_lookup_time) + return window->dns_lookup_time; + if(window->connect_time) + return window->connect_time; + if(window->request_time) + return window->request_time; + if(window->unload_event_end_time) + return window->unload_event_end_time;
- return This->redirect_time; + return window->redirect_time; }
static HRESULT WINAPI HTMLPerformanceTiming_get_navigationStart(IHTMLPerformanceTiming *iface, ULONGLONG *p) @@ -1587,7 +1597,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_navigationStart(IHTMLPerformance
TRACE("(%p)->(%p)\n", This, p);
- *p = This->navigation_start_time; + *p = This->window->navigation_start_time; return S_OK; }
@@ -1597,7 +1607,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_unloadEventStart(IHTMLPerformanc
TRACE("(%p)->(%p)\n", This, p);
- *p = This->unload_event_start_time; + *p = This->window->unload_event_start_time; return S_OK; }
@@ -1607,7 +1617,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_unloadEventEnd(IHTMLPerformanceT
TRACE("(%p)->(%p)\n", This, p);
- *p = This->unload_event_end_time; + *p = This->window->unload_event_end_time; return S_OK; }
@@ -1617,7 +1627,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_redirectStart(IHTMLPerformanceTi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->redirect_time; + *p = This->window->redirect_time; return S_OK; }
@@ -1627,7 +1637,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_redirectEnd(IHTMLPerformanceTimi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->redirect_time ? get_fetch_time(This) : 0; + *p = This->window->redirect_time ? get_fetch_time(This) : 0; return S_OK; }
@@ -1647,7 +1657,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domainLookupStart(IHTMLPerforman
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); + *p = This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1657,8 +1667,8 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domainLookupEnd(IHTMLPerformance
TRACE("(%p)->(%p)\n", This, p);
- *p = This->connect_time ? This->connect_time : - This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); + *p = This->window->connect_time ? This->window->connect_time : + This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1668,8 +1678,8 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_connectStart(IHTMLPerformanceTim
TRACE("(%p)->(%p)\n", This, p);
- *p = This->connect_time ? This->connect_time : - This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); + *p = This->window->connect_time ? This->window->connect_time : + This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1679,9 +1689,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_connectEnd(IHTMLPerformanceTimin
TRACE("(%p)->(%p)\n", This, p);
- *p = This->request_time ? This->request_time : - This->connect_time ? This->connect_time : - This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); + *p = This->window->request_time ? This->window->request_time : + This->window->connect_time ? This->window->connect_time : + This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1691,9 +1701,9 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_requestStart(IHTMLPerformanceTim
TRACE("(%p)->(%p)\n", This, p);
- *p = This->request_time ? This->request_time : - This->connect_time ? This->connect_time : - This->dns_lookup_time ? This->dns_lookup_time : get_fetch_time(This); + *p = This->window->request_time ? This->window->request_time : + This->window->connect_time ? This->window->connect_time : + This->window->dns_lookup_time ? This->window->dns_lookup_time : get_fetch_time(This); return S_OK; }
@@ -1703,7 +1713,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_responseStart(IHTMLPerformanceTi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->response_start_time; + *p = This->window->response_start_time; return S_OK; }
@@ -1713,7 +1723,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_responseEnd(IHTMLPerformanceTimi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->response_end_time; + *p = This->window->response_end_time; return S_OK; }
@@ -1724,7 +1734,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domLoading(IHTMLPerformanceTimin TRACE("(%p)->(%p)\n", This, p);
/* Make sure this is after responseEnd, when the Gecko parser starts */ - *p = This->response_end_time; + *p = This->window->response_end_time; return S_OK; }
@@ -1734,7 +1744,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domInteractive(IHTMLPerformanceT
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dom_interactive_time; + *p = This->window->dom_interactive_time; return S_OK; }
@@ -1744,7 +1754,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domContentLoadedEventStart(IHTML
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dom_content_loaded_event_start_time; + *p = This->window->dom_content_loaded_event_start_time; return S_OK; }
@@ -1754,7 +1764,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domContentLoadedEventEnd(IHTMLPe
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dom_content_loaded_event_end_time; + *p = This->window->dom_content_loaded_event_end_time; return S_OK; }
@@ -1764,7 +1774,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_domComplete(IHTMLPerformanceTimi
TRACE("(%p)->(%p)\n", This, p);
- *p = This->dom_complete_time; + *p = This->window->dom_complete_time; return S_OK; }
@@ -1774,7 +1784,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_loadEventStart(IHTMLPerformanceT
TRACE("(%p)->(%p)\n", This, p);
- *p = This->load_event_start_time; + *p = This->window->load_event_start_time; return S_OK; }
@@ -1784,7 +1794,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_loadEventEnd(IHTMLPerformanceTim
TRACE("(%p)->(%p)\n", This, p);
- *p = This->load_event_end_time; + *p = This->window->load_event_end_time; return S_OK; }
@@ -1794,7 +1804,7 @@ static HRESULT WINAPI HTMLPerformanceTiming_get_msFirstPaint(IHTMLPerformanceTim
TRACE("(%p)->(%p)\n", This, p);
- *p = This->first_paint_time; + *p = This->window->first_paint_time; return S_OK; }
@@ -1858,22 +1868,6 @@ static dispex_static_data_t HTMLPerformanceTiming_dispex = { HTMLPerformanceTiming_iface_tids };
-HRESULT create_performance_timing(HTMLPerformanceTiming **ret) -{ - HTMLPerformanceTiming *timing; - - timing = calloc(1, sizeof(*timing)); - if(!timing) - return E_OUTOFMEMORY; - - timing->IHTMLPerformanceTiming_iface.lpVtbl = &HTMLPerformanceTimingVtbl; - timing->ref = 1; - - /* Defer initializing the dispex until it's actually needed (for compat mode) */ - *ret = timing; - return S_OK; -} - typedef struct { DispatchEx dispex; IHTMLPerformanceNavigation IHTMLPerformanceNavigation_iface; @@ -2039,7 +2033,7 @@ typedef struct {
HTMLInnerWindow *window; IHTMLPerformanceNavigation *navigation; - HTMLPerformanceTiming *timing; + IHTMLPerformanceTiming *timing; } HTMLPerformance;
static inline HTMLPerformance *impl_from_IHTMLPerformance(IHTMLPerformance *iface) @@ -2090,6 +2084,8 @@ static ULONG WINAPI HTMLPerformance_Release(IHTMLPerformance *iface) 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); } @@ -2167,7 +2163,25 @@ static HRESULT WINAPI HTMLPerformance_get_timing(IHTMLPerformance *iface, IHTMLP
TRACE("(%p)->(%p)\n", This, p);
- IHTMLPerformanceTiming_AddRef(*p = &This->timing->IHTMLPerformanceTiming_iface); + if(!This->timing) { + HTMLPerformanceTiming *timing; + + timing = calloc(1, sizeof(*timing)); + if(!timing) + return E_OUTOFMEMORY; + + timing->IHTMLPerformanceTiming_iface.lpVtbl = &HTMLPerformanceTimingVtbl; + timing->ref = 1; + timing->window = This->window; + IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface); + + init_dispatch(&timing->dispex, (IUnknown*)&timing->IHTMLPerformanceTiming_iface, + &HTMLPerformanceTiming_dispex, dispex_compat_mode(&This->dispex)); + + This->timing = &timing->IHTMLPerformanceTiming_iface; + } + + IHTMLPerformanceTiming_AddRef(*p = This->timing); return S_OK; }
@@ -2229,12 +2243,6 @@ HRESULT create_performance(HTMLInnerWindow *window, IHTMLPerformance **ret) init_dispatch(&performance->dispex, (IUnknown*)&performance->IHTMLPerformance_iface, &HTMLPerformance_dispex, compat_mode);
- performance->timing = window->performance_timing; - IHTMLPerformanceTiming_AddRef(&performance->timing->IHTMLPerformanceTiming_iface); - - init_dispatch(&performance->timing->dispex, (IUnknown*)&performance->timing->IHTMLPerformanceTiming_iface, - &HTMLPerformanceTiming_dispex, compat_mode); - *ret = &performance->IHTMLPerformance_iface; return S_OK; } diff --git a/dlls/mshtml/view.c b/dlls/mshtml/view.c index 3f31e609e39..c6b9d8fa576 100644 --- a/dlls/mshtml/view.c +++ b/dlls/mshtml/view.c @@ -50,8 +50,8 @@ static void paint_document(HTMLDocumentObj *This) RECT rect; HDC hdc;
- if(This->window && This->window->base.inner_window && !This->window->base.inner_window->performance_timing->first_paint_time) - This->window->base.inner_window->performance_timing->first_paint_time = get_time_stamp(); + if(This->window && This->window->base.inner_window && !This->window->base.inner_window->first_paint_time) + This->window->base.inner_window->first_paint_time = get_time_stamp();
GetClientRect(This->hwnd, &rect);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmllocation.c | 50 +++++++++++++++++++++++++----------- dlls/mshtml/htmlwindow.c | 32 +++++++++++++++-------- dlls/mshtml/mshtml_private.h | 8 ++++-- 3 files changed, 62 insertions(+), 28 deletions(-)
diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index d9e458d9c5f..c361df7d85e 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -36,19 +36,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
-static inline HTMLOuterWindow *get_window(HTMLLocation *This) -{ - return CONTAINING_RECORD(This, HTMLOuterWindow, location); -} - static IUri *get_uri(HTMLLocation *This) { - return get_window(This)->uri; + return This->window->uri; }
static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url) { - const WCHAR *doc_url = get_window(This)->url ? get_window(This)->url : L"about:blank"; + const WCHAR *doc_url = This->window->url ? This->window->url : L"about:blank";
if(!InternetCrackUrlW(doc_url, 0, 0, url)) { FIXME("InternetCrackUrlW failed: 0x%08lx\n", GetLastError()); @@ -93,13 +88,27 @@ static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID r static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - return IHTMLWindow2_AddRef(&get_window(This)->base.IHTMLWindow2_iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + return ref; }
static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - return IHTMLWindow2_Release(&get_window(This)->base.IHTMLWindow2_iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + if(!ref) { + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + release_dispex(&This->dispex); + free(This); + } + + return ref; }
static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo) @@ -139,7 +148,7 @@ static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- return navigate_url(get_window(This), v, get_uri(This), BINDING_NAVIGATED); + return navigate_url(This->window, v, get_uri(This), BINDING_NAVIGATED); }
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p) @@ -500,7 +509,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) memcpy(hash + 1, v, size - sizeof(WCHAR)); }
- hres = navigate_url(get_window(This), hash, get_uri(This), BINDING_NAVIGATED); + hres = navigate_url(This->window, hash, get_uri(This), BINDING_NAVIGATED);
if(hash != v) free(hash); @@ -544,12 +553,12 @@ static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL fla TRACE("(%p)->(%x)\n", This, flag);
/* reload is supposed to fail if called from a script with different origin, but IE doesn't care */ - if(!is_main_content_window(get_window(This))) { + if(!is_main_content_window(This->window)) { FIXME("Unsupported on iframe\n"); return E_NOTIMPL; }
- return reload_page(get_window(This)); + return reload_page(This->window); }
static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr) @@ -558,7 +567,7 @@ static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
TRACE("(%p)->(%s)\n", This, debugstr_w(bstr));
- return navigate_url(get_window(This), bstr, get_uri(This), BINDING_NAVIGATED | BINDING_REPLACE); + return navigate_url(This->window, bstr, get_uri(This), BINDING_NAVIGATED | BINDING_REPLACE); }
static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr) @@ -618,10 +627,21 @@ static dispex_static_data_t HTMLLocation_dispex = { HTMLLocation_iface_tids };
-void HTMLLocation_Init(HTMLLocation *location) +HRESULT create_location(HTMLOuterWindow *window, HTMLLocation **ret) { + HTMLLocation *location; + + if(!(location = calloc(1, sizeof(*location)))) + return E_OUTOFMEMORY; + location->IHTMLLocation_iface.lpVtbl = &HTMLLocationVtbl; + location->ref = 1; + location->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&location->dispex, (IUnknown*)&location->IHTMLLocation_iface, &HTMLLocation_dispex, COMPAT_MODE_QUIRKS); + + *ret = location; + return S_OK; } diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c2e5b10b90a..ff9c5622ec7 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -67,13 +67,17 @@ static inline BOOL is_outer_window(HTMLWindow *window) return &window->outer_window->base == window; }
-static void get_location(HTMLOuterWindow *This, HTMLLocation **ret) +static HRESULT get_location(HTMLOuterWindow *This, HTMLLocation **ret) { - if(!This->location.dispex.outer) - HTMLLocation_Init(&This->location); + if(!This->location) { + HRESULT hres = create_location(This, &This->location); + if(FAILED(hres)) + return hres; + }
- IHTMLLocation_AddRef(&This->location.IHTMLLocation_iface); - *ret = &This->location; + IHTMLLocation_AddRef(&This->location->IHTMLLocation_iface); + *ret = This->location; + return S_OK; }
void get_top_window(HTMLOuterWindow *window, HTMLOuterWindow **ret) @@ -127,8 +131,8 @@ static void detach_inner_window(HTMLInnerWindow *window) if(doc) detach_document_node(doc);
- if(outer_window && outer_window->location.dispex.outer) - dispex_unlink(&outer_window->location.dispex); + if(outer_window && outer_window->location) + dispex_unlink(&outer_window->location->dispex);
abort_window_bindings(window); remove_target_tasks(window->task_magic); @@ -234,8 +238,8 @@ static void release_outer_window(HTMLOuterWindow *This) if(This->base.inner_window) detach_inner_window(This->base.inner_window);
- if(This->location.dispex.outer) - release_dispex(&This->location.dispex); + if(This->location) + IHTMLLocation_Release(&This->location->IHTMLLocation_iface);
if(This->frame_element) This->frame_element->content_window = NULL; @@ -799,10 +803,14 @@ static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocatio { HTMLWindow *This = impl_from_IHTMLWindow2(iface); HTMLLocation *location; + HRESULT hres;
TRACE("(%p)->(%p)\n", This, p);
- get_location(This->outer_window, &location); + hres = get_location(This->outer_window, &location); + if(FAILED(hres)) + return hres; + *p = &location->IHTMLLocation_iface; return S_OK; } @@ -3920,7 +3928,9 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA
TRACE("forwarding to location.href\n");
- get_location(This->base.outer_window, &location); + hres = get_location(This->base.outer_window, &location); + if(FAILED(hres)) + return hres;
hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller); IHTMLLocation_Release(&location->IHTMLLocation_iface); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 87c3c062483..7987f964ef9 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -491,6 +491,10 @@ typedef struct { struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface; + + LONG ref; + + HTMLOuterWindow *window; };
typedef struct { @@ -546,7 +550,7 @@ struct HTMLOuterWindow { BOOL readystate_pending;
HTMLInnerWindow *pending_window; - HTMLLocation location; + HTMLLocation *location; IMoniker *mon; IUri *uri; IUri *uri_nofrag; @@ -982,7 +986,7 @@ void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**); HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**); HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,HTMLImageElementFactory**); HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFactory**); -void HTMLLocation_Init(HTMLLocation*); +HRESULT create_location(HTMLOuterWindow*,HTMLLocation**); HRESULT create_navigator(compat_mode_t,IOmNavigator**); HRESULT create_html_screen(compat_mode_t,IHTMLScreen**); HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 170 ++++++++++++++++++++++++----------- dlls/mshtml/mshtml_private.h | 3 +- dlls/mshtml/nsembed.c | 1 + dlls/mshtml/persist.c | 3 +- 4 files changed, 125 insertions(+), 52 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index ff9c5622ec7..55a2488155e 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -45,6 +45,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+static ExternalCycleCollectionParticipant window_ccp; + static int window_map_compare(const void *key, const struct wine_rb_entry *entry) { HTMLOuterWindow *window = WINE_RB_ENTRY_VALUE(entry, HTMLOuterWindow, entry); @@ -198,9 +200,12 @@ static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID rii *ppv = NULL; FIXME("(%p)->(IID_IMarshal %p)\n", This, ppv); return E_NOINTERFACE; - }else if(dispex_query_interface(&This->inner_window->event_target.dispex, riid, ppv)) { - assert(!*ppv); - return E_NOINTERFACE; + }else if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) { + *ppv = &window_ccp; + return S_OK; + }else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) { + *ppv = &This->IHTMLWindow2_iface; + return S_OK; }else { return EventTarget_QI(&This->inner_window->event_target, riid, ppv); } @@ -212,47 +217,13 @@ static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID rii static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface) { HTMLWindow *This = impl_from_IHTMLWindow2(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = ccref_incr(&This->ccref, (nsISupports*)&This->IHTMLWindow2_iface);
TRACE("(%p) ref=%ld\n", This, ref);
return ref; }
-static void release_outer_window(HTMLOuterWindow *This) -{ - if(This->browser) { - list_remove(&This->browser_entry); - This->browser = NULL; - } - - if(This->pending_window) { - abort_window_bindings(This->pending_window); - This->pending_window->base.outer_window = NULL; - IHTMLWindow2_Release(&This->pending_window->base.IHTMLWindow2_iface); - } - - remove_target_tasks(This->task_magic); - set_current_mon(This, NULL, 0); - set_current_uri(This, NULL); - if(This->base.inner_window) - detach_inner_window(This->base.inner_window); - - if(This->location) - IHTMLLocation_Release(&This->location->IHTMLLocation_iface); - - if(This->frame_element) - This->frame_element->content_window = NULL; - - if(This->nswindow) - nsIDOMWindow_Release(This->nswindow); - if(This->window_proxy) - mozIDOMWindowProxy_Release(This->window_proxy); - - wine_rb_remove(&window_map, &This->entry); - free(This); -} - static void release_inner_window(HTMLInnerWindow *This) { unsigned i; @@ -318,20 +289,10 @@ static void release_inner_window(HTMLInnerWindow *This) static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface) { HTMLWindow *This = impl_from_IHTMLWindow2(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = ccref_decr(&This->ccref, (nsISupports*)&This->IHTMLWindow2_iface, &window_ccp);
TRACE("(%p) ref=%ld\n", This, ref);
- if(!ref) { - if (This->console) - IWineMSHTMLConsole_Release(This->console); - - if(is_outer_window(This)) - release_outer_window(This->outer_window); - else - release_inner_window(This->inner_window); - } - return ref; }
@@ -4036,6 +3997,115 @@ static dispex_static_data_t HTMLWindow_dispex = { HTMLWindow_init_dispex_info };
+static nsresult NSAPI window_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb) +{ + HTMLWindow *This = impl_from_IHTMLWindow2(p); + HTMLOuterWindow *window; + + if(!is_outer_window(This)) { + /* FIXME: Traverse inner window and its dispex */ + return NS_OK; + } + window = This->outer_window; + + describe_cc_node(&window->base.ccref, "OuterWindow", cb); + + if(window->base.console) + note_cc_edge((nsISupports*)window->base.console, "console", cb); + if(window->pending_window) + note_cc_edge((nsISupports*)&window->pending_window->base.IHTMLWindow2_iface, "pending_window", cb); + if(window->base.inner_window) + note_cc_edge((nsISupports*)&window->base.inner_window->base.IHTMLWindow2_iface, "inner_window", cb); + if(window->location) + note_cc_edge((nsISupports*)&window->location->IHTMLLocation_iface, "location", cb); + if(window->nswindow) + note_cc_edge((nsISupports*)window->nswindow, "nswindow", cb); + if(window->window_proxy) + note_cc_edge((nsISupports*)window->window_proxy, "window_proxy", cb); + return NS_OK; +} + +static nsresult NSAPI window_unlink(void *p) +{ + HTMLWindow *This = impl_from_IHTMLWindow2(p); + HTMLOuterWindow *window; + + if(This->console) { + IWineMSHTMLConsole *console = This->console; + This->console = NULL; + IWineMSHTMLConsole_Release(console); + } + + if(!is_outer_window(This)) { + /* FIXME: Unlink inner window and its dispex */ + return NS_OK; + } + window = This->outer_window; + + remove_target_tasks(window->task_magic); + if(window->browser) { + list_remove(&window->browser_entry); + window->browser = NULL; + } + if(window->pending_window) { + HTMLInnerWindow *pending_window = window->pending_window; + abort_window_bindings(pending_window); + pending_window->base.outer_window = NULL; + window->pending_window = NULL; + IHTMLWindow2_Release(&pending_window->base.IHTMLWindow2_iface); + } + + set_current_mon(window, NULL, 0); + set_current_uri(window, NULL); + if(window->base.inner_window) + detach_inner_window(window->base.inner_window); + if(window->location) { + HTMLLocation *location = window->location; + window->location = NULL; + IHTMLLocation_Release(&location->IHTMLLocation_iface); + } + if(window->frame_element) { + window->frame_element->content_window = NULL; + window->frame_element = NULL; + } + if(window->nswindow) { + nsIDOMWindow *nswindow = window->nswindow; + window->nswindow = NULL; + nsIDOMWindow_Release(nswindow); + } + if(window->window_proxy) { + mozIDOMWindowProxy *window_proxy = window->window_proxy; + window->window_proxy = NULL; + mozIDOMWindowProxy_Release(window_proxy); + + wine_rb_remove(&window_map, &window->entry); + } + return NS_OK; +} + +static void NSAPI window_delete_cycle_collectable(void *p) +{ + HTMLWindow *This = impl_from_IHTMLWindow2(p); + window_unlink(p); + + if(!is_outer_window(This)) { + release_inner_window(This->inner_window); + return; + } + + free(This->outer_window); +} + +void init_window_cc(void) +{ + static const CCObjCallback ccp_callback = { + window_traverse, + window_unlink, + window_delete_cycle_collectable + }; + ccp_init(&window_ccp, &ccp_callback); +} + static void *alloc_window(size_t size) { HTMLWindow *window; @@ -4058,7 +4128,7 @@ static void *alloc_window(size_t size) window->IProvideMultipleClassInfo_iface.lpVtbl = &ProvideMultipleClassInfoVtbl; window->IWineHTMLWindowPrivate_iface.lpVtbl = &WineHTMLWindowPrivateVtbl; window->IWineHTMLWindowCompatPrivate_iface.lpVtbl = &WineHTMLWindowCompatPrivateVtbl; - window->ref = 1; + ccref_init(&window->ccref, 1);
return window; } diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 7987f964ef9..3a05528d97c 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -526,7 +526,7 @@ struct HTMLWindow {
IWineMSHTMLConsole *console;
- LONG ref; + nsCycleCollectingAutoRefCnt ccref;
HTMLInnerWindow *inner_window; HTMLOuterWindow *outer_window; @@ -1047,6 +1047,7 @@ BOOL is_gecko_path(const char*); void set_viewer_zoom(GeckoBrowser*,float); float get_viewer_zoom(GeckoBrowser*);
+void init_window_cc(void); void init_node_cc(void);
HRESULT nsuri_to_url(LPCWSTR,BOOL,BSTR*); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 95c07c90390..3e300d4e3e8 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_window_cc(); init_node_cc();
return TRUE; diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index b1ec172f912..4c3996471b3 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -474,7 +474,8 @@ static void notif_readystate(HTMLOuterWindow *window)
static void notif_readystate_proc(event_task_t *task) { - notif_readystate(task->window->base.outer_window); + if(task->window->base.outer_window) + notif_readystate(task->window->base.outer_window); }
static void notif_readystate_destr(event_task_t *task)
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,
From: Gabriel Ivăncescu gabrielopcode@gmail.com
And get rid of the destroy method. This especially simplifies it when traversal and unlinking is implemented.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 124 +++++++++++++++++++++++++++------------- dlls/mshtml/htmlevent.h | 1 - 2 files changed, 83 insertions(+), 42 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 5d38188d289..f36bcc977cc 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -1241,8 +1241,6 @@ static inline DOMEvent *DOMEvent_from_DispatchEx(DispatchEx *iface) 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); @@ -1398,10 +1396,21 @@ static void *DOMUIEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMUIEvent_destroy(DOMEvent *event) +static void DOMUIEvent_unlink(DispatchEx *dispex) { - DOMUIEvent *This = DOMUIEvent_from_DOMEvent(event); - nsIDOMUIEvent_Release(This->nsevent); + DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + if(This->nsevent) { + nsIDOMUIEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMUIEvent_Release(nsevent); + } +} + +static void DOMUIEvent_destructor(DispatchEx *dispex) +{ + DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMUIEvent_unlink(&This->event.dispex); + DOMEvent_destructor(dispex); }
typedef struct { @@ -1929,11 +1938,12 @@ static void *DOMMouseEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMMouseEvent_destroy(DOMEvent *event) +static void DOMMouseEvent_destructor(DispatchEx *dispex) { - DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(event); - DOMUIEvent_destroy(&This->ui_event.event); + DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMUIEvent_unlink(&This->ui_event.event.dispex); nsIDOMMouseEvent_Release(This->nsevent); + DOMEvent_destructor(dispex); }
typedef struct { @@ -2228,11 +2238,12 @@ static void *DOMKeyboardEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMKeyboardEvent_destroy(DOMEvent *event) +static void DOMKeyboardEvent_destructor(DispatchEx *dispex) { - DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(event); - DOMUIEvent_destroy(&This->ui_event.event); + DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMUIEvent_unlink(&This->ui_event.event.dispex); nsIDOMKeyEvent_Release(This->nsevent); + DOMEvent_destructor(dispex); }
typedef struct { @@ -2436,10 +2447,11 @@ static void *DOMCustomEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMCustomEvent_destroy(DOMEvent *event) +static void DOMCustomEvent_destructor(DispatchEx *dispex) { - DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(event); + DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); VariantClear(&custom_event->detail); + DOMEvent_destructor(dispex); }
typedef struct { @@ -2580,10 +2592,11 @@ static void *DOMMessageEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMMessageEvent_destroy(DOMEvent *event) +static void DOMMessageEvent_destructor(DispatchEx *dispex) { - DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(event); + DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); VariantClear(&message_event->data); + DOMEvent_destructor(dispex); }
static void DOMMessageEvent_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) @@ -2753,10 +2766,11 @@ static void *DOMProgressEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMProgressEvent_destroy(DOMEvent *event) +static void DOMProgressEvent_destructor(DispatchEx *dispex) { - DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(event); + DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); nsIDOMProgressEvent_Release(This->nsevent); + DOMEvent_destructor(dispex); }
typedef struct { @@ -2915,13 +2929,14 @@ static void *DOMStorageEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMStorageEvent_destroy(DOMEvent *event) +static void DOMStorageEvent_destructor(DispatchEx *dispex) { - DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(event); + DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); SysFreeString(storage_event->key); SysFreeString(storage_event->old_value); SysFreeString(storage_event->new_value); SysFreeString(storage_event->url); + DOMEvent_destructor(dispex); }
static const dispex_static_data_vtbl_t DOMEvent_dispex_vtbl = { @@ -2940,6 +2955,10 @@ static dispex_static_data_t DOMEvent_dispex = { DOMEvent_iface_tids };
+static const dispex_static_data_vtbl_t DOMUIEvent_dispex_vtbl = { + DOMUIEvent_destructor, +}; + static const tid_t DOMUIEvent_iface_tids[] = { IDOMEvent_tid, IDOMUIEvent_tid, @@ -2948,11 +2967,15 @@ static const tid_t DOMUIEvent_iface_tids[] = {
static dispex_static_data_t DOMUIEvent_dispex = { L"UIEvent", - &DOMEvent_dispex_vtbl, + &DOMUIEvent_dispex_vtbl, DispDOMUIEvent_tid, DOMUIEvent_iface_tids };
+static const dispex_static_data_vtbl_t DOMMouseEvent_dispex_vtbl = { + DOMMouseEvent_destructor, +}; + static const tid_t DOMMouseEvent_iface_tids[] = { IDOMEvent_tid, IDOMUIEvent_tid, @@ -2962,11 +2985,15 @@ static const tid_t DOMMouseEvent_iface_tids[] = {
static dispex_static_data_t DOMMouseEvent_dispex = { L"MouseEvent", - &DOMEvent_dispex_vtbl, + &DOMMouseEvent_dispex_vtbl, DispDOMMouseEvent_tid, DOMMouseEvent_iface_tids };
+static const dispex_static_data_vtbl_t DOMKeyboardEvent_dispex_vtbl = { + DOMKeyboardEvent_destructor, +}; + static const tid_t DOMKeyboardEvent_iface_tids[] = { IDOMEvent_tid, IDOMUIEvent_tid, @@ -2976,7 +3003,7 @@ static const tid_t DOMKeyboardEvent_iface_tids[] = {
static dispex_static_data_t DOMKeyboardEvent_dispex = { L"KeyboardEvent", - &DOMEvent_dispex_vtbl, + &DOMKeyboardEvent_dispex_vtbl, DispDOMKeyboardEvent_tid, DOMKeyboardEvent_iface_tids }; @@ -2987,7 +3014,7 @@ static void DOMPageTransitionEvent_init_dispex_info(dispex_data_t *info, compat_ dispex_info_add_interface(info, IWinePageTransitionEvent_tid, NULL); }
-dispex_static_data_t DOMPageTransitionEvent_dispex = { +static dispex_static_data_t DOMPageTransitionEvent_dispex = { L"PageTransitionEvent", &DOMEvent_dispex_vtbl, DispDOMEvent_tid, @@ -2995,6 +3022,10 @@ dispex_static_data_t DOMPageTransitionEvent_dispex = { DOMPageTransitionEvent_init_dispex_info };
+static const dispex_static_data_vtbl_t DOMCustomEvent_dispex_vtbl = { + DOMCustomEvent_destructor, +}; + static const tid_t DOMCustomEvent_iface_tids[] = { IDOMEvent_tid, IDOMCustomEvent_tid, @@ -3003,52 +3034,64 @@ static const tid_t DOMCustomEvent_iface_tids[] = {
static dispex_static_data_t DOMCustomEvent_dispex = { L"CustomEvent", - &DOMEvent_dispex_vtbl, + &DOMCustomEvent_dispex_vtbl, DispDOMCustomEvent_tid, DOMCustomEvent_iface_tids };
+static const dispex_static_data_vtbl_t DOMMessageEvent_dispex_vtbl = { + DOMMessageEvent_destructor, +}; + static const tid_t DOMMessageEvent_iface_tids[] = { IDOMEvent_tid, 0 };
-dispex_static_data_t DOMMessageEvent_dispex = { +static dispex_static_data_t DOMMessageEvent_dispex = { L"MessageEvent", - &DOMEvent_dispex_vtbl, + &DOMMessageEvent_dispex_vtbl, DispDOMMessageEvent_tid, DOMMessageEvent_iface_tids, DOMMessageEvent_init_dispex_info };
+static const dispex_static_data_vtbl_t DOMProgressEvent_dispex_vtbl = { + DOMProgressEvent_destructor, +}; + static const tid_t DOMProgressEvent_iface_tids[] = { IDOMEvent_tid, IDOMProgressEvent_tid, 0 };
-dispex_static_data_t DOMProgressEvent_dispex = { +static dispex_static_data_t DOMProgressEvent_dispex = { L"ProgressEvent", - &DOMEvent_dispex_vtbl, + &DOMProgressEvent_dispex_vtbl, DispDOMProgressEvent_tid, DOMProgressEvent_iface_tids };
+static const dispex_static_data_vtbl_t DOMStorageEvent_dispex_vtbl = { + DOMStorageEvent_destructor, +}; + static const tid_t DOMStorageEvent_iface_tids[] = { IDOMEvent_tid, IDOMStorageEvent_tid, 0 };
-dispex_static_data_t DOMStorageEvent_dispex = { +static dispex_static_data_t DOMStorageEvent_dispex = { L"StorageEvent", - &DOMEvent_dispex_vtbl, + &DOMStorageEvent_dispex_vtbl, DispDOMStorageEvent_tid, DOMStorageEvent_iface_tids };
static void *event_ctor(unsigned size, dispex_static_data_t *dispex_data, void *(*query_interface)(DOMEvent*,REFIID), - void (*destroy)(DOMEvent*), nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) + nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMEvent *event = calloc(1, size);
@@ -3056,7 +3099,6 @@ static void *event_ctor(unsigned size, dispex_static_data_t *dispex_data, void * return NULL; event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; event->query_interface = query_interface; - event->destroy = destroy; event->event_id = event_id; if(event_id != EVENTID_LAST) { event->type = wcsdup(event_info[event_id].name); @@ -3084,13 +3126,13 @@ static void fill_parent_ui_event(nsIDOMEvent *nsevent, DOMUIEvent *ui_event)
static DOMEvent *generic_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { - return event_ctor(sizeof(DOMEvent), &DOMEvent_dispex, NULL, NULL, nsevent, event_id, compat_mode); + return event_ctor(sizeof(DOMEvent), &DOMEvent_dispex, NULL, nsevent, event_id, compat_mode); }
static DOMEvent *ui_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMUIEvent *ui_event = event_ctor(sizeof(DOMUIEvent), &DOMUIEvent_dispex, - DOMUIEvent_query_interface, DOMUIEvent_destroy, nsevent, event_id, compat_mode); + DOMUIEvent_query_interface, nsevent, event_id, compat_mode); if(!ui_event) return NULL; ui_event->IDOMUIEvent_iface.lpVtbl = &DOMUIEventVtbl; ui_event->nsevent = iface; @@ -3100,7 +3142,7 @@ static DOMEvent *ui_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t even static DOMEvent *mouse_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMMouseEvent *mouse_event = event_ctor(sizeof(DOMMouseEvent), &DOMMouseEvent_dispex, - DOMMouseEvent_query_interface, DOMMouseEvent_destroy, nsevent, event_id, compat_mode); + DOMMouseEvent_query_interface, nsevent, event_id, compat_mode); if(!mouse_event) return NULL; mouse_event->IDOMMouseEvent_iface.lpVtbl = &DOMMouseEventVtbl; mouse_event->nsevent = iface; @@ -3111,7 +3153,7 @@ static DOMEvent *mouse_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t e static DOMEvent *keyboard_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMKeyboardEvent *keyboard_event = event_ctor(sizeof(DOMKeyboardEvent), &DOMKeyboardEvent_dispex, - DOMKeyboardEvent_query_interface, DOMKeyboardEvent_destroy, nsevent, event_id, compat_mode); + DOMKeyboardEvent_query_interface, nsevent, event_id, compat_mode); if(!keyboard_event) return NULL; keyboard_event->IDOMKeyboardEvent_iface.lpVtbl = &DOMKeyboardEventVtbl; keyboard_event->nsevent = iface; @@ -3122,7 +3164,7 @@ static DOMEvent *keyboard_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_ static DOMEvent *page_transition_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMPageTransitionEvent *page_transition_event = event_ctor(sizeof(DOMCustomEvent), &DOMPageTransitionEvent_dispex, - DOMPageTransitionEvent_query_interface, NULL, nsevent, event_id, compat_mode); + DOMPageTransitionEvent_query_interface, nsevent, event_id, compat_mode); if(!page_transition_event) return NULL; page_transition_event->IWinePageTransitionEvent_iface.lpVtbl = &DOMPageTransitionEventVtbl; return &page_transition_event->event; @@ -3131,7 +3173,7 @@ static DOMEvent *page_transition_event_ctor(void *iface, nsIDOMEvent *nsevent, e static DOMEvent *custom_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMCustomEvent *custom_event = event_ctor(sizeof(DOMCustomEvent), &DOMCustomEvent_dispex, - DOMCustomEvent_query_interface, DOMCustomEvent_destroy, nsevent, event_id, compat_mode); + DOMCustomEvent_query_interface, nsevent, event_id, compat_mode); if(!custom_event) return NULL; custom_event->IDOMCustomEvent_iface.lpVtbl = &DOMCustomEventVtbl; nsIDOMCustomEvent_Release(iface); @@ -3143,7 +3185,7 @@ static DOMEvent *progress_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_ DOMProgressEvent *progress_event;
if(!(progress_event = event_ctor(sizeof(DOMProgressEvent), &DOMProgressEvent_dispex, - DOMProgressEvent_query_interface, DOMProgressEvent_destroy, nsevent, event_id, compat_mode))) + DOMProgressEvent_query_interface, nsevent, event_id, compat_mode))) return NULL; progress_event->IDOMProgressEvent_iface.lpVtbl = &DOMProgressEventVtbl; progress_event->nsevent = iface; @@ -3153,7 +3195,7 @@ static DOMEvent *progress_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_ static DOMEvent *message_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMMessageEvent *message_event = event_ctor(sizeof(DOMMessageEvent), &DOMMessageEvent_dispex, - DOMMessageEvent_query_interface, DOMMessageEvent_destroy, nsevent, event_id, compat_mode); + DOMMessageEvent_query_interface, nsevent, event_id, compat_mode); if(!message_event) return NULL; message_event->IDOMMessageEvent_iface.lpVtbl = &DOMMessageEventVtbl; return &message_event->event; @@ -3162,7 +3204,7 @@ static DOMEvent *message_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t static DOMEvent *storage_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMStorageEvent *storage_event = event_ctor(sizeof(DOMStorageEvent), &DOMStorageEvent_dispex, - DOMStorageEvent_query_interface, DOMStorageEvent_destroy, nsevent, event_id, compat_mode); + DOMStorageEvent_query_interface, nsevent, event_id, compat_mode); if(!storage_event) return NULL; storage_event->IDOMStorageEvent_iface.lpVtbl = &DOMStorageEventVtbl; return &storage_event->event; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 8b8c06999a1..d3a35c883dd 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -78,7 +78,6 @@ typedef struct DOMEvent {
nsCycleCollectingAutoRefCnt ccref; void *(*query_interface)(struct DOMEvent*,REFIID); - void (*destroy)(struct DOMEvent*);
nsIDOMEvent *nsevent;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 28 +++- dlls/mshtml/htmlattr.c | 18 ++- dlls/mshtml/htmldoc.c | 20 +++ dlls/mshtml/htmlelem.c | 108 ++++++++++++++- dlls/mshtml/htmlelemcol.c | 27 +++- dlls/mshtml/htmlevent.c | 201 +++++++++++++++++++++++----- dlls/mshtml/htmlimg.c | 12 ++ dlls/mshtml/htmllocation.c | 22 +++- dlls/mshtml/htmlnode.c | 32 ++++- dlls/mshtml/htmlselect.c | 12 ++ dlls/mshtml/htmlstorage.c | 12 ++ dlls/mshtml/htmlstyle.c | 23 +++- dlls/mshtml/htmlstylesheet.c | 92 +++++++++++-- dlls/mshtml/htmltextnode.c | 10 ++ dlls/mshtml/htmlwindow.c | 123 ++++++++++++----- dlls/mshtml/mshtml_private.h | 6 +- dlls/mshtml/omnavigator.c | 247 ++++++++++++++++++++++++++++++++--- dlls/mshtml/range.c | 50 ++++++- dlls/mshtml/selection.c | 27 +++- dlls/mshtml/xmlhttprequest.c | 59 ++++++++- 20 files changed, 1003 insertions(+), 126 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index d23c37650c1..833dcac504d 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -842,6 +842,16 @@ static inline func_disp_t *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, func_disp_t, dispex); }
+static void function_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + func_disp_t *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "func_disp", cb); +} + +static void function_unlink(DispatchEx *dispex) +{ +} + static void function_destructor(DispatchEx *dispex) { func_disp_t *This = impl_from_DispatchEx(dispex); @@ -906,6 +916,8 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
static const dispex_static_data_vtbl_t function_dispex_vtbl = { function_destructor, + function_traverse, + function_unlink, function_value, NULL, NULL, @@ -2006,6 +2018,8 @@ nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTraversalCal DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop;
+ This->info->desc->vtbl->traverse(This, cb); + if(!This->dynamic_data) return NS_OK;
@@ -2029,13 +2043,12 @@ nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTraversalCal return NS_OK; }
-nsresult NSAPI dispex_unlink(void *p) +void dispex_props_unlink(DispatchEx *This) { - DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop;
if(!This->dynamic_data) - return NS_OK; + return;
for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) { VariantClear(&prop->var); @@ -2056,7 +2069,14 @@ nsresult NSAPI dispex_unlink(void *p) free(This->dynamic_data->func_disps); This->dynamic_data->func_disps = NULL; } +}
+nsresult NSAPI dispex_unlink(void *p) +{ + DispatchEx *This = impl_from_IDispatchEx(p); + + This->info->desc->vtbl->unlink(This); + dispex_props_unlink(This); return NS_OK; }
@@ -2065,6 +2085,8 @@ void NSAPI dispex_delete_cycle_collectable(void *p) DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop;
+ This->info->desc->vtbl->unlink(This); + if(!This->dynamic_data) goto destructor;
diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c index 000e178046e..5fff115a551 100644 --- a/dlls/mshtml/htmlattr.c +++ b/dlls/mshtml/htmlattr.c @@ -477,17 +477,33 @@ static inline HTMLDOMAttribute *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMAttribute, dispex); }
+static void HTMLDOMAttribute_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMAttribute *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMAttribute", cb); + + if(V_VT(&This->value) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&This->value), "value", cb); +} + +static void HTMLDOMAttribute_unlink(DispatchEx *dispex) +{ + HTMLDOMAttribute *This = impl_from_DispatchEx(dispex); + VariantClear(&This->value); +} + 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, + HTMLDOMAttribute_traverse, + HTMLDOMAttribute_unlink };
static const tid_t HTMLDOMAttribute_iface_tids[] = { diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index d40d3c4e799..79ad9752a1a 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -295,6 +295,14 @@ static inline DocumentType *DocumentType_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, DocumentType, node.event_target.dispex); }
+static void DocumentType_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void DocumentType_unlink(DispatchEx *dispex) +{ +} + static void DocumentType_dispex_destructor(DispatchEx *dispex) { } @@ -372,6 +380,8 @@ static IHTMLEventObj *DocumentType_set_current_event(DispatchEx *dispex, IHTMLEv static event_target_vtbl_t DocumentType_event_target_vtbl = { { DocumentType_dispex_destructor, + DocumentType_traverse, + DocumentType_unlink }, DocumentType_get_gecko_target, NULL, @@ -5929,6 +5939,14 @@ static inline HTMLDocumentNode *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDocumentNode, node.event_target.dispex); }
+static void HTMLDocumentNode_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDocumentNode_dispex_unlink(DispatchEx *dispex) +{ +} + static void HTMLDocumentNode_dispex_destructor(DispatchEx *dispex) { } @@ -6105,6 +6123,8 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { { HTMLDocumentNode_dispex_destructor, + HTMLDocumentNode_traverse, + HTMLDocumentNode_dispex_unlink, NULL, NULL, HTMLDocumentNode_get_name, diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 5545d8b91a5..76781cc1e35 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -839,11 +839,28 @@ static inline HTMLRect *HTMLRect_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLRect, dispex); }
-static void HTMLRect_destructor(DispatchEx *dispex) +static void HTMLRect_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLRect *This = HTMLRect_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ClientRect", cb); + if(This->nsrect) - nsIDOMClientRect_Release(This->nsrect); + note_cc_edge((nsISupports*)This->nsrect, "nsrect", cb); +} + +static void HTMLRect_unlink(DispatchEx *dispex) +{ + HTMLRect *This = HTMLRect_from_DispatchEx(dispex); + if(This->nsrect) { + nsIDOMClientRect *nsrect = This->nsrect; + This->nsrect = NULL; + nsIDOMClientRect_Release(nsrect); + } +} + +static void HTMLRect_destructor(DispatchEx *dispex) +{ + HTMLRect *This = HTMLRect_from_DispatchEx(dispex); free(This); }
@@ -855,6 +872,8 @@ void HTMLRect_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
static const dispex_static_data_vtbl_t HTMLRect_dispex_vtbl = { HTMLRect_destructor, + HTMLRect_traverse, + HTMLRect_unlink };
static const tid_t HTMLRect_iface_tids[] = { @@ -1197,11 +1216,28 @@ static inline HTMLRectCollection *HTMLRectCollection_from_DispatchEx(DispatchEx return CONTAINING_RECORD(iface, HTMLRectCollection, dispex); }
-static void HTMLRectCollection_destructor(DispatchEx *dispex) +static void HTMLRectCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ClientRectCollection", cb); + if(This->rect_list) - nsIDOMClientRectList_Release(This->rect_list); + note_cc_edge((nsISupports*)This->rect_list, "rect_list", cb); +} + +static void HTMLRectCollection_unlink(DispatchEx *dispex) +{ + HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); + if(This->rect_list) { + nsIDOMClientRectList *rect_list = This->rect_list; + This->rect_list = NULL; + nsIDOMClientRectList_Release(rect_list); + } +} + +static void HTMLRectCollection_destructor(DispatchEx *dispex) +{ + HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); free(This); }
@@ -1281,6 +1317,8 @@ static HRESULT HTMLRectCollection_invoke(DispatchEx *dispex, DISPID id, LCID lci
static const dispex_static_data_vtbl_t HTMLRectCollection_dispex_vtbl = { HTMLRectCollection_destructor, + HTMLRectCollection_traverse, + HTMLRectCollection_unlink, NULL, HTMLRectCollection_get_dispid, HTMLRectCollection_get_name, @@ -6945,6 +6983,14 @@ static inline HTMLElement *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLElement, node.event_target.dispex); }
+static void HTMLElement_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLElement_unlink(DispatchEx *dispex) +{ +} + static void HTMLElement_dispex_destructor(DispatchEx *dispex) { } @@ -7345,6 +7391,8 @@ static const tid_t HTMLElement_iface_tids[] = { const event_target_vtbl_t HTMLElement_event_target_vtbl = { { HTMLElement_dispex_destructor, + HTMLElement_traverse, + HTMLElement_unlink, NULL, HTMLElement_get_dispid, HTMLElement_get_name, @@ -7731,10 +7779,28 @@ static inline struct token_list *token_list_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, struct token_list, dispex); }
+static void token_list_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct token_list *token_list = token_list_from_DispatchEx(dispex); + describe_cc_node(&token_list->ccref, "DOMTokenList", cb); + + if(token_list->element) + note_cc_edge((nsISupports*)token_list->element, "element", cb); +} + +static void token_list_unlink(DispatchEx *dispex) +{ + struct token_list *token_list = token_list_from_DispatchEx(dispex); + if(token_list->element) { + IHTMLElement *element = token_list->element; + token_list->element = NULL; + IHTMLElement_Release(element); + } +} + 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); }
@@ -7814,6 +7880,8 @@ static HRESULT token_list_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD
static const dispex_static_data_vtbl_t token_list_dispex_vtbl = { token_list_destructor, + token_list_traverse, + token_list_unlink, token_list_value, token_list_get_dispid, token_list_get_name, @@ -8191,6 +8259,16 @@ static inline HTMLFiltersCollection *HTMLFiltersCollection_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLFiltersCollection, dispex); }
+static void HTMLFiltersCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLFiltersCollection *This = HTMLFiltersCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "FiltersCollection", cb); +} + +static void HTMLFiltersCollection_unlink(DispatchEx *dispex) +{ +} + static void HTMLFiltersCollection_destructor(DispatchEx *dispex) { HTMLFiltersCollection *This = HTMLFiltersCollection_from_DispatchEx(dispex); @@ -8237,6 +8315,8 @@ static HRESULT HTMLFiltersCollection_invoke(DispatchEx *dispex, DISPID id, LCID
static const dispex_static_data_vtbl_t HTMLFiltersCollection_dispex_vtbl = { HTMLFiltersCollection_destructor, + HTMLFiltersCollection_traverse, + HTMLFiltersCollection_unlink, NULL, HTMLFiltersCollection_get_dispid, HTMLFiltersCollection_get_name, @@ -8915,10 +8995,20 @@ static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex); }
-static void HTMLAttributeCollection_destructor(DispatchEx *dispex) +static void HTMLAttributeCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); + HTMLDOMAttribute *attr; + + describe_cc_node(&This->ccref, "AttributeCollection", cb); + + LIST_FOR_EACH_ENTRY(attr, &This->attrs, HTMLDOMAttribute, entry) + note_cc_edge((nsISupports*)&attr->IHTMLDOMAttribute_iface, "attr", cb); +}
+static void HTMLAttributeCollection_unlink(DispatchEx *dispex) +{ + HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); while(!list_empty(&This->attrs)) { HTMLDOMAttribute *attr = LIST_ENTRY(list_head(&This->attrs), HTMLDOMAttribute, entry);
@@ -8926,7 +9016,11 @@ static void HTMLAttributeCollection_destructor(DispatchEx *dispex) attr->elem = NULL; IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface); } +}
+static void HTMLAttributeCollection_destructor(DispatchEx *dispex) +{ + HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); free(This); }
@@ -8997,6 +9091,8 @@ static HRESULT HTMLAttributeCollection_invoke(DispatchEx *dispex, DISPID id, LCI
static const dispex_static_data_vtbl_t HTMLAttributeCollection_dispex_vtbl = { HTMLAttributeCollection_destructor, + HTMLAttributeCollection_traverse, + HTMLAttributeCollection_unlink, NULL, HTMLAttributeCollection_get_dispid, HTMLAttributeCollection_get_name, diff --git a/dlls/mshtml/htmlelemcol.c b/dlls/mshtml/htmlelemcol.c index ef610536536..e598a9cc211 100644 --- a/dlls/mshtml/htmlelemcol.c +++ b/dlls/mshtml/htmlelemcol.c @@ -539,14 +539,33 @@ static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); }
-static void HTMLElementCollection_destructor(DispatchEx *dispex) +static void HTMLElementCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLElementCollection *This = impl_from_DispatchEx(dispex); unsigned i;
+ describe_cc_node(&This->ccref, "ElementCollection", cb); + for(i = 0; i < This->len; i++) - node_release(&This->elems[i]->node); - free(This->elems); + note_cc_edge((nsISupports*)&This->elems[i]->node.IHTMLDOMNode_iface, "elem", cb); +} + +static void HTMLElementCollection_unlink(DispatchEx *dispex) +{ + HTMLElementCollection *This = impl_from_DispatchEx(dispex); + unsigned i, len = This->len; + + if(len) { + This->len = 0; + for(i = 0; i < len; i++) + node_release(&This->elems[i]->node); + free(This->elems); + } +} + +static void HTMLElementCollection_destructor(DispatchEx *dispex) +{ + HTMLElementCollection *This = impl_from_DispatchEx(dispex); free(This); }
@@ -623,6 +642,8 @@ static HRESULT HTMLElementCollection_invoke(DispatchEx *dispex, DISPID id, LCID
static const dispex_static_data_vtbl_t HTMLElementColection_dispex_vtbl = { HTMLElementCollection_destructor, + HTMLElementCollection_traverse, + HTMLElementCollection_unlink, NULL, HTMLElementCollection_get_dispid, HTMLElementCollection_get_name, diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index f36bcc977cc..2f4b22acc9c 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -870,16 +870,35 @@ static inline HTMLEventObj *HTMLEventObj_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLEventObj, dispex); }
-static void HTMLEventObj_destructor(DispatchEx *dispex) +static void HTMLEventObj_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "EventObj", cb); + if(This->event) - IDOMEvent_Release(&This->event->IDOMEvent_iface); + note_cc_edge((nsISupports*)&This->event->IDOMEvent_iface, "event", cb); +} + +static void HTMLEventObj_unlink(DispatchEx *dispex) +{ + HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); + if(This->event) { + DOMEvent *event = This->event; + This->event = NULL; + IDOMEvent_Release(&event->IDOMEvent_iface); + } +} + +static void HTMLEventObj_destructor(DispatchEx *dispex) +{ + HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLEventObj_dispex_vtbl = { HTMLEventObj_destructor, + HTMLEventObj_traverse, + HTMLEventObj_unlink };
static const tid_t HTMLEventObj_iface_tids[] = { @@ -1238,12 +1257,39 @@ static inline DOMEvent *DOMEvent_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, DOMEvent, dispex); }
+static void event_traverse(DOMEvent *This, nsCycleCollectionTraversalCallback *cb) +{ + if(This->target) + note_cc_edge((nsISupports*)&This->target->IEventTarget_iface, "target", cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "nsevent", cb); +} + +static void DOMEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMEvent *This = DOMEvent_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMEvent", cb); + event_traverse(This, cb); +} + +static void DOMEvent_unlink(DispatchEx *dispex) +{ + DOMEvent *This = DOMEvent_from_DispatchEx(dispex); + if(This->target) { + EventTarget *target = This->target; + This->target = NULL; + IEventTarget_Release(&target->IEventTarget_iface); + } + if(This->nsevent) { + nsIDOMEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMEvent_Release(nsevent); + } +} + static void DOMEvent_destructor(DispatchEx *dispex) { DOMEvent *This = DOMEvent_from_DispatchEx(dispex); - if(This->target) - IEventTarget_Release(&This->target->IEventTarget_iface); - nsIDOMEvent_Release(This->nsevent); free(This->type); free(This); } @@ -1396,9 +1442,24 @@ static void *DOMUIEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
+static void ui_event_traverse(DOMUIEvent *This, nsCycleCollectionTraversalCallback *cb) +{ + event_traverse(&This->event, cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "UIEvent.nsevent", cb); +} + +static void DOMUIEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->event.ccref, "DOMUIEvent", cb); + ui_event_traverse(This, cb); +} + static void DOMUIEvent_unlink(DispatchEx *dispex) { DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMEvent_unlink(&This->event.dispex); if(This->nsevent) { nsIDOMUIEvent *nsevent = This->nsevent; This->nsevent = NULL; @@ -1406,13 +1467,6 @@ static void DOMUIEvent_unlink(DispatchEx *dispex) } }
-static void DOMUIEvent_destructor(DispatchEx *dispex) -{ - DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); - DOMUIEvent_unlink(&This->event.dispex); - DOMEvent_destructor(dispex); -} - typedef struct { DOMUIEvent ui_event; IDOMMouseEvent IDOMMouseEvent_iface; @@ -1938,12 +1992,25 @@ static void *DOMMouseEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMMouseEvent_destructor(DispatchEx *dispex) +static void DOMMouseEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->ui_event.event.ccref, "DOMMouseEvent", cb); + + ui_event_traverse(&This->ui_event, cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "MouseEvent.nsevent", cb); +} + +static void DOMMouseEvent_unlink(DispatchEx *dispex) { DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); DOMUIEvent_unlink(&This->ui_event.event.dispex); - nsIDOMMouseEvent_Release(This->nsevent); - DOMEvent_destructor(dispex); + if(This->nsevent) { + nsIDOMMouseEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMMouseEvent_Release(nsevent); + } }
typedef struct { @@ -2238,12 +2305,25 @@ static void *DOMKeyboardEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMKeyboardEvent_destructor(DispatchEx *dispex) +static void DOMKeyboardEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->ui_event.event.ccref, "DOMKeyboardEvent", cb); + + ui_event_traverse(&This->ui_event, cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "KeyboardEvent.nsevent", cb); +} + +static void DOMKeyboardEvent_unlink(DispatchEx *dispex) { DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); DOMUIEvent_unlink(&This->ui_event.event.dispex); - nsIDOMKeyEvent_Release(This->nsevent); - DOMEvent_destructor(dispex); + if(This->nsevent) { + nsIDOMKeyEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMKeyEvent_Release(nsevent); + } }
typedef struct { @@ -2447,11 +2527,21 @@ static void *DOMCustomEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMCustomEvent_destructor(DispatchEx *dispex) +static void DOMCustomEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&custom_event->event.ccref, "DOMCustomEvent", cb); + + event_traverse(&custom_event->event, cb); + if(V_VT(&custom_event->detail) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&custom_event->detail), "detail", cb); +} + +static void DOMCustomEvent_unlink(DispatchEx *dispex) { DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMEvent_unlink(&custom_event->event.dispex); VariantClear(&custom_event->detail); - DOMEvent_destructor(dispex); }
typedef struct { @@ -2592,11 +2682,21 @@ static void *DOMMessageEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMMessageEvent_destructor(DispatchEx *dispex) +static void DOMMessageEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&message_event->event.ccref, "DOMMessageEvent", cb); + + event_traverse(&message_event->event, cb); + if(V_VT(&message_event->data) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&message_event->data), "data", cb); +} + +static void DOMMessageEvent_unlink(DispatchEx *dispex) +{ + DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMEvent_unlink(&message_event->event.dispex); VariantClear(&message_event->data); - DOMEvent_destructor(dispex); }
static void DOMMessageEvent_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) @@ -2766,11 +2866,25 @@ static void *DOMProgressEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMProgressEvent_destructor(DispatchEx *dispex) +static void DOMProgressEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); - nsIDOMProgressEvent_Release(This->nsevent); - DOMEvent_destructor(dispex); + describe_cc_node(&This->event.ccref, "DOMProgressEvent", cb); + + event_traverse(&This->event, cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "ProgressEvent.nsevent", cb); +} + +static void DOMProgressEvent_unlink(DispatchEx *dispex) +{ + DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMEvent_unlink(&This->event.dispex); + if(This->nsevent) { + nsIDOMProgressEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMProgressEvent_Release(nsevent); + } }
typedef struct { @@ -2929,6 +3043,12 @@ static void *DOMStorageEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
+static void DOMStorageEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&storage_event->event.ccref, "DOMStorageEvent", cb); +} + static void DOMStorageEvent_destructor(DispatchEx *dispex) { DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -2941,6 +3061,8 @@ static void DOMStorageEvent_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t DOMEvent_dispex_vtbl = { DOMEvent_destructor, + DOMEvent_traverse, + DOMEvent_unlink };
static const tid_t DOMEvent_iface_tids[] = { @@ -2956,7 +3078,9 @@ static dispex_static_data_t DOMEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMUIEvent_dispex_vtbl = { - DOMUIEvent_destructor, + DOMEvent_destructor, + DOMUIEvent_traverse, + DOMUIEvent_unlink };
static const tid_t DOMUIEvent_iface_tids[] = { @@ -2973,7 +3097,9 @@ static dispex_static_data_t DOMUIEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMMouseEvent_dispex_vtbl = { - DOMMouseEvent_destructor, + DOMEvent_destructor, + DOMMouseEvent_traverse, + DOMMouseEvent_unlink };
static const tid_t DOMMouseEvent_iface_tids[] = { @@ -2991,7 +3117,9 @@ static dispex_static_data_t DOMMouseEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMKeyboardEvent_dispex_vtbl = { - DOMKeyboardEvent_destructor, + DOMEvent_destructor, + DOMKeyboardEvent_traverse, + DOMKeyboardEvent_unlink };
static const tid_t DOMKeyboardEvent_iface_tids[] = { @@ -3023,7 +3151,9 @@ static dispex_static_data_t DOMPageTransitionEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMCustomEvent_dispex_vtbl = { - DOMCustomEvent_destructor, + DOMEvent_destructor, + DOMCustomEvent_traverse, + DOMCustomEvent_unlink };
static const tid_t DOMCustomEvent_iface_tids[] = { @@ -3040,7 +3170,9 @@ static dispex_static_data_t DOMCustomEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMMessageEvent_dispex_vtbl = { - DOMMessageEvent_destructor, + DOMEvent_destructor, + DOMMessageEvent_traverse, + DOMMessageEvent_unlink };
static const tid_t DOMMessageEvent_iface_tids[] = { @@ -3057,7 +3189,9 @@ static dispex_static_data_t DOMMessageEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMProgressEvent_dispex_vtbl = { - DOMProgressEvent_destructor, + DOMEvent_destructor, + DOMProgressEvent_traverse, + DOMProgressEvent_unlink };
static const tid_t DOMProgressEvent_iface_tids[] = { @@ -3075,6 +3209,8 @@ static dispex_static_data_t DOMProgressEvent_dispex = {
static const dispex_static_data_vtbl_t DOMStorageEvent_dispex_vtbl = { DOMStorageEvent_destructor, + DOMStorageEvent_traverse, + DOMEvent_unlink };
static const tid_t DOMStorageEvent_iface_tids[] = { @@ -4498,11 +4634,12 @@ void release_event_target(EventTarget *event_target) WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter, iter2, &event_target->handler_map, listener_container_t, entry) { while(!list_empty(&iter->listeners)) { event_listener_t *listener = LIST_ENTRY(list_head(&iter->listeners), event_listener_t, entry); + list_remove(&listener->entry); if(listener->function) IDispatch_Release(listener->function); - list_remove(&listener->entry); free(listener); } free(iter); } + rb_destroy(&event_target->handler_map, NULL, NULL); } diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index 00859733286..d09c828d763 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -942,6 +942,16 @@ static inline HTMLImageElementFactory *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLImageElementFactory, dispex); }
+static void HTMLImageElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ImageElementFactory", cb); +} + +static void HTMLImageElementFactory_unlink(DispatchEx *dispex) +{ +} + static void HTMLImageElementFactory_destructor(DispatchEx *dispex) { HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); @@ -983,6 +993,8 @@ static const tid_t HTMLImageElementFactory_iface_tids[] = {
static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = { HTMLImageElementFactory_destructor, + HTMLImageElementFactory_traverse, + HTMLImageElementFactory_unlink, HTMLImageElementFactory_value, NULL, NULL, diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index 9149251f62d..54fdde96ff5 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -615,15 +615,35 @@ static inline HTMLLocation *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLLocation, dispex); }
+static void HTMLLocation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Location", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLLocation_unlink(DispatchEx *dispex) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + if(This->window) { + HTMLOuterWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + 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, + HTMLLocation_traverse, + HTMLLocation_unlink };
static const tid_t HTMLLocation_iface_tids[] = { diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 354a4719601..f6b4ab4cdb8 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -359,10 +359,28 @@ static inline HTMLDOMChildrenCollection *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, dispex); }
+static void HTMLDOMChildrenCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMChildrenCollection", cb); + + if(This->nslist) + note_cc_edge((nsISupports*)This->nslist, "nslist", cb); +} + +static void HTMLDOMChildrenCollection_unlink(DispatchEx *dispex) +{ + HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); + if(This->nslist) { + nsIDOMNodeList *nslist = This->nslist; + This->nslist = NULL; + nsIDOMNodeList_Release(nslist); + } +} + static void HTMLDOMChildrenCollection_destructor(DispatchEx *dispex) { HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); - nsIDOMNodeList_Release(This->nslist); free(This); }
@@ -436,6 +454,8 @@ static HRESULT HTMLDOMChildrenCollection_invoke(DispatchEx *dispex, DISPID id, L
static const dispex_static_data_vtbl_t HTMLDOMChildrenCollection_dispex_vtbl = { HTMLDOMChildrenCollection_destructor, + HTMLDOMChildrenCollection_traverse, + HTMLDOMChildrenCollection_unlink, NULL, HTMLDOMChildrenCollection_get_dispid, HTMLDOMChildrenCollection_get_name, @@ -1416,6 +1436,14 @@ static const IHTMLDOMNode3Vtbl HTMLDOMNode3Vtbl = { HTMLDOMNode3_isSupported };
+static void HTMLDOMNode_dispex_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDOMNode_dispex_unlink(DispatchEx *dispex) +{ +} + static void HTMLDOMNode_dispex_destructor(DispatchEx *dispex) { } @@ -1504,6 +1532,8 @@ void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsno
static const dispex_static_data_vtbl_t HTMLDOMNode_dispex_vtbl = { HTMLDOMNode_dispex_destructor, + HTMLDOMNode_dispex_traverse, + HTMLDOMNode_dispex_unlink };
static const tid_t HTMLDOMNode_iface_tids[] = { diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 4fc46f5d09b..f0086e0802c 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -592,6 +592,16 @@ static inline HTMLOptionElementFactory *HTMLOptionElementFactory_from_DispatchEx return CONTAINING_RECORD(iface, HTMLOptionElementFactory, dispex); }
+static void HTMLOptionElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "OptionElementFactory", cb); +} + +static void HTMLOptionElementFactory_unlink(DispatchEx *dispex) +{ +} + static void HTMLOptionElementFactory_destructor(DispatchEx *dispex) { HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); @@ -637,6 +647,8 @@ static const tid_t HTMLOptionElementFactory_iface_tids[] = {
static const dispex_static_data_vtbl_t HTMLOptionElementFactory_dispex_vtbl = { HTMLOptionElementFactory_destructor, + HTMLOptionElementFactory_traverse, + HTMLOptionElementFactory_unlink, HTMLOptionElementFactory_value, NULL, NULL, diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index 5d7f2603ac8..3e1d76e491e 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -1054,6 +1054,16 @@ static inline HTMLStorage *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLStorage, dispex); }
+static void HTMLStorage_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLStorage *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Storage", cb); +} + +static void HTMLStorage_unlink(DispatchEx *dispex) +{ +} + static void HTMLStorage_destructor(DispatchEx *dispex) { HTMLStorage *This = impl_from_DispatchEx(dispex); @@ -1310,6 +1320,8 @@ static HRESULT HTMLStorage_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pi
static const dispex_static_data_vtbl_t HTMLStorage_dispex_vtbl = { HTMLStorage_destructor, + HTMLStorage_traverse, + HTMLStorage_unlink, NULL, HTMLStorage_get_dispid, HTMLStorage_get_name, diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index f653f3c38b2..56558adcd9a 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -9962,11 +9962,28 @@ static inline CSSStyle *impl_from_DispatchEx(DispatchEx *dispex) return CONTAINING_RECORD(dispex, CSSStyle, dispex); }
-static void CSSStyle_destructor(DispatchEx *dispex) +static void CSSStyle_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { CSSStyle *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "CSSStyle", cb); + if(This->nsstyle) - nsIDOMCSSStyleDeclaration_Release(This->nsstyle); + note_cc_edge((nsISupports*)This->nsstyle, "nsstyle", cb); +} + +static void CSSStyle_unlink(DispatchEx *dispex) +{ + CSSStyle *This = impl_from_DispatchEx(dispex); + if(This->nsstyle) { + nsIDOMCSSStyleDeclaration *nsstyle = This->nsstyle; + This->nsstyle = NULL; + nsIDOMCSSStyleDeclaration_Release(nsstyle); + } +} + +static void CSSStyle_destructor(DispatchEx *dispex) +{ + CSSStyle *This = impl_from_DispatchEx(dispex); free(This); }
@@ -9999,6 +10016,8 @@ void CSSStyle_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
const dispex_static_data_vtbl_t CSSStyle_dispex_vtbl = { CSSStyle_destructor, + CSSStyle_traverse, + CSSStyle_unlink, NULL, CSSStyle_get_dispid, NULL, diff --git a/dlls/mshtml/htmlstylesheet.c b/dlls/mshtml/htmlstylesheet.c index e78ebe6592d..26b3c933bad 100644 --- a/dlls/mshtml/htmlstylesheet.c +++ b/dlls/mshtml/htmlstylesheet.c @@ -204,16 +204,35 @@ static inline HTMLStyleSheetRule *HTMLStyleSheetRule_from_DispatchEx(DispatchEx return CONTAINING_RECORD(iface, HTMLStyleSheetRule, dispex); }
-static void HTMLStyleSheetRule_destructor(DispatchEx *dispex) +static void HTMLStyleSheetRule_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetRule", cb); + if(This->nsstylesheetrule) - nsIDOMCSSRule_Release(This->nsstylesheetrule); + note_cc_edge((nsISupports*)This->nsstylesheetrule, "nsstylesheetrule", cb); +} + +static void HTMLStyleSheetRule_unlink(DispatchEx *dispex) +{ + HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); + if(This->nsstylesheetrule) { + nsIDOMCSSRule *nsstylesheetrule = This->nsstylesheetrule; + This->nsstylesheetrule = NULL; + nsIDOMCSSRule_Release(nsstylesheetrule); + } +} + +static void HTMLStyleSheetRule_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLStyleSheetRule_dispex_vtbl = { HTMLStyleSheetRule_destructor, + HTMLStyleSheetRule_traverse, + HTMLStyleSheetRule_unlink };
static const tid_t HTMLStyleSheetRule_iface_tids[] = { @@ -392,11 +411,28 @@ static inline HTMLStyleSheetRulesCollection *HTMLStyleSheetRulesCollection_from_ return CONTAINING_RECORD(iface, HTMLStyleSheetRulesCollection, dispex); }
-static void HTMLStyleSheetRulesCollection_destructor(DispatchEx *dispex) +static void HTMLStyleSheetRulesCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetRulesCollection", cb); + if(This->nslist) - nsIDOMCSSRuleList_Release(This->nslist); + note_cc_edge((nsISupports*)This->nslist, "nslist", cb); +} + +static void HTMLStyleSheetRulesCollection_unlink(DispatchEx *dispex) +{ + HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); + if(This->nslist) { + nsIDOMCSSRuleList *nslist = This->nslist; + This->nslist = NULL; + nsIDOMCSSRuleList_Release(nslist); + } +} + +static void HTMLStyleSheetRulesCollection_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); free(This); }
@@ -478,6 +514,8 @@ static HRESULT HTMLStyleSheetRulesCollection_invoke(DispatchEx *dispex, DISPID i
static const dispex_static_data_vtbl_t HTMLStyleSheetRulesCollection_dispex_vtbl = { HTMLStyleSheetRulesCollection_destructor, + HTMLStyleSheetRulesCollection_traverse, + HTMLStyleSheetRulesCollection_unlink, NULL, HTMLStyleSheetRulesCollection_get_dispid, HTMLStyleSheetRulesCollection_get_name, @@ -821,11 +859,28 @@ static inline HTMLStyleSheetsCollection *HTMLStyleSheetsCollection_from_Dispatch return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, dispex); }
-static void HTMLStyleSheetsCollection_destructor(DispatchEx *dispex) +static void HTMLStyleSheetsCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetsCollection", cb); + if(This->nslist) - nsIDOMStyleSheetList_Release(This->nslist); + note_cc_edge((nsISupports*)This->nslist, "nslist", cb); +} + +static void HTMLStyleSheetsCollection_unlink(DispatchEx *dispex) +{ + HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); + if(This->nslist) { + nsIDOMStyleSheetList *nslist = This->nslist; + This->nslist = NULL; + nsIDOMStyleSheetList_Release(nslist); + } +} + +static void HTMLStyleSheetsCollection_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); free(This); }
@@ -907,6 +962,8 @@ static HRESULT HTMLStyleSheetsCollection_invoke(DispatchEx *dispex, DISPID id, L
static const dispex_static_data_vtbl_t HTMLStyleSheetsCollection_dispex_vtbl = { HTMLStyleSheetsCollection_destructor, + HTMLStyleSheetsCollection_traverse, + HTMLStyleSheetsCollection_unlink, NULL, HTMLStyleSheetsCollection_get_dispid, HTMLStyleSheetsCollection_get_name, @@ -1474,11 +1531,28 @@ static inline HTMLStyleSheet *HTMLStyleSheet_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLStyleSheet, dispex); }
-static void HTMLStyleSheet_destructor(DispatchEx *dispex) +static void HTMLStyleSheet_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheet", cb); + if(This->nsstylesheet) - nsIDOMCSSStyleSheet_Release(This->nsstylesheet); + note_cc_edge((nsISupports*)This->nsstylesheet, "nsstylesheet", cb); +} + +static void HTMLStyleSheet_unlink(DispatchEx *dispex) +{ + HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); + if(This->nsstylesheet) { + nsIDOMCSSStyleSheet *nsstylesheet = This->nsstylesheet; + This->nsstylesheet = NULL; + nsIDOMCSSStyleSheet_Release(nsstylesheet); + } +} + +static void HTMLStyleSheet_destructor(DispatchEx *dispex) +{ + HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); free(This); }
@@ -1490,6 +1564,8 @@ static void HTMLStyleSheet_init_dispex_info(dispex_data_t *info, compat_mode_t m
static const dispex_static_data_vtbl_t HTMLStyleSheet_dispex_vtbl = { HTMLStyleSheet_destructor, + HTMLStyleSheet_traverse, + HTMLStyleSheet_unlink };
static const tid_t HTMLStyleSheet_iface_tids[] = { diff --git a/dlls/mshtml/htmltextnode.c b/dlls/mshtml/htmltextnode.c index 76515aa6d95..c24d59086ff 100644 --- a/dlls/mshtml/htmltextnode.c +++ b/dlls/mshtml/htmltextnode.c @@ -319,6 +319,14 @@ static const IHTMLDOMTextNode2Vtbl HTMLDOMTextNode2Vtbl = { HTMLDOMTextNode2_replaceData };
+static void HTMLDOMTextNode_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDOMTextNode_unlink(DispatchEx *dispex) +{ +} + static void HTMLDOMTextNode_destructor(DispatchEx *dispex) { } @@ -364,6 +372,8 @@ static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = {
static const dispex_static_data_vtbl_t HTMLDOMTextNode_dispex_vtbl = { HTMLDOMTextNode_destructor, + HTMLDOMTextNode_traverse, + HTMLDOMTextNode_unlink };
static const tid_t HTMLDOMTextNode_iface_tids[] = { diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 6a0607700bf..0bdd8a6c68b 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.IDispatchEx_iface); + dispex_props_unlink(&outer_window->location->dispex);
abort_window_bindings(window); remove_target_tasks(window->task_magic); @@ -3667,64 +3667,119 @@ static inline HTMLInnerWindow *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLInnerWindow, event_target.dispex); }
-static void HTMLWindow_destructor(DispatchEx *dispex) +static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLInnerWindow *This = impl_from_DispatchEx(dispex); - unsigned i; + HTMLOuterWindow *child;
- TRACE("%p\n", This); + describe_cc_node(&This->base.ccref, "InnerWindow", cb);
if(This->base.console) - IWineMSHTMLConsole_Release(This->base.console); + note_cc_edge((nsISupports*)This->base.console, "console", cb); + LIST_FOR_EACH_ENTRY(child, &This->children, HTMLOuterWindow, sibling_entry) + note_cc_edge((nsISupports*)&child->base.IHTMLWindow2_iface, "child", cb); + if(This->doc) + note_cc_edge((nsISupports*)&This->doc->node.IHTMLDOMNode_iface, "doc", cb); + if(This->image_factory) + note_cc_edge((nsISupports*)&This->image_factory->IHTMLImageElementFactory_iface, "image_factory", cb); + if(This->option_factory) + note_cc_edge((nsISupports*)&This->option_factory->IHTMLOptionElementFactory_iface, "option_factory", cb); + if(This->xhr_factory) + note_cc_edge((nsISupports*)&This->xhr_factory->IHTMLXMLHttpRequestFactory_iface, "xhr_factory", cb); + if(This->screen) + note_cc_edge((nsISupports*)This->screen, "screen", cb); + if(This->history) + note_cc_edge((nsISupports*)&This->history->IOmHistory_iface, "history", cb); + if(This->navigator) + note_cc_edge((nsISupports*)This->navigator, "navigator", cb); + if(This->session_storage) + note_cc_edge((nsISupports*)This->session_storage, "session_storage", cb); + if(This->local_storage) + note_cc_edge((nsISupports*)This->local_storage, "local_storage", cb); + if(V_VT(&This->performance) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&This->performance), "performance", cb); +} + +static void HTMLWindow_unlink(DispatchEx *dispex) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + + TRACE("%p\n", This); + + if(This->base.console) { + IWineMSHTMLConsole *console = This->base.console; + This->base.console = NULL; + IWineMSHTMLConsole_Release(console); + }
detach_inner_window(This);
if(This->doc) { + HTMLDocumentNode *doc = This->doc; This->doc->window = NULL; - IHTMLDOMNode_Release(&This->doc->node.IHTMLDOMNode_iface); + This->doc = NULL; + IHTMLDOMNode_Release(&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) { + HTMLImageElementFactory *image_factory = This->image_factory; This->image_factory->window = NULL; - IHTMLImageElementFactory_Release(&This->image_factory->IHTMLImageElementFactory_iface); + This->image_factory = NULL; + IHTMLImageElementFactory_Release(&image_factory->IHTMLImageElementFactory_iface); } - if(This->option_factory) { + HTMLOptionElementFactory *option_factory = This->option_factory; This->option_factory->window = NULL; - IHTMLOptionElementFactory_Release(&This->option_factory->IHTMLOptionElementFactory_iface); + This->option_factory = NULL; + IHTMLOptionElementFactory_Release(&option_factory->IHTMLOptionElementFactory_iface); } - if(This->xhr_factory) { + HTMLXMLHttpRequestFactory *xhr_factory = This->xhr_factory; This->xhr_factory->window = NULL; - IHTMLXMLHttpRequestFactory_Release(&This->xhr_factory->IHTMLXMLHttpRequestFactory_iface); + This->xhr_factory = NULL; + IHTMLXMLHttpRequestFactory_Release(&xhr_factory->IHTMLXMLHttpRequestFactory_iface); + } + if(This->screen) { + IHTMLScreen *screen = This->screen; + This->screen = NULL; + IHTMLScreen_Release(screen); } - - if(This->screen) - IHTMLScreen_Release(This->screen); - if(This->history) { + OmHistory *history = This->history; This->history->window = NULL; - IOmHistory_Release(&This->history->IOmHistory_iface); + This->history = NULL; + IOmHistory_Release(&history->IOmHistory_iface); + } + if(This->navigator) { + IOmNavigator *navigator = This->navigator; + This->navigator = NULL; + IOmNavigator_Release(navigator); } - - if(This->navigator) - IOmNavigator_Release(This->navigator); if(This->session_storage) { + IHTMLStorage *session_storage = This->session_storage; detach_html_storage(This->session_storage); - IHTMLStorage_Release(This->session_storage); + This->session_storage = NULL; + IHTMLStorage_Release(session_storage); } if(This->local_storage) { + IHTMLStorage *local_storage = This->local_storage; detach_html_storage(This->local_storage); - IHTMLStorage_Release(This->local_storage); + This->local_storage = NULL; + IHTMLStorage_Release(local_storage); } - VariantClear(&This->performance); +} + +static void HTMLWindow_destructor(DispatchEx *dispex) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + unsigned i; + + for(i = 0; i < This->global_prop_cnt; i++) + free(This->global_props[i].name); + free(This->global_props);
if(This->mon) IMoniker_Release(This->mon); @@ -3971,6 +4026,8 @@ static IHTMLEventObj *HTMLWindow_set_current_event(DispatchEx *dispex, IHTMLEven static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { { HTMLWindow_destructor, + HTMLWindow_traverse, + HTMLWindow_unlink, NULL, NULL, HTMLWindow_get_name, @@ -4006,10 +4063,9 @@ static nsresult NSAPI window_traverse(void *ccp, void *p, nsCycleCollectionTrave HTMLWindow *This = impl_from_IHTMLWindow2(p); HTMLOuterWindow *window;
- if(!is_outer_window(This)) { - /* FIXME: Traverse inner window and its dispex */ - return NS_OK; - } + if(!is_outer_window(This)) + return dispex_traverse(&window_ccp, &This->inner_window->event_target.dispex.IDispatchEx_iface, cb); + window = This->outer_window;
describe_cc_node(&window->base.ccref, "OuterWindow", cb); @@ -4040,10 +4096,9 @@ static nsresult NSAPI window_unlink(void *p) IWineMSHTMLConsole_Release(console); }
- if(!is_outer_window(This)) { - /* FIXME: Unlink inner window and its dispex */ - return NS_OK; - } + if(!is_outer_window(This)) + return dispex_unlink(&This->inner_window->event_target.dispex.IDispatchEx_iface); + window = This->outer_window;
remove_target_tasks(window->task_magic); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 119568386fd..c1656dc11be 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -336,9 +336,12 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t; #define MSHTML_CUSTOM_DISPID_CNT (MSHTML_DISPID_CUSTOM_MAX-MSHTML_DISPID_CUSTOM_MIN)
typedef struct DispatchEx DispatchEx; +typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback;
typedef struct { void (*destructor)(DispatchEx*); + void (*traverse)(DispatchEx*,nsCycleCollectionTraversalCallback*); + void (*unlink)(DispatchEx*); HRESULT (*value)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*); HRESULT (*get_dispid)(DispatchEx*,BSTR,DWORD,DISPID*); HRESULT (*get_name)(DispatchEx*,DISPID,BSTR*); @@ -387,8 +390,6 @@ typedef struct { void *callbacks; } ExternalCycleCollectionParticipant;
-typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback; - typedef struct { nsresult (NSAPI *traverse)(void*,void*,nsCycleCollectionTraversalCallback*); nsresult (NSAPI *unlink)(void*); @@ -418,6 +419,7 @@ static inline LONG dispex_ccref_decr(nsCycleCollectingAutoRefCnt *ccref, Dispatc
void init_dispatch(DispatchEx*,IUnknown*,dispex_static_data_t*,compat_mode_t); BOOL dispex_query_interface(DispatchEx*,REFIID,void**); +void dispex_props_unlink(DispatchEx*); nsresult NSAPI dispex_traverse(void*,void*,nsCycleCollectionTraversalCallback*); nsresult NSAPI dispex_unlink(void*); void NSAPI dispex_delete_cycle_collectable(void*); diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 9b0cf027dd5..7c1e19fc711 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -291,17 +291,36 @@ static inline HTMLDOMImplementation *HTMLDOMImplementation_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLDOMImplementation, dispex); }
+static void HTMLDOMImplementation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMImplementation *This = HTMLDOMImplementation_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMImplementation", cb); + + if(This->implementation) + note_cc_edge((nsISupports*)This->implementation, "implementation", cb); +} + +static void HTMLDOMImplementation_unlink(DispatchEx *dispex) +{ + HTMLDOMImplementation *This = HTMLDOMImplementation_from_DispatchEx(dispex); + if(This->implementation) { + nsIDOMDOMImplementation *implementation = This->implementation; + This->implementation = NULL; + nsIDOMDOMImplementation_Release(implementation); + } +} + 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, + HTMLDOMImplementation_traverse, + HTMLDOMImplementation_unlink };
static void HTMLDOMImplementation_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) @@ -563,6 +582,16 @@ static inline HTMLScreen *HTMLScreen_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLScreen, dispex); }
+static void HTMLScreen_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLScreen *This = HTMLScreen_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Screen", cb); +} + +static void HTMLScreen_unlink(DispatchEx *dispex) +{ +} + static void HTMLScreen_destructor(DispatchEx *dispex) { HTMLScreen *This = HTMLScreen_from_DispatchEx(dispex); @@ -571,6 +600,8 @@ static void HTMLScreen_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t HTMLScreen_dispex_vtbl = { HTMLScreen_destructor, + HTMLScreen_traverse, + HTMLScreen_unlink };
static const tid_t HTMLScreen_iface_tids[] = { @@ -737,6 +768,16 @@ static inline OmHistory *OmHistory_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, OmHistory, dispex); }
+static void OmHistory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + OmHistory *This = OmHistory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "History", cb); +} + +static void OmHistory_unlink(DispatchEx *dispex) +{ +} + static void OmHistory_destructor(DispatchEx *dispex) { OmHistory *This = OmHistory_from_DispatchEx(dispex); @@ -745,6 +786,8 @@ static void OmHistory_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t OmHistory_dispex_vtbl = { OmHistory_destructor, + OmHistory_traverse, + OmHistory_unlink };
static const tid_t OmHistory_iface_tids[] = { @@ -902,16 +945,31 @@ static inline HTMLPluginsCollection *HTMLPluginsCollection_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLPluginsCollection, dispex); }
-static void HTMLPluginsCollection_destructor(DispatchEx *dispex) +static void HTMLPluginsCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PluginsCollection", cb); +} + +static void HTMLPluginsCollection_unlink(DispatchEx *dispex) { HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); - if(This->navigator) + if(This->navigator) { This->navigator->plugins = NULL; + This->navigator = NULL; + } +} + +static void HTMLPluginsCollection_destructor(DispatchEx *dispex) +{ + HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLPluginsCollection_dispex_vtbl = { HTMLPluginsCollection_destructor, + HTMLPluginsCollection_traverse, + HTMLPluginsCollection_unlink };
static const tid_t HTMLPluginsCollection_iface_tids[] = { @@ -1057,16 +1115,31 @@ static inline HTMLMimeTypesCollection *HTMLMimeTypesCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLMimeTypesCollection, dispex); }
-static void HTMLMimeTypesCollection_destructor(DispatchEx *dispex) +static void HTMLMimeTypesCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); - if(This->navigator) + describe_cc_node(&This->ccref, "MimeTypesCollection", cb); +} + +static void HTMLMimeTypesCollection_unlink(DispatchEx *dispex) +{ + HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); + if(This->navigator) { This->navigator->mime_types = NULL; + This->navigator = NULL; + } +} + +static void HTMLMimeTypesCollection_destructor(DispatchEx *dispex) +{ + HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLMimeTypesCollection_dispex_vtbl = { HTMLMimeTypesCollection_destructor, + HTMLMimeTypesCollection_traverse, + HTMLMimeTypesCollection_unlink };
static const tid_t HTMLMimeTypesCollection_iface_tids[] = { @@ -1493,18 +1566,35 @@ static inline OmNavigator *OmNavigator_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, OmNavigator, dispex); }
-static void OmNavigator_destructor(DispatchEx *dispex) +static void OmNavigator_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + OmNavigator *This = OmNavigator_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Navigator", cb); +} + +static void OmNavigator_unlink(DispatchEx *dispex) { OmNavigator *This = OmNavigator_from_DispatchEx(dispex); - if(This->plugins) + if(This->plugins) { This->plugins->navigator = NULL; - if(This->mime_types) + This->plugins = NULL; + } + if(This->mime_types) { This->mime_types->navigator = NULL; + This->mime_types = NULL; + } +} + +static void OmNavigator_destructor(DispatchEx *dispex) +{ + OmNavigator *This = OmNavigator_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t OmNavigator_dispex_vtbl = { OmNavigator_destructor, + OmNavigator_traverse, + OmNavigator_unlink };
static const tid_t OmNavigator_iface_tids[] = { @@ -1916,15 +2006,35 @@ static inline HTMLPerformanceTiming *HTMLPerformanceTiming_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLPerformanceTiming, dispex); }
+static void HTMLPerformanceTiming_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PerformanceTiming", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLPerformanceTiming_unlink(DispatchEx *dispex) +{ + HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLPerformanceTiming_destructor(DispatchEx *dispex) { HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); free(This); }
static const dispex_static_data_vtbl_t HTMLPerformanceTiming_dispex_vtbl = { HTMLPerformanceTiming_destructor, + HTMLPerformanceTiming_traverse, + HTMLPerformanceTiming_unlink };
static const tid_t HTMLPerformanceTiming_iface_tids[] = { @@ -2083,15 +2193,35 @@ static inline HTMLPerformanceNavigation *HTMLPerformanceNavigation_from_Dispatch return CONTAINING_RECORD(iface, HTMLPerformanceNavigation, dispex); }
+static void HTMLPerformanceNavigation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PerformanceNavigation", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLPerformanceNavigation_unlink(DispatchEx *dispex) +{ + HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + 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, + HTMLPerformanceNavigation_traverse, + HTMLPerformanceNavigation_unlink };
static const tid_t HTMLPerformanceNavigation_iface_tids[] = { @@ -2290,19 +2420,49 @@ static inline HTMLPerformance *HTMLPerformance_from_DispatchEx(DispatchEx *iface return CONTAINING_RECORD(iface, HTMLPerformance, dispex); }
-static void HTMLPerformance_destructor(DispatchEx *dispex) +static void HTMLPerformance_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + describe_cc_node(&This->ccref, "Performance", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); if(This->navigation) - IHTMLPerformanceNavigation_Release(This->navigation); + note_cc_edge((nsISupports*)This->navigation, "navigation", cb); if(This->timing) - IHTMLPerformanceTiming_Release(This->timing); + note_cc_edge((nsISupports*)This->timing, "timing", cb); +} + +static void HTMLPerformance_unlink(DispatchEx *dispex) +{ + HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } + if(This->navigation) { + IHTMLPerformanceNavigation *navigation = This->navigation; + This->navigation = NULL; + IHTMLPerformanceNavigation_Release(navigation); + } + if(This->timing) { + IHTMLPerformanceTiming *timing = This->timing; + This->timing = NULL; + IHTMLPerformanceTiming_Release(timing); + } +} + +static void HTMLPerformance_destructor(DispatchEx *dispex) +{ + HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLPerformance_dispex_vtbl = { HTMLPerformance_destructor, + HTMLPerformance_traverse, + HTMLPerformance_unlink };
static const tid_t HTMLPerformance_iface_tids[] = { @@ -2467,6 +2627,16 @@ static inline HTMLNamespaceCollection *HTMLNamespaceCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLNamespaceCollection, dispex); }
+static void HTMLNamespaceCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLNamespaceCollection *This = HTMLNamespaceCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "NamespaceCollection", cb); +} + +static void HTMLNamespaceCollection_unlink(DispatchEx *dispex) +{ +} + static void HTMLNamespaceCollection_destructor(DispatchEx *dispex) { HTMLNamespaceCollection *This = HTMLNamespaceCollection_from_DispatchEx(dispex); @@ -2475,6 +2645,8 @@ static void HTMLNamespaceCollection_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t HTMLNamespaceCollection_dispex_vtbl = { HTMLNamespaceCollection_destructor, + HTMLNamespaceCollection_traverse, + HTMLNamespaceCollection_unlink };
static const tid_t HTMLNamespaceCollection_iface_tids[] = { @@ -2733,6 +2905,16 @@ static inline struct console *console_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, struct console, dispex); }
+static void console_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct console *console = console_from_DispatchEx(dispex); + describe_cc_node(&console->ccref, "Console", cb); +} + +static void console_unlink(DispatchEx *dispex) +{ +} + static void console_destructor(DispatchEx *dispex) { struct console *console = console_from_DispatchEx(dispex); @@ -2741,6 +2923,8 @@ static void console_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t console_dispex_vtbl = { console_destructor, + console_traverse, + console_unlink };
static const tid_t console_iface_tids[] = { @@ -3058,23 +3242,48 @@ static inline struct media_query_list *media_query_list_from_DispatchEx(Dispatch return CONTAINING_RECORD(iface, struct media_query_list, dispex); }
-static void media_query_list_destructor(DispatchEx *dispex) +static void media_query_list_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct media_query_list *media_query_list = media_query_list_from_DispatchEx(dispex); + struct media_query_list_listener *listener; + + describe_cc_node(&media_query_list->ccref, "MediaQueryList", cb); + + LIST_FOR_EACH_ENTRY(listener, &media_query_list->listeners, struct media_query_list_listener, entry) + note_cc_edge((nsISupports*)listener->function, "function", cb); + if(media_query_list->nsquerylist) + note_cc_edge((nsISupports*)media_query_list->nsquerylist, "nsquerylist", cb); +} + +static void media_query_list_unlink(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) { + while(!list_empty(&media_query_list->listeners)) { + struct media_query_list_listener *listener = LIST_ENTRY(list_head(&media_query_list->listeners), struct media_query_list_listener, entry); + list_remove(&listener->entry); IDispatch_Release(listener->function); free(listener); } + if(media_query_list->nsquerylist) { + nsIDOMMediaQueryList *nsquerylist = media_query_list->nsquerylist; + media_query_list->nsquerylist = NULL; + nsIDOMMediaQueryList_Release(nsquerylist); + } +} + +static void media_query_list_destructor(DispatchEx *dispex) +{ + struct media_query_list *media_query_list = media_query_list_from_DispatchEx(dispex); 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, + media_query_list_traverse, + media_query_list_unlink };
static const tid_t media_query_list_iface_tids[] = { diff --git a/dlls/mshtml/range.c b/dlls/mshtml/range.c index 20730b5e0f2..599c9ea4b7a 100644 --- a/dlls/mshtml/range.c +++ b/dlls/mshtml/range.c @@ -1714,18 +1714,39 @@ static inline HTMLTxtRange *HTMLTxtRange_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLTxtRange, dispex); }
-static void HTMLTxtRange_destructor(DispatchEx *dispex) +static void HTMLTxtRange_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "TextRange", cb); + if(This->nsrange) - nsIDOMRange_Release(This->nsrange); - if(This->doc) + note_cc_edge((nsISupports*)This->nsrange, "nsrange", cb); +} + +static void HTMLTxtRange_unlink(DispatchEx *dispex) +{ + HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); + if(This->nsrange) { + nsIDOMRange *nsrange = This->nsrange; + This->nsrange = NULL; + nsIDOMRange_Release(nsrange); + } + if(This->doc) { + This->doc = NULL; list_remove(&This->entry); + } +} + +static void HTMLTxtRange_destructor(DispatchEx *dispex) +{ + HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLTxtRange_dispex_vtbl = { HTMLTxtRange_destructor, + HTMLTxtRange_traverse, + HTMLTxtRange_unlink };
static const tid_t HTMLTxtRange_iface_tids[] = { @@ -2071,16 +2092,35 @@ static inline HTMLDOMRange *HTMLDOMRange_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMRange, dispex); }
-static void HTMLDOMRange_destructor(DispatchEx *dispex) +static void HTMLDOMRange_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMRange", cb); + if(This->nsrange) - nsIDOMRange_Release(This->nsrange); + note_cc_edge((nsISupports*)This->nsrange, "nsrange", cb); +} + +static void HTMLDOMRange_unlink(DispatchEx *dispex) +{ + HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); + if(This->nsrange) { + nsIDOMRange *nsrange = This->nsrange; + This->nsrange = NULL; + nsIDOMRange_Release(nsrange); + } +} + +static void HTMLDOMRange_destructor(DispatchEx *dispex) +{ + HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLDOMRange_dispex_vtbl = { HTMLDOMRange_destructor, + HTMLDOMRange_traverse, + HTMLDOMRange_unlink };
static const tid_t HTMLDOMRange_iface_tids[] = { diff --git a/dlls/mshtml/selection.c b/dlls/mshtml/selection.c index 639ab0ce391..91be8bbc8ba 100644 --- a/dlls/mshtml/selection.c +++ b/dlls/mshtml/selection.c @@ -325,18 +325,39 @@ static inline HTMLSelectionObject *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLSelectionObject, dispex); }
-static void HTMLSelectionObject_destructor(DispatchEx *dispex) +static void HTMLSelectionObject_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLSelectionObject *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "SelectionObject", cb); + if(This->nsselection) - nsISelection_Release(This->nsselection); - if(This->doc) + note_cc_edge((nsISupports*)This->nsselection, "nsselection", cb); +} + +static void HTMLSelectionObject_unlink(DispatchEx *dispex) +{ + HTMLSelectionObject *This = impl_from_DispatchEx(dispex); + if(This->nsselection) { + nsISelection *nsselection = This->nsselection; + This->nsselection = NULL; + nsISelection_Release(nsselection); + } + if(This->doc) { + This->doc = NULL; list_remove(&This->entry); + } +} + +static void HTMLSelectionObject_destructor(DispatchEx *dispex) +{ + HTMLSelectionObject *This = impl_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLSelectionObject_dispex_vtbl = { HTMLSelectionObject_destructor, + HTMLSelectionObject_traverse, + HTMLSelectionObject_unlink };
static const tid_t HTMLSelectionObject_iface_tids[] = { diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 2f7544ae191..1afb5131f0d 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -1523,16 +1523,49 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex); }
-static void HTMLXMLHttpRequest_destructor(DispatchEx *dispex) +static void HTMLXMLHttpRequest_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); - remove_target_tasks(This->task_magic); - detach_xhr_event_listener(This->event_listener); + describe_cc_node(&This->ccref, "XMLHttpRequest", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); if(This->pending_progress_event) - IDOMEvent_Release(&This->pending_progress_event->IDOMEvent_iface); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + note_cc_edge((nsISupports*)&This->pending_progress_event->IDOMEvent_iface, "pending_progress_event", cb); + if(This->nsxhr) + note_cc_edge((nsISupports*)This->nsxhr, "nsxhr", cb); +} + +static void HTMLXMLHttpRequest_unlink(DispatchEx *dispex) +{ + HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); + remove_target_tasks(This->task_magic); + if(This->event_listener) { + XMLHttpReqEventListener *event_listener = This->event_listener; + This->event_listener = NULL; + detach_xhr_event_listener(event_listener); + } + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } + if(This->pending_progress_event) { + DOMEvent *pending_progress_event = This->pending_progress_event; + This->pending_progress_event = NULL; + IDOMEvent_Release(&pending_progress_event->IDOMEvent_iface); + } + if(This->nsxhr) { + nsIXMLHttpRequest *nsxhr = This->nsxhr; + This->nsxhr = NULL; + nsIXMLHttpRequest_Release(nsxhr); + } release_event_target(&This->event_target); - nsIXMLHttpRequest_Release(This->nsxhr); +} + +static void HTMLXMLHttpRequest_destructor(DispatchEx *dispex) +{ + HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); free(This); }
@@ -1581,6 +1614,8 @@ static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = { { HTMLXMLHttpRequest_destructor, + HTMLXMLHttpRequest_traverse, + HTMLXMLHttpRequest_unlink }, HTMLXMLHttpRequest_get_gecko_target, HTMLXMLHttpRequest_bind_event @@ -1767,6 +1802,16 @@ static inline HTMLXMLHttpRequestFactory *factory_from_DispatchEx(DispatchEx *ifa return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, dispex); }
+static void HTMLXMLHttpRequestFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "XMLHttpRequestFactory", cb); +} + +static void HTMLXMLHttpRequestFactory_unlink(DispatchEx *dispex) +{ +} + static void HTMLXMLHttpRequestFactory_destructor(DispatchEx *dispex) { HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); @@ -1798,6 +1843,8 @@ static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WOR
static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = { HTMLXMLHttpRequestFactory_destructor, + HTMLXMLHttpRequestFactory_traverse, + HTMLXMLHttpRequestFactory_unlink, HTMLXMLHttpRequestFactory_value };
I think that the series could be split better. One way I'd suggest is to introduce a helper like: ``` void destroy_dispatch(DispatchEx *dispex) { dispex->info->desc->vtbl->unlink(disex); dispex->info->desc->vtbl->destroy(dispex); // maybe if (vtbl->destroy) vtbl->destroy() else free() ?? } ``` Then you could convert all objects to call `destroy_dispatch` in their `Release` implementation in a series of self-contained patches. Once all objects are converted, changing it further will require much less invasive module-wide patches.
Since we will need a lot of unlinking, maybe a helper like: ``` void unlink(void *ptr) { IUnknown **unk_ptr = ptr, unk = *unk_ptr; *unk_ptr = NULL; if (unk) IUnknown_Release(unk); } ``` would make worth it.
One way I'd suggest is to introduce a helper like:
Or, actually, we could probably just do that in `release_dispex`.
On Wed Jul 26 11:39:59 2023 +0000, Jacek Caban wrote:
I think that the series could be split better. One way I'd suggest is to introduce a helper like:
void destroy_dispatch(DispatchEx *dispex) { dispex->info->desc->vtbl->unlink(disex); dispex->info->desc->vtbl->destroy(dispex); // maybe if (vtbl->destroy) vtbl->destroy() else free() ?? }
Then you could convert all objects to call `destroy_dispatch` in their `Release` implementation in a series of self-contained patches. Once all objects are converted, changing it further will require much less invasive module-wide patches. Since we will need a lot of unlinking, maybe a helper like:
void unlink(void *ptr) { IUnknown **unk_ptr = ptr, unk = *unk_ptr; *unk_ptr = NULL; if (unk) IUnknown_Release(unk); }
would make worth it.
Ok, I'll try and see how to split it up with temporary helpers. I'll probably convert this MR just for destruction first, with follow-up MRs doing the unlinking and traversal. I also won't add the cyclic refs (temporary leaks) until later when we actually implement the CC.
In the end, the vtbl won't be optional, which actually simplifies the code *and* makes debugging leaks easier because we can't just "forget" to implement traversal, as it will crash, but that will come later.
I'll probably convert this MR just for destruction first, with follow-up MRs doing the unlinking and traversal.
FWIW, I'm not sure without seeing the result, but it seems to me like introducing unlinking and destructor in the same commit may be better. Once it's done on per-object basis, it should be easy enough and would avoid having to move (and review) the same things twice for each object.