diff options
Diffstat (limited to '')
-rw-r--r-- | src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp | 41 | ||||
-rw-r--r-- | src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h | 9 | ||||
-rw-r--r-- | src/bun.js/builtins/js/JSBufferPrototype.js | 32 | ||||
-rw-r--r-- | test/bun.js/buffer.test.js | 78 |
4 files changed, 111 insertions, 49 deletions
diff --git a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp index d1d9231e7..367041f65 100644 --- a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp +++ b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.cpp @@ -717,40 +717,33 @@ const char* const s_jsBufferPrototypeToJSONCode = "})\n" \ ; -const JSC::ConstructAbility s_jsBufferPrototypeSubarrayCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; -const JSC::ConstructorKind s_jsBufferPrototypeSubarrayCodeConstructorKind = JSC::ConstructorKind::None; -const JSC::ImplementationVisibility s_jsBufferPrototypeSubarrayCodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeSubarrayCodeLength = 196; -static const JSC::Intrinsic s_jsBufferPrototypeSubarrayCodeIntrinsic = JSC::NoIntrinsic; -const char* const s_jsBufferPrototypeSubarrayCode = - "(function (start, end) {\n" \ - " \"use strict\";\n" \ - "\n" \ - " Buffer[Symbol.species] ??= Buffer;\n" \ - " return new Buffer(this.buffer, this.byteOffset + (start || 0), (end || this.byteLength) - (start || 0));\n" \ - "})\n" \ -; - const JSC::ConstructAbility s_jsBufferPrototypeSliceCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_jsBufferPrototypeSliceCodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_jsBufferPrototypeSliceCodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_jsBufferPrototypeSliceCodeLength = 308; +const int s_jsBufferPrototypeSliceCodeLength = 612; static const JSC::Intrinsic s_jsBufferPrototypeSliceCodeIntrinsic = JSC::NoIntrinsic; const char* const s_jsBufferPrototypeSliceCode = "(function (start, end) {\n" \ " \"use strict\";\n" \ - " if (start === undefined && end === undefined) {\n" \ - " return this;\n" \ - " }\n" \ - "\n" \ - " Buffer[Symbol.species] ||= Buffer;\n" \ + " var { buffer, byteOffset, byteLength } = this;\n" \ "\n" \ - " start = start || 0;\n" \ - " if (end !== 0) {\n" \ - " end = end || this.byteLength;\n" \ + " function adjustOffset(offset, length) {\n" \ + " //\n" \ + " //\n" \ + " offset = @trunc(offset);\n" \ + " if (offset === 0 || @isNaN(offset)) {\n" \ + " return 0;\n" \ + " } else if (offset < 0) {\n" \ + " offset += length;\n" \ + " return offset > 0 ? offset : 0;\n" \ + " } else {\n" \ + " return offset < length ? offset : length;\n" \ + " }\n" \ " }\n" \ "\n" \ - " return new Buffer(this.buffer, this.byteOffset + start, end - start);\n" \ + " var start_ = adjustOffset(start, byteLength);\n" \ + " var end_ = end !== undefined ? adjustOffset(end, byteLength) : byteLength;\n" \ + " return new Buffer(buffer, byteOffset + start_, end_ > start_ ? (end_ - start_) : 0);\n" \ "})\n" \ ; diff --git a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h index f17f22dbb..04fa9df0b 100644 --- a/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h +++ b/src/bun.js/builtins/cpp/JSBufferPrototypeBuiltins.h @@ -318,11 +318,6 @@ extern const int s_jsBufferPrototypeToJSONCodeLength; extern const JSC::ConstructAbility s_jsBufferPrototypeToJSONCodeConstructAbility; extern const JSC::ConstructorKind s_jsBufferPrototypeToJSONCodeConstructorKind; extern const JSC::ImplementationVisibility s_jsBufferPrototypeToJSONCodeImplementationVisibility; -extern const char* const s_jsBufferPrototypeSubarrayCode; -extern const int s_jsBufferPrototypeSubarrayCodeLength; -extern const JSC::ConstructAbility s_jsBufferPrototypeSubarrayCodeConstructAbility; -extern const JSC::ConstructorKind s_jsBufferPrototypeSubarrayCodeConstructorKind; -extern const JSC::ImplementationVisibility s_jsBufferPrototypeSubarrayCodeImplementationVisibility; extern const char* const s_jsBufferPrototypeSliceCode; extern const int s_jsBufferPrototypeSliceCodeLength; extern const JSC::ConstructAbility s_jsBufferPrototypeSliceCodeConstructAbility; @@ -389,7 +384,6 @@ extern const JSC::ImplementationVisibility s_jsBufferPrototypeInitializeBunBuffe macro(base64urlSlice, jsBufferPrototypeBase64urlSlice, 2) \ macro(hexSlice, jsBufferPrototypeHexSlice, 2) \ macro(toJSON, jsBufferPrototypeToJSON, 0) \ - macro(subarray, jsBufferPrototypeSubarray, 2) \ macro(slice, jsBufferPrototypeSlice, 2) \ macro(initializeBunBuffer, jsBufferPrototypeInitializeBunBuffer, 1) \ @@ -447,7 +441,6 @@ extern const JSC::ImplementationVisibility s_jsBufferPrototypeInitializeBunBuffe #define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_BASE64URLSLICE 1 #define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_HEXSLICE 1 #define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_TOJSON 1 -#define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_SUBARRAY 1 #define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_SLICE 1 #define WEBCORE_BUILTIN_JSBUFFERPROTOTYPE_INITIALIZEBUNBUFFER 1 @@ -506,7 +499,6 @@ extern const JSC::ImplementationVisibility s_jsBufferPrototypeInitializeBunBuffe macro(jsBufferPrototypeBase64urlSliceCode, base64urlSlice, ASCIILiteral(), s_jsBufferPrototypeBase64urlSliceCodeLength) \ macro(jsBufferPrototypeHexSliceCode, hexSlice, ASCIILiteral(), s_jsBufferPrototypeHexSliceCodeLength) \ macro(jsBufferPrototypeToJSONCode, toJSON, ASCIILiteral(), s_jsBufferPrototypeToJSONCodeLength) \ - macro(jsBufferPrototypeSubarrayCode, subarray, ASCIILiteral(), s_jsBufferPrototypeSubarrayCodeLength) \ macro(jsBufferPrototypeSliceCode, slice, ASCIILiteral(), s_jsBufferPrototypeSliceCodeLength) \ macro(jsBufferPrototypeInitializeBunBufferCode, initializeBunBuffer, ASCIILiteral(), s_jsBufferPrototypeInitializeBunBufferCodeLength) \ @@ -542,7 +534,6 @@ extern const JSC::ImplementationVisibility s_jsBufferPrototypeInitializeBunBuffe macro(readUInt8) \ macro(setBigUint64) \ macro(slice) \ - macro(subarray) \ macro(toJSON) \ macro(ucs2Slice) \ macro(ucs2Write) \ diff --git a/src/bun.js/builtins/js/JSBufferPrototype.js b/src/bun.js/builtins/js/JSBufferPrototype.js index a81634f69..689dc2dde 100644 --- a/src/bun.js/builtins/js/JSBufferPrototype.js +++ b/src/bun.js/builtins/js/JSBufferPrototype.js @@ -277,27 +277,27 @@ function toJSON() { return { type, data }; } -function subarray(start, end) { - "use strict"; - - Buffer[Symbol.species] ??= Buffer; - return new Buffer(this.buffer, this.byteOffset + (start || 0), (end || this.byteLength) - (start || 0)); -} - function slice(start, end) { "use strict"; - if (start === undefined && end === undefined) { - return this; - } - - Buffer[Symbol.species] ||= Buffer; + var { buffer, byteOffset, byteLength } = this; - start = start || 0; - if (end !== 0) { - end = end || this.byteLength; + function adjustOffset(offset, length) { + // Use Math.trunc() to convert offset to an integer value that can be larger + // than an Int32. Hence, don't use offset | 0 or similar techniques. + offset = @trunc(offset); + if (offset === 0 || @isNaN(offset)) { + return 0; + } else if (offset < 0) { + offset += length; + return offset > 0 ? offset : 0; + } else { + return offset < length ? offset : length; + } } - return new Buffer(this.buffer, this.byteOffset + start, end - start); + var start_ = adjustOffset(start, byteLength); + var end_ = end !== undefined ? adjustOffset(end, byteLength) : byteLength; + return new Buffer(buffer, byteOffset + start_, end_ > start_ ? (end_ - start_) : 0); } diff --git a/test/bun.js/buffer.test.js b/test/bun.js/buffer.test.js index 02ee1e75e..23d94abd5 100644 --- a/test/bun.js/buffer.test.js +++ b/test/bun.js/buffer.test.js @@ -213,6 +213,71 @@ it("Buffer.compare", () => { b[2] = 0; expect(a.compare(b)).toBe(1); expect(b.compare(a)).toBe(-1); + + const buf = Buffer.from("0123456789", "utf8"); + const expectedSameBufs = [ + [buf.slice(-10, 10), Buffer.from("0123456789", "utf8")], + [buf.slice(-20, 10), Buffer.from("0123456789", "utf8")], + [buf.slice(-20, -10), Buffer.from("", "utf8")], + [buf.slice(), Buffer.from("0123456789", "utf8")], + [buf.slice(0), Buffer.from("0123456789", "utf8")], + [buf.slice(0, 0), Buffer.from("", "utf8")], + [buf.slice(undefined), Buffer.from("0123456789", "utf8")], + [buf.slice("foobar"), Buffer.from("0123456789", "utf8")], + [buf.slice(undefined, undefined), Buffer.from("0123456789", "utf8")], + [buf.slice(2), Buffer.from("23456789", "utf8")], + [buf.slice(5), Buffer.from("56789", "utf8")], + [buf.slice(10), Buffer.from("", "utf8")], + [buf.slice(5, 8), Buffer.from("567", "utf8")], + [buf.slice(8, -1), Buffer.from("8", "utf8")], + [buf.slice(-10), Buffer.from("0123456789", "utf8")], + [buf.slice(0, -9), Buffer.from("0", "utf8")], + [buf.slice(0, -10), Buffer.from("", "utf8")], + [buf.slice(0, -1), Buffer.from("012345678", "utf8")], + [buf.slice(2, -2), Buffer.from("234567", "utf8")], + [buf.slice(0, 65536), Buffer.from("0123456789", "utf8")], + [buf.slice(65536, 0), Buffer.from("", "utf8")], + [buf.slice(-5, -8), Buffer.from("", "utf8")], + [buf.slice(-5, -3), Buffer.from("56", "utf8")], + [buf.slice(-10, 10), Buffer.from("0123456789", "utf8")], + [buf.slice("0", "1"), Buffer.from("0", "utf8")], + [buf.slice("-5", "10"), Buffer.from("56789", "utf8")], + [buf.slice("-10", "10"), Buffer.from("0123456789", "utf8")], + [buf.slice("-10", "-5"), Buffer.from("01234", "utf8")], + [buf.slice("-10", "-0"), Buffer.from("", "utf8")], + [buf.slice("111"), Buffer.from("", "utf8")], + [buf.slice("0", "-111"), Buffer.from("", "utf8")], + ]; + + for (let i = 0, s = buf.toString(); i < buf.length; ++i) { + expectedSameBufs.push( + [buf.slice(i), Buffer.from(s.slice(i))], + [buf.slice(0, i), Buffer.from(s.slice(0, i))], + [buf.slice(-i), Buffer.from(s.slice(-i))], + [buf.slice(0, -i), Buffer.from(s.slice(0, -i))] + ); + } + + expectedSameBufs.forEach(([buf1, buf2]) => { + expect(Buffer.compare(buf1, buf2)).toBe(0); + }); + + { + const buf = Buffer.from([ + 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0, 0, 0, 18, 184, 6, 0, + 175, 29, 0, 8, 11, 1, 0, 0, + ]); + const chunk1 = Buffer.from([ + 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0, + ]); + const chunk2 = Buffer.from([ + 0, 0, 18, 184, 6, 0, 175, 29, 0, 8, 11, 1, 0, 0, + ]); + const middle = buf.length / 2; + + expect(JSON.stringify(buf.slice(0, middle))).toBe(JSON.stringify(chunk1)); + expect(JSON.stringify(buf.slice(middle))).toBe(JSON.stringify(chunk2)); + } }); it("Buffer.copy", () => { @@ -512,3 +577,16 @@ it("lastIndexOf", () => { expect(b.lastIndexOf("b", null)).toBe(-1); expect(b.lastIndexOf("b", [])).toBe(-1); }); + +for (let fn of [Buffer.prototype.slice, Buffer.prototype.subarray]) { + it(`Buffer.${fn.name}`, () => { + const buf = new Buffer("buffer"); + const slice = fn.call(buf, 1, 3); + expect(slice.toString()).toBe("uf"); + const slice2 = fn.call(slice, 100); + expect(slice2.toString()).toBe(""); + + const slice3 = fn.call(slice, -1); + expect(slice3.toString()).toBe("f"); + }); +} |