Compare commits

...

1 Commits

Author SHA1 Message Date
Jarred Sumner
c7b40925b3 WIP attempt to optimize buffer encoding parsing a little 2025-04-20 18:21:05 -07:00
14 changed files with 158 additions and 61 deletions

View File

@@ -0,0 +1,17 @@
import { group as suite, bench, run } from "mitata";
const bigBuf = Buffer.alloc(1024 * 256);
// Fill with letter "A" encoded as UTF16
for (let i = 0; i < bigBuf.length; i += 2) {
bigBuf[i] = 65; // ASCII/UTF16 code for 'A'
bigBuf[i + 1] = 0; // High byte for UTF16
}
var asUTF16LE = bigBuf.toString("utf16le");
// await run();
console.time("Buffer.from(bigBuf, 'utf16le')");
for (let i = 0; i < 100000; i++) {
bigBuf.asciiWrite(asUTF16LE, 0, asUTF16LE.length);
}
console.timeEnd("Buffer.from(bigBuf, 'utf16le')");

View File

@@ -4,9 +4,18 @@
// The items in this list must also be present in BunBuiltinNames.h
// If we use it as an identifier name in hot code, we should put it in this list.
#define BUN_COMMON_STRINGS_EACH_NAME(macro) \
macro(require) \
macro(ascii) \
macro(base64) \
macro(base64url) \
macro(buffer) \
macro(hex) \
macro(latin1) \
macro(mockedFunction) \
macro(require) \
macro(resolve) \
macro(mockedFunction)
macro(ucs2) \
macro(utf16le) \
macro(utf8) \
// These ones don't need to be in BunBuiltinNames.h
// If we don't use it as an identifier name, but we want to avoid allocating the string frequently, put it in this list.
@@ -54,14 +63,8 @@
macro(httpUNLINK, "UNLINK") \
macro(httpUNLOCK, "UNLOCK") \
macro(httpUNSUBSCRIBE, "UNSUBSCRIBE") \
macro(ascii, "ascii") \
macro(base64, "base64") \
macro(base64url, "base64url") \
macro(buffer, "buffer") \
macro(ec, "ec") \
macro(ed25519, "ed25519") \
macro(hex, "hex") \
macro(latin1, "latin1") \
macro(lax, "lax") \
macro(none, "none") \
macro(rsa, "rsa") \
@@ -88,9 +91,6 @@
macro(jwkX, "x") \
macro(jwkY, "y") \
macro(systemError, "SystemError") \
macro(ucs2, "ucs2") \
macro(utf16le, "utf16le") \
macro(utf8, "utf8") \
macro(x25519, "x25519")
// clang-format on

View File

@@ -277,19 +277,15 @@ static int normalizeCompareVal(int val, size_t a_length, size_t b_length)
return val;
}
static WebCore::BufferEncodingType parseEncoding(JSC::ThrowScope& scope, JSC::JSGlobalObject* lexicalGlobalObject, JSValue arg, bool validateUnknown)
static WebCore::BufferEncodingType parseEncoding(JSC::ThrowScope& scope, JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSValue arg, bool validateUnknown)
{
auto arg_ = arg.toStringOrNull(lexicalGlobalObject);
RETURN_IF_EXCEPTION(scope, {});
const auto& view = arg_->view(lexicalGlobalObject);
std::optional<BufferEncodingType> encoded = parseEnumerationFromView<BufferEncodingType>(view);
std::optional<BufferEncodingType> encoded = parseBufferEncoding(vm, *lexicalGlobalObject, arg);
if (UNLIKELY(!encoded)) {
if (validateUnknown) {
Bun::V::validateString(scope, lexicalGlobalObject, arg, "encoding"_s);
RETURN_IF_EXCEPTION(scope, WebCore::BufferEncodingType::utf8);
}
Bun::ERR::UNKNOWN_ENCODING(scope, lexicalGlobalObject, view);
Bun::ERR::UNKNOWN_ENCODING(scope, lexicalGlobalObject, arg);
return WebCore::BufferEncodingType::utf8;
}
@@ -376,7 +372,7 @@ static JSC::EncodedJSValue writeToBuffer(JSC::JSGlobalObject* lexicalGlobalObjec
return JSC::JSValue::encode(JSC::jsNumber(0));
const auto& view = str->view(lexicalGlobalObject);
if (view->isNull()) {
if (UNLIKELY(view->isNull())) {
return {};
}
@@ -589,7 +585,7 @@ static JSC::EncodedJSValue constructBufferFromStringAndEncoding(JSC::JSGlobalObj
RETURN_IF_EXCEPTION(scope, {});
if (arg1 && arg1.isString()) {
std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, arg1);
std::optional<BufferEncodingType> encoded = parseBufferEncoding(vm, *lexicalGlobalObject, arg1);
if (!encoded) {
auto* encodingString = arg1.toString(lexicalGlobalObject);
RETURN_IF_EXCEPTION(scope, {});
@@ -638,7 +634,7 @@ static JSC::EncodedJSValue jsBufferConstructorFunction_allocBody(JSC::JSGlobalOb
if (callFrame->argumentCount() > 2) {
EnsureStillAliveScope arg2 = callFrame->uncheckedArgument(2);
if (!arg2.value().isUndefined()) {
encoding = parseEncoding(scope, lexicalGlobalObject, arg2.value(), true);
encoding = parseEncoding(scope, vm, lexicalGlobalObject, arg2.value(), true);
RETURN_IF_EXCEPTION(scope, {});
}
}
@@ -749,7 +745,7 @@ static JSC::EncodedJSValue jsBufferConstructorFunction_byteLengthBody(JSC::JSGlo
if (callFrame->argumentCount() > 1) {
if (arg1.value().isString()) {
std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, arg1.value());
std::optional<BufferEncodingType> encoded = parseBufferEncoding(vm, *lexicalGlobalObject, arg1.value());
// this one doesn't fail
if (encoded) {
@@ -989,7 +985,7 @@ static JSC::EncodedJSValue jsBufferConstructorFunction_isEncodingBody(JSC::JSGlo
}
auto* encoding = encodingValue.toString(lexicalGlobalObject);
RETURN_IF_EXCEPTION(throwScope, {});
std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, encoding);
std::optional<BufferEncodingType> encoded = parseBufferEncoding(vm, *lexicalGlobalObject, encoding);
return JSValue::encode(jsBoolean(!!encoded));
}
@@ -1276,7 +1272,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_fillBody(JSC::JSGlobalObjec
}
if (!encodingValue.isUndefined() && value.isString()) {
encoding = parseEncoding(scope, lexicalGlobalObject, encodingValue, true);
encoding = parseEncoding(scope, vm, lexicalGlobalObject, encodingValue, true);
RETURN_IF_EXCEPTION(scope, {});
}
@@ -1890,7 +1886,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_toStringBody(JSC::JSGlobalO
return jsBufferToString(lexicalGlobalObject, scope, castedThis, start, end, encoding);
if (!arg1.isUndefined()) {
encoding = parseEncoding(scope, lexicalGlobalObject, arg1, false);
encoding = parseEncoding(scope, vm, lexicalGlobalObject, arg1, false);
RETURN_IF_EXCEPTION(scope, {});
}
@@ -1974,7 +1970,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_SliceWithEncoding(JSC::JSGl
// IGNORE_WARNINGS_END
// JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
// std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, encodingValue);
// std::optional<BufferEncodingType> encoded = parseBufferEncoding(*lexicalGlobalObject, encodingValue);
// if (!encoded) {
// auto scope = DECLARE_THROW_SCOPE(vm);
@@ -1994,11 +1990,13 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_writeEncodingBody(JSC::VM&
size_t byteLength = castedThis->byteLength();
auto scope = DECLARE_THROW_SCOPE(vm);
double offset;
double length;
int64_t offset;
int64_t length;
if (offsetValue.isUndefined()) {
offset = 0;
} else if (offsetValue.isInt32()) {
offset = offsetValue.asInt32();
} else if (offsetValue.isNumber()) {
offset = offsetValue.asNumber();
} else {
@@ -2006,7 +2004,9 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_writeEncodingBody(JSC::VM&
RETURN_IF_EXCEPTION(scope, {});
}
if (lengthValue.isUndefined()) {
length = byteLength - offset;
length = static_cast<int64_t>(byteLength) - offset;
} else if (lengthValue.isInt32()) {
length = lengthValue.asInt32();
} else if (lengthValue.isNumber()) {
length = lengthValue.asNumber();
} else {
@@ -2023,7 +2023,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_writeEncodingBody(JSC::VM&
RETURN_IF_EXCEPTION(scope, {});
}
RELEASE_AND_RETURN(scope, writeToBuffer(lexicalGlobalObject, castedThis, str, offset, length, encoding));
RELEASE_AND_RETURN(scope, writeToBuffer(lexicalGlobalObject, castedThis, str, static_cast<uint32_t>(offset), static_cast<uint32_t>(length), encoding));
}
template<BufferEncodingType encoding>
@@ -2081,7 +2081,8 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlobalObje
length = castedThis->byteLength();
auto* str = stringValue.toString(lexicalGlobalObject);
auto encoding = parseEncoding(scope, lexicalGlobalObject, encodingValue, false);
RETURN_IF_EXCEPTION(scope, {});
auto encoding = parseEncoding(scope, vm, lexicalGlobalObject, encodingValue, false);
RETURN_IF_EXCEPTION(scope, {});
RELEASE_AND_RETURN(scope, writeToBuffer(lexicalGlobalObject, castedThis, str, offset, length, encoding));
} else {
@@ -2112,7 +2113,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlobalObje
RELEASE_AND_RETURN(scope, writeToBuffer(lexicalGlobalObject, castedThis, str, offset, length, WebCore::BufferEncodingType::utf8));
}
auto encoding = parseEncoding(scope, lexicalGlobalObject, encodingValue, false);
auto encoding = parseEncoding(scope, vm, lexicalGlobalObject, encodingValue, false);
RETURN_IF_EXCEPTION(scope, {});
RELEASE_AND_RETURN(scope, writeToBuffer(lexicalGlobalObject, castedThis, str, offset, length, encoding));

View File

@@ -52,7 +52,7 @@ template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject,
}
template<bool allowBuffer>
static std::optional<BufferEncodingType> parseEnumerationAllowBufferInternal(JSGlobalObject& lexicalGlobalObject, JSValue arg)
static std::optional<BufferEncodingType> parseEnumerationAllowBufferInternal(JSC::VM& vm, JSC::JSGlobalObject& lexicalGlobalObject, JSValue arg)
{
if (UNLIKELY(!arg.isString())) {
return std::nullopt;
@@ -62,32 +62,100 @@ static std::optional<BufferEncodingType> parseEnumerationAllowBufferInternal(JSG
if (!str) {
return std::nullopt;
}
const auto& view = str->view(&lexicalGlobalObject);
auto& builtinNames = Bun::builtinNames(vm);
auto encoding = str->view(&lexicalGlobalObject);
if constexpr (allowBuffer) {
if (WTF::equalIgnoringASCIICase(view, "buffer"_s)) {
if (WTF::equalIgnoringASCIICase(builtinNames.bufferPublicName().string(), encoding)) {
return BufferEncodingType::buffer;
}
}
return parseEnumerationFromView<BufferEncodingType>(view);
// caller must check if value is a string
switch (encoding->length()) {
case 0: {
return BufferEncodingType::utf8;
}
case 1:
case 2: {
return std::nullopt;
}
default: {
}
}
switch (encoding[0]) {
case 'u':
case 'U': {
if (WTF::equalIgnoringASCIICase(encoding, "utf8"_s))
return BufferEncodingType::utf8;
if (WTF::equalIgnoringASCIICase(encoding, "utf-8"_s))
return BufferEncodingType::utf8;
if (WTF::equalIgnoringASCIICase(encoding, "ucs2"_s))
return BufferEncodingType::ucs2;
if (WTF::equalIgnoringASCIICase(encoding, "ucs-2"_s))
return BufferEncodingType::ucs2;
if (WTF::equalIgnoringASCIICase(encoding, "utf16le"_s))
return BufferEncodingType::ucs2;
if (WTF::equalIgnoringASCIICase(encoding, "utf-16le"_s))
return BufferEncodingType::ucs2;
break;
}
case 'l':
case 'L': {
if (WTF::equalIgnoringASCIICase(encoding, "latin1"_s))
return BufferEncodingType::latin1;
break;
}
case 'b':
case 'B': {
if (WTF::equalIgnoringASCIICase(encoding, "binary"_s))
return BufferEncodingType::latin1; // BINARY is a deprecated alias of LATIN1.
if (WTF::equalIgnoringASCIICase(encoding, "base64"_s))
return BufferEncodingType::base64;
if (WTF::equalIgnoringASCIICase(encoding, "base64url"_s))
return BufferEncodingType::base64url;
break;
}
case 'a':
case 'A':
// ascii
if (WTF::equalLettersIgnoringASCIICase(encoding, "ascii"_s))
return BufferEncodingType::ascii;
break;
case 'h':
case 'H':
// hex
if (WTF::equalIgnoringASCIICase(encoding, "hex"_s))
return BufferEncodingType::hex;
if (WTF::equalIgnoringASCIICase(encoding, "hex\0"_s))
return BufferEncodingType::hex;
break;
}
return std::nullopt;
}
std::optional<BufferEncodingType> parseEnumerationAllowBuffer(JSGlobalObject& lexicalGlobalObject, JSValue arg)
std::optional<BufferEncodingType> parseEnumerationAllowBuffer(JSC::VM& vm, JSC::JSGlobalObject& lexicalGlobalObject, JSValue arg)
{
return parseEnumerationAllowBufferInternal<true>(lexicalGlobalObject, arg);
return parseEnumerationAllowBufferInternal<true>(vm, lexicalGlobalObject, arg);
}
template<> std::optional<BufferEncodingType> parseEnumeration<BufferEncodingType>(JSGlobalObject& lexicalGlobalObject, JSValue arg)
std::optional<BufferEncodingType> parseBufferEncoding(JSC::VM& vm, JSGlobalObject& lexicalGlobalObject, JSValue arg)
{
return parseEnumerationAllowBufferInternal<false>(lexicalGlobalObject, arg);
return parseEnumerationAllowBufferInternal<false>(vm, lexicalGlobalObject, arg);
}
template<bool allowBuffer>
std::optional<BufferEncodingType> validateBufferEncoding(JSGlobalObject& lexicalGlobalObject, JSValue arg)
std::optional<BufferEncodingType> validateBufferEncoding(JSC::VM& vm, JSC::JSGlobalObject& lexicalGlobalObject, JSValue arg)
{
auto value = parseEnumerationAllowBufferInternal<allowBuffer>(lexicalGlobalObject, arg);
if (!value) {
auto scope = DECLARE_THROW_SCOPE(lexicalGlobalObject.vm());
auto value = parseEnumerationAllowBufferInternal<allowBuffer>(vm, lexicalGlobalObject, arg);
if (UNLIKELY(!value)) {
auto scope = DECLARE_THROW_SCOPE(vm);
Bun::throwError(&lexicalGlobalObject, scope, Bun::ErrorCode::ERR_UNKNOWN_ENCODING, "Invalid encoding"_s);
return std::nullopt;
}
@@ -176,15 +244,15 @@ template<> ASCIILiteral expectedEnumerationValues<BufferEncodingType>()
}
template<>
std::optional<BufferEncodingType> validateBufferEncoding<true>(JSGlobalObject& lexicalGlobalObject, JSValue arg)
std::optional<BufferEncodingType> validateBufferEncoding<true>(JSC::VM& vm, JSC::JSGlobalObject& lexicalGlobalObject, JSValue arg)
{
return parseEnumerationAllowBufferInternal<true>(lexicalGlobalObject, arg);
return parseEnumerationAllowBufferInternal<true>(vm, lexicalGlobalObject, arg);
}
template<>
std::optional<BufferEncodingType> validateBufferEncoding<false>(JSGlobalObject& lexicalGlobalObject, JSValue arg)
std::optional<BufferEncodingType> validateBufferEncoding<false>(JSC::VM& vm, JSC::JSGlobalObject& lexicalGlobalObject, JSValue arg)
{
return parseEnumerationAllowBufferInternal<false>(lexicalGlobalObject, arg);
return parseEnumerationAllowBufferInternal<false>(vm, lexicalGlobalObject, arg);
}
} // namespace WebCore

View File

@@ -7,10 +7,11 @@ namespace WebCore {
String convertEnumerationToString(BufferEncodingType);
template<> JSC::JSString* convertEnumerationToJS(JSC::JSGlobalObject&, BufferEncodingType);
template<> std::optional<BufferEncodingType> parseEnumeration<BufferEncodingType>(JSC::JSGlobalObject&, JSValue);
std::optional<BufferEncodingType> parseEnumerationAllowBuffer(JSC::JSGlobalObject&, JSValue);
std::optional<BufferEncodingType> parseBufferEncoding(JSC::VM&, JSC::JSGlobalObject&, JSValue);
std::optional<BufferEncodingType> parseEnumerationAllowBuffer(JSC::VM&, JSC::JSGlobalObject&, JSValue);
template<> std::optional<BufferEncodingType> parseEnumerationFromString(const WTF::String&);
template<> std::optional<BufferEncodingType> parseEnumerationFromView(const WTF::StringView&);
template<> std::optional<BufferEncodingType> parseEnumerationFromView(const WTF::StringView&);
template<> WTF::ASCIILiteral expectedEnumerationValues<BufferEncodingType>();
template<bool allowBuffer>

View File

@@ -15,6 +15,7 @@
#include "wtf/unicode/CharacterNames.h"
#include "wtf/SIMDUTF.h"
#include "ErrorCode.h"
#include "JSBufferEncodingType.h"
namespace WebCore {
@@ -567,7 +568,7 @@ JSC::EncodedJSValue JSStringDecoderConstructor::construct(JSC::JSGlobalObject* l
auto encoding = BufferEncodingType::utf8;
auto jsEncoding = callFrame->argument(0);
if (!jsEncoding.isUndefinedOrNull()) {
std::optional<BufferEncodingType> opt = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, jsEncoding);
std::optional<BufferEncodingType> opt = parseBufferEncoding(vm, *lexicalGlobalObject, jsEncoding);
if (opt.has_value()) {
encoding = opt.value();
} else {

View File

@@ -553,7 +553,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunction_validateEncoding, (JSC::JSGlobalObject * glo
auto encoding = callFrame->argument(1);
auto normalized = WebCore::parseEnumeration<BufferEncodingType>(*globalObject, encoding);
auto normalized = WebCore::parseBufferEncoding(vm, *globalObject, encoding);
if (normalized == BufferEncodingType::hex) {
auto data = callFrame->argument(0);

View File

@@ -583,7 +583,7 @@ JSC::JSArrayBufferView* getArrayBufferOrView(JSGlobalObject* globalObject, Throw
JSString* dataString = value.toString(globalObject);
RETURN_IF_EXCEPTION(scope, {});
auto maybeEncoding = encodingValue.pureToBoolean() == TriState::True ? WebCore::parseEnumerationAllowBuffer(*globalObject, encodingValue) : std::optional<BufferEncodingType> { BufferEncodingType::utf8 };
auto maybeEncoding = encodingValue.pureToBoolean() == TriState::True ? WebCore::parseBufferEncoding(globalObject->vm(), *globalObject, encodingValue) : std::optional<BufferEncodingType> { BufferEncodingType::utf8 };
RETURN_IF_EXCEPTION(scope, {});
if (!maybeEncoding && !defaultBufferEncoding) {

View File

@@ -163,7 +163,7 @@ JSC_DEFINE_HOST_FUNCTION(jsHashProtoFuncUpdate, (JSC::JSGlobalObject * globalObj
JSString* inputString = inputValue.toString(globalObject);
RETURN_IF_EXCEPTION(scope, {});
auto encoding = parseEnumeration<WebCore::BufferEncodingType>(*globalObject, encodingValue).value_or(WebCore::BufferEncodingType::utf8);
auto encoding = parseBufferEncoding(vm, *globalObject, encodingValue).value_or(WebCore::BufferEncodingType::utf8);
RETURN_IF_EXCEPTION(scope, {});
// Validate encoding

View File

@@ -132,7 +132,7 @@ JSC_DEFINE_HOST_FUNCTION(jsHmacProtoFuncUpdate, (JSC::JSGlobalObject * globalObj
JSString* inputString = inputValue.toString(globalObject);
RETURN_IF_EXCEPTION(scope, {});
auto encoding = parseEnumeration<WebCore::BufferEncodingType>(*globalObject, encodingValue).value_or(WebCore::BufferEncodingType::utf8);
auto encoding = parseBufferEncoding(vm, *globalObject, encodingValue).value_or(WebCore::BufferEncodingType::utf8);
RETURN_IF_EXCEPTION(scope, {});
// validateEncoding()
@@ -181,7 +181,7 @@ JSC_DEFINE_HOST_FUNCTION(jsHmacProtoFuncDigest, (JSC::JSGlobalObject * lexicalGl
// Handle encoding if provided
JSC::JSValue encodingValue = callFrame->argument(0);
auto encoding = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, encodingValue);
auto encoding = parseBufferEncoding(vm, *lexicalGlobalObject, encodingValue);
RETURN_IF_EXCEPTION(scope, {});
if (encoding.has_value() && encoding.value() != BufferEncodingType::buffer) {

View File

@@ -253,7 +253,7 @@ JSC_DEFINE_HOST_FUNCTION(jsSignProtoFuncUpdate, (JSC::JSGlobalObject * globalObj
RETURN_IF_EXCEPTION(scope, JSValue::encode({}));
JSValue encodingValue = callFrame->argument(2);
auto encoding = parseEnumeration<BufferEncodingType>(*globalObject, encodingValue).value_or(BufferEncodingType::utf8);
auto encoding = parseBufferEncoding(vm, *globalObject, encodingValue).value_or(BufferEncodingType::utf8);
RETURN_IF_EXCEPTION(scope, {});
if (encoding == BufferEncodingType::hex && dataString->length() % 2 != 0) {
@@ -415,7 +415,7 @@ JSC_DEFINE_HOST_FUNCTION(jsSignProtoFuncSign, (JSC::JSGlobalObject * lexicalGlob
}
JSValue outputEncodingValue = callFrame->argument(1);
auto outputEncoding = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, outputEncodingValue).value_or(BufferEncodingType::buffer);
auto outputEncoding = parseBufferEncoding(vm, *lexicalGlobalObject, outputEncodingValue).value_or(BufferEncodingType::buffer);
RETURN_IF_EXCEPTION(scope, JSValue::encode({}));
// Get RSA padding mode and salt length if applicable

View File

@@ -233,7 +233,7 @@ JSC_DEFINE_HOST_FUNCTION(jsVerifyProtoFuncUpdate, (JSGlobalObject * globalObject
RETURN_IF_EXCEPTION(scope, JSValue::encode({}));
JSValue encodingValue = callFrame->argument(2);
auto encoding = parseEnumeration<BufferEncodingType>(*globalObject, encodingValue).value_or(BufferEncodingType::utf8);
auto encoding = parseBufferEncoding(vm, *globalObject, encodingValue).value_or(BufferEncodingType::utf8);
RETURN_IF_EXCEPTION(scope, {});
if (encoding == BufferEncodingType::hex && dataString->length() % 2 != 0) {

View File

@@ -1438,7 +1438,7 @@ KeyObject KeyObject::prepareSecretKey(JSGlobalObject* globalObject, ThrowScope&
auto keyView = keyString->view(globalObject);
RETURN_IF_EXCEPTION(scope, {});
BufferEncodingType encoding = parseEnumerationAllowBuffer(*globalObject, encodingValue).value_or(BufferEncodingType::utf8);
BufferEncodingType encoding = parseBufferEncoding(globalObject->vm(), *globalObject, encodingValue).value_or(BufferEncodingType::utf8);
RETURN_IF_EXCEPTION(scope, {});
JSValue buffer = JSValue::decode(constructFromEncoding(globalObject, keyView, encoding));

View File

@@ -46,23 +46,27 @@ using namespace JSC;
macro(addEventListener) \
macro(appendFromJS) \
macro(argv) \
macro(ascii) \
macro(assignToStream) \
macro(associatedReadableByteStreamController) \
macro(atimeMs) \
macro(autoAllocateChunkSize) \
macro(backpressure) \
macro(backpressureChangePromise) \
macro(base64) \
macro(base64url) \
macro(basename) \
macro(birthtimeMs) \
macro(body) \
macro(buffer) \
macro(bunNativePtr) \
macro(bunNativeType) \
macro(byobRequest) \
macro(cancel) \
macro(cancelAlgorithm) \
macro(chdir) \
macro(checks) \
macro(checkBufferRead) \
macro(checks) \
macro(cloneArrayBuffer) \
macro(close) \
macro(closeAlgorithm) \
@@ -129,6 +133,7 @@ using namespace JSC;
macro(hash) \
macro(header) \
macro(headers) \
macro(hex) \
macro(highWaterMark) \
macro(host) \
macro(hostname) \
@@ -151,6 +156,7 @@ using namespace JSC;
macro(isWindows) \
macro(join) \
macro(kind) \
macro(latin1) \
macro(lazy) \
macro(lazyStreamPrototypeMap) \
macro(lineText) \
@@ -258,6 +264,7 @@ using namespace JSC;
macro(toNamespacedPath) \
macro(trace) \
macro(transformAlgorithm) \
macro(ucs2) \
macro(uncork) \
macro(underlyingByteSource) \
macro(underlyingSink) \
@@ -266,6 +273,8 @@ using namespace JSC;
macro(unshift) \
macro(url) \
macro(username) \
macro(utf16le) \
macro(utf8) \
macro(version) \
macro(versions) \
macro(view) \