vbscript: Added class_terminate support.

This commit is contained in:
Jacek Caban 2011-09-16 13:29:37 +02:00 committed by Alexandre Julliard
parent 28bddf8dd1
commit 8b6b334c89
4 changed files with 52 additions and 1 deletions

View File

@ -894,6 +894,7 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
HRESULT hres;
static const WCHAR class_initializeW[] = {'c','l','a','s','s','_','i','n','i','t','i','a','l','i','z','e',0};
static const WCHAR class_terminateW[] = {'c','l','a','s','s','_','t','e','r','m','i','n','a','t','e',0};
if(lookup_dim_decls(ctx, class_decl->name) || lookup_funcs_name(ctx, class_decl->name)
|| lookup_class_name(ctx, class_decl->name)) {
@ -912,6 +913,7 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
class_desc->func_cnt = 1; /* always allocate slot for default getter */
class_desc->prop_cnt = 0;
class_desc->class_initialize_id = 0;
class_desc->class_terminate_id = 0;
for(func_decl = class_decl->funcs; func_decl; func_decl = func_decl->next) {
for(func_prop_decl = func_decl; func_prop_decl; func_prop_decl = func_prop_decl->next_prop_func) {
@ -942,6 +944,13 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl)
}
class_desc->class_initialize_id = i;
}else if(!strcmpiW(class_terminateW, func_decl->name)) {
if(func_decl->type != FUNC_SUB) {
FIXME("class terminator is not sub\n");
return E_FAIL;
}
class_desc->class_terminate_id = i;
}
hres = create_class_funcprop(ctx, func_decl, class_desc->funcs + (func_prop_decl ? 0 : i));

View File

@ -491,4 +491,23 @@ Call ok(obj.getPrivateProp() = true, "obj.getPrivateProp() = " & obj.getPrivateP
x = (New testclass).publicProp
Class TermTest
Public Sub Class_Terminate()
funcCalled = "terminate"
End Sub
End Class
Set obj = New TermTest
funcCalled = ""
Set obj = Nothing
Call ok(funcCalled = "terminate", "funcCalled = " & funcCalled)
Set obj = New TermTest
funcCalled = ""
Call obj.Class_Terminate
Call ok(funcCalled = "terminate", "funcCalled = " & funcCalled)
funcCalled = ""
Set obj = Nothing
Call ok(funcCalled = "terminate", "funcCalled = " & funcCalled)
reportSuccess()

View File

@ -123,6 +123,23 @@ static HRESULT invoke_variant_prop(vbdisp_t *This, VARIANT *v, WORD flags, DISPP
return hres;
}
static void run_terminator(vbdisp_t *This)
{
if(This->terminator_ran)
return;
This->terminator_ran = TRUE;
if(This->desc->class_terminate_id) {
DISPPARAMS dp = {0};
This->ref++;
exec_script(This->desc->ctx, This->desc->funcs[This->desc->class_terminate_id].entries[VBDISP_CALLGET],
(IDispatch*)&This->IDispatchEx_iface, &dp, NULL);
This->ref--;
}
}
static void clean_props(vbdisp_t *This)
{
unsigned i;
@ -172,8 +189,12 @@ static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
{
vbdisp_t *This = impl_from_IDispatchEx(iface);
LONG ref = InterlockedIncrement(&This->ref);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref)
run_terminator(This);
if(!ref) {
clean_props(This);
heap_free(This);

View File

@ -77,6 +77,7 @@ typedef struct _class_desc_t {
const WCHAR *name;
script_ctx_t *ctx;
unsigned class_initialize_id;
unsigned class_terminate_id;
unsigned func_cnt;
vbdisp_funcprop_desc_t *funcs;
unsigned prop_cnt;
@ -88,6 +89,7 @@ typedef struct {
IDispatchEx IDispatchEx_iface;
LONG ref;
BOOL terminator_ran;
const class_desc_t *desc;
VARIANT props[1];