aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/JSBuffer.cpp
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-02-05 07:07:35 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-02-05 07:07:35 -0800
commitca2e708be11e9481938965ee92acc38c01a7726a (patch)
tree5af19d1f7de4807d333334f804d286f230612164 /src/bun.js/bindings/JSBuffer.cpp
parent864913684558466f8517de9d474180a6bc19915c (diff)
downloadbun-ca2e708be11e9481938965ee92acc38c01a7726a.tar.gz
bun-ca2e708be11e9481938965ee92acc38c01a7726a.tar.zst
bun-ca2e708be11e9481938965ee92acc38c01a7726a.zip
speed it up a little more
Diffstat (limited to 'src/bun.js/bindings/JSBuffer.cpp')
-rw-r--r--src/bun.js/bindings/JSBuffer.cpp141
1 files changed, 91 insertions, 50 deletions
diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp
index a6c735af7..2ce07617a 100644
--- a/src/bun.js/bindings/JSBuffer.cpp
+++ b/src/bun.js/bindings/JSBuffer.cpp
@@ -1350,6 +1350,73 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_swap64Body(JSC::JSGl
return JSC::JSValue::encode(castedThis);
}
+static inline JSC::EncodedJSValue jsBufferToString(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSUint8Array* castedThis, size_t offset, size_t length, WebCore::BufferEncodingType encoding)
+{
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ if (UNLIKELY(length == 0)) {
+ RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::jsEmptyString(vm)));
+ }
+
+ JSC::EncodedJSValue ret = 0;
+
+ switch (encoding) {
+ case WebCore::BufferEncodingType::latin1: {
+ LChar* data = nullptr;
+ auto str = String::createUninitialized(length, data);
+ memcpy(data, reinterpret_cast<const char*>(castedThis->typedVector() + offset), length);
+ return JSC::JSValue::encode(JSC::jsString(vm, WTFMove(str)));
+ }
+
+ case WebCore::BufferEncodingType::ucs2:
+ case WebCore::BufferEncodingType::utf16le: {
+ UChar* data = nullptr;
+ size_t u16length = length / 2;
+ if (u16length == 0) {
+ return JSC::JSValue::encode(JSC::jsEmptyString(vm));
+ } else {
+ auto str = String::createUninitialized(u16length, data);
+ // always zero out the last byte of the string incase the buffer is not a multiple of 2
+ data[u16length - 1] = 0;
+ memcpy(data, reinterpret_cast<const char*>(castedThis->typedVector() + offset), length);
+ return JSC::JSValue::encode(JSC::jsString(vm, WTFMove(str)));
+ }
+
+ break;
+ }
+
+ case WebCore::BufferEncodingType::ascii: {
+ // ascii: we always know the length
+ // so we might as well allocate upfront
+ LChar* data = nullptr;
+ auto str = String::createUninitialized(length, data);
+ Bun__encoding__writeLatin1(castedThis->typedVector() + offset, length, data, length, static_cast<uint8_t>(encoding));
+ return JSC::JSValue::encode(JSC::jsString(vm, WTFMove(str)));
+ }
+
+ case WebCore::BufferEncodingType::buffer:
+ case WebCore::BufferEncodingType::utf8:
+ case WebCore::BufferEncodingType::base64:
+ case WebCore::BufferEncodingType::base64url:
+ case WebCore::BufferEncodingType::hex: {
+ ret = Bun__encoding__toString(castedThis->typedVector() + offset, length, lexicalGlobalObject, static_cast<uint8_t>(encoding));
+ break;
+ }
+ default: {
+ throwTypeError(lexicalGlobalObject, scope, "Unsupported encoding? This shouldn't happen"_s);
+ break;
+ }
+ }
+
+ JSC::JSValue retValue = JSC::JSValue::decode(ret);
+ if (UNLIKELY(!retValue.isString())) {
+ scope.throwException(lexicalGlobalObject, retValue);
+ return JSC::JSValue::encode(jsUndefined());
+ }
+
+ RELEASE_AND_RETURN(scope, JSC::JSValue::encode(retValue));
+}
+
static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
@@ -1361,8 +1428,6 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JS
if (length == 0)
return JSC::JSValue::encode(JSC::jsEmptyString(vm));
- auto scope = DECLARE_THROW_SCOPE(vm);
-
switch (callFrame->argumentCount()) {
case 0: {
break;
@@ -1374,6 +1439,8 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JS
if (arg1.value().isString()) {
std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, arg1.value());
if (!encoded) {
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
throwTypeError(lexicalGlobalObject, scope, "Invalid encoding"_s);
return JSC::JSValue::encode(jsUndefined());
}
@@ -1389,6 +1456,8 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JS
JSC::JSValue arg2 = callFrame->uncheckedArgument(1);
int32_t ioffset = arg2.toInt32(lexicalGlobalObject);
if (ioffset < 0) {
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
throwTypeError(lexicalGlobalObject, scope, "Offset must be a positive integer"_s);
return JSC::JSValue::encode(jsUndefined());
}
@@ -1406,61 +1475,33 @@ static inline JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JS
length -= std::min(offset, length);
- if (UNLIKELY(length == 0)) {
- RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::jsEmptyString(vm)));
- }
+ return jsBufferToString(vm, lexicalGlobalObject, castedThis, offset, length, encoding);
+}
- JSC::EncodedJSValue ret = 0;
+// DOMJIT makes it slower! TODO: investigate why
+// JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsBufferPrototypeToStringWithoutTypeChecks, JSValue, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::JSUint8Array* thisValue, JSC::JSString* encodingValue));
- switch (encoding) {
- case WebCore::BufferEncodingType::latin1: {
- LChar* data = nullptr;
- auto str = String::createUninitialized(length, data);
- memcpy(data, reinterpret_cast<const char*>(castedThis->typedVector() + offset), length);
- ret = JSC::JSValue::encode(JSC::jsString(vm, WTFMove(str)));
- break;
- }
+// JSC_DEFINE_JIT_OPERATION(jsBufferPrototypeToStringWithoutTypeChecks, JSValue, (JSC::JSGlobalObject * lexicalGlobalObject, JSUint8Array* thisValue, JSString* encodingValue))
+// {
+// VM& vm = JSC::getVM(lexicalGlobalObject);
+// IGNORE_WARNINGS_BEGIN("frame-address")
+// CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
+// IGNORE_WARNINGS_END
+// JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
- case WebCore::BufferEncodingType::ucs2:
- case WebCore::BufferEncodingType::utf16le: {
- UChar* data = nullptr;
- size_t u16length = length / 2;
- if (u16length == 0) {
- ret = JSC::JSValue::encode(JSC::jsEmptyString(vm));
- } else {
- auto str = String::createUninitialized(u16length, data);
- // always zero out the last byte of the string incase the buffer is not a multiple of 2
- data[u16length - 1] = 0;
- memcpy(data, reinterpret_cast<const char*>(castedThis->typedVector() + offset), length);
- ret = JSC::JSValue::encode(JSC::jsString(vm, WTFMove(str)));
- }
+// std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, encodingValue);
+// if (!encoded) {
+// auto scope = DECLARE_THROW_SCOPE(vm);
- break;
- }
+// throwTypeError(lexicalGlobalObject, scope, "Invalid encoding"_s);
+// return {};
+// }
- case WebCore::BufferEncodingType::buffer:
- case WebCore::BufferEncodingType::utf8:
- case WebCore::BufferEncodingType::ascii:
- case WebCore::BufferEncodingType::base64:
- case WebCore::BufferEncodingType::base64url:
- case WebCore::BufferEncodingType::hex: {
- ret = Bun__encoding__toString(castedThis->typedVector() + offset, length, lexicalGlobalObject, static_cast<uint8_t>(encoding));
- break;
- }
- default: {
- throwTypeError(lexicalGlobalObject, scope, "Unsupported encoding? This shouldn't happen"_s);
- break;
- }
- }
+// auto encoding = encoded.value();
- JSC::JSValue retValue = JSC::JSValue::decode(ret);
- if (UNLIKELY(!retValue.isString())) {
- scope.throwException(lexicalGlobalObject, retValue);
- return JSC::JSValue::encode(jsUndefined());
- }
+// return JSValue::decode(jsBufferToString(vm, lexicalGlobalObject, thisValue, 0, thisValue->byteLength(), encoding));
+// }
- RELEASE_AND_RETURN(scope, JSC::JSValue::encode(retValue));
-}
static inline JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSArrayBufferView>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);