diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index c2ea230229c..3863f7dab37 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -41,7 +41,6 @@ static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0}; 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 toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0}; -static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; static const WCHAR applyW[] = {'a','p','p','l','y',0}; static const WCHAR callW[] = {'c','a','l','l',0}; static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0}; @@ -299,21 +298,6 @@ static HRESULT Function_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags return E_NOTIMPL; } -static HRESULT Function_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, - VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) -{ - WARN("should be inherited from Object\n"); - - if(retv) { - IDispatchEx_AddRef(_IDispatchEx_(dispex)); - - V_VT(retv) = VT_DISPATCH; - V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(dispex); - } - - return S_OK; -} - static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { @@ -416,8 +400,7 @@ static const builtin_prop_t Function_props[] = { {lengthW, Function_length, 0}, {propertyIsEnumerableW, Function_propertyIsEnumerable, PROPF_METHOD}, {toLocaleStringW, Function_toLocaleString, PROPF_METHOD}, - {toStringW, Function_toString, PROPF_METHOD}, - {valueOfW, Function_valueOf, PROPF_METHOD} + {toStringW, Function_toString, PROPF_METHOD} }; static const builtin_info_t Function_info = { @@ -465,35 +448,38 @@ static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_ function->flags = flags; function->length = flags & PROPF_ARGMASK; - if(prototype) { - jsexcept_t jsexcept; - VARIANT var; - - V_VT(&var) = VT_DISPATCH; - V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype); - memset(&jsexcept, 0, sizeof(jsexcept)); - - hres = jsdisp_propput_name(&function->dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/); - if(FAILED(hres)) { - IDispatchEx_Release(_IDispatchEx_(&function->dispex)); - return hres; - } - } - *ret = function; return S_OK; } +static HRESULT set_prototype(script_ctx_t *ctx, DispatchEx *dispex, DispatchEx *prototype) +{ + jsexcept_t jsexcept; + VARIANT var; + + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype); + memset(&jsexcept, 0, sizeof(jsexcept)); + + return jsdisp_propput_name(dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/); +} + HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, const builtin_info_t *builtin_info, DWORD flags, DispatchEx *prototype, DispatchEx **ret) { FunctionInstance *function; HRESULT hres; - hres = create_function(ctx, builtin_info, flags, FALSE, prototype, &function); + hres = create_function(ctx, builtin_info, flags, FALSE, NULL, &function); if(FAILED(hres)) return hres; + hres = set_prototype(ctx, &function->dispex, prototype); + if(FAILED(hres)) { + jsdisp_release(&function->dispex); + return hres; + } + function->value_proc = value_proc; *ret = &function->dispex; @@ -513,7 +499,12 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc if(FAILED(hres)) return hres; - hres = create_function(ctx->script, NULL, PROPF_CONSTR, FALSE, prototype, &function); + hres = create_function(ctx->script, NULL, PROPF_CONSTR, FALSE, NULL, &function); + if(SUCCEEDED(hres)) { + hres = set_prototype(ctx->script, &function->dispex, prototype); + if(FAILED(hres)) + jsdisp_release(&function->dispex); + } jsdisp_release(prototype); if(FAILED(hres)) return hres; @@ -540,23 +531,28 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc return S_OK; } -HRESULT init_function_constr(script_ctx_t *ctx) +HRESULT init_function_constr(script_ctx_t *ctx, DispatchEx *object_prototype) { FunctionInstance *prot, *constr; HRESULT hres; - hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, NULL, &prot); + hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, object_prototype, &prot); if(FAILED(hres)) return hres; prot->value_proc = FunctionProt_value; hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, &prot->dispex, &constr); + if(SUCCEEDED(hres)) { + constr->value_proc = FunctionConstr_value; + hres = set_prototype(ctx, &constr->dispex, &prot->dispex); + if(FAILED(hres)) + jsdisp_release(&constr->dispex); + } jsdisp_release(&prot->dispex); if(FAILED(hres)) return hres; - constr->value_proc = FunctionConstr_value; ctx->function_constr = &constr->dispex; - return hres; + return S_OK; } diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index 4f95653173a..9428e6578e2 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -574,15 +574,15 @@ static const builtin_info_t JSGlobal_info = { NULL }; -static HRESULT init_constructors(script_ctx_t *ctx) +static HRESULT init_constructors(script_ctx_t *ctx, DispatchEx *object_prototype) { HRESULT hres; - hres = init_function_constr(ctx); + hres = init_function_constr(ctx, object_prototype); if(FAILED(hres)) return hres; - hres = create_object_constr(ctx, &ctx->object_constr); + hres = create_object_constr(ctx, object_prototype, &ctx->object_constr); if(FAILED(hres)) return hres; @@ -615,14 +615,19 @@ static HRESULT init_constructors(script_ctx_t *ctx) HRESULT init_global(script_ctx_t *ctx) { - DispatchEx *math; + DispatchEx *math, *object_prototype; VARIANT var; HRESULT hres; if(ctx->global) return S_OK; - hres = init_constructors(ctx); + hres = create_object_prototype(ctx, &object_prototype); + if(FAILED(hres)) + return hres; + + hres = init_constructors(ctx, object_prototype); + jsdisp_release(object_prototype); if(FAILED(hres)) return hres; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 8d7d61f1018..258f3d3bcd6 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -200,13 +200,14 @@ static inline void script_addref(script_ctx_t *ctx) } HRESULT init_global(script_ctx_t*); -HRESULT init_function_constr(script_ctx_t*); +HRESULT init_function_constr(script_ctx_t*,DispatchEx*); +HRESULT create_object_prototype(script_ctx_t*,DispatchEx**); HRESULT create_array_constr(script_ctx_t*,DispatchEx**); HRESULT create_bool_constr(script_ctx_t*,DispatchEx**); HRESULT create_date_constr(script_ctx_t*,DispatchEx**); HRESULT create_number_constr(script_ctx_t*,DispatchEx**); -HRESULT create_object_constr(script_ctx_t*,DispatchEx**); +HRESULT create_object_constr(script_ctx_t*,DispatchEx*,DispatchEx**); HRESULT create_regexp_constr(script_ctx_t*,DispatchEx**); HRESULT create_string_constr(script_ctx_t*,DispatchEx**); diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index fe9a50c9c72..0dca008d08f 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -161,19 +161,15 @@ static HRESULT ObjectConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS return S_OK; } -HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx **ret) +HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret) { - DispatchEx *object; - HRESULT hres; + return create_builtin_function(ctx, ObjectConstr_value, NULL, PROPF_CONSTR, + object_prototype, ret); +} - hres = create_dispex(ctx, &Object_info, NULL, &object); - if(FAILED(hres)) - return hres; - - hres = create_builtin_function(ctx, ObjectConstr_value, NULL, PROPF_CONSTR, object, ret); - - jsdisp_release(object); - return hres; +HRESULT create_object_prototype(script_ctx_t *ctx, DispatchEx **ret) +{ + return create_dispex(ctx, &Object_info, NULL, ret); } HRESULT create_object(script_ctx_t *ctx, DispatchEx *constr, DispatchEx **ret) diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 22b531704ca..db03fdb8cb3 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -972,16 +972,18 @@ ok(isNaN(tmp), "Math.tan(-Infinity) is not NaN"); var func = function (a) { var a = 1; if(a) return; - }.toString(); + }; ok(func.toString() === "function (a) {\n var a = 1;\n if(a) return;\n }", "func.toString() = " + func.toString()); ok("" + func === "function (a) {\n var a = 1;\n if(a) return;\n }", "'' + func.toString() = " + func); +ok(func.valueOf === Object.prototype.valueOf, "func.valueOf !== Object.prototype.valueOf"); +ok(func === func.valueOf(), "func !== func.valueOf()"); + function testFuncToString(x,y) { return x+y; } - ok(testFuncToString.toString() === "function testFuncToString(x,y) {\n return x+y;\n}", "testFuncToString.toString() = " + testFuncToString.toString()); ok("" + testFuncToString === "function testFuncToString(x,y) {\n return x+y;\n}", diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index fcd6ec3d5c7..b865ad5c023 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -84,7 +84,7 @@ ok(RegExp.prototype !== undefined, "RegExp.prototype is undefined"); ok(Math !== undefined, "Math is undefined"); ok(Math.prototype === undefined, "Math.prototype is not undefined"); ok(Function.prototype !== undefined, "Function.prototype is undefined"); -ok(Function.prototype.prototype === undefined, "Function.prototype is not undefined"); +ok(Function.prototype.prototype === undefined, "Function.prototype.prototype is not undefined"); ok(Date.prototype !== undefined, "Date.prototype is undefined"); ok(Date.prototype.prototype === undefined, "Date.prototype is not undefined");