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