Convert Buffers and DataViews to BigInt through their own text

BigInt of byte storage joined the elements with "," for every kind, so a
Buffer, whose text is its UTF-8 decoding, and a DataView, whose text is
"[object DataView]", converted as typed arrays. BigInt now parses the
value's ToString, which the runtime value decides, as String does. This also
covers a Buffer held in a Uint8Array slot.

Corpus 7403 adds Buffers, a DataView, and a Buffer in a typed array slot.

Refs #1647
This commit is contained in:
Chris Tate
2026-10-22 23:29:34 -05:00
parent 84eba88276
commit d027786c80
2 changed files with 24 additions and 8 deletions
@@ -2400,15 +2400,15 @@ function lowerBigIntConstructorValue(lowerer: Lowerer, arg: IrExpr, loc: SrcLoc)
return { kind: "libCall", fn: "bigint.parse", args: [arg], type: BIGINT_T, loc };
if (arg.type.kind === "f64")
return { kind: "libCall", fn: "bigint.fromF64", args: [arg], type: BIGINT_T, loc };
// A typed array converts through ToPrimitive to its elements joined with
// ",", which BigInt then parses: one element reads as that element, none
// as 0n, and several throw the SyntaxError for the joined text.
// Byte storage converts through ToPrimitive, which BigInt then parses: a
// typed array's text is its elements joined with "," (one element reads
// as that element, none as 0n, several throw the SyntaxError for the
// joined text), a Buffer's is its UTF-8 decoding and a DataView's is
// "[object DataView]". The runtime value tells them apart, as for String.
if (arg.type.kind === "bytes") {
const text: IrExpr = {
kind: "bytesIntrinsic",
method: "join",
receiver: arg,
args: [{ kind: "strLit", value: ",", type: STRING, loc }],
kind: "toString",
operand: { kind: "dynFrom", value: arg, type: DYN, loc },
type: STRING,
loc,
};
+17 -1
View File
@@ -2,7 +2,9 @@
// "," and parses that text, as in Node: one element reads as its value,
// an empty array as 0n, and anything else throws the SyntaxError for the
// joined text. Every element kind, negative and clamped values, float
// formatting, views and the results in arithmetic.
// formatting, views and the results in arithmetic. A Buffer converts
// through its UTF-8 text instead, also when a typed array slot holds it,
// and a DataView through "[object DataView]".
const one = [
new Int8Array([-5]),
@@ -44,3 +46,17 @@ for (let i = 0; i < 100; i++) {
total += BigInt(window) * 3n;
}
console.log("window", BigInt(window), total, BigInt(bytes.subarray(2)) ** 2n);
function convert(label, make) {
try {
console.log(label, BigInt(make()));
} catch (e) {
console.log(label, e instanceof SyntaxError, e.message);
}
}
convert("buffer", () => Buffer.from("12"));
convert("spaced buffer", () => Buffer.from(" -7 "));
convert("empty buffer", () => Buffer.alloc(0));
convert("fraction buffer", () => Buffer.from("1.5"));
convert("data view", () => new DataView(new ArrayBuffer(2)));
for (const view of [new Uint8Array([5]), Buffer.from("64")]) console.log("slot", BigInt(view));