Jacek Caban : vbscript: Added class_terminate support.

Alexandre Julliard julliard at winehq.org
Fri Sep 16 13:28:33 CDT 2011


Module: wine
Branch: master
Commit: 8b6b334c89e8414c5b8bb2d08b4a6123a4b0482f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8b6b334c89e8414c5b8bb2d08b4a6123a4b0482f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep 16 13:29:37 2011 +0200

vbscript: Added class_terminate support.

---

 dlls/vbscript/compile.c      |    9 +++++++++
 dlls/vbscript/tests/lang.vbs |   19 +++++++++++++++++++
 dlls/vbscript/vbdisp.c       |   23 ++++++++++++++++++++++-
 dlls/vbscript/vbscript.h     |    2 ++
 4 files changed, 52 insertions(+), 1 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 00dfc50..6bacaa0 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -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));
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 46317b9..961eea2 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -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()
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index e1386be..c948f13 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -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);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 270e223..5dd434a 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -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];




More information about the wine-cvs mailing list