mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 961494 - Adjust an assertion to properly handle objects with built-in properties stored in reserved slots, where the last property of such an object may use a reserved slot that's not the last reserved slot. r=jorendorff, f=bhackett
This commit is contained in:
parent
d1872d42a6
commit
03fcb98c2b
@ -29,6 +29,7 @@ UNIFIED_SOURCES += [
|
||||
'testException.cpp',
|
||||
'testExternalStrings.cpp',
|
||||
'testFindSCCs.cpp',
|
||||
'testFreshGlobalEvalRedefinition.cpp',
|
||||
'testFuncCallback.cpp',
|
||||
'testFunctionProperties.cpp',
|
||||
'testGCExactRooting.cpp',
|
||||
|
47
js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
Normal file
47
js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
static bool
|
||||
GlobalEnumerate(JSContext *cx, JS::Handle<JSObject*> obj)
|
||||
{
|
||||
return JS_EnumerateStandardClasses(cx, obj);
|
||||
}
|
||||
|
||||
static bool
|
||||
GlobalResolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id)
|
||||
{
|
||||
bool resolved = false;
|
||||
return JS_ResolveStandardClass(cx, obj, id, &resolved);
|
||||
}
|
||||
|
||||
BEGIN_TEST(testRedefineGlobalEval)
|
||||
{
|
||||
static const JSClass cls = {
|
||||
"global", JSCLASS_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
GlobalEnumerate, GlobalResolve, JS_ConvertStub
|
||||
};
|
||||
|
||||
/* Create the global object. */
|
||||
JS::CompartmentOptions options;
|
||||
options.setVersion(JSVERSION_LATEST);
|
||||
JS::Rooted<JSObject*> g(cx, JS_NewGlobalObject(cx, &cls, nullptr, JS::FireOnNewGlobalHook, options));
|
||||
if (!g)
|
||||
return false;
|
||||
|
||||
JSAutoCompartment ac(cx, g);
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
CHECK(JS_GetProperty(cx, g, "Object", &v));
|
||||
|
||||
static const char data[] = "Object.defineProperty(this, 'eval', { configurable: false });";
|
||||
CHECK(JS_EvaluateScript(cx, g, data, mozilla::ArrayLength(data) - 1, __FILE__, __LINE__, v.address()));
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testRedefineGlobalEval)
|
28
js/src/tests/ecma_5/Exceptions/error-expando-reconfigure.js
Normal file
28
js/src/tests/ecma_5/Exceptions/error-expando-reconfigure.js
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var gTestfile = "error-expando-reconfigure.js"
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 961494;
|
||||
var summary =
|
||||
"Reconfiguring the first expando property added to an Error object " +
|
||||
"shouldn't assert";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
var err = new Error(); // no message argument => no err.message property
|
||||
err.expando = 17;
|
||||
Object.defineProperty(err, "expando", { configurable: false });
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
@ -352,10 +352,20 @@ JSObject::getChildPropertyOnDictionary(ThreadSafeContext *cx, JS::HandleObject o
|
||||
return nullptr;
|
||||
child.setSlot(slot);
|
||||
} else {
|
||||
/* Slots can only be allocated out of order on objects in dictionary mode. */
|
||||
/*
|
||||
* Slots can only be allocated out of order on objects in
|
||||
* dictionary mode. Otherwise the child's slot must be after the
|
||||
* parent's slot (if it has one), because slot number determines
|
||||
* slot span for objects with that shape. Usually child slot
|
||||
* *immediately* follows parent slot, but there may be a slot gap
|
||||
* when the object uses some -- but not all -- of its reserved
|
||||
* slots to store properties.
|
||||
*/
|
||||
JS_ASSERT(obj->inDictionaryMode() ||
|
||||
parent->hasMissingSlot() ||
|
||||
child.slot() == parent->maybeSlot() + 1);
|
||||
child.slot() == parent->maybeSlot() + 1 ||
|
||||
(parent->maybeSlot() + 1 < JSSLOT_FREE(obj->getClass()) &&
|
||||
child.slot() == JSSLOT_FREE(obj->getClass())));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user