diff options
author | 2023-01-08 23:52:53 -0800 | |
---|---|---|
committer | 2023-01-08 23:53:31 -0800 | |
commit | 5f1150442ac32150b4338d97ab78d586953a444b (patch) | |
tree | 5c706d27f8943128e4e6d0615e0320b68dd077e2 /src | |
parent | 94b6ab02c2cf1e94e2b81164bf0f22927bc925c7 (diff) | |
download | bun-5f1150442ac32150b4338d97ab78d586953a444b.tar.gz bun-5f1150442ac32150b4338d97ab78d586953a444b.tar.zst bun-5f1150442ac32150b4338d97ab78d586953a444b.zip |
Revert "lazily create buffer/string slices (#1735)"
This reverts commit e2ed31b7e79d1cb4fca492de3be0324afc9fd3a1.
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/bindings/JSBufferList.cpp | 122 | ||||
-rw-r--r-- | src/bun.js/bindings/JSBufferList.h | 31 |
2 files changed, 33 insertions, 120 deletions
diff --git a/src/bun.js/bindings/JSBufferList.cpp b/src/bun.js/bindings/JSBufferList.cpp index 37b14143c..e54b433e5 100644 --- a/src/bun.js/bindings/JSBufferList.cpp +++ b/src/bun.js/bindings/JSBufferList.cpp @@ -39,26 +39,17 @@ JSC::JSValue JSBufferList::concat(JSC::VM& vm, JSC::JSGlobalObject* lexicalGloba const size_t len = length(); if (len == 0) { // Buffer.alloc(0) - auto array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0); - RETURN_IF_EXCEPTION(throwScope, {}); - RELEASE_AND_RETURN(throwScope, array); + RELEASE_AND_RETURN(throwScope, JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0)); } auto iter = m_deque.begin(); - size_t offset = m_read; if (len == 1) { auto array = JSC::jsDynamicCast<JSC::JSUint8Array*>(iter->get()); if (UNLIKELY(!array)) { return throwTypeError(lexicalGlobalObject, throwScope, "concat can only be called when all buffers are Uint8Array"_s); } - const size_t length = array->byteLength() - offset; - if (UNLIKELY(length > n)) { + if (UNLIKELY(array->byteLength() > n)) { return throwRangeError(lexicalGlobalObject, throwScope, "specified size too small to fit all buffers"_s); } - if (offset > 0) { - auto buffer = array->possiblySharedBuffer(); - array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, offset, len); - RETURN_IF_EXCEPTION(throwScope, {}); - } RELEASE_AND_RETURN(throwScope, array); } // Buffer.allocUnsafe(n >>> 0) @@ -67,7 +58,6 @@ JSC::JSValue JSBufferList::concat(JSC::VM& vm, JSC::JSGlobalObject* lexicalGloba return throwOutOfMemoryError(lexicalGlobalObject, throwScope); } JSC::JSUint8Array* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(arrayBuffer), 0, n); - RETURN_IF_EXCEPTION(throwScope, {}); size_t i = 0; for (const auto end = m_deque.end(); iter != end; ++iter) { @@ -75,26 +65,19 @@ JSC::JSValue JSBufferList::concat(JSC::VM& vm, JSC::JSGlobalObject* lexicalGloba if (UNLIKELY(!array)) { return throwTypeError(lexicalGlobalObject, throwScope, "concat can only be called when all buffers are Uint8Array"_s); } - const size_t length = array->byteLength() - offset; + const size_t length = array->byteLength(); if (UNLIKELY(i + length > n)) { return throwRangeError(lexicalGlobalObject, throwScope, "specified size too small to fit all buffers"_s); } - if (UNLIKELY(!uint8Array->setFromTypedArray(lexicalGlobalObject, i, array, offset, length, JSC::CopyType::Unobservable))) { + if (UNLIKELY(!uint8Array->setFromTypedArray(lexicalGlobalObject, i, array, 0, length, JSC::CopyType::Unobservable))) { return throwOutOfMemoryError(lexicalGlobalObject, throwScope); } - offset = 0; i += length; } RELEASE_AND_RETURN(throwScope, uint8Array); } -inline size_t slicedLength(JSString* str, size_t offset) -{ - const auto len = str->length(); - return len < offset ? 0 : len - offset; -} - JSC::JSValue JSBufferList::join(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSString* seq) { auto throwScope = DECLARE_THROW_SCOPE(vm); @@ -103,16 +86,9 @@ JSC::JSValue JSBufferList::join(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalO } const bool needSeq = seq->length() != 0; const auto end = m_deque.end(); - size_t offset = m_read; JSRopeString::RopeBuilder<RecordOverflow> ropeBuilder(vm); for (auto iter = m_deque.begin();;) { auto str = iter->get().toString(lexicalGlobalObject); - if (offset > 0) { - const size_t len = slicedLength(str, offset); - str = JSC::jsSubstring(lexicalGlobalObject, str, offset, len); - RETURN_IF_EXCEPTION(throwScope, {}); - offset = 0; - } if (!ropeBuilder.append(str)) return throwOutOfMemoryError(lexicalGlobalObject, throwScope); if (++iter == end) @@ -144,22 +120,16 @@ JSC::JSValue JSBufferList::_getString(JSC::VM& vm, JSC::JSGlobalObject* lexicalG if (UNLIKELY(!str)) { return throwTypeError(lexicalGlobalObject, throwScope, "_getString can only be called when all buffers are string"_s); } - const size_t len = slicedLength(str, m_read); + const size_t len = str->length(); size_t n = total; if (n == len) { m_deque.removeFirst(); - if (m_read > 0) { - str = JSC::jsSubstring(lexicalGlobalObject, str, m_read, len); - RETURN_IF_EXCEPTION(throwScope, {}); - m_read = 0; - } RELEASE_AND_RETURN(throwScope, str); } if (n < len) { - JSString* firstHalf = JSC::jsSubstring(lexicalGlobalObject, str, m_read, n); - RETURN_IF_EXCEPTION(throwScope, {}); - m_read += n; + JSString* firstHalf = JSC::jsSubstring(lexicalGlobalObject, str, 0, n); + iter->set(vm, this, JSC::jsSubstring(lexicalGlobalObject, str, n, len - n)); RELEASE_AND_RETURN(throwScope, firstHalf); } @@ -169,25 +139,18 @@ JSC::JSValue JSBufferList::_getString(JSC::VM& vm, JSC::JSGlobalObject* lexicalG if (UNLIKELY(!str)) { return throwTypeError(lexicalGlobalObject, throwScope, "_getString can only be called when all buffers are string"_s); } - const size_t len = slicedLength(str, m_read); + const size_t len = str->length(); if (n < len) { - JSString* firstHalf = JSC::jsSubstring(lexicalGlobalObject, str, m_read, n); - RETURN_IF_EXCEPTION(throwScope, {}); - m_read += n; + JSString* firstHalf = JSC::jsSubstring(lexicalGlobalObject, str, 0, n); if (!ropeBuilder.append(firstHalf)) return throwOutOfMemoryError(lexicalGlobalObject, throwScope); + iter->set(vm, this, JSC::jsSubstring(lexicalGlobalObject, str, n, len - n)); break; } - if (m_read > 0) { - str = JSC::jsSubstring(lexicalGlobalObject, str, m_read, len); - RETURN_IF_EXCEPTION(throwScope, {}); - m_read = 0; - } if (!ropeBuilder.append(str)) return throwOutOfMemoryError(lexicalGlobalObject, throwScope); m_deque.removeFirst(); - if (n == len) - break; + if (n == len) break; n -= len; } RELEASE_AND_RETURN(throwScope, ropeBuilder.release()); @@ -199,9 +162,7 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG auto* subclassStructure = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)->JSBufferSubclassStructure(); if (total <= 0 || length() == 0) { // Buffer.alloc(0) - JSC::JSUint8Array* array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0); - RETURN_IF_EXCEPTION(throwScope, {}); - RELEASE_AND_RETURN(throwScope, array); + RELEASE_AND_RETURN(throwScope, JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0)); } auto iter = m_deque.begin(); @@ -209,25 +170,19 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG if (UNLIKELY(!array)) { return throwTypeError(lexicalGlobalObject, throwScope, "_getBuffer can only be called when all buffers are Uint8Array"_s); } - const size_t len = array->byteLength() - m_read; + const size_t len = array->byteLength(); size_t n = total; if (n == len) { m_deque.removeFirst(); - if (m_read > 0) { - auto buffer = array->possiblySharedBuffer(); - array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, m_read, len); - RETURN_IF_EXCEPTION(throwScope, {}); - m_read = 0; - } RELEASE_AND_RETURN(throwScope, array); } if (n < len) { auto buffer = array->possiblySharedBuffer(); - JSC::JSUint8Array* head = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, m_read, n); - RETURN_IF_EXCEPTION(throwScope, {}); - m_read += n; - RELEASE_AND_RETURN(throwScope, head); + JSC::JSUint8Array* retArray = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, 0, n); + JSC::JSUint8Array* newArray = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, n, len - n); + iter->set(vm, this, newArray); + RELEASE_AND_RETURN(throwScope, retArray); } // Buffer.allocUnsafe(n >>> 0) @@ -236,56 +191,33 @@ JSC::JSValue JSBufferList::_getBuffer(JSC::VM& vm, JSC::JSGlobalObject* lexicalG return throwOutOfMemoryError(lexicalGlobalObject, throwScope); } JSC::JSUint8Array* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(arrayBuffer), 0, n); - RETURN_IF_EXCEPTION(throwScope, {}); size_t offset = 0; for (const auto end = m_deque.end(); iter != end; ++iter) { JSC::JSUint8Array* array = JSC::jsDynamicCast<JSC::JSUint8Array*>(iter->get()); if (UNLIKELY(!array)) { return throwTypeError(lexicalGlobalObject, throwScope, "_getBuffer can only be called when all buffers are Uint8Array"_s); } - const size_t len = array->byteLength() - m_read; + const size_t len = array->byteLength(); if (n < len) { - if (UNLIKELY(!uint8Array->setFromTypedArray(lexicalGlobalObject, offset, array, m_read, n, JSC::CopyType::Unobservable))) { + if (UNLIKELY(!uint8Array->setFromTypedArray(lexicalGlobalObject, offset, array, 0, n, JSC::CopyType::Unobservable))) { return throwOutOfMemoryError(lexicalGlobalObject, throwScope); } - m_read += n; + auto buffer = array->possiblySharedBuffer(); + JSC::JSUint8Array* newArray = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, n, len - n); + iter->set(vm, this, newArray); break; } - if (UNLIKELY(!uint8Array->setFromTypedArray(lexicalGlobalObject, offset, array, m_read, len, JSC::CopyType::Unobservable))) { + if (UNLIKELY(!uint8Array->setFromTypedArray(lexicalGlobalObject, offset, array, 0, len, JSC::CopyType::Unobservable))) { return throwOutOfMemoryError(lexicalGlobalObject, throwScope); } - m_read = 0; m_deque.removeFirst(); - if (n == len) - break; + if (n == len) break; n -= len; offset += len; } RELEASE_AND_RETURN(throwScope, uint8Array); } -// assumes `length() > 0` and `m_read > 0` -inline JSC::JSValue JSBufferList::trim(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSValue value) -{ - auto throwScope = DECLARE_THROW_SCOPE(vm); - JSC::JSString* str = JSC::jsDynamicCast<JSC::JSString*>(value); - if (str) { - const size_t len = slicedLength(str, m_read); - str = JSC::jsSubstring(lexicalGlobalObject, str, m_read, len); - RETURN_IF_EXCEPTION(throwScope, {}); - RELEASE_AND_RETURN(throwScope, str); - } - JSC::JSUint8Array* array = JSC::jsDynamicCast<JSC::JSUint8Array*>(value); - if (UNLIKELY(!array)) - return throwTypeError(lexicalGlobalObject, throwScope, "expected string or Uint8Array"_s); - auto* subclassStructure = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject)->JSBufferSubclassStructure(); - const size_t len = array->byteLength() - m_read; - auto buffer = array->possiblySharedBuffer(); - JSC::JSUint8Array* head = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, buffer, m_read, len); - RETURN_IF_EXCEPTION(throwScope, {}); - RELEASE_AND_RETURN(throwScope, head); -} - const JSC::ClassInfo JSBufferList::s_info = { "BufferList"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSBufferList) }; JSC::GCClient::IsoSubspace* JSBufferList::subspaceForImpl(JSC::VM& vm) @@ -334,14 +266,14 @@ static inline JSC::EncodedJSValue jsBufferListPrototypeFunction_unshiftBody(JSC: } auto v = callFrame->uncheckedArgument(0); - castedThis->unshift(vm, lexicalGlobalObject, v); + castedThis->unshift(vm, v); RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(JSC::jsUndefined())); } static inline JSC::EncodedJSValue jsBufferListPrototypeFunction_shiftBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBufferList>::ClassParameter castedThis) { auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); - RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(castedThis->shift(vm, lexicalGlobalObject))); + RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(castedThis->shift())); } static inline JSC::EncodedJSValue jsBufferListPrototypeFunction_clearBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBufferList>::ClassParameter castedThis) { @@ -354,7 +286,7 @@ static inline JSC::EncodedJSValue jsBufferListPrototypeFunction_firstBody(JSC::J { auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); - RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(castedThis->first(vm, lexicalGlobalObject))); + RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(castedThis->first())); } static inline JSC::EncodedJSValue jsBufferListPrototypeFunction_concatBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSBufferList>::ClassParameter castedThis) { diff --git a/src/bun.js/bindings/JSBufferList.h b/src/bun.js/bindings/JSBufferList.h index c34a0ee95..a9227e981 100644 --- a/src/bun.js/bindings/JSBufferList.h +++ b/src/bun.js/bindings/JSBufferList.h @@ -52,43 +52,28 @@ public: m_deque.append(WriteBarrier<Unknown>()); m_deque.last().set(vm, this, v); } - void unshift(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSValue v) + void unshift(JSC::VM& vm, JSC::JSValue v) { - if (m_read > 0) { - m_deque.first().set(vm, this, trim(vm, lexicalGlobalObject, m_deque.first().get())); - m_read = 0; - } m_deque.prepend(WriteBarrier<Unknown>()); m_deque.first().set(vm, this, v); } - JSC::JSValue shift(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject) + JSC::JSValue shift() { if (UNLIKELY(length() == 0)) return JSC::jsUndefined(); - auto value = m_deque.first().get(); - if (m_read > 0) { - value = trim(vm, lexicalGlobalObject, value); - m_read = 0; - } + auto v = m_deque.first().get(); m_deque.removeFirst(); - return value; + return v; } void clear() { m_deque.clear(); - m_read = 0; } - JSC::JSValue first(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject) + JSC::JSValue first() { if (UNLIKELY(length() == 0)) return JSC::jsUndefined(); - auto value = m_deque.first().get(); - if (m_read > 0) { - value = trim(vm, lexicalGlobalObject, value); - m_deque.first().set(vm, this, value); - m_read = 0; - } - return value; + return JSC::JSValue(m_deque.first().get()); } JSC::JSValue concat(JSC::VM&, JSC::JSGlobalObject*, int32_t); @@ -99,9 +84,6 @@ public: private: Deque<WriteBarrier<Unknown>> m_deque; - size_t m_read = 0; - - JSC::JSValue trim(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSValue value); }; class JSBufferListPrototype : public JSC::JSNonFinalObject { @@ -152,7 +134,6 @@ public: // Must be defined for each specialization class. static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); DECLARE_EXPORT_INFO; - private: JSBufferListConstructor(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction nativeFunction) : Base(vm, structure, nativeFunction, nativeFunction) |