diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 44008bdc7eb..909ed37874f 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -922,7 +922,6 @@ HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const built dispex_prop_t *prop; HRESULT hres; - static const WCHAR constructorW[] = {'c','o','n','s','t','r','u','c','t','o','r',0}; static const WCHAR prototypeW[] = {'p','r','o','t','o','t','y','p','e',0}; hres = find_prop_name_prot(constr, string_hash(prototypeW), prototypeW, &prop); @@ -947,21 +946,6 @@ HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const built if(prot) jsdisp_release(prot); - if(FAILED(hres)) - return hres; - - hres = ensure_prop_name(dispex, constructorW, FALSE, 0, &prop); - if(SUCCEEDED(hres)) { - jsexcept_t jsexcept; - VARIANT var; - - var_set_jsdisp(&var, constr); - memset(&jsexcept, 0, sizeof(jsexcept)); - hres = prop_put(dispex, prop, &var, &jsexcept, NULL/*FIXME*/); - } - if(FAILED(hres)) - jsdisp_release(dispex); - return hres; } @@ -1245,6 +1229,18 @@ HRESULT jsdisp_propput_const(jsdisp_t *obj, const WCHAR *name, VARIANT *val) return VariantCopy(&prop->u.var, val); } +HRESULT jsdisp_propput_dontenum(jsdisp_t *obj, const WCHAR *name, VARIANT *val) +{ + dispex_prop_t *prop; + HRESULT hres; + + hres = ensure_prop_name(obj, name, FALSE, 0, &prop); + if(FAILED(hres)) + return hres; + + return VariantCopy(&prop->u.var, val); +} + HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, VARIANT *val, jsexcept_t *ei) { WCHAR buf[12]; diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 1d188e77238..1ce1124bcdf 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -647,7 +647,7 @@ static HRESULT set_constructor_prop(script_ctx_t *ctx, jsdisp_t *constr, jsdisp_ V_VT(&v) = VT_DISPATCH; V_DISPATCH(&v) = to_disp(constr); - return jsdisp_propput_name(prot, constructorW, &v, NULL); + return jsdisp_propput_dontenum(prot, constructorW, &v); } HRESULT create_builtin_constructor(script_ctx_t *ctx, builtin_invoke_t value_proc, const WCHAR *name, @@ -684,6 +684,8 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod hres = create_function(ctx, NULL, PROPF_CONSTR, FALSE, NULL, &function); if(SUCCEEDED(hres)) { hres = set_prototype(ctx, &function->dispex, prototype); + if(SUCCEEDED(hres)) + hres = set_constructor_prop(ctx, &function->dispex, prototype); if(FAILED(hres)) jsdisp_release(&function->dispex); } diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index ca91ee69abf..484049ca790 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -216,6 +216,7 @@ HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*) DECLS HRESULT jsdisp_propget(jsdisp_t*,DISPID,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_propput_name(jsdisp_t*,const WCHAR*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_propput_const(jsdisp_t*,const WCHAR*,VARIANT*) DECLSPEC_HIDDEN; +HRESULT jsdisp_propput_dontenum(jsdisp_t*,const WCHAR*,VARIANT*) DECLSPEC_HIDDEN; HRESULT jsdisp_propput_idx(jsdisp_t*,DWORD,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_propget_name(jsdisp_t*,LPCWSTR,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_get_idx(jsdisp_t*,DWORD,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 515f1b56ea1..26a28b84215 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -91,8 +91,15 @@ ok(Function.prototype.prototype === undefined, "Function.prototype.prototype is ok(Date.prototype !== undefined, "Date.prototype is undefined"); ok(Date.prototype.prototype === undefined, "Date.prototype is not undefined"); -function testConstructor(constr, name) { +function testConstructor(constr, name, inst) { ok(constr.prototype.constructor === constr, name + ".prototype.constructor !== " + name); + ok(constr.prototype.hasOwnProperty("constructor"), name + ".prototype.hasOwnProperty('constructor')"); + + if(!inst) + inst = new constr(); + + ok(inst.constructor === constr, "(new " + name + "()).constructor !== " + name); + ok(!inst.hasOwnProperty("constructor"), "(new " + name + "()).hasOwnProperty('constructor')"); } testConstructor(Object, "Object"); @@ -100,10 +107,10 @@ testConstructor(String, "String"); testConstructor(Array, "Array"); testConstructor(Boolean, "Boolean"); testConstructor(Number, "Number"); -testConstructor(RegExp, "RegExp"); +testConstructor(RegExp, "RegExp", /x/); testConstructor(Function, "Function"); testConstructor(Date, "Date"); -testConstructor(VBArray, "VBArray"); +testConstructor(VBArray, "VBArray", new VBArray(createArray())); testConstructor(Error, "Error"); testConstructor(EvalError, "EvalError"); testConstructor(RangeError, "RangeError"); @@ -194,11 +201,13 @@ function testConstr1() { } testConstr1.prototype.pvar = 1; +ok(testConstr1.prototype.constructor === testConstr1, "testConstr1.prototype.constructor !== testConstr1"); var obj2 = new testConstr1(true); ok(typeof(obj2) === "object", "typeof(obj2) is not object"); ok(obj2.constructor === testConstr1, "unexpected obj2.constructor"); ok(obj2.pvar === 1, "obj2.pvar is not 1"); +ok(!obj2.hasOwnProperty('constructor'), "obj2.hasOwnProperty('constructor')"); testConstr1.prototype.pvar = 2; ok(obj2.pvar === 2, "obj2.pvar is not 2");