From a16f205382994d39a0a10cafac9857a3682321d3 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 9 Sep 2008 01:25:05 +0200 Subject: [PATCH] jscript: Added call expression implementation. --- dlls/jscript/engine.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++-- dlls/jscript/tests/run.c | 28 +++++++++++++++ 2 files changed, 115 insertions(+), 3 deletions(-) diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index b3ae71f3ab3..b74ca47dba9 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -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) diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c index cb71fa88ed2..10c97cdf864 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -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) -- 2.11.4.GIT