mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 649567 - Propagate atributes on Arguments object properties. Patch also partially by Tom Schuster <evilpies@gmail.com>. r=jwalden
--HG-- extra : rebase_source : 237525c25bb4e3cdc3a2a4ee1553a892b76de3b4
This commit is contained in:
parent
fe8c169a92
commit
4037cc2173
75
js/src/jit-test/tests/arguments/args-attributes.js
Normal file
75
js/src/jit-test/tests/arguments/args-attributes.js
Normal file
@ -0,0 +1,75 @@
|
||||
function strictArgs() {
|
||||
return (function (a, b, c) {'use strict'; return arguments; })(1, 2);
|
||||
}
|
||||
|
||||
function normalArgs() {
|
||||
return (function (a, b, c) { return arguments; })(1, 2);
|
||||
}
|
||||
|
||||
function checkProperty(options, prop, shouldThrow) {
|
||||
var desc, orig;
|
||||
var obj = options.strict ? strictArgs() : normalArgs();
|
||||
var objType = options.strict ? "strict arguments." : "normal arguments.";
|
||||
|
||||
function check() {
|
||||
orig = Object.getOwnPropertyDescriptor(obj, prop);
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
obj[prop] = obj[prop];
|
||||
}
|
||||
catch (e) {
|
||||
threw = true;
|
||||
}
|
||||
assertEq(threw, shouldThrow, objType + prop + " threw");
|
||||
|
||||
if (orig === undefined) {
|
||||
// The property wasn't defined, so we can skip it.
|
||||
return;
|
||||
}
|
||||
|
||||
desc = Object.getOwnPropertyDescriptor(obj, prop);
|
||||
if ("value" in orig) {
|
||||
assertEq(desc.value, orig.value, objType + prop + " value");
|
||||
} else {
|
||||
assertEq(desc.get, orig.get, objType + prop + " get");
|
||||
assertEq(desc.set, orig.set, objType + prop + " set");
|
||||
}
|
||||
assertEq(desc.writable, orig.writable, objType + prop + " writable");
|
||||
assertEq(desc.enumerable, orig.enumerable, objType + prop + " enumerable");
|
||||
assertEq(desc.configurable, orig.configurable, objType + prop + " configurable");
|
||||
}
|
||||
|
||||
check();
|
||||
|
||||
if (orig && orig.configurable) {
|
||||
if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); }
|
||||
Object.defineProperty(obj, prop, {writable: false, enumerable: true});
|
||||
check();
|
||||
|
||||
if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); }
|
||||
Object.defineProperty(obj, prop, {writable: true, enumerable: false});
|
||||
check();
|
||||
|
||||
if(options.refresh) { obj = options.strict ? strictArgs() : normalArgs(); }
|
||||
Object.defineProperty(obj, prop, {writable: false, configurable: false});
|
||||
check();
|
||||
}
|
||||
}
|
||||
|
||||
checkProperty({strict: true, refresh: true}, 'callee', true);
|
||||
checkProperty({strict: true, refresh: false}, 'callee', true);
|
||||
checkProperty({strict: false, refresh: true}, 'callee', false);
|
||||
checkProperty({strict: false, refresh: false}, 'callee', false);
|
||||
|
||||
checkProperty({strict: true, refresh: true}, 'length', false);
|
||||
checkProperty({strict: true, refresh: false}, 'length', false);
|
||||
checkProperty({strict: false, refresh: true}, 'length', false);
|
||||
checkProperty({strict: false, refresh: false}, 'length', false);
|
||||
|
||||
for (var i = 0; i <= 5; i++) {
|
||||
checkProperty({strict: true, refresh: true}, "" + i, false);
|
||||
checkProperty({strict: true, refresh: false}, "" + i, false);
|
||||
checkProperty({strict: false, refresh: true}, "" + i, false);
|
||||
checkProperty({strict: false, refresh: false}, "" + i, false);
|
||||
}
|
@ -162,6 +162,12 @@ ArgSetter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, MutableHa
|
||||
if (!obj->isNormalArguments())
|
||||
return true;
|
||||
|
||||
unsigned attrs;
|
||||
if (!baseops::GetAttributes(cx, obj, id, &attrs))
|
||||
return false;
|
||||
JS_ASSERT(!(attrs & JSPROP_READONLY));
|
||||
attrs &= (JSPROP_ENUMERATE | JSPROP_PERMANENT); /* only valid attributes */
|
||||
|
||||
NormalArgumentsObject &argsobj = obj->asNormalArguments();
|
||||
JSScript *script = argsobj.containingScript();
|
||||
|
||||
@ -191,7 +197,7 @@ ArgSetter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, MutableHa
|
||||
*/
|
||||
RootedValue value(cx);
|
||||
return baseops::DeleteGeneric(cx, obj, id, &value, false) &&
|
||||
baseops::DefineGeneric(cx, obj, id, vp, NULL, NULL, JSPROP_ENUMERATE);
|
||||
baseops::DefineGeneric(cx, obj, id, vp, NULL, NULL, attrs);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -284,6 +290,12 @@ StrictArgSetter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, Mut
|
||||
if (!obj->isStrictArguments())
|
||||
return true;
|
||||
|
||||
unsigned attrs;
|
||||
if (!baseops::GetAttributes(cx, obj, id, &attrs))
|
||||
return false;
|
||||
JS_ASSERT(!(attrs & JSPROP_READONLY));
|
||||
attrs &= (JSPROP_ENUMERATE | JSPROP_PERMANENT); /* only valid attributes */
|
||||
|
||||
Rooted<StrictArgumentsObject*> argsobj(cx, &obj->asStrictArguments());
|
||||
|
||||
if (JSID_IS_INT(id)) {
|
||||
@ -297,14 +309,14 @@ StrictArgSetter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, Mut
|
||||
}
|
||||
|
||||
/*
|
||||
* For simplicity we use delete/set to replace the property with one
|
||||
* For simplicity we use delete/define to replace the property with one
|
||||
* backed by the default Object getter and setter. Note that we rely on
|
||||
* args_delProperty to clear the corresponding reserved slot so the GC can
|
||||
* collect its value.
|
||||
*/
|
||||
RootedValue value(cx);
|
||||
return baseops::DeleteGeneric(cx, argsobj, id, &value, strict) &&
|
||||
baseops::SetPropertyHelper(cx, argsobj, argsobj, id, 0, vp, strict);
|
||||
baseops::DefineGeneric(cx, argsobj, id, vp, NULL, NULL, attrs);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
Loading…
Reference in New Issue
Block a user