diff options
author | 2023-01-21 03:12:59 -0800 | |
---|---|---|
committer | 2023-01-21 03:12:59 -0800 | |
commit | d955bfe50f7aa15aca9df3bf0a40fea26a132381 (patch) | |
tree | 2433e2b9dfc4bf712903417008f9b0c5b3900d69 /src/bun.js/builtins/js | |
parent | b8648adf873758a83911d3d28c94255d8c3fdd3c (diff) | |
download | bun-d955bfe50f7aa15aca9df3bf0a40fea26a132381.tar.gz bun-d955bfe50f7aa15aca9df3bf0a40fea26a132381.tar.zst bun-d955bfe50f7aa15aca9df3bf0a40fea26a132381.zip |
[buffer] Make Buffer.from pass more tests
Diffstat (limited to 'src/bun.js/builtins/js')
-rw-r--r-- | src/bun.js/builtins/js/JSBufferConstructor.js | 96 |
1 files changed, 59 insertions, 37 deletions
diff --git a/src/bun.js/builtins/js/JSBufferConstructor.js b/src/bun.js/builtins/js/JSBufferConstructor.js index 48342fe26..9f61220cc 100644 --- a/src/bun.js/builtins/js/JSBufferConstructor.js +++ b/src/bun.js/builtins/js/JSBufferConstructor.js @@ -25,52 +25,74 @@ // ^ that comment is required or the builtins generator will have a fit. -function alloc(n) { - "use strict"; - if (typeof n !== "number" || n < 0) { - @throwRangeError("n must be a positive integer less than 2^32"); - } - - return new this(n); -} - function from(items) { "use strict"; if (!@isConstructor(this)) - @throwTypeError("Buffer.from requires |this| to be a constructor"); + @throwTypeError("Buffer.from requires |this| to be a constructor"); + if (@isUndefinedOrNull(items)) + @throwTypeError( + "The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object.", + ); - // TODO: figure out why private symbol not found - if (typeof items === 'string' || (typeof items === 'object' && items && (items instanceof ArrayBuffer || items instanceof SharedArrayBuffer))) { - switch (@argumentCount()) { - case 1: { - return new this(items); - } - case 2: { - return new this(items, @argument(1)); - } - default: { - return new this(items, @argument(1), @argument(2)); - } - } + // TODO: figure out why private symbol not found + if ( + typeof items === "string" || + (typeof items === "object" && + (@isTypedArrayView(items) || + items instanceof ArrayBuffer || + items instanceof SharedArrayBuffer || + items instanceof @String)) + ) { + switch (@argumentCount()) { + case 1: { + return new this(items); + } + case 2: { + return new this(items, @argument(1)); + } + default: { + return new this(items, @argument(1), @argument(2)); + } } + } + + var arrayLike = @toObject( + items, + "The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object.", + ); + if (!@isJSArray(arrayLike)) { + const toPrimitive = @tryGetByIdWithWellKnownSymbol(items, "toPrimitive"); - var arrayLike = @toObject(items, "Buffer.from requires an array-like object - not null or undefined"); + if (toPrimitive) { + const primitive = toPrimitive.@call(items, "string"); - // Buffer-specific fast path: - // - uninitialized memory - // - use .set - if (@isTypedArrayView(arrayLike)) { - var length = @typedArrayLength(arrayLike); - var result = this.allocUnsafe(length); - result.set(arrayLike); - return result; - } + if (typeof primitive === "string") { + switch (@argumentCount()) { + case 1: { + return new this(primitive); + } + case 2: { + return new this(primitive, @argument(1)); + } + default: { + return new this(primitive, @argument(1), @argument(2)); + } + } + } + } + + if (!("length" in arrayLike) || @isCallable(arrayLike)) { + @throwTypeError( + "The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object.", + ); + } + } - // Don't pass the second argument because Node's Buffer.from doesn't accept - // a function and Uint8Array.from requires it if it exists - // That means we cannot use @tailCallFowrardArguments here, sadly - return new this(@Uint8Array.from(arrayLike).buffer); + // Don't pass the second argument because Node's Buffer.from doesn't accept + // a function and Uint8Array.from requires it if it exists + // That means we cannot use @tailCallFowrardArguments here, sadly + return new this(@Uint8Array.from(arrayLike).buffer); } |