vbscript: Added class_terminate support.
This commit is contained in:
parent
28bddf8dd1
commit
8b6b334c89
dlls/vbscript
|
@ -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));
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue