From 5dd3fa961e427d875f6368a641c2c2c52ba85f85 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 8 Apr 2024 09:27:16 -0500 Subject: [PATCH] Native BigInt (#890) --- packages/driver/src/codecs/datetime.ts | 84 +++++------ packages/driver/src/codecs/numbers.ts | 3 +- packages/driver/src/compat.ts | 82 ----------- packages/driver/src/datatypes/datetime.ts | 31 ++-- packages/driver/src/datatypes/memory.ts | 40 +++-- packages/driver/src/index.shared.ts | 3 - packages/driver/src/primitives/bigint.ts | 172 ---------------------- packages/driver/src/primitives/buffer.ts | 55 ++----- packages/driver/test/misc.test.ts | 5 +- 9 files changed, 83 insertions(+), 392 deletions(-) delete mode 100644 packages/driver/src/compat.ts delete mode 100644 packages/driver/src/primitives/bigint.ts diff --git a/packages/driver/src/codecs/datetime.ts b/packages/driver/src/codecs/datetime.ts index 977d3017c..e79ea053e 100644 --- a/packages/driver/src/codecs/datetime.ts +++ b/packages/driver/src/codecs/datetime.ts @@ -18,7 +18,6 @@ import { ReadBuffer, WriteBuffer } from "../primitives/buffer"; import { ICodec, ScalarCodec } from "./ifaces"; -import * as bi from "../primitives/bigint"; import { LocalDateTime, LocalDate, @@ -77,23 +76,22 @@ export class LocalDateTimeCodec extends ScalarCodec implements ICodec { ); } - const ms = bi.make(localDateInstances.get(object)!.getTime() - TIMESHIFT); - let us = bi.add( - bi.mul(ms, bi.make(1000)), - bi.make( - object.hour * 3_600_000_000 + - object.minute * 60_000_000 + - object.second * 1_000_000 + - object.millisecond * 1000 + + const ms = BigInt(localDateInstances.get(object)!.getTime() - TIMESHIFT); + let us = + ms * 1000n + + BigInt( + object.hour * 36e8 + + object.minute * 6e7 + + object.second * 1e6 + + object.millisecond * 1e3 + object.microsecond - ) - ); + ); if ( (object.nanosecond === 500 && Math.abs(object.microsecond) % 2 === 1) || object.nanosecond > 500 ) { - us = bi.add(us, bi.make(1)); + us += 1n; } buf.writeInt32(8); @@ -101,10 +99,9 @@ export class LocalDateTimeCodec extends ScalarCodec implements ICodec { } decode(buf: ReadBuffer): LocalDateTime { - const bi1000 = bi.make(1000); const bi_us = buf.readBigInt64(); - const bi_ms = bi.div(bi_us, bi1000); - let us = Number(bi.sub(bi_us, bi.mul(bi_ms, bi1000))); + const bi_ms = bi_us / 1000n; + let us = Number(bi_us - bi_ms * 1000n); let ms = Number(bi_ms); if (us < 0) { us += 1000; @@ -217,38 +214,26 @@ export class DurationCodec extends ScalarCodec implements ICodec { ); } - let us = bi.make(Math.abs(object.microseconds)); - us = bi.add( - us, - bi.mul(bi.make(Math.abs(object.milliseconds)), bi.make(1_000)) - ); - us = bi.add( - us, - bi.mul(bi.make(Math.abs(object.seconds)), bi.make(1_000_000)) - ); - us = bi.add( - us, - bi.mul(bi.make(Math.abs(object.minutes)), bi.make(60_000_000)) - ); - us = bi.add( - us, - bi.mul(bi.make(Math.abs(object.hours)), bi.make(3_600_000_000)) - ); + let us = BigInt(Math.abs(object.microseconds)); + us += BigInt(Math.abs(object.milliseconds)) * BigInt(1e3); + us += BigInt(Math.abs(object.seconds)) * BigInt(1e6); + us += BigInt(Math.abs(object.minutes)) * BigInt(6e7); + us += BigInt(Math.abs(object.hours)) * BigInt(36e8); if ( (Math.abs(object.nanoseconds) === 500 && Math.abs(object.microseconds) % 2 === 1) || Math.abs(object.nanoseconds) > 500 ) { - us = bi.add(us, bi.make(1)); + us += 1n; } if (object.sign < 0) { - us = bi.mul(us, bi.make(-1)); + us *= -1n; } buf.writeInt32(16); - buf.writeBigInt64(us as bigint); + buf.writeBigInt64(us); buf.writeInt32(0); buf.writeInt32(0); } @@ -267,13 +252,13 @@ export class DurationCodec extends ScalarCodec implements ICodec { let sign = 1; if (Number(bius) < 0) { sign = -1; - bius = bi.mul(bi.make(-1), bius); + bius *= -1n; } - const biMillion = bi.make(1_000_000); + const biMillion = 1_000_000n; - const biSeconds = bi.div(bius, biMillion); - let us = Number(bi.sub(bius, bi.mul(biSeconds, biMillion))); + const biSeconds = bius / biMillion; + let us = Number(bius - biSeconds * biMillion); const ms = Math.floor(us / 1000); us = us % 1000; @@ -307,14 +292,15 @@ export class RelativeDurationCodec extends ScalarCodec implements ICodec { `); } - let us = bi.make(object.microseconds); - us = bi.add(us, bi.mul(bi.make(object.milliseconds), bi.make(1_000))); - us = bi.add(us, bi.mul(bi.make(object.seconds), bi.make(1_000_000))); - us = bi.add(us, bi.mul(bi.make(object.minutes), bi.make(60_000_000))); - us = bi.add(us, bi.mul(bi.make(object.hours), bi.make(3_600_000_000))); + const us = + BigInt(object.microseconds) + + BigInt(object.milliseconds) * BigInt(1e3) + + BigInt(object.seconds) * BigInt(1e6) + + BigInt(object.minutes) * BigInt(6e7) + + BigInt(object.hours) * BigInt(36e8); buf.writeInt32(16); - buf.writeBigInt64(us as bigint); + buf.writeBigInt64(us); buf.writeInt32(object.days + 7 * object.weeks); buf.writeInt32(object.months + 12 * object.years); } @@ -327,13 +313,13 @@ export class RelativeDurationCodec extends ScalarCodec implements ICodec { let sign = 1; if (Number(bius) < 0) { sign = -1; - bius = bi.mul(bi.make(-1), bius); + bius *= -1n; } - const biMillion = bi.make(1_000_000); + const million = BigInt(1e6); - const biSeconds = bi.div(bius, biMillion); - let us = Number(bi.sub(bius, bi.mul(biSeconds, biMillion))); + const biSeconds = bius / million; + let us = Number(bius - biSeconds * million); const ms = Math.trunc(us / 1000); us = us % 1000; diff --git a/packages/driver/src/codecs/numbers.ts b/packages/driver/src/codecs/numbers.ts index 36738f7bb..dc0061238 100644 --- a/packages/driver/src/codecs/numbers.ts +++ b/packages/driver/src/codecs/numbers.ts @@ -17,7 +17,6 @@ */ import { ReadBuffer, WriteBuffer } from "../primitives/buffer"; -import * as bi from "../primitives/bigint"; import { ICodec, ScalarCodec } from "./ifaces"; import { InvalidArgumentError } from "../errors"; @@ -38,7 +37,7 @@ export class Int64Codec extends ScalarCodec implements ICodec { export class Int64BigintCodec extends ScalarCodec implements ICodec { encode(buf: WriteBuffer, object: any): void { - if (!bi.isBigInt(object)) { + if (typeof object !== "bigint") { throw new InvalidArgumentError(`a bigint was expected, got "${object}"`); } buf.writeInt32(8); diff --git a/packages/driver/src/compat.ts b/packages/driver/src/compat.ts deleted file mode 100644 index ea9ffc5d6..000000000 --- a/packages/driver/src/compat.ts +++ /dev/null @@ -1,82 +0,0 @@ -/*! - * This source file is part of the EdgeDB open source project. - * - * Copyright 2019-present MagicStack Inc. and the EdgeDB authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* A compatibility layer for symbols/functions required in both - browser and NodeJS environments. -*/ - -export function decodeInt64ToString(buf: Uint8Array): string { - /* Render int64 binary into a decimal string. - - Avoid using BigInts (not all platforms support them) or number - arithmetics (there's no int64 in JS). - */ - - if (buf.length !== 8) { - throw new Error("expected 8 bytes buffer"); - } - - let inp: number[] = Array.from(buf); - - let negative = false; - if (inp[0] & 0x80) { - // A negative integer; invert all bits. - inp = inp.map((x) => x ^ 0xff); - // Account for the two's compliment's `1`. - inp[inp.length - 1]++; - - negative = true; - } - - let result = "0"; - - for (const digit of inp) { - /* The algorithm: - - An int64 is a sequence of 8 bytes on the wire, say - - b1 b2 b3 b4 b5 b6 b7 b8 - - To decode this into a decimal number we can use the following - formula: - - b8 * 256^0 + b7 * 256^1 + b6 * 256^2 + ... + b1 * 256^7 - - which can be represented as - - b8 + 256 * (b7 + 256 * (b6 + 256 * (b5 + 256 * (... b1 * 256)))) - - The code below does exactly that only using a string as a storage - for the result number. That way we can circumvent the JS limitation - of not supporting proper integers. - */ - - let acc = digit; - let ret = ""; - - for (let j = result.length - 1; j >= 0; j--) { - const num = parseInt(result[j], 10) * 256 + acc; - ret = (num % 10) + ret; - acc = Math.floor(num / 10); - } - - result = acc ? acc + ret : ret; - } - - return negative ? `-${result}` : result; -} diff --git a/packages/driver/src/datatypes/datetime.ts b/packages/driver/src/datatypes/datetime.ts index 746502fde..01a9c28f6 100644 --- a/packages/driver/src/datatypes/datetime.ts +++ b/packages/driver/src/datatypes/datetime.ts @@ -16,8 +16,6 @@ * limitations under the License. */ -import * as bi from "../primitives/bigint"; - import { daysInMonth, ymd2ord, @@ -388,24 +386,24 @@ export class Duration { toString(): string { let dateParts = ""; if (this.years) { - dateParts += bi.make(Math.abs(this.years)) + "Y"; + dateParts += BigInt(Math.abs(this.years)) + "Y"; } if (this.months) { - dateParts += bi.make(Math.abs(this.months)) + "M"; + dateParts += BigInt(Math.abs(this.months)) + "M"; } if (this.weeks) { - dateParts += bi.make(Math.abs(this.weeks)) + "W"; + dateParts += BigInt(Math.abs(this.weeks)) + "W"; } if (this.days) { - dateParts += bi.make(Math.abs(this.days)) + "D"; + dateParts += BigInt(Math.abs(this.days)) + "D"; } let timeParts = ""; if (this.hours) { - timeParts += bi.make(Math.abs(this.hours)) + "H"; + timeParts += BigInt(Math.abs(this.hours)) + "H"; } if (this.minutes) { - timeParts += bi.make(Math.abs(this.minutes)) + "M"; + timeParts += BigInt(Math.abs(this.minutes)) + "M"; } if ( (!dateParts && !timeParts) || @@ -414,17 +412,12 @@ export class Duration { this.microseconds || this.nanoseconds ) { - const totalNanoseconds = bi - .add( - bi.add( - bi.add( - bi.mul(bi.make(Math.abs(this.seconds)), bi.make(1e9)), - bi.mul(bi.make(Math.abs(this.milliseconds)), bi.make(1e6)) - ), - bi.mul(bi.make(Math.abs(this.microseconds)), bi.make(1e3)) - ), - bi.make(Math.abs(this.nanoseconds)) - ) + const totalNanoseconds = ( + BigInt(Math.abs(this.seconds)) * BigInt(1e9) + + BigInt(Math.abs(this.milliseconds)) * BigInt(1e6) + + BigInt(Math.abs(this.microseconds)) * BigInt(1e3) + + BigInt(Math.abs(this.nanoseconds)) + ) .toString() .padStart(10, "0"); diff --git a/packages/driver/src/datatypes/memory.ts b/packages/driver/src/datatypes/memory.ts index a99e5d719..30f3797ca 100644 --- a/packages/driver/src/datatypes/memory.ts +++ b/packages/driver/src/datatypes/memory.ts @@ -16,8 +16,6 @@ * limitations under the License. */ -import * as bi from "../primitives/bigint"; - const KiB = 1024; const MiB = 1024 * KiB; const GiB = 1024 * MiB; @@ -25,9 +23,9 @@ const TiB = 1024 * GiB; const PiB = 1024 * TiB; export class ConfigMemory { - private readonly _bytes: bi.BigIntLike; + private readonly _bytes: bigint; - constructor(bytes: bi.BigIntLike) { + constructor(bytes: bigint) { this._bytes = bytes; } @@ -35,8 +33,8 @@ export class ConfigMemory { return Number(this._bytes); } - get bytesBigInt(): BigInt { - return this._bytes as BigInt; + get bytesBigInt(): bigint { + return this._bytes; } get kibibytes(): number { @@ -61,25 +59,25 @@ export class ConfigMemory { toString(): string { const bytes = this._bytes; - const bigPiB = bi.make(PiB); - if (bi.gte(bytes, bigPiB) && Number(bi.remainder(bytes, bigPiB)) === 0) { - return `${bi.div(bytes, bigPiB)}PiB`; + const bigPiB = BigInt(PiB); + if (bytes >= bigPiB && Number(bytes % bigPiB) === 0) { + return `${bytes / bigPiB}PiB`; } - const bigTiB = bi.make(TiB); - if (bi.gte(bytes, bigTiB) && Number(bi.remainder(bytes, bigTiB)) === 0) { - return `${bi.div(bytes, bigTiB)}TiB`; + const bigTiB = BigInt(TiB); + if (bytes >= bigTiB && Number(bytes % bigTiB) === 0) { + return `${bytes / bigTiB}TiB`; } - const bigGiB = bi.make(GiB); - if (bi.gte(bytes, bigGiB) && Number(bi.remainder(bytes, bigGiB)) === 0) { - return `${bi.div(bytes, bigGiB)}GiB`; + const bigGiB = BigInt(GiB); + if (bytes >= bigGiB && Number(bytes % bigGiB) === 0) { + return `${bytes / bigGiB}GiB`; } - const bigMiB = bi.make(MiB); - if (bi.gte(bytes, bigMiB) && Number(bi.remainder(bytes, bigMiB)) === 0) { - return `${bi.div(bytes, bigMiB)}MiB`; + const bigMiB = BigInt(MiB); + if (bytes >= bigMiB && Number(bytes % bigMiB) === 0) { + return `${bytes / bigMiB}MiB`; } - const bigKiB = bi.make(KiB); - if (bi.gte(bytes, bigKiB) && Number(bi.remainder(bytes, bigKiB)) === 0) { - return `${bi.div(bytes, bigKiB)}KiB`; + const bigKiB = BigInt(KiB); + if (bytes >= bigKiB && Number(bytes % bigKiB) === 0) { + return `${bytes / bigKiB}KiB`; } return `${bytes}B`; } diff --git a/packages/driver/src/index.shared.ts b/packages/driver/src/index.shared.ts index a12976798..03b43d99c 100644 --- a/packages/driver/src/index.shared.ts +++ b/packages/driver/src/index.shared.ts @@ -40,6 +40,3 @@ import * as buf from "./primitives/buffer"; export const _CodecsRegistry = reg.CodecsRegistry; export const _ReadBuffer = buf.ReadBuffer; export type _ICodec = codecs.ICodec; - -import { plugJSBI } from "./primitives/bigint"; -export const _plugJSBI = plugJSBI; diff --git a/packages/driver/src/primitives/bigint.ts b/packages/driver/src/primitives/bigint.ts deleted file mode 100644 index eca6e2a92..000000000 --- a/packages/driver/src/primitives/bigint.ts +++ /dev/null @@ -1,172 +0,0 @@ -/* Safari does not support BigInt, hence this polyfill. */ - -interface JSBI { - BigInt(from: number | string | boolean | object): JSBI; - isBigInt(x: JSBI): boolean; - - toNumber(x: JSBI): number; - - unaryMinus(x: JSBI): JSBI; - bitwiseNot(x: JSBI): JSBI; - - exponentiate(x: JSBI, y: JSBI): JSBI; - multiply(x: JSBI, y: JSBI): JSBI; - divide(x: JSBI, y: JSBI): JSBI; - remainder(x: JSBI, y: JSBI): JSBI; - add(x: JSBI, y: JSBI): JSBI; - subtract(x: JSBI, y: JSBI): JSBI; - leftShift(x: JSBI, y: JSBI): JSBI; - signedRightShift(x: JSBI, y: JSBI): JSBI; - - lessThan(x: JSBI, y: JSBI): boolean; - lessThanOrEqual(x: JSBI, y: JSBI): boolean; - greaterThan(x: JSBI, y: JSBI): boolean; - greaterThanOrEqual(x: JSBI, y: JSBI): boolean; - equal(x: JSBI, y: JSBI): boolean; - notEqual(x: JSBI, y: JSBI): boolean; - - bitwiseAnd(x: JSBI, y: JSBI): JSBI; - bitwiseXor(x: JSBI, y: JSBI): JSBI; - bitwiseOr(x: JSBI, y: JSBI): JSBI; - - asIntN(n: number, x: JSBI): JSBI; - asUintN(n: number, x: JSBI): JSBI; - - ADD(x: any, y: any): any; - LT(x: any, y: any): boolean; - LE(x: any, y: any): boolean; - GT(x: any, y: any): boolean; - GE(x: any, y: any): boolean; - EQ(x: any, y: any): boolean; - NE(x: any, y: any): boolean; -} - -export type BigIntLike = bigint | JSBI; - -let JSBI: JSBI | null = null; - -export const hasNativeBigInt = typeof BigInt !== "undefined"; - -export function plugJSBI(jsbi: any): void { - JSBI = jsbi as JSBI; -} - -let _isBigInt; -let _make; -let _add; -let _div; -let _sub; -let _mul; -let _rshift; -let _bitand; -let _gte; -let _lt; -let _remainder; - -if (hasNativeBigInt) { - _isBigInt = (val: BigIntLike): boolean => typeof val === "bigint"; - - _make = (val: string | number): BigIntLike => BigInt(val); - - _add = (op1: BigIntLike, op2: BigIntLike): BigIntLike => - ((op1 as bigint) + (op2 as bigint)) as BigIntLike; - - _sub = (op1: BigIntLike, op2: BigIntLike): BigIntLike => - ((op1 as bigint) - (op2 as bigint)) as BigIntLike; - - _div = (op1: BigIntLike, op2: BigIntLike): BigIntLike => - ((op1 as bigint) / (op2 as bigint)) as BigIntLike; - - _mul = (op1: BigIntLike, op2: BigIntLike): BigIntLike => - ((op1 as bigint) * (op2 as bigint)) as BigIntLike; - - _rshift = (op1: BigIntLike, op2: BigIntLike): BigIntLike => - ((op1 as bigint) >> (op2 as bigint)) as BigIntLike; - - _bitand = (op1: BigIntLike, op2: BigIntLike): BigIntLike => - ((op1 as bigint) & (op2 as bigint)) as BigIntLike; - - _gte = (op1: BigIntLike, op2: BigIntLike): boolean => - (op1 as bigint) >= (op2 as bigint); - - _lt = (op1: BigIntLike, op2: BigIntLike): boolean => - (op1 as bigint) < (op2 as bigint); - - _remainder = (op1: BigIntLike, op2: BigIntLike): BigIntLike => - ((op1 as bigint) % (op2 as bigint)) as BigIntLike; -} else { - _isBigInt = (val: BigIntLike): boolean => { - const j: any = ensureJSBI(); - return val instanceof j; - }; - - _make = (val: string | number): BigIntLike => { - const j = ensureJSBI(); - return j.BigInt(val); - }; - - _add = (op1: BigIntLike, op2: BigIntLike): BigIntLike => { - const j = ensureJSBI(); - return j.add(op1 as JSBI, op2 as JSBI); - }; - - _sub = (op1: BigIntLike, op2: BigIntLike): BigIntLike => { - const j = ensureJSBI(); - return j.subtract(op1 as JSBI, op2 as JSBI); - }; - - _div = (op1: BigIntLike, op2: BigIntLike): BigIntLike => { - const j = ensureJSBI(); - return j.divide(op1 as JSBI, op2 as JSBI); - }; - - _mul = (op1: BigIntLike, op2: BigIntLike): BigIntLike => { - const j = ensureJSBI(); - return j.multiply(op1 as JSBI, op2 as JSBI); - }; - - _rshift = (op1: BigIntLike, op2: BigIntLike): BigIntLike => { - const j = ensureJSBI(); - return j.signedRightShift(op1 as JSBI, op2 as JSBI); - }; - - _bitand = (op1: BigIntLike, op2: BigIntLike): BigIntLike => { - const j = ensureJSBI(); - return j.bitwiseAnd(op1 as JSBI, op2 as JSBI); - }; - - _gte = (op1: BigIntLike, op2: BigIntLike): boolean => { - const j = ensureJSBI(); - return j.greaterThanOrEqual(op1 as JSBI, op2 as JSBI); - }; - - _lt = (op1: BigIntLike, op2: BigIntLike): boolean => { - const j = ensureJSBI(); - return j.lessThan(op1 as JSBI, op2 as JSBI); - }; - - _remainder = (op1: BigIntLike, op2: BigIntLike): BigIntLike => { - const j = ensureJSBI(); - return j.remainder(op1 as JSBI, op2 as JSBI); - }; -} - -function ensureJSBI(): JSBI { - if (JSBI == null) { - throw new Error("JSBI library is required to polyfill BigInt"); - } - - return JSBI; -} - -export const isBigInt = _isBigInt; -export const make = _make; -export const add = _add; -export const sub = _sub; -export const div = _div; -export const mul = _mul; -export const rshift = _rshift; -export const bitand = _bitand; -export const gte = _gte; -export const lt = _lt; -export const remainder = _remainder; diff --git a/packages/driver/src/primitives/buffer.ts b/packages/driver/src/primitives/buffer.ts index 536e39005..5f17e2632 100644 --- a/packages/driver/src/primitives/buffer.ts +++ b/packages/driver/src/primitives/buffer.ts @@ -18,8 +18,6 @@ import type char from "./chars"; import * as chars from "./chars"; -import * as bi from "./bigint"; -import * as compat from "../compat"; import { LegacyHeaderCodes } from "../ifaces"; /* WriteBuffer over-allocation */ @@ -65,9 +63,6 @@ if (Buffer === "function") { export { decodeB64, encodeB64 }; -const useBigInt64Fallback = - typeof DataView.prototype.getBigInt64 === "undefined"; - export class BufferError extends Error {} export class WriteBuffer { @@ -186,13 +181,13 @@ export class WriteBuffer { return this; } - writeBigInt64(i: bi.BigIntLike): this { - let ii: bi.BigIntLike = i; - if (bi.lt(ii, bi.make(0))) { - ii = bi.add(bi.make("18446744073709551616"), i); + writeBigInt64(i: bigint): this { + let ii = i; + if (ii < 0n) { + ii = 18446744073709551616n + i; } - const hi = bi.rshift(ii, bi.make(32)); - const lo = bi.bitand(ii, bi.make(0xffffffff)); + const hi = ii >> 32n; + const lo = ii & 0xffffffffn; this.writeUInt32(Number(hi)); this.writeUInt32(Number(lo)); return this; @@ -340,7 +335,7 @@ export class WriteMessageBuffer { return this; } - writeBigInt64(i: bi.BigIntLike): this { + writeBigInt64(i: bigint): this { if (this.messagePos < 0) { throw new BufferError("cannot writeChar: no current message"); } @@ -977,9 +972,9 @@ export class ReadBuffer { } private reportInt64Overflow(hi: number, lo: number): never { - const bhi = bi.make(hi); - const blo = bi.make(lo >>> 0); - const num = bi.add(bi.mul(bhi, bi.make(0x100000000)), blo); + const bhi = BigInt(hi); + const blo = BigInt(lo >>> 0); + const num = bhi * BigInt(0x100000000) + blo; throw new BufferError( `integer overflow: cannot unpack '${num.toString()}' ` + @@ -1005,35 +1000,13 @@ export class ReadBuffer { return this.reportInt64Overflow(hi, lo); } - readBigInt64Fallback(): bi.BigIntLike { - if (bi.hasNativeBigInt) { - const hi = this.buffer.getUint32(this.pos); - const lo = this.buffer.getUint32(this.pos + 4); - this.pos += 8; - - let res = (BigInt(hi) << BigInt(32)) + BigInt(lo); - if (hi >= 0x80000000) { - res = BigInt("-18446744073709551616") + res; - } - return res; - } else { - const buf = this.readBuffer(8); - const snum = compat.decodeInt64ToString(buf); - return bi.make(snum); - } - } - - readBigInt64(): bi.BigIntLike { + readBigInt64(): bigint { if (this.pos + 8 > this.len) { throw new BufferError("buffer overread"); } - if (!useBigInt64Fallback) { - const ret = this.buffer.getBigInt64(this.pos); - this.pos += 8; - return ret; - } else { - return this.readBigInt64Fallback(); - } + const ret = this.buffer.getBigInt64(this.pos); + this.pos += 8; + return ret; } readBuffer(size: number): Uint8Array { diff --git a/packages/driver/test/misc.test.ts b/packages/driver/test/misc.test.ts index 7b9f58205..310456b3d 100644 --- a/packages/driver/test/misc.test.ts +++ b/packages/driver/test/misc.test.ts @@ -16,8 +16,7 @@ * limitations under the License. */ -import { decodeInt64ToString } from "../src/compat"; -import { WriteBuffer } from "../src/primitives/buffer"; +import { ReadBuffer, WriteBuffer } from "../src/primitives/buffer"; test("int64 rendering", () => { const genInt = (min: number, max: number): number => @@ -29,7 +28,7 @@ test("int64 rendering", () => { wbuf.reset(); wbuf.writeInt64(inp); const buf = wbuf.unwrap(); - const out = decodeInt64ToString(buf); + const out = new ReadBuffer(buf).readBigInt64().toString(); expect(out).toBe(inp.toString()); };