jscript: Added Function.apply implementation.
This commit is contained in:
parent
8761462b82
commit
5c819cb21b
|
@ -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,
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue