jscript: Add Object.isFrozen and Object.isSealed implementation.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f5b6c7cc7e
commit
1f49903e66
|
@ -2646,6 +2646,26 @@ void jsdisp_freeze(jsdisp_t *obj, BOOL seal)
|
||||||
obj->extensible = FALSE;
|
obj->extensible = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL jsdisp_is_frozen(jsdisp_t *obj, BOOL sealed)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if(obj->extensible)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for(i = 0; i < obj->prop_cnt; i++) {
|
||||||
|
if(obj->props[i].type == PROP_JSVAL) {
|
||||||
|
if(!sealed && (obj->props[i].flags & PROPF_WRITABLE))
|
||||||
|
return FALSE;
|
||||||
|
}else if(obj->props[i].type != PROP_ACCESSOR)
|
||||||
|
continue;
|
||||||
|
if(obj->props[i].flags & PROPF_CONFIGURABLE)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT jsdisp_get_prop_name(jsdisp_t *obj, DISPID id, jsstr_t **r)
|
HRESULT jsdisp_get_prop_name(jsdisp_t *obj, DISPID id, jsstr_t **r)
|
||||||
{
|
{
|
||||||
dispex_prop_t *prop = get_prop(obj, id);
|
dispex_prop_t *prop = get_prop(obj, id);
|
||||||
|
|
|
@ -318,6 +318,7 @@ HRESULT jsdisp_define_data_property(jsdisp_t*,const WCHAR*,unsigned,jsval_t) DEC
|
||||||
HRESULT jsdisp_next_prop(jsdisp_t*,DISPID,BOOL,DISPID*) DECLSPEC_HIDDEN;
|
HRESULT jsdisp_next_prop(jsdisp_t*,DISPID,BOOL,DISPID*) DECLSPEC_HIDDEN;
|
||||||
HRESULT jsdisp_get_prop_name(jsdisp_t*,DISPID,jsstr_t**);
|
HRESULT jsdisp_get_prop_name(jsdisp_t*,DISPID,jsstr_t**);
|
||||||
void jsdisp_freeze(jsdisp_t*,BOOL) DECLSPEC_HIDDEN;
|
void jsdisp_freeze(jsdisp_t*,BOOL) DECLSPEC_HIDDEN;
|
||||||
|
BOOL jsdisp_is_frozen(jsdisp_t*,BOOL) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
|
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
|
||||||
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
|
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -760,6 +760,50 @@ static HRESULT Object_isExtensible(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT Object_isFrozen(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc,
|
||||||
|
jsval_t *argv, jsval_t *r)
|
||||||
|
{
|
||||||
|
jsdisp_t *obj;
|
||||||
|
|
||||||
|
if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) {
|
||||||
|
WARN("argument is not an object\n");
|
||||||
|
return JS_E_OBJECT_EXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("(%s)\n", debugstr_jsval(argv[0]));
|
||||||
|
|
||||||
|
obj = to_jsdisp(get_object(argv[0]));
|
||||||
|
if(!obj) {
|
||||||
|
FIXME("Non-JS object\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(r) *r = jsval_bool(jsdisp_is_frozen(obj, FALSE));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT Object_isSealed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc,
|
||||||
|
jsval_t *argv, jsval_t *r)
|
||||||
|
{
|
||||||
|
jsdisp_t *obj;
|
||||||
|
|
||||||
|
if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) {
|
||||||
|
WARN("argument is not an object\n");
|
||||||
|
return JS_E_OBJECT_EXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("(%s)\n", debugstr_jsval(argv[0]));
|
||||||
|
|
||||||
|
obj = to_jsdisp(get_object(argv[0]));
|
||||||
|
if(!obj) {
|
||||||
|
FIXME("Non-JS object\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(r) *r = jsval_bool(jsdisp_is_frozen(obj, TRUE));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static const builtin_prop_t ObjectConstr_props[] = {
|
static const builtin_prop_t ObjectConstr_props[] = {
|
||||||
{L"create", Object_create, PROPF_ES5|PROPF_METHOD|2},
|
{L"create", Object_create, PROPF_ES5|PROPF_METHOD|2},
|
||||||
{L"defineProperties", Object_defineProperties, PROPF_ES5|PROPF_METHOD|2},
|
{L"defineProperties", Object_defineProperties, PROPF_ES5|PROPF_METHOD|2},
|
||||||
|
@ -768,6 +812,8 @@ static const builtin_prop_t ObjectConstr_props[] = {
|
||||||
{L"getOwnPropertyDescriptor", Object_getOwnPropertyDescriptor, PROPF_ES5|PROPF_METHOD|2},
|
{L"getOwnPropertyDescriptor", Object_getOwnPropertyDescriptor, PROPF_ES5|PROPF_METHOD|2},
|
||||||
{L"getPrototypeOf", Object_getPrototypeOf, PROPF_ES5|PROPF_METHOD|1},
|
{L"getPrototypeOf", Object_getPrototypeOf, PROPF_ES5|PROPF_METHOD|1},
|
||||||
{L"isExtensible", Object_isExtensible, PROPF_ES5|PROPF_METHOD|1},
|
{L"isExtensible", Object_isExtensible, PROPF_ES5|PROPF_METHOD|1},
|
||||||
|
{L"isFrozen", Object_isFrozen, PROPF_ES5|PROPF_METHOD|1},
|
||||||
|
{L"isSealed", Object_isSealed, PROPF_ES5|PROPF_METHOD|1},
|
||||||
{L"keys", Object_keys, PROPF_ES5|PROPF_METHOD|1},
|
{L"keys", Object_keys, PROPF_ES5|PROPF_METHOD|1},
|
||||||
{L"preventExtensions", Object_preventExtensions, PROPF_ES5|PROPF_METHOD|1},
|
{L"preventExtensions", Object_preventExtensions, PROPF_ES5|PROPF_METHOD|1},
|
||||||
{L"seal", Object_seal, PROPF_ES5|PROPF_METHOD|1},
|
{L"seal", Object_seal, PROPF_ES5|PROPF_METHOD|1},
|
||||||
|
|
|
@ -1104,6 +1104,74 @@ sync_test("seal", function() {
|
||||||
ok(o.length === 1, "o.length = " + o.length);
|
ok(o.length === 1, "o.length = " + o.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sync_test("isFrozen", function() {
|
||||||
|
ok(Object.isFrozen.length === 1, "Object.isFrozen.length = " + Object.isFrozen.length);
|
||||||
|
ok(Object.isSealed.length === 1, "Object.isSealed.length = " + Object.isSealed.length);
|
||||||
|
|
||||||
|
var o = Object.freeze({});
|
||||||
|
ok(Object.isFrozen(o) === true, "o is not frozen");
|
||||||
|
ok(Object.isSealed(o) === true, "o is not sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
ok(Object.isFrozen({}) === false, "{} is frozen");
|
||||||
|
ok(Object.isSealed({}) === false, "{} is sealed");
|
||||||
|
|
||||||
|
o = Object.preventExtensions({});
|
||||||
|
ok(Object.isFrozen(o) === true, "o is not frozen");
|
||||||
|
ok(Object.isSealed(o) === true, "o is not sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
o = Object.preventExtensions({ prop: 1 });
|
||||||
|
ok(Object.isFrozen(o) === false, "o is frozen");
|
||||||
|
ok(Object.isSealed(o) === false, "o is sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
o = Object.freeze({ prop: 1 });
|
||||||
|
ok(Object.isFrozen(o) === true, "o is not frozen");
|
||||||
|
ok(Object.isSealed(o) === true, "o is not sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
o = Object.seal({ prop: 1 });
|
||||||
|
ok(Object.isFrozen(o) === false, "o is frozen");
|
||||||
|
ok(Object.isSealed(o) === true, "o is not sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
o = {};
|
||||||
|
Object.defineProperty(o, "prop", { value: 1 });
|
||||||
|
Object.preventExtensions(o);
|
||||||
|
ok(Object.isFrozen(o) === true, "o is not frozen");
|
||||||
|
ok(Object.isSealed(o) === true, "o is not sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
o = {};
|
||||||
|
Object.defineProperty(o, "prop", { value: 1, writable: true });
|
||||||
|
Object.preventExtensions(o);
|
||||||
|
ok(Object.isFrozen(o) === false, "o is frozen");
|
||||||
|
ok(Object.isSealed(o) === true, "o is not sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
o = {};
|
||||||
|
Object.defineProperty(o, "prop", { value: 1, writable: true, configurable: true });
|
||||||
|
Object.preventExtensions(o);
|
||||||
|
ok(Object.isFrozen(o) === false, "o is frozen");
|
||||||
|
ok(Object.isSealed(o) === false, "o is sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
o = {};
|
||||||
|
Object.defineProperty(o, "prop", { value: 1, configurable: true });
|
||||||
|
Object.preventExtensions(o);
|
||||||
|
ok(Object.isFrozen(o) === false, "o is frozen");
|
||||||
|
ok(Object.isSealed(o) === false, "o is sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
|
||||||
|
o = {};
|
||||||
|
Object.defineProperty(o, "prop", { get: function() {}, set: function() {} });
|
||||||
|
Object.preventExtensions(o);
|
||||||
|
ok(Object.isFrozen(o) === true, "o is not frozen");
|
||||||
|
ok(Object.isSealed(o) === true, "o is not sealed");
|
||||||
|
ok(Object.isExtensible(o) === false, "o is extensible");
|
||||||
|
});
|
||||||
|
|
||||||
sync_test("head_setter", function() {
|
sync_test("head_setter", function() {
|
||||||
document.head = "";
|
document.head = "";
|
||||||
ok(typeof(document.head) === "object", "typeof(document.head) = " + typeof(document.head));
|
ok(typeof(document.head) === "object", "typeof(document.head) = " + typeof(document.head));
|
||||||
|
|
Loading…
Reference in New Issue