Module: wine Branch: master Commit: f9edb683d260b2175da90e58119aa22ce98a7cd0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f9edb683d260b2175da90e5811...
Author: Jacek Caban jacek@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*);