diff --git a/js/src/jstypedarray.cpp b/js/src/jstypedarray.cpp index 707dbfcdb4fe..e6e05266386e 100644 --- a/js/src/jstypedarray.cpp +++ b/js/src/jstypedarray.cpp @@ -273,36 +273,40 @@ GetViewList(ArrayBufferObject *obj) #endif } +void +ArrayBufferObject::changeContents(ObjectElements *newHeader) +{ + // Grab out data before invalidating it. + uint32_t byteLengthCopy = byteLength(); + uintptr_t oldDataPointer = uintptr_t(dataPointer()); + JSObject *viewListHead = *GetViewList(this); + + // Update all views. + uintptr_t newDataPointer = uintptr_t(newHeader->elements()); + for (JSObject *view = viewListHead; view; view = NextView(view)) { + uintptr_t newDataPtr = uintptr_t(view->getPrivate()) - oldDataPointer + newDataPointer; + view->setPrivate(reinterpret_cast(newDataPtr)); + } + + // Change to the new header (now, so we can use GetViewList). + elements = newHeader->elements(); + + // Initialize 'newHeader'. + ArrayBufferObject::setElementsHeader(newHeader, byteLengthCopy); + *GetViewList(this) = viewListHead; +} + bool ArrayBufferObject::uninlineData(JSContext *maybecx) { if (hasDynamicElements()) return true; - // Grab out data before invalidating it - uint32_t bytes = byteLength(); - uintptr_t oldPointer = uintptr_t(dataPointer()); - JSObject *view = *GetViewList(this); - JSObject *viewListHead = view; - - ObjectElements *header = AllocateArrayBufferContents(maybecx, bytes, - reinterpret_cast(oldPointer)); - if (!header) + ObjectElements *newHeader = AllocateArrayBufferContents(maybecx, byteLength(), dataPointer()); + if (!newHeader) return false; - elements = header->elements(); - setElementsHeader(getElementsHeader(), bytes); - - // Update all views - uintptr_t newPointer = uintptr_t(dataPointer()); - while (view) { - uintptr_t newDataPtr = uintptr_t(view->getPrivate()) - oldPointer + newPointer; - view->setPrivate(reinterpret_cast(newDataPtr)); - view = NextView(view); - } - - // Restore the list of views - *GetViewList(this) = viewListHead; + changeContents(newHeader); return true; } diff --git a/js/src/jstypedarray.h b/js/src/jstypedarray.h index ccafea0b21ec..140278956f47 100644 --- a/js/src/jstypedarray.h +++ b/js/src/jstypedarray.h @@ -146,6 +146,7 @@ class ArrayBufferObject : public JSObject void addView(RawObject view); bool allocateSlots(JSContext *cx, uint32_t size, uint8_t *contents = NULL); + void changeContents(ObjectElements *newHeader); /* * Ensure that the data is not stored inline. Used when handing back a