Jacek Caban : jscript: Added support for Function.arguments property.
Alexandre Julliard
julliard at winehq.org
Wed Jul 28 10:45:03 CDT 2010
Module: wine
Branch: master
Commit: 922efb88bbdb56fa12149bdd6bd377934f8b3b3b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=922efb88bbdb56fa12149bdd6bd377934f8b3b3b
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Jul 27 11:31:01 2010 +0200
jscript: Added support for Function.arguments property.
---
dlls/jscript/function.c | 80 ++++++++++++++++++++++++++++++++------------
dlls/jscript/tests/lang.js | 18 ++++++++++
2 files changed, 76 insertions(+), 22 deletions(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index df46f1d..9f5fb3b 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -35,6 +35,7 @@ typedef struct {
const WCHAR *src_str;
DWORD src_len;
DWORD length;
+ DispatchEx *arguments;
} FunctionInstance;
static inline FunctionInstance *function_from_vdisp(vdisp_t *vdisp)
@@ -53,6 +54,7 @@ static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
static const WCHAR applyW[] = {'a','p','p','l','y',0};
static const WCHAR callW[] = {'c','a','l','l',0};
+static const WCHAR argumentsW[] = {'a','r','g','u','m','e','n','t','s',0};
static IDispatch *get_this(DISPPARAMS *dp)
{
@@ -157,29 +159,20 @@ static HRESULT create_arguments(script_ctx_t *ctx, IDispatch *calee, DISPPARAMS
return S_OK;
}
-static HRESULT create_var_disp(script_ctx_t *ctx, FunctionInstance *function, DISPPARAMS *dp, jsexcept_t *ei,
- IServiceProvider *caller, DispatchEx **ret)
+static HRESULT create_var_disp(script_ctx_t *ctx, FunctionInstance *function, DispatchEx *arg_disp,
+ DISPPARAMS *dp, jsexcept_t *ei, IServiceProvider *caller, DispatchEx **ret)
{
- DispatchEx *var_disp, *arg_disp;
+ DispatchEx *var_disp;
+ VARIANT var;
HRESULT hres;
- static const WCHAR argumentsW[] = {'a','r','g','u','m','e','n','t','s',0};
-
hres = create_dispex(ctx, NULL, NULL, &var_disp);
if(FAILED(hres))
return hres;
- hres = create_arguments(ctx, (IDispatch*)_IDispatchEx_(&function->dispex),
- dp, ei, caller, &arg_disp);
- if(SUCCEEDED(hres)) {
- VARIANT var;
-
- V_VT(&var) = VT_DISPATCH;
- V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(arg_disp);
- hres = jsdisp_propput_name(var_disp, argumentsW, &var, ei, caller);
- jsdisp_release(arg_disp);
- }
-
+ V_VT(&var) = VT_DISPATCH;
+ V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(arg_disp);
+ hres = jsdisp_propput_name(var_disp, argumentsW, &var, ei, caller);
if(SUCCEEDED(hres))
hres = init_parameters(var_disp, function, dp, ei, caller);
if(FAILED(hres)) {
@@ -194,7 +187,7 @@ static HRESULT create_var_disp(script_ctx_t *ctx, FunctionInstance *function, DI
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
- DispatchEx *var_disp;
+ DispatchEx *var_disp, *arg_disp;
exec_ctx_t *exec_ctx;
scope_chain_t *scope;
HRESULT hres;
@@ -204,21 +197,34 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
return E_FAIL;
}
- hres = create_var_disp(ctx, function, dp, ei, caller, &var_disp);
+ hres = create_arguments(ctx, (IDispatch*)_IDispatchEx_(&function->dispex),
+ dp, ei, caller, &arg_disp);
if(FAILED(hres))
return hres;
+ hres = create_var_disp(ctx, function, arg_disp, dp, ei, caller, &var_disp);
+ if(FAILED(hres)) {
+ jsdisp_release(arg_disp);
+ return hres;
+ }
+
hres = scope_push(function->scope_chain, var_disp, &scope);
if(SUCCEEDED(hres)) {
hres = create_exec_ctx(ctx, this_obj, var_disp, scope, &exec_ctx);
scope_release(scope);
}
jsdisp_release(var_disp);
- if(FAILED(hres))
- return hres;
+ if(SUCCEEDED(hres)) {
+ DispatchEx *prev_args;
+
+ prev_args = function->arguments;
+ function->arguments = arg_disp;
+ hres = exec_source(exec_ctx, function->parser, function->source, EXECT_FUNCTION, ei, retv);
+ function->arguments = prev_args;
- hres = exec_source(exec_ctx, function->parser, function->source, EXECT_FUNCTION, ei, retv);
- exec_release(exec_ctx);
+ jsdisp_release(arg_disp);
+ exec_release(exec_ctx);
+ }
return hres;
}
@@ -531,6 +537,35 @@ HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAM
return S_OK;
}
+static HRESULT Function_arguments(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
+ DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+ FunctionInstance *function = (FunctionInstance*)jsthis->u.jsdisp;
+ HRESULT hres = S_OK;
+
+ TRACE("\n");
+
+ switch(flags) {
+ case DISPATCH_PROPERTYGET: {
+ if(function->arguments) {
+ IDispatchEx_AddRef(_IDispatchEx_(function->arguments));
+ V_VT(retv) = VT_DISPATCH;
+ V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(function->arguments);
+ }else {
+ V_VT(retv) = VT_NULL;
+ }
+ break;
+ }
+ case DISPATCH_PROPERTYPUT:
+ break;
+ default:
+ FIXME("unimplemented flags %x\n", flags);
+ hres = E_NOTIMPL;
+ }
+
+ return hres;
+}
+
static void Function_destructor(DispatchEx *dispex)
{
FunctionInstance *This = (FunctionInstance*)dispex;
@@ -544,6 +579,7 @@ static void Function_destructor(DispatchEx *dispex)
static const builtin_prop_t Function_props[] = {
{applyW, Function_apply, PROPF_METHOD|2},
+ {argumentsW, Function_arguments, 0},
{callW, Function_call, PROPF_METHOD|1},
{lengthW, Function_length, 0},
{toStringW, Function_toString, PROPF_METHOD}
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index 36a75f5..c3059be 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -69,11 +69,13 @@ function testFunc1(x, y) {
ok(arguments["0"] === true, "arguments[0] is not true");
ok(arguments["1"] === "test", "arguments[1] is not \"test\"");
ok(arguments.callee === testFunc1, "arguments.calee !== testFunc1");
+ ok(testFunc1.arguments === arguments, "testFunc1.arguments = " + testFunc1.arguments);
return true;
}
ok(testFunc1.length === 2, "testFunc1.length is not 2");
+ok(testFunc1.arguments === null, "testFunc1.arguments = " + testFunc1.arguments);
ok(Object.prototype !== undefined, "Object.prototype is undefined");
ok(Object.prototype.prototype === undefined, "Object.prototype is not undefined");
@@ -109,6 +111,22 @@ ok(typeof(this) === "object", "typeof(this) is not object");
ok(testFunc1(true, "test") === true, "testFunc1 not returned true");
+ok(testFunc1.arguments === null, "testFunc1.arguments = " + testFunc1.arguments);
+
+function testRecFunc(x) {
+ ok(testRecFunc.arguments === arguments, "testRecFunc.arguments = " + testRecFunc.arguments);
+ if(x) {
+ testRecFunc(false);
+ ok(testRecFunc.arguments === arguments, "testRecFunc.arguments = " + testRecFunc.arguments);
+ ok(testRecFunc.arguments[0] === true, "testRecFunc.arguments.x = " + testRecFunc.arguments[0]);
+ }
+}
+
+testRecFunc.arguments = 5;
+ok(testRecFunc.arguments === null, "testRecFunc.arguments = " + testRecFunc.arguments);
+testRecFunc(true);
+ok(testRecFunc.arguments === null, "testRecFunc.arguments = " + testRecFunc.arguments);
+
tmp = (function() {1;})();
ok(tmp === undefined, "tmp = " + tmp);
tmp = eval("1;");
More information about the wine-cvs
mailing list