vbscript: Added support for returning value from function.

This commit is contained in:
Jacek Caban 2011-09-14 12:58:30 +02:00 committed by Alexandre Julliard
parent 1cefcdb6b7
commit f9edb683d2
3 changed files with 45 additions and 8 deletions

View File

@ -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;

View File

@ -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()

View File

@ -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*);