Module: wine Branch: master Commit: 7750753758693cbd09b978dfb53557c3b0715335 URL: https://source.winehq.org/git/wine.git/?a=commit;h=7750753758693cbd09b978dfb...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Apr 1 18:18:40 2021 +0200
jscript: Support non-extensible objects.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/jscript/dispex.c | 12 +++++++++--- dlls/jscript/jscript.h | 1 + dlls/jscript/object.c | 3 ++- dlls/mshtml/tests/es5.js | 8 +++++++- 4 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 0f0907063f8..303e5bb8c99 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -474,6 +474,8 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val) return prop->u.p->setter(This->ctx, This, val); case PROP_PROTREF: case PROP_DELETED: + if(!This->extensible) + return S_OK; prop->type = PROP_JSVAL; prop->flags = PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE; prop->u.val = jsval_undefined(); @@ -1747,6 +1749,7 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl; dispex->ref = 1; dispex->builtin_info = builtin_info; + dispex->extensible = TRUE;
dispex->props = heap_alloc_zero(sizeof(dispex_prop_t)*(dispex->buf_size=4)); if(!dispex->props) @@ -1894,7 +1897,7 @@ HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID * dispex_prop_t *prop; HRESULT hres;
- if(flags & fdexNameEnsure) + if(jsdisp->extensible && (flags & fdexNameEnsure)) hres = ensure_prop_name(jsdisp, name, PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE, &prop); else @@ -2147,8 +2150,11 @@ HRESULT jsdisp_propput(jsdisp_t *obj, const WCHAR *name, DWORD flags, jsval_t va dispex_prop_t *prop; HRESULT hres;
- hres = ensure_prop_name(obj, name, flags, &prop); - if(FAILED(hres)) + if(obj->extensible) + hres = ensure_prop_name(obj, name, flags, &prop); + else + hres = find_prop_name_prot(obj, string_hash(name), name, &prop); + if(FAILED(hres) || !prop) return hres;
return prop_put(obj, prop, val); diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index c8ec7622caf..f27f660d802 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -247,6 +247,7 @@ struct jsdisp_t { DWORD prop_cnt; dispex_prop_t *props; script_ctx_t *ctx; + BOOL extensible;
jsdisp_t *prototype;
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c index 1e94f163446..da91b744128 100644 --- a/dlls/jscript/object.c +++ b/dlls/jscript/object.c @@ -680,7 +680,7 @@ static HRESULT Object_preventExtensions(script_ctx_t *ctx, vdisp_t *jsthis, WORD return E_NOTIMPL; }
- FIXME("(%s) semi-stub\n", debugstr_jsval(argv[0])); + TRACE("(%s)\n", debugstr_jsval(argv[0]));
obj = to_jsdisp(get_object(argv[0])); if(!obj) { @@ -688,6 +688,7 @@ static HRESULT Object_preventExtensions(script_ctx_t *ctx, vdisp_t *jsthis, WORD return E_NOTIMPL; }
+ obj->extensible = FALSE; if(r) *r = jsval_obj(jsdisp_addref(obj)); return S_OK; } diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index e8c523b0bf7..3eccc38fada 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -947,7 +947,6 @@ sync_test("preventExtensions", function() { var r = Object.preventExtensions(o); ok(r === o, "r != o"); o.x = 1; - todo_wine. ok(!("x" in o), "x property added to o"); try { Object.defineProperty(o, "y", { value: true }); @@ -960,6 +959,13 @@ sync_test("preventExtensions", function() { r = Object.preventExtensions(o); ok(r === o, "r != o");
+ function Constr() {} + o = Object.preventExtensions(new Constr()); + Constr.prototype.prop = 1; + ok(o.prop === 1, "o.prop = " + o.prop); + o.prop = 2; + ok(o.prop === 1, "o.prop = " + o.prop); + ok(Object.preventExtensions.length === 1, "Object.preventExtensions.length = " + Object.preventExtensions.length); });