mirror of
https://github.com/reactos/wine.git
synced 2024-11-26 13:10:28 +00:00
mshtml: Make node object cycle collector aware.
This commit is contained in:
parent
4c7e608d5c
commit
97ff991f46
@ -312,7 +312,7 @@ static HRESULT WINAPI HTMLDOMNode_QueryInterface(IHTMLDOMNode *iface,
|
||||
static ULONG WINAPI HTMLDOMNode_AddRef(IHTMLDOMNode *iface)
|
||||
{
|
||||
HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
LONG ref = ccref_incr(&This->ccref, (nsISupports*)&This->IHTMLDOMNode_iface);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
@ -322,7 +322,7 @@ static ULONG WINAPI HTMLDOMNode_AddRef(IHTMLDOMNode *iface)
|
||||
static ULONG WINAPI HTMLDOMNode_Release(IHTMLDOMNode *iface)
|
||||
{
|
||||
HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
LONG ref = ccref_decr(&This->ccref, (nsISupports*)&This->IHTMLDOMNode_iface);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
@ -977,6 +977,8 @@ static const IHTMLDOMNode2Vtbl HTMLDOMNode2Vtbl = {
|
||||
HTMLDOMNode2_get_ownerDocument
|
||||
};
|
||||
|
||||
static nsXPCOMCycleCollectionParticipant node_ccp;
|
||||
|
||||
HRESULT HTMLDOMNode_QI(HTMLDOMNode *This, REFIID riid, void **ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
@ -1001,6 +1003,14 @@ HRESULT HTMLDOMNode_QI(HTMLDOMNode *This, REFIID riid, void **ppv)
|
||||
}else if(IsEqualGUID(&IID_IHTMLDOMNode2, riid)) {
|
||||
TRACE("(%p)->(IID_IHTMLDOMNode2 %p)\n", This, ppv);
|
||||
*ppv = &This->IHTMLDOMNode2_iface;
|
||||
}else if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) {
|
||||
TRACE("(%p)->(IID_nsXPCOMCycleCollectionParticipant %p)\n", This, ppv);
|
||||
*ppv = &node_ccp;
|
||||
return NS_OK;
|
||||
}else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) {
|
||||
TRACE("(%p)->(IID_nsCycleCollectionISupports %p)\n", This, ppv);
|
||||
*ppv = &This->IHTMLDOMNode_iface;
|
||||
return NS_OK;
|
||||
}else if(dispex_query_interface(&This->dispex, riid, ppv)) {
|
||||
return *ppv ? S_OK : E_NOINTERFACE;
|
||||
}
|
||||
@ -1037,12 +1047,9 @@ void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsno
|
||||
{
|
||||
node->IHTMLDOMNode_iface.lpVtbl = &HTMLDOMNodeVtbl;
|
||||
node->IHTMLDOMNode2_iface.lpVtbl = &HTMLDOMNode2Vtbl;
|
||||
node->ref = 2;
|
||||
ccref_init(&node->ccref, &doc->node != node ? 2 : 1);
|
||||
node->doc = doc;
|
||||
|
||||
if(&doc->node != node)
|
||||
node->ref++; /* one extra for list entry reference */
|
||||
|
||||
if(nsnode)
|
||||
nsIDOMNode_AddRef(nsnode);
|
||||
node->nsnode = nsnode;
|
||||
@ -1100,6 +1107,52 @@ static HRESULT create_node(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLDOMNod
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void NSAPI HTMLDOMNode_unmark_if_purple(void *p)
|
||||
{
|
||||
HTMLDOMNode *This = impl_from_IHTMLDOMNode(p);
|
||||
ccref_unmark_if_purple(&This->ccref);
|
||||
}
|
||||
|
||||
static nsresult NSAPI HTMLDOMNode_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb)
|
||||
{
|
||||
HTMLDOMNode *This = impl_from_IHTMLDOMNode(p);
|
||||
|
||||
TRACE("%p\n", This);
|
||||
|
||||
describe_cc_node(&This->ccref, sizeof(*This), "HTMLDOMNode", cb);
|
||||
|
||||
if(This->nsnode)
|
||||
note_cc_edge((nsISupports*)This->nsnode, "This->nsnode", cb);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult NSAPI HTMLDOMNode_unlink(void *p)
|
||||
{
|
||||
HTMLDOMNode *This = impl_from_IHTMLDOMNode(p);
|
||||
|
||||
TRACE("%p\n", This);
|
||||
|
||||
if(This->nsnode) {
|
||||
nsIDOMNode *nsnode = This->nsnode;
|
||||
This->nsnode = NULL;
|
||||
nsIDOMNode_Release(nsnode);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void init_node_cc(void)
|
||||
{
|
||||
static const CCObjCallback node_ccp_callback = {
|
||||
HTMLDOMNode_unmark_if_purple,
|
||||
HTMLDOMNode_traverse,
|
||||
HTMLDOMNode_unlink
|
||||
};
|
||||
|
||||
ccp_init(&node_ccp, &node_ccp_callback);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME
|
||||
* List looks really ugly here. We should use a better data structure or
|
||||
|
@ -225,6 +225,32 @@ struct DispatchEx {
|
||||
dispex_dynamic_data_t *dynamic_data;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *x;
|
||||
} nsCycleCollectingAutoRefCnt;
|
||||
|
||||
typedef struct {
|
||||
void *x[3];
|
||||
} nsXPCOMCycleCollectionParticipant;
|
||||
|
||||
typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback;
|
||||
|
||||
typedef struct {
|
||||
void (NSAPI *unmark_if_purple)(void*);
|
||||
nsresult (NSAPI *traverse)(void*,void*,nsCycleCollectionTraversalCallback*);
|
||||
nsresult (NSAPI *unlink)(void*);
|
||||
} CCObjCallback;
|
||||
|
||||
DEFINE_GUID(IID_nsXPCOMCycleCollectionParticipant, 0x9674489b,0x1f6f,0x4550,0xa7,0x30, 0xcc,0xae,0xdd,0x10,0x4c,0xf9);
|
||||
|
||||
nsrefcnt (__cdecl *ccref_incr)(nsCycleCollectingAutoRefCnt*,nsISupports*);
|
||||
nsrefcnt (__cdecl *ccref_decr)(nsCycleCollectingAutoRefCnt*,nsISupports*);
|
||||
void (__cdecl *ccref_init)(nsCycleCollectingAutoRefCnt*,nsrefcnt);
|
||||
void (__cdecl *ccref_unmark_if_purple)(nsCycleCollectingAutoRefCnt*);
|
||||
void (__cdecl *ccp_init)(nsXPCOMCycleCollectionParticipant*,const CCObjCallback*);
|
||||
void (__cdecl *describe_cc_node)(nsCycleCollectingAutoRefCnt*,size_t,const char*,nsCycleCollectionTraversalCallback*);
|
||||
void (__cdecl *note_cc_edge)(nsISupports*,const char*,nsCycleCollectionTraversalCallback*);
|
||||
|
||||
void init_dispex(DispatchEx*,IUnknown*,dispex_static_data_t*) DECLSPEC_HIDDEN;
|
||||
void release_dispex(DispatchEx*) DECLSPEC_HIDDEN;
|
||||
BOOL dispex_query_interface(DispatchEx*,REFIID,void**) DECLSPEC_HIDDEN;
|
||||
@ -567,7 +593,7 @@ struct HTMLDOMNode {
|
||||
IHTMLDOMNode2 IHTMLDOMNode2_iface;
|
||||
const NodeImplVtbl *vtbl;
|
||||
|
||||
LONG ref;
|
||||
nsCycleCollectingAutoRefCnt ccref;
|
||||
|
||||
nsIDOMNode *nsnode;
|
||||
HTMLDocumentNode *doc;
|
||||
@ -723,6 +749,8 @@ void init_nsio(nsIComponentManager*,nsIComponentRegistrar*) DECLSPEC_HIDDEN;
|
||||
void release_nsio(void) DECLSPEC_HIDDEN;
|
||||
BOOL is_gecko_path(const char*) DECLSPEC_HIDDEN;
|
||||
|
||||
void init_node_cc(void);
|
||||
|
||||
HRESULT nsuri_to_url(LPCWSTR,BOOL,BSTR*) DECLSPEC_HIDDEN;
|
||||
BOOL compare_ignoring_frag(IUri*,IUri*) DECLSPEC_HIDDEN;
|
||||
|
||||
|
@ -345,6 +345,21 @@ static BOOL load_xul(const PRUnichar *gre_path)
|
||||
NS_DLSYM(NS_StringGetData);
|
||||
NS_DLSYM(NS_CStringGetData);
|
||||
|
||||
#undef NS_DLSYM
|
||||
|
||||
#define NS_DLSYM(func) \
|
||||
func = (void *)GetProcAddress(xul_handle, #func); \
|
||||
if(!func) \
|
||||
ERR("Could not GetProcAddress(" #func ") failed\n")
|
||||
|
||||
NS_DLSYM(ccref_incr);
|
||||
NS_DLSYM(ccref_decr);
|
||||
NS_DLSYM(ccref_init);
|
||||
NS_DLSYM(ccref_unmark_if_purple);
|
||||
NS_DLSYM(ccp_init);
|
||||
NS_DLSYM(describe_cc_node);
|
||||
NS_DLSYM(note_cc_edge);
|
||||
|
||||
#undef NS_DLSYM
|
||||
|
||||
return TRUE;
|
||||
@ -561,6 +576,8 @@ static BOOL init_xpcom(const PRUnichar *gre_path)
|
||||
nsIComponentRegistrar_Release(registrar);
|
||||
}
|
||||
|
||||
init_node_cc();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -3448,6 +3448,13 @@ interface nsIDocumentObserver : nsIMutationObserver
|
||||
void AttemptToExecuteScript(nsIContent *aContent, nsIParser *aParser, bool *aBlock);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(c61eac14-5f7a-4481-965e-7eaa6effa85f),
|
||||
local
|
||||
]
|
||||
interface nsCycleCollectionISupports {}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(3682dd99-8560-44f4-9b8f-ccce9d7b96fb),
|
||||
|
Loading…
Reference in New Issue
Block a user