Jacek Caban : vbscript: Added support for VARIANT references to interp_newenum.

Alexandre Julliard julliard at winehq.org
Mon Mar 10 14:38:29 CDT 2014


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sat Mar  8 14:53:10 2014 +0100

vbscript: Added support for VARIANT references to interp_newenum.

---

 dlls/vbscript/interp.c       |   63 +++++++++++++++++++++++-------------------
 dlls/vbscript/tests/lang.vbs |   13 ++++++++-
 2 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index d05c961..066d675 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -309,33 +309,42 @@ static void stack_popn(exec_ctx_t *ctx, unsigned n)
         VariantClear(stack_pop(ctx));
 }
 
-static HRESULT stack_pop_val(exec_ctx_t *ctx, variant_val_t *v)
+static void stack_pop_deref(exec_ctx_t *ctx, variant_val_t *r)
 {
-    VARIANT *var;
-
-    var = stack_pop(ctx);
+    VARIANT *v;
 
-    if(V_VT(var) == (VT_BYREF|VT_VARIANT)) {
-        v->owned = FALSE;
-        var = V_VARIANTREF(var);
+    v = stack_pop(ctx);
+    if(V_VT(v) == (VT_BYREF|VT_VARIANT)) {
+        r->owned = FALSE;
+        r->v = V_VARIANTREF(v);
     }else {
-        v->owned = TRUE;
+        r->owned = TRUE;
+        r->v = v;
     }
+}
+
+static inline void release_val(variant_val_t *v)
+{
+    if(v->owned)
+        VariantClear(v->v);
+}
+
+static HRESULT stack_pop_val(exec_ctx_t *ctx, variant_val_t *r)
+{
+    stack_pop_deref(ctx, r);
 
-    if(V_VT(var) == VT_DISPATCH) {
+    if(V_VT(r->v) == VT_DISPATCH) {
         DISPPARAMS dp = {0};
         HRESULT hres;
 
-        hres = disp_call(ctx->script, V_DISPATCH(var), DISPID_VALUE, &dp, &v->store);
-        if(v->owned)
-            IDispatch_Release(V_DISPATCH(var));
+        hres = disp_call(ctx->script, V_DISPATCH(r->v), DISPID_VALUE, &dp, &r->store);
+        if(r->owned)
+            IDispatch_Release(V_DISPATCH(r->v));
         if(FAILED(hres))
             return hres;
 
-        v->owned = TRUE;
-        v->v = &v->store;
-    }else {
-        v->v = var;
+        r->owned = TRUE;
+        r->v = &r->store;
     }
 
     return S_OK;
@@ -370,12 +379,6 @@ static HRESULT stack_assume_val(exec_ctx_t *ctx, unsigned n)
     return S_OK;
 }
 
-static inline void release_val(variant_val_t *v)
-{
-    if(v->owned)
-        VariantClear(v->v);
-}
-
 static int stack_pop_bool(exec_ctx_t *ctx, BOOL *b)
 {
     variant_val_t val;
@@ -1079,21 +1082,23 @@ static HRESULT interp_step(exec_ctx_t *ctx)
 
 static HRESULT interp_newenum(exec_ctx_t *ctx)
 {
-    VARIANT *v, r;
+    variant_val_t v;
+    VARIANT r;
     HRESULT hres;
 
     TRACE("\n");
 
-    v = stack_pop(ctx);
-    switch(V_VT(v)) {
+    stack_pop_deref(ctx, &v);
+
+    switch(V_VT(v.v)) {
     case VT_DISPATCH|VT_BYREF:
     case VT_DISPATCH: {
         IEnumVARIANT *iter;
         DISPPARAMS dp = {0};
         VARIANT iterv;
 
-        hres = disp_call(ctx->script, V_ISBYREF(v) ? *V_DISPATCHREF(v) : V_DISPATCH(v), DISPID_NEWENUM, &dp, &iterv);
-        VariantClear(v);
+        hres = disp_call(ctx->script, V_ISBYREF(v.v) ? *V_DISPATCHREF(v.v) : V_DISPATCH(v.v), DISPID_NEWENUM, &dp, &iterv);
+        release_val(&v);
         if(FAILED(hres))
             return hres;
 
@@ -1115,8 +1120,8 @@ static HRESULT interp_newenum(exec_ctx_t *ctx)
         break;
     }
     default:
-        FIXME("Unsupported for %s\n", debugstr_variant(v));
-        VariantClear(v);
+        FIXME("Unsupported for %s\n", debugstr_variant(v.v));
+        release_val(&v);
         return E_NOTIMPL;
     }
 
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 374a986..c1af191 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -19,6 +19,7 @@
 Option Explicit
 
 dim x, y, z
+Dim obj
 
 call ok(true, "true is not true?")
 ok true, "true is not true?"
@@ -486,6 +487,17 @@ next
 Call ok(y = 1, "y = " & y)
 Call ok(x = 2, "x = " & x)
 
+Set obj = collectionObj
+Call obj.reset()
+y = 0
+x = 10
+for each x in obj
+    y = y+1
+    Call ok(x = y, "x <> y")
+next
+Call ok(y = 3, "y = " & y)
+Call ok(getVT(x) = "VT_EMPTY*", "getVT(x) = " & getVT(x))
+
 x = false
 select case 3
     case 2
@@ -767,7 +779,6 @@ Stop
 set x = testObj
 Call ok(getVT(x) = "VT_DISPATCH*", "getVT(x=testObj) = " & getVT(x))
 
-Dim obj
 Set obj = New EmptyClass
 Call ok(getVT(obj) = "VT_DISPATCH*", "getVT(obj) = " & getVT(obj))
 




More information about the wine-cvs mailing list