diff options
author | Leo Kettmeir <crowlkats@toaxl.com> | 2023-02-07 20:22:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-07 20:22:46 +0100 |
commit | b4aa1530970f7b9cc4e6f2f27e077852c4e178d3 (patch) | |
tree | 3d008912affe8550692183bd2697a386db5e3c79 /runtime/js/13_buffer.js | |
parent | 65500f36e870b4ada3996b06aa287e30177d21a3 (diff) |
refactor: Use ES modules for internal runtime code (#17648)
This PR refactors all internal js files (except core) to be written as
ES modules.
`__bootstrap`has been mostly replaced with static imports in form in
`internal:[path to file from repo root]`.
To specify if files are ESM, an `esm` method has been added to
`Extension`, similar to the `js` method.
A new ModuleLoader called `InternalModuleLoader` has been added to
enable the loading of internal specifiers, which is used in all
situations except when a snapshot is only loaded, and not a new one is
created from it.
---------
Co-authored-by: Bartek IwaĆczuk <biwanczuk@gmail.com>
Diffstat (limited to 'runtime/js/13_buffer.js')
-rw-r--r-- | runtime/js/13_buffer.js | 428 |
1 files changed, 210 insertions, 218 deletions
diff --git a/runtime/js/13_buffer.js b/runtime/js/13_buffer.js index 180e9d26d..8e87eefa5 100644 --- a/runtime/js/13_buffer.js +++ b/runtime/js/13_buffer.js @@ -3,257 +3,249 @@ // This code has been ported almost directly from Go's src/bytes/buffer.go // Copyright 2009 The Go Authors. All rights reserved. BSD license. // https://github.com/golang/go/blob/master/LICENSE -"use strict"; - -((window) => { - const { assert } = window.__bootstrap.infra; - const { - TypedArrayPrototypeSubarray, - TypedArrayPrototypeSlice, - TypedArrayPrototypeSet, - MathFloor, - MathMin, - PromiseResolve, - Uint8Array, - Error, - } = window.__bootstrap.primordials; - - // MIN_READ is the minimum ArrayBuffer size passed to a read call by - // buffer.ReadFrom. As long as the Buffer has at least MIN_READ bytes beyond - // what is required to hold the contents of r, readFrom() will not grow the - // underlying buffer. - const MIN_READ = 32 * 1024; - const MAX_SIZE = 2 ** 32 - 2; - - // `off` is the offset into `dst` where it will at which to begin writing values - // from `src`. - // Returns the number of bytes copied. - function copyBytes(src, dst, off = 0) { - const r = dst.byteLength - off; - if (src.byteLength > r) { - src = TypedArrayPrototypeSubarray(src, 0, r); - } - TypedArrayPrototypeSet(dst, src, off); - return src.byteLength; - } - class Buffer { - #buf = null; // contents are the bytes buf[off : len(buf)] - #off = 0; // read at buf[off], write at buf[buf.byteLength] +import { assert } from "internal:ext/web/00_infra.js"; +const primordials = globalThis.__bootstrap.primordials; +const { + TypedArrayPrototypeSubarray, + TypedArrayPrototypeSlice, + TypedArrayPrototypeSet, + MathFloor, + MathMin, + PromiseResolve, + Uint8Array, + Error, +} = primordials; + +// MIN_READ is the minimum ArrayBuffer size passed to a read call by +// buffer.ReadFrom. As long as the Buffer has at least MIN_READ bytes beyond +// what is required to hold the contents of r, readFrom() will not grow the +// underlying buffer. +const MIN_READ = 32 * 1024; +const MAX_SIZE = 2 ** 32 - 2; + +// `off` is the offset into `dst` where it will at which to begin writing values +// from `src`. +// Returns the number of bytes copied. +function copyBytes(src, dst, off = 0) { + const r = dst.byteLength - off; + if (src.byteLength > r) { + src = TypedArrayPrototypeSubarray(src, 0, r); + } + TypedArrayPrototypeSet(dst, src, off); + return src.byteLength; +} - constructor(ab) { - if (ab == null) { - this.#buf = new Uint8Array(0); - return; - } +class Buffer { + #buf = null; // contents are the bytes buf[off : len(buf)] + #off = 0; // read at buf[off], write at buf[buf.byteLength] - this.#buf = new Uint8Array(ab); + constructor(ab) { + if (ab == null) { + this.#buf = new Uint8Array(0); + return; } - bytes(options = { copy: true }) { - if (options.copy === false) { - return TypedArrayPrototypeSubarray(this.#buf, this.#off); - } - return TypedArrayPrototypeSlice(this.#buf, this.#off); - } + this.#buf = new Uint8Array(ab); + } - empty() { - return this.#buf.byteLength <= this.#off; + bytes(options = { copy: true }) { + if (options.copy === false) { + return TypedArrayPrototypeSubarray(this.#buf, this.#off); } + return TypedArrayPrototypeSlice(this.#buf, this.#off); + } - get length() { - return this.#buf.byteLength - this.#off; - } + empty() { + return this.#buf.byteLength <= this.#off; + } - get capacity() { - return this.#buf.buffer.byteLength; - } + get length() { + return this.#buf.byteLength - this.#off; + } - truncate(n) { - if (n === 0) { - this.reset(); - return; - } - if (n < 0 || n > this.length) { - throw Error("bytes.Buffer: truncation out of range"); - } - this.#reslice(this.#off + n); - } + get capacity() { + return this.#buf.buffer.byteLength; + } - reset() { - this.#reslice(0); - this.#off = 0; + truncate(n) { + if (n === 0) { + this.reset(); + return; } - - #tryGrowByReslice(n) { - const l = this.#buf.byteLength; - if (n <= this.capacity - l) { - this.#reslice(l + n); - return l; - } - return -1; + if (n < 0 || n > this.length) { + throw Error("bytes.Buffer: truncation out of range"); } + this.#reslice(this.#off + n); + } + + reset() { + this.#reslice(0); + this.#off = 0; + } - #reslice(len) { - assert(len <= this.#buf.buffer.byteLength); - this.#buf = new Uint8Array(this.#buf.buffer, 0, len); + #tryGrowByReslice(n) { + const l = this.#buf.byteLength; + if (n <= this.capacity - l) { + this.#reslice(l + n); + return l; } + return -1; + } + + #reslice(len) { + assert(len <= this.#buf.buffer.byteLength); + this.#buf = new Uint8Array(this.#buf.buffer, 0, len); + } - readSync(p) { - if (this.empty()) { - // Buffer is empty, reset to recover space. - this.reset(); - if (p.byteLength === 0) { - // this edge case is tested in 'bufferReadEmptyAtEOF' test - return 0; - } - return null; + readSync(p) { + if (this.empty()) { + // Buffer is empty, reset to recover space. + this.reset(); + if (p.byteLength === 0) { + // this edge case is tested in 'bufferReadEmptyAtEOF' test + return 0; } - const nread = copyBytes( - TypedArrayPrototypeSubarray(this.#buf, this.#off), - p, - ); - this.#off += nread; - return nread; - } + return null; + } + const nread = copyBytes( + TypedArrayPrototypeSubarray(this.#buf, this.#off), + p, + ); + this.#off += nread; + return nread; + } - read(p) { - const rr = this.readSync(p); - return PromiseResolve(rr); - } + read(p) { + const rr = this.readSync(p); + return PromiseResolve(rr); + } - writeSync(p) { - const m = this.#grow(p.byteLength); - return copyBytes(p, this.#buf, m); - } + writeSync(p) { + const m = this.#grow(p.byteLength); + return copyBytes(p, this.#buf, m); + } - write(p) { - const n = this.writeSync(p); - return PromiseResolve(n); - } + write(p) { + const n = this.writeSync(p); + return PromiseResolve(n); + } - #grow(n) { - const m = this.length; - // If buffer is empty, reset to recover space. - if (m === 0 && this.#off !== 0) { - this.reset(); - } - // Fast: Try to grow by means of a reslice. - const i = this.#tryGrowByReslice(n); - if (i >= 0) { - return i; - } - const c = this.capacity; - if (n <= MathFloor(c / 2) - m) { - // We can slide things down instead of allocating a new - // ArrayBuffer. We only need m+n <= c to slide, but - // we instead let capacity get twice as large so we - // don't spend all our time copying. - copyBytes(TypedArrayPrototypeSubarray(this.#buf, this.#off), this.#buf); - } else if (c + n > MAX_SIZE) { - throw new Error("The buffer cannot be grown beyond the maximum size."); - } else { - // Not enough space anywhere, we need to allocate. - const buf = new Uint8Array(MathMin(2 * c + n, MAX_SIZE)); - copyBytes(TypedArrayPrototypeSubarray(this.#buf, this.#off), buf); - this.#buf = buf; - } - // Restore this.#off and len(this.#buf). - this.#off = 0; - this.#reslice(MathMin(m + n, MAX_SIZE)); - return m; - } + #grow(n) { + const m = this.length; + // If buffer is empty, reset to recover space. + if (m === 0 && this.#off !== 0) { + this.reset(); + } + // Fast: Try to grow by means of a reslice. + const i = this.#tryGrowByReslice(n); + if (i >= 0) { + return i; + } + const c = this.capacity; + if (n <= MathFloor(c / 2) - m) { + // We can slide things down instead of allocating a new + // ArrayBuffer. We only need m+n <= c to slide, but + // we instead let capacity get twice as large so we + // don't spend all our time copying. + copyBytes(TypedArrayPrototypeSubarray(this.#buf, this.#off), this.#buf); + } else if (c + n > MAX_SIZE) { + throw new Error("The buffer cannot be grown beyond the maximum size."); + } else { + // Not enough space anywhere, we need to allocate. + const buf = new Uint8Array(MathMin(2 * c + n, MAX_SIZE)); + copyBytes(TypedArrayPrototypeSubarray(this.#buf, this.#off), buf); + this.#buf = buf; + } + // Restore this.#off and len(this.#buf). + this.#off = 0; + this.#reslice(MathMin(m + n, MAX_SIZE)); + return m; + } - grow(n) { - if (n < 0) { - throw Error("Buffer.grow: negative count"); - } - const m = this.#grow(n); - this.#reslice(m); + grow(n) { + if (n < 0) { + throw Error("Buffer.grow: negative count"); } + const m = this.#grow(n); + this.#reslice(m); + } - async readFrom(r) { - let n = 0; - const tmp = new Uint8Array(MIN_READ); - while (true) { - const shouldGrow = this.capacity - this.length < MIN_READ; - // read into tmp buffer if there's not enough room - // otherwise read directly into the internal buffer - const buf = shouldGrow - ? tmp - : new Uint8Array(this.#buf.buffer, this.length); - - const nread = await r.read(buf); - if (nread === null) { - return n; - } - - // write will grow if needed - if (shouldGrow) { - this.writeSync(TypedArrayPrototypeSubarray(buf, 0, nread)); - } else this.#reslice(this.length + nread); - - n += nread; + async readFrom(r) { + let n = 0; + const tmp = new Uint8Array(MIN_READ); + while (true) { + const shouldGrow = this.capacity - this.length < MIN_READ; + // read into tmp buffer if there's not enough room + // otherwise read directly into the internal buffer + const buf = shouldGrow + ? tmp + : new Uint8Array(this.#buf.buffer, this.length); + + const nread = await r.read(buf); + if (nread === null) { + return n; } - } - readFromSync(r) { - let n = 0; - const tmp = new Uint8Array(MIN_READ); - while (true) { - const shouldGrow = this.capacity - this.length < MIN_READ; - // read into tmp buffer if there's not enough room - // otherwise read directly into the internal buffer - const buf = shouldGrow - ? tmp - : new Uint8Array(this.#buf.buffer, this.length); - - const nread = r.readSync(buf); - if (nread === null) { - return n; - } - - // write will grow if needed - if (shouldGrow) { - this.writeSync(TypedArrayPrototypeSubarray(buf, 0, nread)); - } else this.#reslice(this.length + nread); - - n += nread; - } + // write will grow if needed + if (shouldGrow) { + this.writeSync(TypedArrayPrototypeSubarray(buf, 0, nread)); + } else this.#reslice(this.length + nread); + + n += nread; } } - async function readAll(r) { - const buf = new Buffer(); - await buf.readFrom(r); - return buf.bytes(); - } + readFromSync(r) { + let n = 0; + const tmp = new Uint8Array(MIN_READ); + while (true) { + const shouldGrow = this.capacity - this.length < MIN_READ; + // read into tmp buffer if there's not enough room + // otherwise read directly into the internal buffer + const buf = shouldGrow + ? tmp + : new Uint8Array(this.#buf.buffer, this.length); + + const nread = r.readSync(buf); + if (nread === null) { + return n; + } - function readAllSync(r) { - const buf = new Buffer(); - buf.readFromSync(r); - return buf.bytes(); - } + // write will grow if needed + if (shouldGrow) { + this.writeSync(TypedArrayPrototypeSubarray(buf, 0, nread)); + } else this.#reslice(this.length + nread); - async function writeAll(w, arr) { - let nwritten = 0; - while (nwritten < arr.length) { - nwritten += await w.write(TypedArrayPrototypeSubarray(arr, nwritten)); + n += nread; } } +} + +async function readAll(r) { + const buf = new Buffer(); + await buf.readFrom(r); + return buf.bytes(); +} + +function readAllSync(r) { + const buf = new Buffer(); + buf.readFromSync(r); + return buf.bytes(); +} + +async function writeAll(w, arr) { + let nwritten = 0; + while (nwritten < arr.length) { + nwritten += await w.write(TypedArrayPrototypeSubarray(arr, nwritten)); + } +} - function writeAllSync(w, arr) { - let nwritten = 0; - while (nwritten < arr.length) { - nwritten += w.writeSync(TypedArrayPrototypeSubarray(arr, nwritten)); - } +function writeAllSync(w, arr) { + let nwritten = 0; + while (nwritten < arr.length) { + nwritten += w.writeSync(TypedArrayPrototypeSubarray(arr, nwritten)); } +} - window.__bootstrap.buffer = { - writeAll, - writeAllSync, - readAll, - readAllSync, - Buffer, - }; -})(this); +export { Buffer, readAll, readAllSync, writeAll, writeAllSync }; |