jscript: Pass jsthis internally without using DISPPARAMS.
This commit is contained in:
parent
17ff7829d3
commit
1dd4cbc491
|
@ -646,7 +646,7 @@ static HRESULT sort_cmp(script_ctx_t *ctx, jsdisp_t *cmp_func, VARIANT *v1, VARI
|
|||
args[0] = *v2;
|
||||
args[1] = *v1;
|
||||
|
||||
hres = jsdisp_call_value(cmp_func, DISPATCH_METHOD, &dp, &res, ei);
|
||||
hres = jsdisp_call_value(cmp_func, NULL, DISPATCH_METHOD, &dp, &res, ei);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ static HRESULT ensure_prop_name(jsdisp_t *This, const WCHAR *name, BOOL search_p
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT set_this(DISPPARAMS *dp, DISPPARAMS *olddp, IDispatch *jsthis)
|
||||
static HRESULT set_this(DISPPARAMS *dp, const DISPPARAMS *olddp, IDispatch *jsthis)
|
||||
{
|
||||
VARIANTARG *oldargs;
|
||||
int i;
|
||||
|
@ -333,6 +333,24 @@ static HRESULT set_this(DISPPARAMS *dp, DISPPARAMS *olddp, IDispatch *jsthis)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static IDispatch *get_this(DISPPARAMS *dp)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
for(i=0; i < dp->cNamedArgs; i++) {
|
||||
if(dp->rgdispidNamedArgs[i] == DISPID_THIS) {
|
||||
if(V_VT(dp->rgvarg+i) == VT_DISPATCH)
|
||||
return V_DISPATCH(dp->rgvarg+i);
|
||||
|
||||
WARN("This is not VT_DISPATCH\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("no this passed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HRESULT convert_params(const DISPPARAMS *dp, VARIANT *buf, DISPPARAMS *ret)
|
||||
{
|
||||
BOOL need_conversion = FALSE;
|
||||
|
@ -382,7 +400,7 @@ static HRESULT convert_params(const DISPPARAMS *dp, VARIANT *buf, DISPPARAMS *re
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT invoke_prop_func(jsdisp_t *This, jsdisp_t *jsthis, dispex_prop_t *prop, WORD flags,
|
||||
static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t *prop, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
@ -401,15 +419,18 @@ static HRESULT invoke_prop_func(jsdisp_t *This, jsdisp_t *jsthis, dispex_prop_t
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(prop->name || jsthis->builtin_info->class != JSCLASS_FUNCTION) {
|
||||
if(prop->name || This->builtin_info->class != JSCLASS_FUNCTION) {
|
||||
vdisp_t vthis;
|
||||
|
||||
set_jsdisp(&vthis, jsthis);
|
||||
if(jsthis)
|
||||
set_disp(&vthis, jsthis);
|
||||
else
|
||||
set_jsdisp(&vthis, This);
|
||||
hres = prop->u.p->invoke(This->ctx, &vthis, flags, ¶ms, retv, ei);
|
||||
vdisp_release(&vthis);
|
||||
}else {
|
||||
/* Function object calls are special case */
|
||||
hres = Function_invoke(This, flags, ¶ms, retv, ei);
|
||||
hres = Function_invoke(This, jsthis, flags, ¶ms, retv, ei);
|
||||
}
|
||||
if(params.rgvarg != buf && params.rgvarg != dp->rgvarg)
|
||||
heap_free(params.rgvarg);
|
||||
|
@ -418,8 +439,6 @@ static HRESULT invoke_prop_func(jsdisp_t *This, jsdisp_t *jsthis, dispex_prop_t
|
|||
case PROP_PROTREF:
|
||||
return invoke_prop_func(This->prototype, jsthis, This->prototype->props+prop->u.ref, flags, dp, retv, ei, caller);
|
||||
case PROP_VARIANT: {
|
||||
DISPPARAMS new_dp;
|
||||
|
||||
if(V_VT(&prop->u.var) != VT_DISPATCH) {
|
||||
FIXME("invoke vt %d\n", V_VT(&prop->u.var));
|
||||
return E_FAIL;
|
||||
|
@ -427,19 +446,7 @@ static HRESULT invoke_prop_func(jsdisp_t *This, jsdisp_t *jsthis, dispex_prop_t
|
|||
|
||||
TRACE("call %s %p\n", debugstr_w(prop->name), V_DISPATCH(&prop->u.var));
|
||||
|
||||
hres = set_this(&new_dp, dp, to_disp(jsthis));
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = disp_call(This->ctx, V_DISPATCH(&prop->u.var), DISPID_VALUE, flags, &new_dp, retv, ei);
|
||||
|
||||
if(new_dp.rgvarg != dp->rgvarg) {
|
||||
heap_free(new_dp.rgvarg);
|
||||
if(new_dp.cNamedArgs > 1)
|
||||
heap_free(new_dp.rgdispidNamedArgs);
|
||||
}
|
||||
|
||||
return hres;
|
||||
return disp_call_value(This->ctx, V_DISPATCH(&prop->u.var), jsthis, flags, dp, retv, ei);
|
||||
}
|
||||
default:
|
||||
ERR("type %d\n", prop->type);
|
||||
|
@ -732,7 +739,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
/* fall through */
|
||||
case DISPATCH_METHOD:
|
||||
case DISPATCH_CONSTRUCT:
|
||||
hres = invoke_prop_func(This, This, prop, wFlags, pdp, pvarRes, &jsexcept, pspCaller);
|
||||
hres = invoke_prop_func(This, get_this(pdp), prop, wFlags, pdp, pvarRes, &jsexcept, pspCaller);
|
||||
break;
|
||||
case DISPATCH_PROPERTYGET:
|
||||
hres = prop_get(This, prop, pdp, pvarRes, &jsexcept, pspCaller);
|
||||
|
@ -1055,14 +1062,21 @@ HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *
|
|||
return DISP_E_UNKNOWNNAME;
|
||||
}
|
||||
|
||||
HRESULT jsdisp_call_value(jsdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei)
|
||||
HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei)
|
||||
{
|
||||
vdisp_t vdisp;
|
||||
HRESULT hres;
|
||||
|
||||
set_jsdisp(&vdisp, jsthis);
|
||||
hres = jsthis->builtin_info->value_prop.invoke(jsthis->ctx, &vdisp, flags, dp, retv, ei);
|
||||
vdisp_release(&vdisp);
|
||||
TRACE("args %p\n", dp->rgvarg);
|
||||
|
||||
if(is_class(jsfunc, JSCLASS_FUNCTION)) {
|
||||
hres = Function_invoke(jsfunc, jsthis, flags, dp, retv, ei);
|
||||
}else {
|
||||
vdisp_t vdisp;
|
||||
|
||||
set_disp(&vdisp, jsthis);
|
||||
hres = jsfunc->builtin_info->value_prop.invoke(jsfunc->ctx, &vdisp, flags, dp, retv, ei);
|
||||
vdisp_release(&vdisp);
|
||||
}
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1092,7 @@ HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, DISPPARAMS *dp, VARIA
|
|||
if(!prop)
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
return invoke_prop_func(disp, disp, prop, flags, dp, retv, ei, NULL);
|
||||
return invoke_prop_func(disp, to_disp(disp), prop, flags, dp, retv, ei, NULL);
|
||||
}
|
||||
|
||||
HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, DISPPARAMS *dp, VARIANT *retv,
|
||||
|
@ -1095,7 +1109,7 @@ HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, DISPPARA
|
|||
if(retv)
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
|
||||
return invoke_prop_func(disp, disp, prop, flags, dp, retv, ei, NULL);
|
||||
return invoke_prop_func(disp, to_disp(disp), prop, flags, dp, retv, ei, NULL);
|
||||
}
|
||||
|
||||
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei)
|
||||
|
@ -1146,6 +1160,71 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DIS
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei)
|
||||
{
|
||||
DISPPARAMS params;
|
||||
jsdisp_t *jsdisp;
|
||||
IDispatchEx *dispex;
|
||||
HRESULT hres;
|
||||
|
||||
jsdisp = iface_to_jsdisp((IUnknown*)disp);
|
||||
if(jsdisp) {
|
||||
if(flags & DISPATCH_PROPERTYPUT) {
|
||||
FIXME("disp_call(propput) on builtin object\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hres = jsdisp_call_value(jsdisp, jsthis, flags, dp, retv, ei);
|
||||
jsdisp_release(jsdisp);
|
||||
return hres;
|
||||
}
|
||||
|
||||
memset(ei, 0, sizeof(*ei));
|
||||
if(retv && arg_cnt(dp))
|
||||
flags |= DISPATCH_PROPERTYGET;
|
||||
|
||||
if(jsthis) {
|
||||
hres = set_this(¶ms, dp, jsthis);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}else {
|
||||
params = *dp;
|
||||
}
|
||||
|
||||
if(retv)
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, ctx->lcid, flags, ¶ms, retv, &ei->ei,
|
||||
&ctx->jscaller->IServiceProvider_iface);
|
||||
IDispatchEx_Release(dispex);
|
||||
}else {
|
||||
UINT err = 0;
|
||||
|
||||
if(flags == DISPATCH_CONSTRUCT) {
|
||||
WARN("IDispatch cannot be constructor\n");
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
}
|
||||
|
||||
TRACE("using IDispatch\n");
|
||||
hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, ctx->lcid, flags, ¶ms, retv, &ei->ei, &err);
|
||||
}
|
||||
|
||||
if(params.rgvarg != dp->rgvarg) {
|
||||
heap_free(params.rgvarg);
|
||||
if(params.cNamedArgs > 1)
|
||||
heap_free(params.rgdispidNamedArgs);
|
||||
}
|
||||
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(retv)
|
||||
ensure_retval_type(retv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, VARIANT *val, jsexcept_t *ei)
|
||||
{
|
||||
dispex_prop_t *prop;
|
||||
|
|
|
@ -1014,8 +1014,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
|
|||
return throw_type_error(ctx->script, ctx->ei, JS_E_INVALID_PROPERTY, NULL);
|
||||
|
||||
jsstack_to_dp(ctx, arg, &dp);
|
||||
hres = disp_call(ctx->script, V_DISPATCH(constr), DISPID_VALUE,
|
||||
DISPATCH_CONSTRUCT, &dp, &v, ctx->ei);
|
||||
hres = disp_call_value(ctx->script, V_DISPATCH(constr), NULL, DISPATCH_CONSTRUCT, &dp, &v, ctx->ei);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -1039,7 +1038,7 @@ static HRESULT interp_call(exec_ctx_t *ctx)
|
|||
return throw_type_error(ctx->script, ctx->ei, JS_E_INVALID_PROPERTY, NULL);
|
||||
|
||||
jsstack_to_dp(ctx, argn, &dp);
|
||||
hres = disp_call(ctx->script, V_DISPATCH(objv), DISPID_VALUE, DISPATCH_METHOD, &dp,
|
||||
hres = disp_call_value(ctx->script, V_DISPATCH(objv), NULL, DISPATCH_METHOD, &dp,
|
||||
do_ret ? &v : NULL, ctx->ei);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
|
|
@ -307,23 +307,23 @@ static HRESULT function_to_string(FunctionInstance *function, BSTR *ret)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Function_invoke(jsdisp_t *func_this, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei)
|
||||
HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei)
|
||||
{
|
||||
FunctionInstance *function;
|
||||
|
||||
TRACE("\n");
|
||||
TRACE("func %p this %p\n", func_this, jsthis);
|
||||
|
||||
assert(is_class(func_this, JSCLASS_FUNCTION));
|
||||
function = (FunctionInstance*)func_this;
|
||||
|
||||
if(function->value_proc)
|
||||
return invoke_value_proc(function->dispex.ctx, function, get_this(dp), flags, dp, retv, ei);
|
||||
return invoke_value_proc(function->dispex.ctx, function, jsthis, flags, dp, retv, ei);
|
||||
|
||||
if(flags == DISPATCH_CONSTRUCT)
|
||||
return invoke_constructor(function->dispex.ctx, function, dp, retv, ei);
|
||||
|
||||
assert(flags == DISPATCH_METHOD);
|
||||
return invoke_source(function->dispex.ctx, function, get_this(dp), dp, retv, ei);
|
||||
return invoke_source(function->dispex.ctx, function, jsthis, dp, retv, ei);
|
||||
}
|
||||
|
||||
static HRESULT Function_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
|
|
|
@ -117,7 +117,7 @@ static HRESULT constructor_call(jsdisp_t *constr, WORD flags, DISPPARAMS *dp,
|
|||
VARIANT *retv, jsexcept_t *ei)
|
||||
{
|
||||
if(flags != DISPATCH_PROPERTYGET)
|
||||
return jsdisp_call_value(constr, flags, dp, retv, ei);
|
||||
return jsdisp_call_value(constr, NULL, flags, dp, retv, ei);
|
||||
|
||||
jsdisp_addref(constr);
|
||||
var_set_jsdisp(retv, constr);
|
||||
|
|
|
@ -207,7 +207,8 @@ HRESULT init_dispex(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DEC
|
|||
HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_call_value(jsdisp_t*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_call_value(script_ctx_t*,IDispatch*,IDispatch*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_call_value(jsdisp_t*,IDispatch*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_call(jsdisp_t*,DISPID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT jsdisp_call_name(jsdisp_t*,const WCHAR*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT disp_propget(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
|
||||
|
@ -225,7 +226,7 @@ VARIANT_BOOL jsdisp_is_own_prop(jsdisp_t *obj, BSTR name) DECLSPEC_HIDDEN;
|
|||
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
|
||||
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||
HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
|
||||
HRESULT Function_invoke(jsdisp_t*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*);
|
||||
HRESULT Function_invoke(jsdisp_t*,IDispatch*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*);
|
||||
|
||||
HRESULT throw_eval_error(script_ctx_t*,jsexcept_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
|
||||
HRESULT throw_generic_error(script_ctx_t*,jsexcept_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -728,7 +728,7 @@ static HRESULT rep_call(script_ctx_t *ctx, jsdisp_t *func, const WCHAR *str, mat
|
|||
}
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
hres = jsdisp_call_value(func, DISPATCH_METHOD, &dp, &var, ei);
|
||||
hres = jsdisp_call_value(func, NULL, DISPATCH_METHOD, &dp, &var, ei);
|
||||
|
||||
for(i=0; i < parens_cnt+3; i++) {
|
||||
if(i != parens_cnt+1)
|
||||
|
|
Loading…
Reference in New Issue