jscript: Added Function.apply implementation.

This commit is contained in:
Jacek Caban 2009-08-29 00:02:49 +02:00 committed by Alexandre Julliard
parent 8761462b82
commit 5c819cb21b
2 changed files with 94 additions and 4 deletions

View File

@ -346,11 +346,94 @@ static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISP
return S_OK; return S_OK;
} }
static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, static HRESULT array_to_args(DispatchEx *arg_array, LCID lcid, jsexcept_t *ei, IServiceProvider *caller,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) DISPPARAMS *args)
{ {
FIXME("\n"); VARIANT var, *argv;
return E_NOTIMPL; DWORD length, i;
HRESULT hres;
hres = jsdisp_propget_name(arg_array, lengthW, lcid, &var, ei, NULL/*FIXME*/);
if(FAILED(hres))
return hres;
hres = to_uint32(arg_array->ctx, &var, ei, &length);
VariantClear(&var);
if(FAILED(hres))
return hres;
argv = heap_alloc(length * sizeof(VARIANT));
if(FAILED(hres))
return E_OUTOFMEMORY;
for(i=0; i<length; i++) {
hres = jsdisp_propget_idx(arg_array, i, lcid, argv+i, ei, caller);
if(FAILED(hres)) {
while(i--)
VariantClear(argv+i);
heap_free(argv);
return hres;
}
}
args->cArgs = length;
args->rgvarg = argv;
return S_OK;
}
static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
FunctionInstance *function;
DISPPARAMS args = {NULL,NULL,0,0};
DWORD argc, i;
IDispatch *this_obj;
HRESULT hres = S_OK;
TRACE("\n");
if(!is_class(dispex, JSCLASS_FUNCTION)) {
FIXME("dispex is not a function\n");
return E_FAIL;
}
function = (FunctionInstance*)dispex;
argc = arg_cnt(dp);
if(argc) {
hres = to_object(dispex->ctx, get_arg(dp,0), &this_obj);
if(FAILED(hres))
return hres;
}
if(argc >= 2) {
DispatchEx *arg_array = NULL;
if(V_VT(get_arg(dp,1)) == VT_DISPATCH) {
arg_array = iface_to_jsdisp((IUnknown*)V_DISPATCH(get_arg(dp,1)));
if(!is_class(arg_array, JSCLASS_ARRAY) && !is_class(arg_array, JSCLASS_ARGUMENTS)) {
jsdisp_release(arg_array);
arg_array = NULL;
}
}
if(arg_array) {
hres = array_to_args(arg_array, lcid, ei, caller, &args);
jsdisp_release(arg_array);
}else {
FIXME("throw TypeError");
hres = E_FAIL;
}
}
hres = call_function(function, this_obj, lcid, &args, retv, ei, caller);
if(this_obj)
IDispatch_Release(this_obj);
for(i=0; i<args.cArgs; i++)
VariantClear(args.rgvarg+i);
heap_free(args.rgvarg);
return hres;
} }
static HRESULT Function_call(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, static HRESULT Function_call(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,

View File

@ -1137,12 +1137,19 @@ function callTest(argc) {
callTest.call(tmp, 1, 1); callTest.call(tmp, 1, 1);
callTest.call(tmp, 2, 1, 2); callTest.call(tmp, 2, 1, 2);
callTest.apply(tmp, [1, 1]);
callTest.apply(tmp, [2, 1, 2]);
(function () { callTest.apply(tmp, arguments); })(2,1,2);
function callTest2() { function callTest2() {
ok(this === tmp, "this !== tmp\n"); ok(this === tmp, "this !== tmp\n");
ok(arguments.length === 0, "callTest2: arguments.length = " + arguments.length + " expected 0"); ok(arguments.length === 0, "callTest2: arguments.length = " + arguments.length + " expected 0");
} }
callTest2.call(tmp); callTest2.call(tmp);
callTest2.apply(tmp, []);
callTest2.apply(tmp);
(function () { callTest2.apply(tmp, arguments); })();
function callTest3() { function callTest3() {
ok(arguments.length === 0, "arguments.length = " + arguments.length + " expected 0"); ok(arguments.length === 0, "arguments.length = " + arguments.length + " expected 0");