Bug 886087 - Explicitly tell js_ReportGetterOnlyAssignment whether the assignment was strict rather than examining the stack. r=Waldo.

This commit is contained in:
Jason Orendorff 2013-07-10 08:14:02 -05:00
Родитель 11c11d8f5b
Коммит 50a04a5f70
8 изменённых файлов: 64 добавлений и 13 удалений

Просмотреть файл

@ -0,0 +1,13 @@
// Array.prototype.pop does a strict assignment to this.length even if the
// caller is nonstrict. Bug 886087.
load(libdir + "asserts.js");
// obj.length is read-only
var obj = {pop: [].pop, 0: "zero"};
Object.defineProperty(obj, "length", {configurable: true, value: 1, writable: false});
assertThrowsInstanceOf(() => obj.pop(), TypeError);
// obj.length has only a getter
obj = {pop: [].pop, 0: "zero", get length() { return 1; }};
assertThrowsInstanceOf(() => obj.pop(), TypeError);

Просмотреть файл

@ -0,0 +1,13 @@
// Array.prototype.reverse does a strict assignment to this.length even if the
// caller is nonstrict. Bug 886087.
load(libdir + "asserts.js");
// obj[1] is read-only
var obj = {0: "zero", length: 2, reverse: [].reverse};
Object.defineProperty(obj, "1", {configurable: true, value: "one", writable: false});
assertThrowsInstanceOf(() => obj.reverse(), TypeError);
// obj[1] has only a getter
Object.defineProperty(obj, "1", {configurable: true, get: () => "one"});
assertThrowsInstanceOf(() => obj.reverse(), TypeError);

Просмотреть файл

@ -0,0 +1,29 @@
// The property assignments in Array.prototype.sort are strict assignments.
load(libdir + "asserts.js");
var a = ["A", , "B", "C", "D"];
var normalArrayElementDesc = Object.getOwnPropertyDescriptor(a, 0);
var getterDesc = {
configurable: false,
enumerable: true,
get: function () { return "F"; },
set: undefined
};
Object.defineProperty(a, 1, getterDesc);
// a.sort is permitted to try to delete a[1] or to try to assign a[1], but it
// must try one or the other. Either one will fail, throwing a TypeError.
assertThrowsInstanceOf(() => a.sort(), TypeError);
// a.sort() is not permitted to delete the nonconfigurable property.
assertDeepEq(Object.getOwnPropertyDescriptor(a, 1), getterDesc);
// The values left in the other elements of a are unspecified; some or all may
// have been deleted.
for (var i = 0; i < a.length; i++) {
if (i !== 1 && a.hasOwnProperty(i)) {
normalArrayElementDesc.value = a[i];
assertDeepEq(Object.getOwnPropertyDescriptor(a, i), normalArrayElementDesc);
}
}

Просмотреть файл

@ -328,7 +328,7 @@ CallSetter(JSContext *cx, HandleObject obj, HandleId id, StrictPropertyOp op, un
}
if (attrs & JSPROP_GETTER)
return js_ReportGetterOnlyAssignment(cx);
return js_ReportGetterOnlyAssignment(cx, strict);
if (!(attrs & JSPROP_SHORTID))
return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp);

Просмотреть файл

@ -3944,7 +3944,7 @@ js_NativeSet(JSContext *cx, Handle<JSObject*> obj, Handle<JSObject*> receiver,
* or throw if we're in strict mode.
*/
if (!shape->hasGetterValue() && shape->hasDefaultSetter())
return js_ReportGetterOnlyAssignment(cx);
return js_ReportGetterOnlyAssignment(cx, strict);
}
RootedValue ovp(cx, vp);
@ -4475,7 +4475,7 @@ baseops::SetPropertyHelper(JSContext *cx, HandleObject obj, HandleObject receive
/* ES5 8.12.4 [[Put]] step 2. */
if (shape->isAccessorDescriptor()) {
if (shape->hasDefaultSetter())
return js_ReportGetterOnlyAssignment(cx);
return js_ReportGetterOnlyAssignment(cx, strict);
} else {
JS_ASSERT(shape->isDataDescriptor());
@ -5132,11 +5132,12 @@ js_GetObjectSlotName(JSTracer *trc, char *buf, size_t bufsize)
}
JSBool
js_ReportGetterOnlyAssignment(JSContext *cx)
js_ReportGetterOnlyAssignment(JSContext *cx, bool strict)
{
return JS_ReportErrorFlagsAndNumber(cx,
JSREPORT_WARNING | JSREPORT_STRICT |
JSREPORT_STRICT_MODE_ERROR,
strict
? JSREPORT_ERROR
: JSREPORT_WARNING | JSREPORT_STRICT,
js_GetErrorMessage, NULL,
JSMSG_GETTER_ONLY);
}

Просмотреть файл

@ -1513,7 +1513,7 @@ extern void
js_GetObjectSlotName(JSTracer *trc, char *buf, size_t bufsize);
extern JSBool
js_ReportGetterOnlyAssignment(JSContext *cx);
js_ReportGetterOnlyAssignment(JSContext *cx, bool strict);
extern unsigned
js_InferFlags(JSContext *cx, unsigned defaultFlags);

Просмотреть файл

@ -26,12 +26,7 @@ reportCompare("3|54|1|", actual, "forEach");
actual = a.join(' - ');
reportCompare("3 - 54 - 1", actual, "join");
actual = String(a.sort());
reportCompare("1,54,54", actual, "sort");
a[2]=3;
reportCompare(actual, "1,54,54", "setter");
actual = a.pop();
reportCompare(actual, 3, "pop");

Просмотреть файл

@ -327,7 +327,7 @@ Shape::set(JSContext* cx, HandleObject obj, HandleObject receiver, bool strict,
}
if (attrs & JSPROP_GETTER)
return js_ReportGetterOnlyAssignment(cx);
return js_ReportGetterOnlyAssignment(cx, strict);
Rooted<Shape *> self(cx, this);
RootedId id(cx);