From: Gabriel Ivăncescu gabrielopcode@gmail.com
This avoids having to keep refs to the window from the performance timing. The dispex initialization is deferred until it's actually used, however, so it has the proper compat mode.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 8 ++++++ dlls/mshtml/mshtml_private.h | 11 +++++++- dlls/mshtml/omnavigator.c | 53 ++++++++++++++++++------------------ 3 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 5c5f0542ddd..0bf1a2c6ce3 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -308,6 +308,7 @@ static void release_inner_window(HTMLInnerWindow *This) IHTMLStorage_Release(This->local_storage); }
+ IHTMLPerformanceTiming_Release(&This->performance_timing->IHTMLPerformanceTiming_iface); VariantClear(&This->performance);
if(This->mon) @@ -4056,11 +4057,18 @@ 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)) { + heap_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 d9e2d93d220..744dc4c7801 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -503,6 +503,13 @@ typedef struct { HTMLInnerWindow *window; } OmHistory;
+typedef struct { + DispatchEx dispex; + IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; + + LONG ref; +} HTMLPerformanceTiming; + typedef struct nsChannelBSC nsChannelBSC;
struct HTMLWindow { @@ -579,6 +586,7 @@ struct HTMLInnerWindow {
BOOL performance_initialized; VARIANT performance; + HTMLPerformanceTiming *performance_timing;
unsigned parser_callback_cnt; struct list script_queue; @@ -966,7 +974,8 @@ HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFact HRESULT HTMLLocation_Create(HTMLInnerWindow*,HTMLLocation**) DECLSPEC_HIDDEN; HRESULT create_navigator(compat_mode_t,IOmNavigator**) DECLSPEC_HIDDEN; HRESULT create_html_screen(compat_mode_t,IHTMLScreen**) DECLSPEC_HIDDEN; -HRESULT create_performance(compat_mode_t,IHTMLPerformance**) DECLSPEC_HIDDEN; +HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**) DECLSPEC_HIDDEN; +HRESULT create_performance_timing(HTMLPerformanceTiming**) DECLSPEC_HIDDEN; HRESULT create_history(HTMLInnerWindow*,OmHistory**) DECLSPEC_HIDDEN; HRESULT create_namespace_collection(compat_mode_t,IHTMLNamespaceCollection**) DECLSPEC_HIDDEN; HRESULT create_dom_implementation(HTMLDocumentNode*,IHTMLDOMImplementation**) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index db48cc6213b..4551f4e2dc3 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1497,13 +1497,6 @@ HRESULT create_navigator(compat_mode_t compat_mode, IOmNavigator **navigator) return S_OK; }
-typedef struct { - DispatchEx dispex; - IHTMLPerformanceTiming IHTMLPerformanceTiming_iface; - - LONG ref; -} HTMLPerformanceTiming; - static inline HTMLPerformanceTiming *impl_from_IHTMLPerformanceTiming(IHTMLPerformanceTiming *iface) { return CONTAINING_RECORD(iface, HTMLPerformanceTiming, IHTMLPerformanceTiming_iface); @@ -1549,7 +1542,8 @@ static ULONG WINAPI HTMLPerformanceTiming_Release(IHTMLPerformanceTiming *iface) TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) { - release_dispex(&This->dispex); + if(This->dispex.outer) + release_dispex(&This->dispex); heap_free(This); }
@@ -1863,6 +1857,22 @@ static dispex_static_data_t HTMLPerformanceTiming_dispex = { HTMLPerformanceTiming_iface_tids };
+HRESULT create_performance_timing(HTMLPerformanceTiming **ret) +{ + HTMLPerformanceTiming *timing; + + timing = heap_alloc_zero(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; @@ -2070,8 +2080,7 @@ static ULONG WINAPI HTMLPerformance_Release(IHTMLPerformance *iface) TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) { - if(This->timing) - IHTMLPerformanceTiming_Release(This->timing); + IHTMLPerformanceTiming_Release(This->timing); if(This->navigation) IHTMLPerformanceNavigation_Release(This->navigation); release_dispex(&This->dispex); @@ -2148,21 +2157,6 @@ static HRESULT WINAPI HTMLPerformance_get_timing(IHTMLPerformance *iface, IHTMLP
TRACE("(%p)->(%p)\n", This, p);
- if(!This->timing) { - HTMLPerformanceTiming *timing; - - timing = heap_alloc_zero(sizeof(*timing)); - if(!timing) - return E_OUTOFMEMORY; - - timing->IHTMLPerformanceTiming_iface.lpVtbl = &HTMLPerformanceTimingVtbl; - timing->ref = 1; - 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; } @@ -2208,8 +2202,9 @@ static dispex_static_data_t HTMLPerformance_dispex = { HTMLPerformance_iface_tids };
-HRESULT create_performance(compat_mode_t compat_mode, IHTMLPerformance **ret) +HRESULT create_performance(HTMLInnerWindow *window, IHTMLPerformance **ret) { + compat_mode_t compat_mode = dispex_compat_mode(&window->event_target.dispex); HTMLPerformance *performance;
performance = heap_alloc_zero(sizeof(*performance)); @@ -2222,6 +2217,12 @@ HRESULT create_performance(compat_mode_t compat_mode, IHTMLPerformance **ret) init_dispatch(&performance->dispex, (IUnknown*)&performance->IHTMLPerformance_iface, &HTMLPerformance_dispex, compat_mode);
+ performance->timing = &window->performance_timing->IHTMLPerformanceTiming_iface; + IHTMLPerformanceTiming_AddRef(performance->timing); + + init_dispatch(&window->performance_timing->dispex, (IUnknown*)&window->performance_timing->IHTMLPerformanceTiming_iface, + &HTMLPerformanceTiming_dispex, compat_mode); + *ret = &performance->IHTMLPerformance_iface; return S_OK; }