diff options
author | 2023-02-05 07:07:35 -0800 | |
---|---|---|
committer | 2023-02-05 07:07:35 -0800 | |
commit | ca2e708be11e9481938965ee92acc38c01a7726a (patch) | |
tree | 5af19d1f7de4807d333334f804d286f230612164 /src/bun.js/bindings/JSBuffer.cpp | |
parent | 864913684558466f8517de9d474180a6bc19915c (diff) | |
download | bun-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.cpp | 141 |
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); |