From 8d8d2261a5f8ded7eddc6fa4cd713d0eca4b1589 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Wed, 18 Nov 2020 10:27:50 +0100 Subject: [PATCH] buffer: refactor to use more primordials PR-URL: https://github.com/nodejs/node/pull/36166 Reviewed-By: James M Snell Reviewed-By: Rich Trott --- lib/buffer.js | 58 +++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index 0daf5636edad46..e902ad8d00bf14 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -35,12 +35,20 @@ const { ObjectDefineProperties, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, - ObjectGetPrototypeOf, ObjectSetPrototypeOf, + StringPrototypeCharCodeAt, + StringPrototypeReplace, + StringPrototypeSlice, + StringPrototypeToLowerCase, + StringPrototypeTrim, SymbolSpecies, SymbolToPrimitive, + TypedArrayPrototype, + TypedArrayPrototypeFill, + TypedArrayPrototypeSet, Uint8Array, Uint8ArrayPrototype, + uncurryThis, } = primordials; const { @@ -108,12 +116,9 @@ const { createUnsafeBuffer } = require('internal/buffer'); -const TypedArrayPrototype = ObjectGetPrototypeOf(Uint8ArrayPrototype); - -const TypedArrayProto_byteLength = - ObjectGetOwnPropertyDescriptor(TypedArrayPrototype, - 'byteLength').get; -const TypedArrayFill = TypedArrayPrototype.fill; +const TypedArrayProto_byteLength = uncurryThis( + ObjectGetOwnPropertyDescriptor(TypedArrayPrototype, + 'byteLength').get); FastBuffer.prototype.constructor = Buffer; Buffer.prototype = FastBuffer.prototype; @@ -246,7 +251,7 @@ function _copyActual(source, target, targetStart, sourceStart, sourceEnd) { if (sourceStart !== 0 || sourceEnd < source.length) source = new Uint8Array(source.buffer, source.byteOffset + sourceStart, nb); - target.set(source, targetStart); + TypedArrayPrototypeSet(target, source, targetStart); return nb; } @@ -480,7 +485,7 @@ function fromArrayLike(obj) { if (obj.length > (poolSize - poolOffset)) createPool(); const b = new FastBuffer(allocPool, poolOffset, obj.length); - b.set(obj, 0); + TypedArrayPrototypeSet(b, obj, 0); poolOffset += obj.length; alignPool(); return b; @@ -566,7 +571,7 @@ Buffer.concat = function concat(list, length) { // Zero-fill the remaining bytes if the specified `length` was more than // the actual total length, i.e. if we have some remaining allocated bytes // there were not initialized. - TypedArrayFill.call(buffer, 0, pos, length); + TypedArrayPrototypeFill(buffer, 0, pos, length); } return buffer; @@ -574,9 +579,9 @@ Buffer.concat = function concat(list, length) { function base64ByteLength(str, bytes) { // Handle padding - if (str.charCodeAt(bytes - 1) === 0x3D) + if (StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D) bytes--; - if (bytes > 1 && str.charCodeAt(bytes - 1) === 0x3D) + if (bytes > 1 && StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D) bytes--; // Base64 ratio: 3/4 @@ -666,7 +671,7 @@ function getEncodingOps(encoding) { case 4: if (encoding === 'utf8') return encodingOps.utf8; if (encoding === 'ucs2') return encodingOps.ucs2; - encoding = encoding.toLowerCase(); + encoding = StringPrototypeToLowerCase(encoding); if (encoding === 'utf8') return encodingOps.utf8; if (encoding === 'ucs2') return encodingOps.ucs2; break; @@ -674,30 +679,32 @@ function getEncodingOps(encoding) { if (encoding === 'utf-8') return encodingOps.utf8; if (encoding === 'ascii') return encodingOps.ascii; if (encoding === 'ucs-2') return encodingOps.ucs2; - encoding = encoding.toLowerCase(); + encoding = StringPrototypeToLowerCase(encoding); if (encoding === 'utf-8') return encodingOps.utf8; if (encoding === 'ascii') return encodingOps.ascii; if (encoding === 'ucs-2') return encodingOps.ucs2; break; case 7: - if (encoding === 'utf16le' || encoding.toLowerCase() === 'utf16le') + if (encoding === 'utf16le' || + StringPrototypeToLowerCase(encoding) === 'utf16le') return encodingOps.utf16le; break; case 8: - if (encoding === 'utf-16le' || encoding.toLowerCase() === 'utf-16le') + if (encoding === 'utf-16le' || + StringPrototypeToLowerCase(encoding) === 'utf-16le') return encodingOps.utf16le; break; case 6: if (encoding === 'latin1' || encoding === 'binary') return encodingOps.latin1; if (encoding === 'base64') return encodingOps.base64; - encoding = encoding.toLowerCase(); + encoding = StringPrototypeToLowerCase(encoding); if (encoding === 'latin1' || encoding === 'binary') return encodingOps.latin1; if (encoding === 'base64') return encodingOps.base64; break; case 3: - if (encoding === 'hex' || encoding.toLowerCase() === 'hex') + if (encoding === 'hex' || StringPrototypeToLowerCase(encoding) === 'hex') return encodingOps.hex; break; } @@ -810,7 +817,8 @@ Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) { const max = INSPECT_MAX_BYTES; const actualMax = MathMin(max, this.length); const remaining = this.length - max; - let str = this.hexSlice(0, actualMax).replace(/(.{2})/g, '$1 ').trim(); + let str = StringPrototypeTrim(StringPrototypeReplace( + this.hexSlice(0, actualMax), /(.{2})/g, '$1 ')); if (remaining > 0) str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`; // Inspect special properties as well, if possible. @@ -827,11 +835,11 @@ Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) { str += ', '; // '[Object: null prototype] {'.length === 26 // This is guarded with a test. - str += utilInspect(obj, { + str += StringPrototypeSlice(utilInspect(obj, { ...ctx, breakLength: Infinity, compact: true - }).slice(27, -2); + }), 27, -2); } } return `<${this.constructor.name} ${str}>`; @@ -975,12 +983,12 @@ function _fill(buf, value, offset, end, encoding) { } else if (value.length === 1) { // Fast path: If `value` fits into a single byte, use that numeric value. if (normalizedEncoding === 'utf8') { - const code = value.charCodeAt(0); + const code = StringPrototypeCharCodeAt(value, 0); if (code < 128) { value = code; } } else if (normalizedEncoding === 'latin1') { - value = value.charCodeAt(0); + value = StringPrototypeCharCodeAt(value, 0); } } } else { @@ -1005,12 +1013,12 @@ function _fill(buf, value, offset, end, encoding) { if (typeof value === 'number') { // OOB check - const byteLen = TypedArrayProto_byteLength.call(buf); + const byteLen = TypedArrayProto_byteLength(buf); const fillLength = end - offset; if (offset > end || fillLength + offset > byteLen) throw new ERR_BUFFER_OUT_OF_BOUNDS(); - TypedArrayFill.call(buf, value, offset, end); + TypedArrayPrototypeFill(buf, value, offset, end); } else { const res = bindingFill(buf, value, offset, end, encoding); if (res < 0) {