jscript: Support non-extensible objects.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-04-01 18:18:40 +02:00 committed by Alexandre Julliard
parent f568b48e66
commit 7750753758
4 changed files with 19 additions and 5 deletions

View File

@ -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);

View File

@ -247,6 +247,7 @@ struct jsdisp_t {
DWORD prop_cnt;
dispex_prop_t *props;
script_ctx_t *ctx;
BOOL extensible;
jsdisp_t *prototype;

View File

@ -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;
}

View File

@ -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);
});