From: Jacek Caban Subject: wscript: Added support for calling object by DISPID_VALUE in do_icall. Message-Id: <53CD3ACC.80805@codeweavers.com> Date: Mon, 21 Jul 2014 18:07:40 +0200 --- dlls/vbscript/interp.c | 11 ++++++++++- dlls/vbscript/tests/run.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index 10641db..7c66096 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -561,7 +561,7 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res) v = V_VT(ref.u.v) == (VT_VARIANT|VT_BYREF) ? V_VARIANTREF(ref.u.v) : ref.u.v; if(arg_cnt) { - SAFEARRAY *array; + SAFEARRAY *array = NULL; switch(V_VT(v)) { case VT_ARRAY|VT_BYREF|VT_VARIANT: @@ -570,11 +570,20 @@ static HRESULT do_icall(exec_ctx_t *ctx, VARIANT *res) case VT_ARRAY|VT_VARIANT: array = V_ARRAY(ref.u.v); break; + case VT_DISPATCH: + vbstack_to_dp(ctx, arg_cnt, FALSE, &dp); + hres = disp_call(ctx->script, V_DISPATCH(v), DISPID_VALUE, &dp, res); + if(FAILED(hres)) + return hres; + break; default: FIXME("arguments not implemented\n"); return E_NOTIMPL; } + if(!array) + break; + vbstack_to_dp(ctx, arg_cnt, FALSE, &dp); hres = array_access(ctx, array, &dp, &v); if(FAILED(hres)) diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 56361bf..33cf0cd 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -87,6 +87,7 @@ DEFINE_EXPECT(testobj_propget_d); DEFINE_EXPECT(testobj_propget_i); DEFINE_EXPECT(testobj_propput_d); DEFINE_EXPECT(testobj_propput_i); +DEFINE_EXPECT(testobj_value_i); DEFINE_EXPECT(global_propargput_d); DEFINE_EXPECT(global_propargput_i); DEFINE_EXPECT(global_propargput1_d); @@ -718,6 +719,29 @@ static HRESULT WINAPI testObj_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { switch(id) { + case DISPID_VALUE: { + VARIANT *arg; + int i; + + CHECK_EXPECT(testobj_value_i); + + ok(wFlags == (DISPATCH_PROPERTYGET|DISPATCH_METHOD), "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(pei != NULL, "pei == NULL\n"); + + for(i=0; icArgs; i++) { + arg = pdp->rgvarg+pdp->cArgs-i-1; + ok(V_VT(arg) == VT_I2, "V_VT(arg) = %d\n", V_VT(arg)); + ok(V_I2(arg) == i+1, "V_I2(arg) = %d\n", V_I2(arg)); + } + + V_VT(pvarRes) = VT_I2; + V_I2(pvarRes) = pdp->cArgs; + return S_OK; + } case DISPID_TESTOBJ_PROPGET: CHECK_EXPECT(testobj_propget_i); @@ -2053,6 +2077,14 @@ static void run_tests(void) strict_dispid_check = FALSE; + SET_EXPECT(testobj_value_i); + parse_script_a("dim n,o\n set o = testObj\n n = o(1,2)\n call ok(n=2, \"n = \" & n)\n"); + CHECK_CALLED(testobj_value_i); + + SET_EXPECT(testobj_value_i); + parse_script_a("dim n,o\n set o = testObj\n n = o\n call ok(n=0, \"n = \" & n)\n"); + CHECK_CALLED(testobj_value_i); + parse_script_a("Sub testsub\n" "x = 1\n" "Call ok(x = 1, \"x = \" & x)\n"