jscript: Added call expression implementation.

This commit is contained in:
Jacek Caban 2008-09-09 01:25:05 +02:00 committed by Alexandre Julliard
parent 652a0121a9
commit a16f205382
2 changed files with 115 additions and 3 deletions

View File

@ -464,16 +464,100 @@ HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags,
return E_NOTIMPL;
}
static void free_dp(DISPPARAMS *dp)
{
DWORD i;
for(i=0; i < dp->cArgs; i++)
VariantClear(dp->rgvarg+i);
heap_free(dp->rgvarg);
}
static HRESULT args_to_param(exec_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp)
{
VARIANTARG *vargs;
exprval_t exprval;
argument_t *iter;
DWORD cnt = 0, i;
HRESULT hres = S_OK;
memset(dp, 0, sizeof(*dp));
for(iter = args; iter; iter = iter->next)
cnt++;
if(!cnt)
return S_OK;
vargs = heap_alloc_zero(cnt * sizeof(*vargs));
if(!vargs)
return E_OUTOFMEMORY;
for(i = cnt, iter = args; iter; iter = iter->next) {
hres = expr_eval(ctx, iter->expr, 0, ei, &exprval);
if(FAILED(hres))
break;
hres = exprval_to_value(ctx->parser->script, &exprval, ei, vargs + (--i));
exprval_release(&exprval);
if(FAILED(hres))
break;
}
if(FAILED(hres)) {
free_dp(dp);
return hres;
}
dp->rgvarg = vargs;
dp->cArgs = cnt;
return S_OK;
}
HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
{
FIXME("\n");
return E_NOTIMPL;
}
HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
{
FIXME("\n");
return E_NOTIMPL;
call_expression_t *expr = (call_expression_t*)_expr;
VARIANT func, var;
exprval_t exprval;
DISPPARAMS dp;
HRESULT hres;
TRACE("\n");
hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
if(FAILED(hres))
return hres;
hres = args_to_param(ctx, expr->argument_list, ei, &dp);
if(SUCCEEDED(hres)) {
switch(exprval.type) {
case EXPRVAL_IDREF:
hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid, DISPATCH_METHOD,
&dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
if(flags & EXPR_NOVAL)
V_VT(&var) = VT_EMPTY;
break;
default:
FIXME("unimplemented type %d\n", V_VT(&func));
hres = E_NOTIMPL;
}
free_dp(&dp);
}
exprval_release(&exprval);
if(FAILED(hres))
return hres;
TRACE("= %s\n", debugstr_variant(&var));
ret->type = EXPRVAL_VARIANT;
ret->u.var = var;
return S_OK;
}
HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)

View File

@ -61,9 +61,12 @@ DEFINE_EXPECT(global_propget_d);
DEFINE_EXPECT(global_propget_i);
DEFINE_EXPECT(global_propput_d);
DEFINE_EXPECT(global_propput_i);
DEFINE_EXPECT(global_success_d);
DEFINE_EXPECT(global_success_i);
#define DISPID_GLOBAL_TESTPROPGET 0x1000
#define DISPID_GLOBAL_TESTPROPPUT 0x1001
#define DISPID_GLOBAL_REPORTSUCCESS 0x1002
static const WCHAR testW[] = {'t','e','s','t',0};
@ -188,6 +191,12 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown
static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
if(!strcmp_wa(bstrName, "reportSuccess")) {
CHECK_EXPECT(global_success_d);
ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
*pid = DISPID_GLOBAL_REPORTSUCCESS;
return S_OK;
}
if(!strcmp_wa(bstrName, "testPropGet")) {
CHECK_EXPECT(global_propget_d);
ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
@ -209,6 +218,19 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
switch(id) {
case DISPID_GLOBAL_REPORTSUCCESS:
CHECK_EXPECT(global_success_i);
ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
ok(pdp != NULL, "pdp == NULL\n");
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
ok(!pvarRes, "pvarRes != NULL\n");
ok(pei != NULL, "pei == NULL\n");
return S_OK;
case DISPID_GLOBAL_TESTPROPGET:
CHECK_EXPECT(global_propget_i);
@ -427,6 +449,12 @@ static void run_tests(void)
parse_script_a("testPropPut = 1;");
CHECK_CALLED(global_propput_d);
CHECK_CALLED(global_propput_i);
SET_EXPECT(global_success_d);
SET_EXPECT(global_success_i);
parse_script_a("reportSuccess();");
CHECK_CALLED(global_success_d);
CHECK_CALLED(global_success_i);
}
START_TEST(run)