Jacek Caban : vbscript: Added support for returning value from function.

Alexandre Julliard julliard at winehq.org
Wed Sep 14 12:25:41 CDT 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 14 12:58:30 2011 +0200

vbscript: Added support for returning value from function.

---

 dlls/vbscript/interp.c       |   29 +++++++++++++++++++++--------
 dlls/vbscript/tests/lang.vbs |   17 +++++++++++++++++
 dlls/vbscript/vbscript.h     |    7 +++++++
 3 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index bb2c282..5c75a14 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -37,6 +37,8 @@ typedef struct {
     unsigned stack_size;
     unsigned top;
     VARIANT *stack;
+
+    VARIANT ret_val;
 } exec_ctx_t;
 
 typedef HRESULT (*instr_func_t)(exec_ctx_t*);
@@ -81,7 +83,7 @@ static BOOL lookup_dynamic_vars(dynamic_var_t *var, const WCHAR *name, ref_t *re
     return FALSE;
 }
 
-static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, ref_t *ref)
+static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_t invoke_type, ref_t *ref)
 {
     named_item_t *item;
     function_t *func;
@@ -89,6 +91,12 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, ref_t *ref)
     DISPID id;
     HRESULT hres;
 
+    if(invoke_type == VBDISP_LET && ctx->func->type == FUNC_FUNCTION && !strcmpiW(name, ctx->func->name)) {
+        ref->type = REF_VAR;
+        ref->u.v = &ctx->ret_val;
+        return S_OK;
+    }
+
     for(i=0; i < ctx->func->var_cnt; i++) {
         if(!strcmpiW(ctx->func->vars[i].name, name)) {
             ref->type = REF_VAR;
@@ -259,7 +267,7 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res)
     DISPPARAMS dp;
     HRESULT hres;
 
-    hres = lookup_identifier(ctx, identifier, &ref);
+    hres = lookup_identifier(ctx, identifier, VBDISP_CALLGET, &ref);
     if(FAILED(hres))
         return hres;
 
@@ -324,7 +332,7 @@ static HRESULT assign_ident(exec_ctx_t *ctx, BSTR name, VARIANT *val, BOOL own_v
     ref_t ref;
     HRESULT hres;
 
-    hres = lookup_identifier(ctx, name, &ref);
+    hres = lookup_identifier(ctx, name, VBDISP_LET, &ref);
     if(FAILED(hres))
         return hres;
 
@@ -838,6 +846,8 @@ static void release_exec(exec_ctx_t *ctx)
 {
     unsigned i;
 
+    VariantClear(&ctx->ret_val);
+
     if(ctx->args) {
         for(i=0; i < ctx->func->arg_cnt; i++)
             VariantClear(ctx->args+i);
@@ -859,11 +869,6 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, DISPPARAMS *dp, VARIANT
     vbsop_t op;
     HRESULT hres = S_OK;
 
-    if(res) {
-        FIXME("returning value is not implemented\n");
-        return E_NOTIMPL;
-    }
-
     exec.code = func->code_ctx;
 
     if(dp ? func->arg_cnt != arg_cnt(dp) : func->arg_cnt) {
@@ -935,6 +940,14 @@ HRESULT exec_script(script_ctx_t *ctx, function_t *func, DISPPARAMS *dp, VARIANT
     }
 
     assert(!exec.top);
+    if(func->type != FUNC_FUNCTION)
+        assert(V_VT(&exec.ret_val) == VT_EMPTY);
+
+    if(SUCCEEDED(hres) && res) {
+        *res = exec.ret_val;
+        V_VT(&exec.ret_val) = VT_EMPTY;
+    }
+
     release_exec(&exec);
 
     return hres;
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 93af6b6..10f03f0 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -313,4 +313,21 @@ End Function
 
 Call TestFuncExit(true)
 
+Function ReturnTrue
+     ReturnTrue = false
+     ReturnTrue = true
+End Function
+
+Call ok(ReturnTrue(), "ReturnTrue returned false?")
+
+Function SetVal(ByRef x, ByVal v)
+    x = v
+    SetVal = x
+    Exit Function
+End Function
+
+x = false
+ok SetVal(x, true), "SetVal returned false?"
+Call ok(x, "x is not set to true by SetVal?")
+
 reportSuccess()
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index 5e86176..3fb57e4 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -61,6 +61,13 @@ typedef struct {
     LONG ref;
 } vbdisp_t;
 
+typedef enum {
+    VBDISP_CALLGET,
+    VBDISP_LET,
+    VBDISP_SET,
+    VBDISP_ANY
+} vbdisp_invoke_type_t;
+
 HRESULT disp_get_id(IDispatch*,BSTR,DISPID*);
 HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,DISPPARAMS*,VARIANT*);
 HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*);




More information about the wine-cvs mailing list