From 0fecd165f292f2dcbd381f24444746b2802b5f96 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 2 Nov 2012 23:42:59 +1300 Subject: [PATCH] Bug 807237. Add 'data' parameter to JS_StealArrayBufferContents. r=sfink --HG-- extra : rebase_source : 5c9fe8f9b09ac63f3e130e7ff3418301f868cb8d --- js/src/jsapi-tests/testArrayBuffer.cpp | 15 ++++++++++----- js/src/jsapi.h | 9 +++++++-- js/src/jsclone.cpp | 3 ++- js/src/jstypedarray.cpp | 10 +++++++--- js/src/jstypedarray.h | 3 ++- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/js/src/jsapi-tests/testArrayBuffer.cpp b/js/src/jsapi-tests/testArrayBuffer.cpp index 403d3e447fd8..2dd591e53593 100644 --- a/js/src/jsapi-tests/testArrayBuffer.cpp +++ b/js/src/jsapi-tests/testArrayBuffer.cpp @@ -52,8 +52,9 @@ BEGIN_TEST(testArrayBuffer_bug720949_steal) // Steal the contents void *contents; - CHECK(JS_StealArrayBufferContents(cx, obj, &contents)); + CHECK(JS_StealArrayBufferContents(cx, obj, &contents, &data)); CHECK(contents != NULL); + CHECK(data != NULL); // Check that the original ArrayBuffer is neutered CHECK_EQUAL(JS_GetArrayBufferByteLength(obj, cx), 0); @@ -111,9 +112,11 @@ BEGIN_TEST(testArrayBuffer_bug720949_viewList) buffer = JS_NewArrayBuffer(cx, 2000); js::RootedObject view(cx, JS_NewUint8ArrayWithBuffer(cx, buffer, 0, -1)); void *contents; - CHECK(JS_StealArrayBufferContents(cx, buffer, &contents)); + uint8_t *data; + CHECK(JS_StealArrayBufferContents(cx, buffer, &contents, &data)); CHECK(contents != NULL); - JS_free(cx, contents); + CHECK(data != NULL); + JS_free(NULL, contents); GC(cx); CHECK(isNeutered(view)); CHECK(isNeutered(buffer)); @@ -137,9 +140,11 @@ BEGIN_TEST(testArrayBuffer_bug720949_viewList) // Neuter void *contents; - CHECK(JS_StealArrayBufferContents(cx, buffer, &contents)); + uint8_t *data; + CHECK(JS_StealArrayBufferContents(cx, buffer, &contents, &data)); CHECK(contents != NULL); - JS_free(cx, contents); + CHECK(data != NULL); + JS_free(NULL, contents); CHECK(isNeutered(view1)); CHECK(isNeutered(view2)); diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 0940bf6422c6..ab5cbaa654f6 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -3409,6 +3409,7 @@ JS_realloc(JSContext *cx, void *p, size_t nbytes); /* * A wrapper for js_free(p) that may delay js_free(p) invocation as a * performance optimization. + * cx may be NULL. */ extern JS_PUBLIC_API(void) JS_free(JSContext *cx, void *p); @@ -4617,11 +4618,15 @@ JS_NewArrayBufferWithContents(JSContext *cx, void *contents); /* * Steal the contents of the given array buffer. The array buffer has its * length set to 0 and its contents array cleared. The caller takes ownership - * of |contents| and must free it or transfer ownership via + * of |*contents| and must free it or transfer ownership via * JS_NewArrayBufferWithContents when done using it. + * To free |*contents|, call free(). + * A pointer to the buffer's data is returned in |*data|. This pointer can + * be used until |*contents| is freed or has its ownership transferred. */ extern JS_PUBLIC_API(JSBool) -JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents); +JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents, + uint8_t **data); /* * Allocate memory that may be eventually passed to diff --git a/js/src/jsclone.cpp b/js/src/jsclone.cpp index d2409c6c1fe4..58d33da2580c 100644 --- a/js/src/jsclone.cpp +++ b/js/src/jsclone.cpp @@ -732,7 +732,8 @@ JSStructuredCloneWriter::writeTransferMap() return false; void *content; - if (!JS_StealArrayBufferContents(context(), obj, &content)) + uint8_t *data; + if (!JS_StealArrayBufferContents(context(), obj, &content, &data)) return false; if (!out.writePair(SCTAG_TRANSFER_MAP, 0) || !out.writePtr(content)) diff --git a/js/src/jstypedarray.cpp b/js/src/jstypedarray.cpp index 4b3f39d0c276..ac0572628e7b 100644 --- a/js/src/jstypedarray.cpp +++ b/js/src/jstypedarray.cpp @@ -461,13 +461,15 @@ ArrayBufferObject::createDataViewForThis(JSContext *cx, unsigned argc, Value *vp } bool -ArrayBufferObject::stealContents(JSContext *cx, JSObject *obj, void **contents) +ArrayBufferObject::stealContents(JSContext *cx, JSObject *obj, void **contents, + uint8_t **data) { ArrayBufferObject &buffer = obj->asArrayBuffer(); JSObject *views = *GetViewList(&buffer); js::ObjectElements *header = js::ObjectElements::fromElements((js::HeapSlot*)buffer.dataPointer()); if (buffer.hasDynamicElements()) { *contents = header; + *data = buffer.dataPointer(); buffer.setFixedElements(); header = js::ObjectElements::fromElements((js::HeapSlot*)buffer.dataPointer()); @@ -482,6 +484,7 @@ ArrayBufferObject::stealContents(JSContext *cx, JSObject *obj, void **contents) ArrayBufferObject::setElementsHeader(newheader, length); *contents = newheader; + *data = reinterpret_cast(newheader + 1); } // Neuter the donor ArrayBuffer and all views of it @@ -3675,7 +3678,8 @@ JS_AllocateArrayBufferContents(JSContext *cx, uint32_t nbytes, void **contents, } JS_PUBLIC_API(JSBool) -JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents) +JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents, + uint8_t **data) { if (!(obj = UnwrapObjectChecked(cx, obj))) return false; @@ -3685,7 +3689,7 @@ JS_StealArrayBufferContents(JSContext *cx, JSObject *obj, void **contents) return false; } - if (!ArrayBufferObject::stealContents(cx, obj, contents)) + if (!ArrayBufferObject::stealContents(cx, obj, contents, data)) return false; return true; diff --git a/js/src/jstypedarray.h b/js/src/jstypedarray.h index 4181f7a0580e..081776f54e14 100644 --- a/js/src/jstypedarray.h +++ b/js/src/jstypedarray.h @@ -132,7 +132,8 @@ class ArrayBufferObject : public JSObject static void sweepAll(JSRuntime *rt); - static bool stealContents(JSContext *cx, JSObject *obj, void **contents); + static bool stealContents(JSContext *cx, JSObject *obj, void **contents, + uint8_t **data); static inline void setElementsHeader(js::ObjectElements *header, uint32_t bytes);