Skip to content

Commit c49f781

Browse files
committed
util: improve text-decoder performance
PR-URL: nodejs#45363 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Rich Trott <[email protected]> # Conflicts: # lib/internal/encoding.js
1 parent 459faeb commit c49f781

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

lib/internal/encoding.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,9 +411,7 @@ function makeTextDecoderICU() {
411411

412412
decode(input = empty, options = kEmptyObject) {
413413
validateDecoder(this);
414-
if (isAnyArrayBuffer(input)) {
415-
input = lazyBuffer().from(input);
416-
} else if (!isArrayBufferView(input)) {
414+
if (!isAnyArrayBuffer(input) && !isArrayBufferView(input)) {
417415
throw new ERR_INVALID_ARG_TYPE('input',
418416
['ArrayBuffer', 'ArrayBufferView'],
419417
input);
@@ -485,10 +483,18 @@ function makeTextDecoderJS() {
485483
decode(input = empty, options = kEmptyObject) {
486484
validateDecoder(this);
487485
if (isAnyArrayBuffer(input)) {
488-
input = lazyBuffer().from(input);
486+
try {
487+
input = lazyBuffer().from(input);
488+
} catch {
489+
input = empty;
490+
}
489491
} else if (isArrayBufferView(input)) {
490-
input = lazyBuffer().from(input.buffer, input.byteOffset,
491-
input.byteLength);
492+
try {
493+
input = lazyBuffer().from(input.buffer, input.byteOffset,
494+
input.byteLength);
495+
} catch {
496+
input = empty;
497+
}
492498
} else {
493499
throw new ERR_INVALID_ARG_TYPE('input',
494500
['ArrayBuffer', 'ArrayBufferView'],

src/util-inl.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,9 @@ SlicedArguments::SlicedArguments(
513513
template <typename T, size_t S>
514514
ArrayBufferViewContents<T, S>::ArrayBufferViewContents(
515515
v8::Local<v8::Value> value) {
516-
CHECK(value->IsArrayBufferView());
517-
Read(value.As<v8::ArrayBufferView>());
516+
DCHECK(value->IsArrayBufferView() || value->IsSharedArrayBuffer() ||
517+
value->IsArrayBuffer());
518+
ReadValue(value);
518519
}
519520

520521
template <typename T, size_t S>
@@ -542,6 +543,26 @@ void ArrayBufferViewContents<T, S>::Read(v8::Local<v8::ArrayBufferView> abv) {
542543
}
543544
}
544545

546+
template <typename T, size_t S>
547+
void ArrayBufferViewContents<T, S>::ReadValue(v8::Local<v8::Value> buf) {
548+
static_assert(sizeof(T) == 1, "Only supports one-byte data at the moment");
549+
DCHECK(buf->IsArrayBufferView() || buf->IsSharedArrayBuffer() ||
550+
buf->IsArrayBuffer());
551+
552+
if (buf->IsArrayBufferView()) {
553+
Read(buf.As<v8::ArrayBufferView>());
554+
} else if (buf->IsArrayBuffer()) {
555+
auto ab = buf.As<v8::ArrayBuffer>();
556+
length_ = ab->ByteLength();
557+
data_ = static_cast<T*>(ab->Data());
558+
} else {
559+
CHECK(buf->IsSharedArrayBuffer());
560+
auto sab = buf.As<v8::SharedArrayBuffer>();
561+
length_ = sab->ByteLength();
562+
data_ = static_cast<T*>(sab->Data());
563+
}
564+
}
565+
545566
// ECMA262 20.1.2.5
546567
inline bool IsSafeJsInt(v8::Local<v8::Value> v) {
547568
if (!v->IsNumber()) return false;

src/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ class ArrayBufferViewContents {
505505
explicit inline ArrayBufferViewContents(v8::Local<v8::Object> value);
506506
explicit inline ArrayBufferViewContents(v8::Local<v8::ArrayBufferView> abv);
507507
inline void Read(v8::Local<v8::ArrayBufferView> abv);
508+
inline void ReadValue(v8::Local<v8::Value> buf);
508509

509510
inline const T* data() const { return data_; }
510511
inline size_t length() const { return length_; }

0 commit comments

Comments
 (0)