aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-01-08 23:52:53 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-01-08 23:53:31 -0800
commit5f1150442ac32150b4338d97ab78d586953a444b (patch)
tree5c706d27f8943128e4e6d0615e0320b68dd077e2 /src
parent94b6ab02c2cf1e94e2b81164bf0f22927bc925c7 (diff)
downloadbun-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.cpp122
-rw-r--r--src/bun.js/bindings/JSBufferList.h31
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)