From 0d04f93519c1f70ade792a9730b37148915fc704 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 28 Jul 2011 14:35:38 -0700 Subject: [PATCH] Backout 2e0fea2cbd9b for windows linker lameness --- dom/base/nsGlobalWindow.cpp | 4 +- dom/indexedDB/AsyncConnectionHelper.cpp | 2 +- dom/indexedDB/IDBCursor.cpp | 4 +- dom/indexedDB/IDBIndex.cpp | 4 +- dom/indexedDB/IDBObjectStore.cpp | 37 +++++++--- dom/workers/Events.cpp | 4 +- dom/workers/WorkerPrivate.cpp | 2 +- dom/workers/XMLHttpRequestPrivate.cpp | 4 +- js/src/Makefile.in | 2 +- js/src/jsapi.cpp | 93 +------------------------ js/src/jsapi.h | 93 ++++++++++++++++++++----- 11 files changed, 120 insertions(+), 129 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 1199b4179b57..6162025679d6 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -5986,7 +5986,7 @@ PostMessageEvent::Run() // Ensure that the buffer is freed even if we fail to post the message JSAutoStructuredCloneBuffer buffer; - buffer.adopt(mMessage, mMessageLen); + buffer.adopt(cx, mMessage, mMessageLen); mMessage = nsnull; mMessageLen = 0; @@ -6040,7 +6040,7 @@ PostMessageEvent::Run() { JSAutoRequest ar(cx); - if (!buffer.read(cx, &messageData, nsnull)) + if (!buffer.read(&messageData, cx, nsnull)) return NS_ERROR_DOM_DATA_CLONE_ERR; } diff --git a/dom/indexedDB/AsyncConnectionHelper.cpp b/dom/indexedDB/AsyncConnectionHelper.cpp index de7585de32cc..6387c6afe1ea 100644 --- a/dom/indexedDB/AsyncConnectionHelper.cpp +++ b/dom/indexedDB/AsyncConnectionHelper.cpp @@ -506,7 +506,7 @@ AsyncConnectionHelper::ConvertCloneBuffersToArray( nsresult rv = ConvertCloneBuffersToArrayInternal(aCx, aBuffers, aResult); for (PRUint32 index = 0; index < aBuffers.Length(); index++) { - aBuffers[index].clear(); + aBuffers[index].clear(aCx); } aBuffers.Clear(); diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp index 6b2ff9a39e2d..7e31f1e072f8 100644 --- a/dom/indexedDB/IDBCursor.cpp +++ b/dom/indexedDB/IDBCursor.cpp @@ -475,7 +475,7 @@ IDBCursor::GetValue(JSContext* aCx, return NS_ERROR_DOM_DATA_CLONE_ERR; } - mCloneBuffer.clear(); + mCloneBuffer.clear(aCx); mHaveCachedValue = true; } @@ -720,7 +720,7 @@ ContinueHelper::GetSuccessResult(JSContext* aCx, mCursor->mContinueToKey = Key::UNSETKEY; mCursor->mCloneBuffer.swap(mCloneBuffer); - mCloneBuffer.clear(); + mCloneBuffer.clear(aCx); nsresult rv = WrapNative(aCx, mCursor, aVal); NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/indexedDB/IDBIndex.cpp b/dom/indexedDB/IDBIndex.cpp index ad13fd4a15a1..2729cdaeb166 100644 --- a/dom/indexedDB/IDBIndex.cpp +++ b/dom/indexedDB/IDBIndex.cpp @@ -782,7 +782,7 @@ GetHelper::GetSuccessResult(JSContext* aCx, { bool result = IDBObjectStore::DeserializeValue(aCx, mCloneBuffer, aVal); - mCloneBuffer.clear(); + mCloneBuffer.clear(aCx); NS_ENSURE_TRUE(result, NS_ERROR_FAILURE); return NS_OK; @@ -1056,7 +1056,7 @@ GetAllHelper::GetSuccessResult(JSContext* aCx, nsresult rv = ConvertCloneBuffersToArray(aCx, mCloneBuffers, aVal); for (PRUint32 index = 0; index < mCloneBuffers.Length(); index++) { - mCloneBuffers[index].clear(); + mCloneBuffers[index].clear(aCx); } NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 48cf62071fae..f059637b2ff4 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -839,9 +839,19 @@ IDBObjectStore::GetStructuredCloneDataFromStatement( nsresult rv = aStatement->GetSharedBlob(aIndex, &dataLength, &data); NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - return aBuffer.copy(reinterpret_cast(data), dataLength) ? - NS_OK : - NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + JSContext* cx; + rv = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx); + NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + + JSAutoRequest ar(cx); + + uint64* newData = static_cast(JS_malloc(cx, dataLength)); + NS_ENSURE_TRUE(newData, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + + memcpy(newData, data, dataLength); + aBuffer.adopt(cx, newData, dataLength); + + return NS_OK; } // static @@ -849,7 +859,18 @@ void IDBObjectStore::ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer) { if (aBuffer.data()) { - aBuffer.clear(); + JSContext* cx; + if (NS_SUCCEEDED(nsContentUtils::ThreadJSContextStack()-> + GetSafeJSContext(&cx))) { + JSAutoRequest ar(cx); + aBuffer.clear(cx); + } + else { + NS_WARNING("Couldn't get safe JSContext! Leaking data!"); + uint64* data; + size_t length; + aBuffer.steal(&data, &length); + } } } @@ -872,7 +893,7 @@ IDBObjectStore::DeserializeValue(JSContext* aCx, JSAutoRequest ar(aCx); - return aBuffer.read(aCx, aValue, aCallbacks, aClosure); + return aBuffer.read(aValue, aCx, aCallbacks, aClosure); } // static @@ -1879,7 +1900,7 @@ AddHelper::GetSuccessResult(JSContext* aCx, { NS_ASSERTION(!mKey.IsUnset(), "Badness!"); - mCloneBuffer.clear(); + mCloneBuffer.clear(aCx); return IDBObjectStore::GetJSValFromKey(mKey, aCx, aVal); } @@ -1934,7 +1955,7 @@ GetHelper::GetSuccessResult(JSContext* aCx, { bool result = IDBObjectStore::DeserializeValue(aCx, mCloneBuffer, aVal); - mCloneBuffer.clear(); + mCloneBuffer.clear(aCx); NS_ENSURE_TRUE(result, NS_ERROR_FAILURE); return NS_OK; @@ -2509,7 +2530,7 @@ GetAllHelper::GetSuccessResult(JSContext* aCx, nsresult rv = ConvertCloneBuffersToArray(aCx, mCloneBuffers, aVal); for (PRUint32 index = 0; index < mCloneBuffers.Length(); index++) { - mCloneBuffers[index].clear(); + mCloneBuffers[index].clear(aCx); } NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/workers/Events.cpp b/dom/workers/Events.cpp index ff35f312824f..a08f88d789ff 100644 --- a/dom/workers/Events.cpp +++ b/dom/workers/Events.cpp @@ -565,13 +565,13 @@ private: // Deserialize and save the data value if we can. if (slot == SLOT_data && event->mData) { JSAutoStructuredCloneBuffer buffer; - buffer.adopt(event->mData, event->mDataByteCount); + buffer.adopt(aCx, event->mData, event->mDataByteCount); event->mData = NULL; event->mDataByteCount = 0; jsval data; - if (!buffer.read(aCx, &data) || + if (!buffer.read(&data) || !JS_SetReservedSlot(aCx, aObj, slot, data)) { return false; } diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index e2a741d1eafe..1755d22b1c77 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -532,7 +532,7 @@ public: WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { JSAutoStructuredCloneBuffer buffer; - buffer.adopt(mData, mDataByteCount); + buffer.adopt(aCx, mData, mDataByteCount); mData = nsnull; mDataByteCount = 0; diff --git a/dom/workers/XMLHttpRequestPrivate.cpp b/dom/workers/XMLHttpRequestPrivate.cpp index 0462f86a96c4..1f8059926577 100644 --- a/dom/workers/XMLHttpRequestPrivate.cpp +++ b/dom/workers/XMLHttpRequestPrivate.cpp @@ -955,7 +955,7 @@ public: intN error = 0; jsval body; - if (mBody.read(cx, &body)) { + if (mBody.read(&body, cx)) { if (NS_FAILED(xpc->JSValToVariant(cx, &body, getter_AddRefs(variant)))) { error = INVALID_STATE_ERR; @@ -965,7 +965,7 @@ public: error = DATA_CLONE_ERR; } - mBody.clear(); + mBody.clear(cx); if (error) { return error; diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 7dd8d00983cc..b953a54ae1a4 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -675,7 +675,7 @@ check-malloc-function-usage: $(filter-out %jsalloc.h %jscntxt.h %jsutil.h, $(ALL # We desire these numbers to go down, not up. See "User guide to memory # management within SpiderMonkey" in jsutil.h. - $(srcdir)/config/check_source_count.py OffTheBooks:: 59 \ + $(srcdir)/config/check_source_count.py OffTheBooks:: 58 \ "in Makefile.in" "{cx,rt}->{new_,new_array,malloc_,calloc_,realloc_}" $^ # This should go to zero, if possible. $(srcdir)/config/check_source_count.py UnwantedForeground:: 31 \ diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 79a491082eb2..162f78ecba2c 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -5598,98 +5598,7 @@ JS_StructuredClone(JSContext *cx, jsval v, jsval *vp, cx->runtime->structuredCloneCallbacks; JSAutoStructuredCloneBuffer buf; return buf.write(cx, v, callbacks, closure) && - buf.read(cx, vp, callbacks, closure); -} - -void -JSAutoStructuredCloneBuffer::clear() -{ - if (data_) { - Foreground::free_(data_); - data_ = NULL; - nbytes_ = 0; - version_ = 0; - } -} - -void -JSAutoStructuredCloneBuffer::adopt(uint64 *data, size_t nbytes, uint32 version) -{ - clear(); - data_ = data; - nbytes_ = nbytes; - version_ = version; -} - -bool -JSAutoStructuredCloneBuffer::copy(const uint64 *srcData, size_t nbytes, uint32 version) -{ - uint64 *newData = static_cast(OffTheBooks::malloc_(nbytes)); - if (!newData) - return false; - - memcpy(newData, srcData, nbytes); - - clear(); - data_ = newData; - nbytes_ = nbytes; - version_ = version; - return true; -} -void -JSAutoStructuredCloneBuffer::steal(uint64 **datap, size_t *nbytesp, uint32 *versionp) -{ - *datap = data_; - *nbytesp = nbytes_; - if (versionp) - *versionp = version_; - - data_ = NULL; - nbytes_ = 0; - version_ = 0; -} - -bool -JSAutoStructuredCloneBuffer::read(JSContext *cx, jsval *vp, - const JSStructuredCloneCallbacks *optionalCallbacks, - void *closure) const -{ - JS_ASSERT(cx); - JS_ASSERT(data_); - return !!JS_ReadStructuredClone(cx, data_, nbytes_, version_, vp, - optionalCallbacks, closure); -} - -bool -JSAutoStructuredCloneBuffer::write(JSContext *cx, jsval v, - const JSStructuredCloneCallbacks *optionalCallbacks, - void *closure) -{ - clear(); - bool ok = !!JS_WriteStructuredClone(cx, v, &data_, &nbytes_, - optionalCallbacks, closure); - if (!ok) { - data_ = NULL; - nbytes_ = 0; - version_ = JS_STRUCTURED_CLONE_VERSION; - } - return ok; -} - -void -JSAutoStructuredCloneBuffer::swap(JSAutoStructuredCloneBuffer &other) -{ - uint64 *data = other.data_; - size_t nbytes = other.nbytes_; - uint32 version = other.version_; - - other.data_ = this->data_; - other.nbytes_ = this->nbytes_; - other.version_ = this->version_; - - this->data_ = data; - this->nbytes_ = nbytes; - this->version_ = version; + buf.read(vp, cx, callbacks, closure); } JS_PUBLIC_API(void) diff --git a/js/src/jsapi.h b/js/src/jsapi.h index da448e2946b6..57001a97ba41 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -3375,51 +3375,112 @@ JS_StructuredClone(JSContext *cx, jsval v, jsval *vp, #ifdef __cplusplus /* RAII sugar for JS_WriteStructuredClone. */ -class JS_PUBLIC_API(JSAutoStructuredCloneBuffer) { +class JSAutoStructuredCloneBuffer { + JSContext *cx_; uint64 *data_; size_t nbytes_; uint32 version_; public: JSAutoStructuredCloneBuffer() - : data_(NULL), nbytes_(0), version_(JS_STRUCTURED_CLONE_VERSION) {} + : cx_(NULL), data_(NULL), nbytes_(0), version_(JS_STRUCTURED_CLONE_VERSION) {} ~JSAutoStructuredCloneBuffer() { clear(); } + JSContext *cx() const { return cx_; } uint64 *data() const { return data_; } size_t nbytes() const { return nbytes_; } - void clear(); - - /* Copy some memory. It will be automatically freed by the destructor. */ - bool copy(const uint64 *data, size_t nbytes, uint32 version=JS_STRUCTURED_CLONE_VERSION); + void clear(JSContext *cx=NULL) { + if (data_) { + if (!cx) + cx = cx_; + JS_ASSERT(cx); + JS_free(cx, data_); + cx_ = NULL; + data_ = NULL; + nbytes_ = 0; + version_ = 0; + } + } /* * Adopt some memory. It will be automatically freed by the destructor. - * data must have been allocated by the JS engine (e.g., extracted via - * JSAutoStructuredCloneBuffer::steal). + * data must have been allocated using JS_malloc. */ - void adopt(uint64 *data, size_t nbytes, uint32 version=JS_STRUCTURED_CLONE_VERSION); + void adopt(JSContext *cx, uint64 *data, size_t nbytes, + uint32 version=JS_STRUCTURED_CLONE_VERSION) { + clear(cx); + cx_ = cx; + data_ = data; + nbytes_ = nbytes; + version_ = version; + } /* * Remove the buffer so that it will not be automatically freed. - * After this, the caller is responsible for feeding the memory back to - * JSAutoStructuredCloneBuffer::adopt. + * After this, the caller is responsible for calling JS_free(*datap). */ - void steal(uint64 **datap, size_t *nbytesp, uint32 *versionp=NULL); + void steal(uint64 **datap, size_t *nbytesp, JSContext **cxp=NULL, + uint32 *versionp=NULL) { + *datap = data_; + *nbytesp = nbytes_; + if (cxp) + *cxp = cx_; + if (versionp) + *versionp = version_; - bool read(JSContext *cx, jsval *vp, + cx_ = NULL; + data_ = NULL; + nbytes_ = 0; + version_ = 0; + } + + bool read(jsval *vp, JSContext *cx=NULL, const JSStructuredCloneCallbacks *optionalCallbacks=NULL, - void *closure=NULL) const; + void *closure=NULL) const { + if (!cx) + cx = cx_; + JS_ASSERT(cx); + JS_ASSERT(data_); + return !!JS_ReadStructuredClone(cx, data_, nbytes_, version_, vp, + optionalCallbacks, closure); + } bool write(JSContext *cx, jsval v, const JSStructuredCloneCallbacks *optionalCallbacks=NULL, - void *closure=NULL); + void *closure=NULL) { + clear(cx); + cx_ = cx; + bool ok = !!JS_WriteStructuredClone(cx, v, &data_, &nbytes_, + optionalCallbacks, closure); + if (!ok) { + data_ = NULL; + nbytes_ = 0; + version_ = JS_STRUCTURED_CLONE_VERSION; + } + return ok; + } /** * Swap ownership with another JSAutoStructuredCloneBuffer. */ - void swap(JSAutoStructuredCloneBuffer &other); + void swap(JSAutoStructuredCloneBuffer &other) { + JSContext *cx = other.cx_; + uint64 *data = other.data_; + size_t nbytes = other.nbytes_; + uint32 version = other.version_; + + other.cx_ = this->cx_; + other.data_ = this->data_; + other.nbytes_ = this->nbytes_; + other.version_ = this->version_; + + this->cx_ = cx; + this->data_ = data; + this->nbytes_ = nbytes; + this->version_ = version; + } private: /* Copy and assignment are not supported. */