Jacek Caban : vbscript: Added GC implementation.
Alexandre Julliard
julliard at winehq.org
Fri Sep 16 13:28:33 CDT 2011
Module: wine
Branch: master
Commit: a99dc8cb3dc2ff90f894c746f17ea7b5d7e8c13f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a99dc8cb3dc2ff90f894c746f17ea7b5d7e8c13f
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Sep 16 13:29:47 2011 +0200
vbscript: Added GC implementation.
---
dlls/vbscript/tests/run.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
dlls/vbscript/vbdisp.c | 24 ++++++++++++++++++
dlls/vbscript/vbscript.c | 3 ++
dlls/vbscript/vbscript.h | 3 ++
4 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c
index 3fee711..9aba091 100644
--- a/dlls/vbscript/tests/run.c
+++ b/dlls/vbscript/tests/run.c
@@ -884,6 +884,8 @@ static HRESULT parse_script(DWORD flags, BSTR script_str)
hres = IActiveScriptParse64_ParseScriptText(parser, script_str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ IActiveScript_Close(engine);
+
IDispatch_Release(script_disp);
IActiveScript_Release(engine);
IUnknown_Release(parser);
@@ -907,6 +909,61 @@ static void parse_script_a(const char *src)
parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src);
}
+static void test_gc(void)
+{
+ IActiveScriptParse *parser;
+ IActiveScript *engine;
+ BSTR src;
+ HRESULT hres;
+
+ strict_dispid_check = FALSE;
+
+ engine = create_script();
+ if(!engine)
+ return;
+
+ hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
+
+ hres = IActiveScriptParse64_InitNew(parser);
+ ok(hres == S_OK, "InitNew failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptSite(engine, &ActiveScriptSite);
+ ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
+
+ hres = IActiveScript_AddNamedItem(engine, testW,
+ SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+ ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+
+ hres = IActiveScript_SetScriptState(engine, SCRIPTSTATE_STARTED);
+ ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
+
+ src = a2bstr(
+ "class C\n"
+ " Public ref\n"
+ " Public Sub Class_Terminate\n"
+ " Call reportSuccess()\n"
+ " End Sub\n"
+ "End Class\n"
+ "Dim x\n"
+ "set x = new C\n"
+ "set x.ref = x\n"
+ "set x = nothing\n");
+
+ hres = IActiveScriptParse64_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+ SysFreeString(src);
+
+ SET_EXPECT(global_success_d);
+ SET_EXPECT(global_success_i);
+ IActiveScript_Close(engine);
+ CHECK_CALLED(global_success_d);
+ CHECK_CALLED(global_success_i);
+
+ IActiveScript_Release(engine);
+ IUnknown_Release(parser);
+}
+
static BSTR get_script_from_file(const char *filename)
{
DWORD size, len;
@@ -1041,6 +1098,8 @@ static void run_tests(void)
CHECK_CALLED(testobj_propput_i);
run_from_res("lang.vbs");
+
+ test_gc();
}
static BOOL check_vbscript(void)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index c948f13..c1eba23 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -144,6 +144,9 @@ static void clean_props(vbdisp_t *This)
{
unsigned i;
+ if(!This->desc)
+ return;
+
for(i=0; i < This->desc->prop_cnt; i++)
VariantClear(This->props+i);
}
@@ -197,6 +200,7 @@ static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
run_terminator(This);
if(!ref) {
clean_props(This);
+ list_remove(&This->entry);
heap_free(This);
}
@@ -247,6 +251,9 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
+ if(!This->desc)
+ return E_UNEXPECTED;
+
if(grfdex & ~(fdexNameEnsure|fdexNameCaseInsensitive)) {
FIXME("unsupported flags %x\n", grfdex);
return E_NOTIMPL;
@@ -262,6 +269,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
+ if(!This->desc)
+ return E_UNEXPECTED;
+
if(pvarRes)
V_VT(pvarRes) = VT_EMPTY;
@@ -408,10 +418,24 @@ HRESULT create_vbdisp(const class_desc_t *desc, vbdisp_t **ret)
}
}
+ list_add_tail(&desc->ctx->objects, &vbdisp->entry);
*ret = vbdisp;
return S_OK;
}
+void collect_objects(script_ctx_t *ctx)
+{
+ vbdisp_t *iter, *iter2;
+
+ LIST_FOR_EACH_ENTRY_SAFE(iter, iter2, &ctx->objects, vbdisp_t, entry)
+ run_terminator(iter);
+
+ LIST_FOR_EACH_ENTRY_SAFE(iter, iter2, &ctx->objects, vbdisp_t, entry) {
+ clean_props(iter);
+ iter->desc = NULL;
+ }
+}
+
HRESULT init_global(script_ctx_t *ctx)
{
ctx->script_desc.ctx = ctx;
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index e0598a9..8074799 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -112,6 +112,8 @@ static HRESULT set_ctx_site(VBScript *This)
static void destroy_script(script_ctx_t *ctx)
{
+ collect_objects(ctx);
+
while(!list_empty(&ctx->code_list))
release_vbscode(LIST_ENTRY(list_head(&ctx->code_list), vbscode_t, entry));
@@ -509,6 +511,7 @@ static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface)
if(!ctx)
return E_OUTOFMEMORY;
+ list_init(&ctx->objects);
list_init(&ctx->code_list);
list_init(&ctx->named_items);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 5dd434a..a2c23ea 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -90,6 +90,7 @@ typedef struct {
LONG ref;
BOOL terminator_ran;
+ struct list entry;
const class_desc_t *desc;
VARIANT props[1];
@@ -99,6 +100,7 @@ HRESULT create_vbdisp(const class_desc_t*,vbdisp_t**);
HRESULT disp_get_id(IDispatch*,BSTR,vbdisp_invoke_type_t,BOOL,DISPID*);
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*);
+void collect_objects(script_ctx_t*);
static inline unsigned arg_cnt(const DISPPARAMS *dp)
{
@@ -129,6 +131,7 @@ struct _script_ctx_t {
function_t *global_funcs;
class_desc_t *classes;
+ struct list objects;
struct list code_list;
struct list named_items;
};
More information about the wine-cvs
mailing list