Bug 975456 -- Preserve invariant that views on a neutered buffer have a NULL data pointer r=shu

This commit is contained in:
Nicholas D. Matsakis 2014-02-21 12:32:24 -05:00
Родитель 4aa21b8b61
Коммит 82ad8a4c2a
4 изменённых файлов: 19 добавлений и 10 удалений

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

@ -1,6 +1,3 @@
// FIXME bug 975456
quit();
if (!this.hasOwnProperty("TypedObject"))
quit();

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

@ -1,6 +1,3 @@
// FIXME bug 975456
quit();
// Test the case where we neuter an instance of a fixed-sized array.
// This is a bit of a tricky case because we cannot (necessarily) fold
// the neuter check into the bounds check, as we obtain the bounds

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

@ -396,8 +396,17 @@ ArrayBufferObject::changeContents(JSContext *cx, ObjectElements *newHeader)
// Update all views.
uintptr_t newDataPointer = uintptr_t(newHeader->elements());
for (ArrayBufferViewObject *view = viewListHead; view; view = view->nextView()) {
uintptr_t newDataPtr = uintptr_t(view->getPrivate()) - oldDataPointer + newDataPointer;
view->setPrivate(reinterpret_cast<uint8_t*>(newDataPtr));
// Watch out for NULL data pointers in views. This either
// means that the view is not fully initialized (in which case
// it'll be initialized later with the correct pointer) or
// that the view has been neutered. In that case, the buffer
// is "en route" to being neutered but the isNeuteredBuffer()
// flag may not yet be set.
uint8_t *viewDataPointer = static_cast<uint8_t*>(view->getPrivate());
if (viewDataPointer) {
viewDataPointer += newDataPointer - oldDataPointer;
view->setPrivate(viewDataPointer);
}
// Notify compiled jit code that the base pointer has moved.
MarkObjectStateChange(cx, view);
@ -1200,8 +1209,13 @@ ArrayBufferViewObject::trace(JSTracer *trc, JSObject *obj)
* initialization, bufSlot may still be JSVAL_VOID. */
if (bufSlot.isObject()) {
ArrayBufferObject &buf = bufSlot.toObject().as<ArrayBufferObject>();
int32_t offset = obj->getReservedSlot(BYTEOFFSET_SLOT).toInt32();
obj->initPrivate(buf.dataPointer() + offset);
if (buf.getElementsHeader()->isNeuteredBuffer()) {
// When a view is neutered, it is set to NULL
JS_ASSERT(obj->getPrivate() == nullptr);
} else {
int32_t offset = obj->getReservedSlot(BYTEOFFSET_SLOT).toInt32();
obj->initPrivate(buf.dataPointer() + offset);
}
}
/* Update NEXT_VIEW_SLOT, if the view moved. */

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

@ -770,6 +770,7 @@ class ObjectElements
friend class ObjectImpl;
friend class ArrayObject;
friend class ArrayBufferObject;
friend class ArrayBufferViewObject;
friend class TypedArrayObject;
friend class Nursery;