Bug 1206300 - Allow immutable prototypes to be disabled at compile time with a single-line change, but don't actually disable them. r=jorendorff

This commit is contained in:
Jeff Walden 2015-09-18 17:16:08 -07:00
Родитель bdefda6d0b
Коммит 9f027cf405
4 изменённых файлов: 34 добавлений и 3 удалений

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

@ -2463,6 +2463,15 @@ ByteSize(JSContext* cx, unsigned argc, Value* vp)
return true;
}
static bool
ImmutablePrototypesEnabled(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().setBoolean(JS_ImmutablePrototypesEnabled());
return true;
}
static bool
SetImmutablePrototype(JSContext* cx, unsigned argc, Value* vp)
{
@ -3215,6 +3224,11 @@ gc::ZealModeHelpText),
" Return the size in bytes occupied by |value|, or |undefined| if value\n"
" is not allocated in memory.\n"),
JS_FN_HELP("immutablePrototypesEnabled", ImmutablePrototypesEnabled, 0, 0,
"immutablePrototypesEnabled()",
" Returns true if immutable-prototype behavior (triggered by setImmutablePrototype)\n"
" is enabled, such that modifying an immutable prototype will fail."),
JS_FN_HELP("setImmutablePrototype", SetImmutablePrototype, 1, 0,
"setImmutablePrototype(obj)",
" Try to make obj's [[Prototype]] immutable, such that subsequent attempts to\n"

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

@ -70,6 +70,9 @@ JS_ObjectCountDynamicSlots(JS::HandleObject obj);
extern JS_FRIEND_API(size_t)
JS_SetProtoCalled(JSContext* cx);
extern JS_FRIEND_API(bool)
JS_ImmutablePrototypesEnabled();
extern JS_FRIEND_API(size_t)
JS_GetCustomIteratorCount(JSContext* cx);

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

@ -2387,6 +2387,19 @@ JSObject::reportNotExtensible(JSContext* cx, unsigned report)
nullptr, nullptr);
}
// Our immutable-prototype behavior is non-standard, and it's unclear whether
// it's shippable. (Or at least it's unclear whether it's shippable with any
// provided-by-default uses exposed to script.) If this bool is true,
// immutable-prototype behavior is enforced; if it's false, behavior is not
// enforced, and immutable-prototype bits stored on objects are completely
// ignored.
static const bool ImmutablePrototypesEnabled = true;
JS_FRIEND_API(bool)
JS_ImmutablePrototypesEnabled()
{
return ImmutablePrototypesEnabled;
}
/*** ES6 standard internal methods ***************************************************************/
@ -2405,9 +2418,8 @@ js::SetPrototype(JSContext* cx, HandleObject obj, HandleObject proto, JS::Object
}
/* Disallow mutation of immutable [[Prototype]]s. */
if (obj->nonLazyPrototypeIsImmutable()) {
if (obj->nonLazyPrototypeIsImmutable() && ImmutablePrototypesEnabled)
return result.fail(JSMSG_CANT_SET_PROTO);
}
/*
* Disallow mutating the [[Prototype]] on ArrayBuffer objects, which

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

@ -86,7 +86,9 @@ function checkPrototypeMutationFailure(obj, desc)
function runNormalTests(global)
{
if (typeof setImmutablePrototype !== "function")
if (typeof setImmutablePrototype !== "function" ||
(typeof immutablePrototypesEnabled === "function" &&
!immutablePrototypesEnabled()))
{
print("no usable setImmutablePrototype function available, skipping tests");
return;