From cd740d0b0d7234fbc5ed16e246805e4a5d135d46 Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Wed, 9 Nov 2022 09:18:42 -0500 Subject: [PATCH] util: improve text decoder performance PR-URL: https://github.com/nodejs/node/pull/45388 Reviewed-By: Anna Henningsen Reviewed-By: Santiago Gimeno Reviewed-By: Rich Trott --- lib/internal/encoding.js | 12 +----------- src/node_errors.h | 1 + src/node_i18n.cc | 24 ++++++++++++++++++------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/internal/encoding.js b/lib/internal/encoding.js index 40c87a0a8719ff..66dc0ce9c8609a 100644 --- a/lib/internal/encoding.js +++ b/lib/internal/encoding.js @@ -18,7 +18,6 @@ const { } = primordials; const { - ERR_ENCODING_INVALID_ENCODED_DATA, ERR_ENCODING_NOT_SUPPORTED, ERR_INVALID_ARG_TYPE, ERR_INVALID_THIS, @@ -411,11 +410,6 @@ function makeTextDecoderICU() { decode(input = empty, options = kEmptyObject) { validateDecoder(this); - if (!isAnyArrayBuffer(input) && !isArrayBufferView(input)) { - throw new ERR_INVALID_ARG_TYPE('input', - ['ArrayBuffer', 'ArrayBufferView'], - input); - } validateObject(options, 'options', { nullable: true, allowArray: true, @@ -426,11 +420,7 @@ function makeTextDecoderICU() { if (options !== null) flags |= options.stream ? 0 : CONVERTER_FLAGS_FLUSH; - const ret = _decode(this[kHandle], input, flags); - if (typeof ret === 'number') { - throw new ERR_ENCODING_INVALID_ENCODED_DATA(this.encoding, ret); - } - return ret; + return _decode(this[kHandle], input, flags, this.encoding); } } diff --git a/src/node_errors.h b/src/node_errors.h index 5587c234862610..926f54286ec72f 100644 --- a/src/node_errors.h +++ b/src/node_errors.h @@ -60,6 +60,7 @@ void OOMErrorHandler(const char* location, bool is_heap_oom); V(ERR_CRYPTO_JOB_INIT_FAILED, Error) \ V(ERR_DLOPEN_DISABLED, Error) \ V(ERR_DLOPEN_FAILED, Error) \ + V(ERR_ENCODING_INVALID_ENCODED_DATA, TypeError) \ V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, Error) \ V(ERR_INVALID_ADDRESS, Error) \ V(ERR_INVALID_ARG_VALUE, TypeError) \ diff --git a/src/node_i18n.cc b/src/node_i18n.cc index ed7b72c31f975e..441c2b32763a96 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -436,13 +436,25 @@ void ConverterObject::Create(const FunctionCallbackInfo& args) { void ConverterObject::Decode(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - CHECK_GE(args.Length(), 3); // Converter, Buffer, Flags + CHECK_GE(args.Length(), 4); // Converter, Buffer, Flags, Encoding ConverterObject* converter; ASSIGN_OR_RETURN_UNWRAP(&converter, args[0].As()); + + if (!(args[1]->IsArrayBuffer() || args[1]->IsSharedArrayBuffer() || + args[1]->IsArrayBufferView())) { + return node::THROW_ERR_INVALID_ARG_TYPE( + env->isolate(), + "The \"input\" argument must be an instance of SharedArrayBuffer, " + "ArrayBuffer or ArrayBufferView."); + } + ArrayBufferViewContents input(args[1]); int flags = args[2]->Uint32Value(env->context()).ToChecked(); + CHECK(args[3]->IsString()); + Local from_encoding = args[3].As(); + UErrorCode status = U_ZERO_ERROR; MaybeStackBuffer result; @@ -524,14 +536,14 @@ void ConverterObject::Decode(const FunctionCallbackInfo& args) { Local ret; if (encoded.ToLocal(&ret)) { args.GetReturnValue().Set(ret); - } else { - args.GetReturnValue().Set(error); + return; } - - return; } - args.GetReturnValue().Set(status); + node::THROW_ERR_ENCODING_INVALID_ENCODED_DATA( + env->isolate(), + "The encoded data was not valid for encoding %s", + *node::Utf8Value(env->isolate(), from_encoding)); } ConverterObject::ConverterObject(