Module: wine Branch: master Commit: 8761462b8236d47318081edb95524453423fcdef URL: http://source.winehq.org/git/wine.git/?a=commit;h=8761462b8236d47318081edb95...
Author: Jacek Caban jacek@codeweavers.com Date: Sat Aug 29 00:02:22 2009 +0200
jscript: Added Function.call implementation.
---
dlls/jscript/function.c | 63 ++++++++++++++++++++++++++++++++++++++++++-- dlls/jscript/tests/api.js | 28 ++++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 59ece20..3ba4481 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -254,6 +254,34 @@ static HRESULT invoke_value_proc(FunctionInstance *function, LCID lcid, WORD fla return hres; }
+static HRESULT call_function(FunctionInstance *function, IDispatch *this_obj, LCID lcid, DISPPARAMS *args, + VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) +{ + HRESULT hres; + + if(function->value_proc) { + DispatchEx *jsthis = NULL; + + if(this_obj) { + jsthis = iface_to_jsdisp((IUnknown*)this_obj); + if(!jsthis) + FIXME("this_obj is not DispatchEx\n"); + } + + hres = function->value_proc(jsthis ? jsthis : function->dispex.ctx->script_disp, lcid, + DISPATCH_METHOD, args, retv, ei, caller); + + if(jsthis) + jsdisp_release(jsthis); + }else { + hres = invoke_source(function, + this_obj ? this_obj : (IDispatch*)_IDispatchEx_(function->dispex.ctx->script_disp), + lcid, args, retv, ei, caller); + } + + return hres; +} + static HRESULT function_to_string(FunctionInstance *function, BSTR *ret) { BSTR str; @@ -326,10 +354,39 @@ static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR }
static HRESULT Function_call(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, - VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) + VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { - FIXME("\n"); - return E_NOTIMPL; + FunctionInstance *function; + DISPPARAMS args = {NULL,NULL,0,0}; + IDispatch *this_obj = NULL; + DWORD argc; + HRESULT hres; + + 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; + args.cArgs = argc-1; + } + + if(args.cArgs) + args.rgvarg = dp->rgvarg + dp->cArgs - args.cArgs-1; + + hres = call_function(function, this_obj, lcid, &args, retv, ei, caller); + + if(this_obj) + IDispatch_Release(this_obj); + return hres; }
HRESULT Function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index db7bf68..06df0ae 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -1125,6 +1125,34 @@ ok(testFuncToString.toString() === "function testFuncToString(x,y) {\n return ok("" + testFuncToString === "function testFuncToString(x,y) {\n return x+y;\n}", "'' + testFuncToString = " + testFuncToString);
+tmp = new Object(); + +function callTest(argc) { + ok(this === tmp, "this !== tmp\n"); + ok(arguments.length === argc+1, "arguments.length = " + arguments.length + " expected " + (argc+1)); + for(var i=1; i <= argc; i++) + ok(arguments[i] === i, "arguments[i] = " + arguments[i]); +} + +callTest.call(tmp, 1, 1); +callTest.call(tmp, 2, 1, 2); + +function callTest2() { + ok(this === tmp, "this !== tmp\n"); + ok(arguments.length === 0, "callTest2: arguments.length = " + arguments.length + " expected 0"); +} + +callTest2.call(tmp); + +function callTest3() { + ok(arguments.length === 0, "arguments.length = " + arguments.length + " expected 0"); +} + +callTest3.call(); + +tmp = Number.prototype.toString.call(3); +ok(tmp === "3", "Number.prototype.toString.call(3) = " + tmp); + var date = new Date();
date = new Date(100);