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