UNPKG

fable-compiler

Version:
1,102 lines 35.8 kB
// Adapted from: https://github.com/dcodeIO/long.js/blob/f572e3a17d313730cf11eb838f6d2a5e31626f8a/src/long.js // Apache License 2.0: https://github.com/dcodeIO/long.js/blob/master/LICENSE /* tslint:disable */ import { isValid } from "./Int32"; import { combineHashCodes } from "./Util"; /** * wasm optimizations, to do native i64 multiplication and divide */ var wasm = null; try { wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([ 0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11 ])), {}).exports; } catch (e) { // no wasm support :( } /** * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers. * See the from* functions below for more convenient ways of constructing Longs. * @exports Long * @class A Long class for representing a 64 bit two's-complement integer value. * @param {number} low The low (signed) 32 bits of the long * @param {number} high The high (signed) 32 bits of the long * @param {boolean=} unsigned Whether unsigned or not, defaults to signed * @constructor */ export default function Long(low, high, unsigned) { /** * The low 32 bits as a signed value. * @type {number} */ this.low = low | 0; /** * The high 32 bits as a signed value. * @type {number} */ this.high = high | 0; /** * Whether unsigned or not. * @type {boolean} */ this.unsigned = !!unsigned; } Long.prototype.GetHashCode = function () { return combineHashCodes([this.unsigned ? 1 : 0, this.high, this.low]); }; Long.prototype.Equals = function (x) { return equals(this, x); }; Long.prototype.CompareTo = function (x) { return compare(this, x); }; Long.prototype.toString = function (radix) { return toString(this, radix); }; Long.prototype.toJSON = function () { return toString(this); }; export const neg = op_UnaryNegation; export const not = op_LogicalNot; export const add = op_Addition; export const sub = op_Subtraction; export const mul = op_Multiply; export const div = op_Division; export const mod = op_Modulus; export const shl = op_LeftShift; export const shr = op_RightShift; export const and = op_BitwiseAnd; export const or = op_BitwiseOr; export const xor = op_ExclusiveOr; // The internal representation of a long is the two given signed, 32-bit values. // We use 32-bit pieces because these are the size of integers on which // Javascript performs bit-operations. For operations like addition and // multiplication, we split each number into 16 bit pieces, which can easily be // multiplied within Javascript's floating-point representation without overflow // or change in sign. // // In the algorithms below, we frequently reduce the negative case to the // positive case by negating the input(s) and then post-processing the result. // Note that we must ALWAYS check specially whether those values are MIN_VALUE // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as // a positive number, it overflows back into a negative). Not handling this // case would often result in infinite recursion. // // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from* // methods on which they depend. /** * An indicator used to reliably determine if an object is a Long or not. * @type {boolean} * @const * @private */ Long.prototype.__isLong__; Object.defineProperty(Long.prototype, "__isLong__", { value: true }); /** * @function * @param {*} obj Object * @returns {boolean} * @inner */ function isLong(obj) { return (obj && obj["__isLong__"]) === true; } /** * A cache of the Long representations of small integer values. * @type {!Object} * @inner */ var INT_CACHE = {}; /** * A cache of the Long representations of small unsigned integer values. * @type {!Object} * @inner */ var UINT_CACHE = {}; /** * @param {number} value * @param {boolean=} unsigned * @returns {!Long} * @inner */ export function fromInt(value, unsigned) { var obj, cachedObj, cache; if (unsigned) { value >>>= 0; if (cache = (0 <= value && value < 256)) { cachedObj = UINT_CACHE[value]; if (cachedObj) return cachedObj; } obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true); if (cache) UINT_CACHE[value] = obj; return obj; } else { value |= 0; if (cache = (-128 <= value && value < 128)) { cachedObj = INT_CACHE[value]; if (cachedObj) return cachedObj; } obj = fromBits(value, value < 0 ? -1 : 0, false); if (cache) INT_CACHE[value] = obj; return obj; } } /** * @param {number} value * @param {boolean=} unsigned * @returns {!Long} * @inner */ export function fromNumber(value, unsigned) { if (isNaN(value)) return unsigned ? UZERO : ZERO; if (unsigned) { if (value < 0) return UZERO; if (value >= TWO_PWR_64_DBL) return MAX_UNSIGNED_VALUE; } else { if (value <= -TWO_PWR_63_DBL) return MIN_VALUE; if (value + 1 >= TWO_PWR_63_DBL) return MAX_VALUE; } if (value < 0) return op_UnaryNegation(fromNumber(-value, unsigned)); return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned); } /** * @param {number} value * @param {boolean} unsigned * @param {number} kind * @returns {!Long} * @inner */ export function fromInteger(value, unsigned, kind) { var x; var xh = 0; switch (kind) { case 0: x = value << 24 >> 24; xh = x; break; case 4: x = value << 24 >>> 24; break; case 1: x = value << 16 >> 16; xh = x; break; case 5: x = value << 16 >>> 16; break; case 2: x = value >> 0; xh = x; break; case 6: x = value >>> 0; } return fromBits(x, xh >> 31, unsigned); } /** * @param {number} lowBits * @param {number} highBits * @param {boolean=} unsigned * @returns {!Long} * @inner */ export function fromBits(lowBits, highBits, unsigned) { return new Long(lowBits, highBits, unsigned); } /** * @function * @param {number} base * @param {number} exponent * @returns {number} * @inner */ var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4) /** * @param {string} str * @param {(boolean|number)=} unsigned * @param {number=} radix * @returns {!Long} * @inner */ export function fromString(str, unsigned, radix) { if (str.length === 0) throw Error('empty string'); if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") return ZERO; if (typeof unsigned === 'number') { // For goog.math.long compatibility radix = unsigned, unsigned = false; } else { unsigned = !!unsigned; } radix = radix || 10; if (radix < 2 || 36 < radix) throw RangeError('radix'); var p = str.indexOf('-'); if (p > 0) throw Error('interior hyphen'); else if (p === 0) { return op_UnaryNegation(fromString(str.substring(1), unsigned, radix)); } // Do several (8) digits each time through the loop, so as to // minimize the calls to the very expensive emulated div. var radixToPower = fromNumber(pow_dbl(radix, 8)); var result = ZERO; for (var i = 0; i < str.length; i += 8) { var size = Math.min(8, str.length - i), value = parseInt(str.substring(i, i + size), radix); if (size < 8) { var power = fromNumber(pow_dbl(radix, size)); result = op_Addition(op_Multiply(result, power), fromNumber(value)); } else { result = op_Multiply(result, radixToPower); result = op_Addition(result, fromNumber(value)); } } result.unsigned = unsigned; return result; } function getMaxValue(unsigned, radix, isNegative) { switch (radix) { case 2: return unsigned ? "1111111111111111111111111111111111111111111111111111111111111111" : (isNegative ? "1000000000000000000000000000000000000000000000000000000000000000" : "111111111111111111111111111111111111111111111111111111111111111"); case 8: return unsigned ? "1777777777777777777777" : (isNegative ? "1000000000000000000000" : "777777777777777777777"); case 10: return unsigned ? "18446744073709551615" : (isNegative ? "9223372036854775808" : "9223372036854775807"); case 16: return unsigned ? "FFFFFFFFFFFFFFFF" : (isNegative ? "8000000000000000" : "7FFFFFFFFFFFFFFF"); default: throw new Error("Invalid radix."); } } export function parse(str, style, unsigned, bitsize, radix) { const res = isValid(str, style, radix); if (res != null) { const lessOrEqual = (x, y) => { const len = Math.max(x.length, y.length); return x.padStart(len, "0") <= y.padStart(len, "0"); }; const isNegative = res.sign === "-"; const maxValue = getMaxValue(unsigned || res.radix !== 10, res.radix, isNegative); if (lessOrEqual(res.digits.toUpperCase(), maxValue)) { str = isNegative ? res.sign + res.digits : res.digits; return fromString(str, unsigned, res.radix); } } throw new Error("Input string was not in a correct format."); } export function tryParse(str, style, unsigned, bitsize) { try { const v = parse(str, style, unsigned, bitsize); return [true, v]; } catch (_a) { // supress error } return [false, ZERO]; } /** * @function * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val * @param {boolean=} unsigned * @returns {!Long} * @inner */ export function fromValue(val, unsigned) { if (typeof val === 'number') return fromNumber(val, unsigned); if (typeof val === 'string') return fromString(val, unsigned); // Throws for non-objects, converts non-instanceof Long: return fromBits(val.low, val.high, typeof unsigned === 'boolean' ? unsigned : val.unsigned); } // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be // no runtime penalty for these. /** * @type {number} * @const * @inner */ var TWO_PWR_16_DBL = 1 << 16; /** * @type {number} * @const * @inner */ var TWO_PWR_24_DBL = 1 << 24; /** * @type {number} * @const * @inner */ var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; /** * @type {number} * @const * @inner */ var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; /** * @type {number} * @const * @inner */ var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; /** * @type {!Long} * @const * @inner */ var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL); /** * @type {!Long} * @inner */ export var ZERO = fromInt(0); /** * @type {!Long} * @inner */ export var UZERO = fromInt(0, true); /** * @type {!Long} * @inner */ export var ONE = fromInt(1); /** * @type {!Long} * @inner */ export var UONE = fromInt(1, true); /** * @type {!Long} * @inner */ export var NEG_ONE = fromInt(-1); /** * @type {!Long} * @inner */ export var MAX_VALUE = fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0, false); /** * @type {!Long} * @inner */ export var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF | 0, 0xFFFFFFFF | 0, true); /** * @type {!Long} * @inner */ export var MIN_VALUE = fromBits(0, 0x80000000 | 0, false); /** * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer. * @returns {number} */ export function toInt($this) { return $this.unsigned ? $this.low >>> 0 : $this.low; } ; /** * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa). * @returns {number} */ export function toNumber($this) { if ($this.unsigned) return (($this.high >>> 0) * TWO_PWR_32_DBL) + ($this.low >>> 0); return $this.high * TWO_PWR_32_DBL + ($this.low >>> 0); } ; /** * Converts the Long to a string written in the specified radix. * @param {number=} radix Radix (2-36), defaults to 10 * @returns {string} * @override * @throws {RangeError} If `radix` is out of range */ export function toString($this, radix) { radix = radix || 10; if (radix < 2 || 36 < radix) throw RangeError('radix'); if (isZero($this)) return '0'; if (isNegative($this)) { // Unsigned Longs are never negative if (equals($this, MIN_VALUE)) { // We need to change the Long value before it can be negated, so we remove // the bottom-most digit in this base and then recurse to do the rest. var radixLong = fromNumber(radix), div = op_Division($this, radixLong), rem1 = op_Subtraction(op_Multiply(div, radixLong), $this); return toString(div, radix) + toInt(rem1).toString(radix); } else return '-' + toString(op_UnaryNegation($this), radix); } // Do several (6) digits each time through the loop, so as to // minimize the calls to the very expensive emulated div. var radixToPower = fromNumber(pow_dbl(radix, 6), $this.unsigned), rem = $this; var result = ''; while (true) { var remDiv = op_Division(rem, radixToPower), intval = toInt(op_Subtraction(rem, op_Multiply(remDiv, radixToPower))) >>> 0, digits = intval.toString(radix); rem = remDiv; if (isZero(rem)) return digits + result; else { while (digits.length < 6) digits = '0' + digits; result = '' + digits + result; } } } ; /** * Gets the high 32 bits as a signed integer. * @returns {number} Signed high bits */ export function getHighBits($this) { return $this.high; } ; /** * Gets the high 32 bits as an unsigned integer. * @returns {number} Unsigned high bits */ export function getHighBitsUnsigned($this) { return $this.high >>> 0; } ; /** * Gets the low 32 bits as a signed integer. * @returns {number} Signed low bits */ export function getLowBits($this) { return $this.low; } ; /** * Gets the low 32 bits as an unsigned integer. * @returns {number} Unsigned low bits */ export function getLowBitsUnsigned($this) { return $this.low >>> 0; } ; /** * Gets the number of bits needed to represent the absolute value of this Long. * @returns {number} */ export function getNumBitsAbs($this) { if (isNegative($this)) // Unsigned Longs are never negative return equals($this, MIN_VALUE) ? 64 : getNumBitsAbs(op_UnaryNegation($this)); var val = $this.high != 0 ? $this.high : $this.low; for (var bit = 31; bit > 0; bit--) if ((val & (1 << bit)) != 0) break; return $this.high != 0 ? bit + 33 : bit + 1; } ; /** * Tests if this Long's value equals zero. * @returns {boolean} */ export function isZero($this) { return $this.high === 0 && $this.low === 0; } ; /** * Tests if this Long's value is negative. * @returns {boolean} */ export function isNegative($this) { return !$this.unsigned && $this.high < 0; } ; /** * Tests if this Long's value is positive. * @returns {boolean} */ export function isPositive($this) { return $this.unsigned || $this.high >= 0; } ; /** * Tests if this Long's value is odd. * @returns {boolean} */ export function isOdd($this) { return ($this.low & 1) === 1; } ; /** * Tests if this Long's value is even. * @returns {boolean} */ export function isEven($this) { return ($this.low & 1) === 0; } ; /** * Tests if this Long's value equals the specified's. * @param {!Long|number|string} other Other value * @returns {boolean} */ export function equals($this, other) { if (!isLong(other)) other = fromValue(other); if ($this.unsigned !== other.unsigned && ($this.high >>> 31) === 1 && (other.high >>> 31) === 1) return false; return $this.high === other.high && $this.low === other.low; } ; /** * Tests if this Long's value differs from the specified's. * @param {!Long|number|string} other Other value * @returns {boolean} */ export function notEquals($this, other) { return !equals($this, /* validates */ other); } ; /** * Tests if this Long's value is less than the specified's. * @param {!Long|number|string} other Other value * @returns {boolean} */ export function lessThan($this, other) { return compare($this, /* validates */ other) < 0; } ; /** * Tests if this Long's value is less than or equal the specified's. * @param {!Long|number|string} other Other value * @returns {boolean} */ export function lessThanOrEqual($this, other) { return compare($this, /* validates */ other) <= 0; } ; /** * Tests if this Long's value is greater than the specified's. * @param {!Long|number|string} other Other value * @returns {boolean} */ export function greaterThan($this, other) { return compare($this, /* validates */ other) > 0; } ; /** * Tests if this Long's value is greater than or equal the specified's. * @param {!Long|number|string} other Other value * @returns {boolean} */ export function greaterThanOrEqual($this, other) { return compare($this, /* validates */ other) >= 0; } ; /** * Compares this Long's value with the specified's. * @param {!Long|number|string} other Other value * @returns {number} 0 if they are the same, 1 if the this is greater and -1 * if the given one is greater */ export function compare($this, other) { if (!isLong(other)) other = fromValue(other); if (equals($this, other)) return 0; var thisNeg = isNegative($this), otherNeg = isNegative(other); if (thisNeg && !otherNeg) return -1; if (!thisNeg && otherNeg) return 1; // At this point the sign bits are the same if (!$this.unsigned) return isNegative(op_Subtraction($this, other)) ? -1 : 1; // Both are positive if at least one is unsigned return (other.high >>> 0) > ($this.high >>> 0) || (other.high === $this.high && (other.low >>> 0) > ($this.low >>> 0)) ? -1 : 1; } ; /** * Absolute value of the given number. */ export function abs($this) { if (!$this.unsigned && isNegative($this)) return op_UnaryNegation($this); else return $this; } /** * Negates this Long's value. * @returns {!Long} Negated Long */ export function op_UnaryNegation($this) { if (!$this.unsigned && equals($this, MIN_VALUE)) return MIN_VALUE; return op_Addition(op_LogicalNot($this), ONE); } ; /** * Returns the sum of this and the specified Long. * @param {!Long|number|string} addend Addend * @returns {!Long} Sum */ export function op_Addition($this, addend) { if (!isLong(addend)) addend = fromValue(addend); // Divide each number into 4 chunks of 16 bits, and then sum the chunks. var a48 = $this.high >>> 16; var a32 = $this.high & 0xFFFF; var a16 = $this.low >>> 16; var a00 = $this.low & 0xFFFF; var b48 = addend.high >>> 16; var b32 = addend.high & 0xFFFF; var b16 = addend.low >>> 16; var b00 = addend.low & 0xFFFF; var c48 = 0, c32 = 0, c16 = 0, c00 = 0; c00 += a00 + b00; c16 += c00 >>> 16; c00 &= 0xFFFF; c16 += a16 + b16; c32 += c16 >>> 16; c16 &= 0xFFFF; c32 += a32 + b32; c48 += c32 >>> 16; c32 &= 0xFFFF; c48 += a48 + b48; c48 &= 0xFFFF; return fromBits((c16 << 16) | c00, (c48 << 16) | c32, $this.unsigned); } ; /** * Returns the difference of this and the specified Long. * @param {!Long|number|string} subtrahend Subtrahend * @returns {!Long} Difference */ export function op_Subtraction($this, subtrahend) { if (!isLong(subtrahend)) subtrahend = fromValue(subtrahend); return op_Addition($this, op_UnaryNegation(subtrahend)); } ; /** * Returns the product of this and the specified Long. * @param {!Long|number|string} multiplier Multiplier * @returns {!Long} Product */ export function op_Multiply($this, multiplier) { if (isZero($this)) return $this.unsigned ? UZERO : ZERO; if (!isLong(multiplier)) multiplier = fromValue(multiplier); // use wasm support if present if (wasm) { var low = wasm.mul($this.low, $this.high, multiplier.low, multiplier.high); return fromBits(low, wasm.get_high(), $this.unsigned); } if (isZero(multiplier)) return $this.unsigned ? UZERO : ZERO; if (equals($this, MIN_VALUE)) return isOdd(multiplier) ? MIN_VALUE : ZERO; if (equals(multiplier, MIN_VALUE)) return isOdd($this) ? MIN_VALUE : ZERO; if (isNegative($this)) { if (isNegative(multiplier)) return op_Multiply(op_UnaryNegation($this), op_UnaryNegation(multiplier)); else return op_UnaryNegation(op_Multiply(op_UnaryNegation($this), multiplier)); } else if (isNegative(multiplier)) return op_UnaryNegation(op_Multiply($this, op_UnaryNegation(multiplier))); // If both longs are small, use float multiplication if (lessThan($this, TWO_PWR_24) && lessThan(multiplier, TWO_PWR_24)) return fromNumber(toNumber($this) * toNumber(multiplier), $this.unsigned); // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products. // We can skip products that would overflow. var a48 = $this.high >>> 16; var a32 = $this.high & 0xFFFF; var a16 = $this.low >>> 16; var a00 = $this.low & 0xFFFF; var b48 = multiplier.high >>> 16; var b32 = multiplier.high & 0xFFFF; var b16 = multiplier.low >>> 16; var b00 = multiplier.low & 0xFFFF; var c48 = 0, c32 = 0, c16 = 0, c00 = 0; c00 += a00 * b00; c16 += c00 >>> 16; c00 &= 0xFFFF; c16 += a16 * b00; c32 += c16 >>> 16; c16 &= 0xFFFF; c16 += a00 * b16; c32 += c16 >>> 16; c16 &= 0xFFFF; c32 += a32 * b00; c48 += c32 >>> 16; c32 &= 0xFFFF; c32 += a16 * b16; c48 += c32 >>> 16; c32 &= 0xFFFF; c32 += a00 * b32; c48 += c32 >>> 16; c32 &= 0xFFFF; c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; c48 &= 0xFFFF; return fromBits((c16 << 16) | c00, (c48 << 16) | c32, $this.unsigned); } ; /** * Returns this Long divided by the specified. The result is signed if this Long is signed or * unsigned if this Long is unsigned. * @param {!Long|number|string} divisor Divisor * @returns {!Long} Quotient */ export function op_Division($this, divisor) { if (!isLong(divisor)) divisor = fromValue(divisor); if (isZero(divisor)) throw Error('division by zero'); // use wasm support if present if (wasm) { // guard against signed division overflow: the largest // negative number / -1 would be 1 larger than the largest // positive number, due to two's complement. if (!$this.unsigned && $this.high === -0x80000000 && divisor.low === -1 && divisor.high === -1) { // be consistent with non-wasm code path return $this; } var low = ($this.unsigned ? wasm.div_u : wasm.div_s)($this.low, $this.high, divisor.low, divisor.high); return fromBits(low, wasm.get_high(), $this.unsigned); } if (isZero($this)) return $this.unsigned ? UZERO : ZERO; var approx, rem, res; if (!$this.unsigned) { // This section is only relevant for signed longs and is derived from the // closure library as a whole. if (equals($this, MIN_VALUE)) { if (equals(divisor, ONE) || equals(divisor, NEG_ONE)) return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE else if (equals(divisor, MIN_VALUE)) return ONE; else { // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. var halfThis = op_RightShift($this, 1); approx = op_LeftShift(op_Division(halfThis, divisor), 1); if (equals(approx, ZERO)) { return isNegative(divisor) ? ONE : NEG_ONE; } else { rem = op_Subtraction($this, op_Multiply(divisor, approx)); res = op_Addition(approx, op_Division(rem, divisor)); return res; } } } else if (equals(divisor, MIN_VALUE)) return $this.unsigned ? UZERO : ZERO; if (isNegative($this)) { if (isNegative(divisor)) return op_Division(op_UnaryNegation($this), op_UnaryNegation(divisor)); return op_UnaryNegation(op_Division(op_UnaryNegation($this), divisor)); } else if (isNegative(divisor)) return op_UnaryNegation(op_Division($this, op_UnaryNegation(divisor))); res = ZERO; } else { // The algorithm below has not been made for unsigned longs. It's therefore // required to take special care of the MSB prior to running it. if (!divisor.unsigned) divisor = toUnsigned(divisor); if (greaterThan(divisor, $this)) return UZERO; if (greaterThan(divisor, op_RightShiftUnsigned($this, 1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true return UONE; res = UZERO; } // Repeat the following until the remainder is less than other: find a // floating-point that approximates remainder / other *from below*, add this // into the result, and subtract it from the remainder. It is critical that // the approximate value is less than or equal to the real value so that the // remainder never becomes negative. rem = $this; while (greaterThanOrEqual(rem, divisor)) { // Approximate the result of division. This may be a little greater or // smaller than the actual value. approx = Math.max(1, Math.floor(toNumber(rem) / toNumber(divisor))); // We will tweak the approximate result by changing it in the 48-th digit or // the smallest non-fractional digit, whichever is larger. var log2 = Math.ceil(Math.log(approx) / Math.LN2), delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48), // Decrease the approximation until it is smaller than the remainder. Note // that if it is too large, the product overflows and is negative. approxRes = fromNumber(approx), approxRem = op_Multiply(approxRes, divisor); while (isNegative(approxRem) || greaterThan(approxRem, rem)) { approx -= delta; approxRes = fromNumber(approx, $this.unsigned); approxRem = op_Multiply(approxRes, divisor); } // We know the answer can't be zero... and actually, zero would cause // infinite recursion since we would make no progress. if (isZero(approxRes)) approxRes = ONE; res = op_Addition(res, approxRes); rem = op_Subtraction(rem, approxRem); } return res; } ; /** * Returns this Long modulo the specified. * @param {!Long|number|string} divisor Divisor * @returns {!Long} Remainder */ export function op_Modulus($this, divisor) { if (!isLong(divisor)) divisor = fromValue(divisor); // use wasm support if present if (wasm) { var low = ($this.unsigned ? wasm.rem_u : wasm.rem_s)($this.low, $this.high, divisor.low, divisor.high); return fromBits(low, wasm.get_high(), $this.unsigned); } return op_Subtraction($this, op_Multiply(op_Division($this, divisor), divisor)); } ; /** * Returns the bitwise NOT of this Long. * @returns {!Long} */ export function op_LogicalNot($this) { return fromBits(~$this.low, ~$this.high, $this.unsigned); } ; /** * Returns the bitwise AND of this Long and the specified. * @param {!Long|number|string} other Other Long * @returns {!Long} */ export function op_BitwiseAnd($this, other) { if (!isLong(other)) other = fromValue(other); return fromBits($this.low & other.low, $this.high & other.high, $this.unsigned); } ; /** * Returns the bitwise OR of this Long and the specified. * @param {!Long|number|string} other Other Long * @returns {!Long} */ export function op_BitwiseOr($this, other) { if (!isLong(other)) other = fromValue(other); return fromBits($this.low | other.low, $this.high | other.high, $this.unsigned); } ; /** * Returns the bitwise XOR of this Long and the given one. * @param {!Long|number|string} other Other Long * @returns {!Long} */ export function op_ExclusiveOr($this, other) { if (!isLong(other)) other = fromValue(other); return fromBits($this.low ^ other.low, $this.high ^ other.high, $this.unsigned); } ; /** * Returns this Long with bits shifted to the left by the given amount. * @param {number|!Long} numBits Number of bits * @returns {!Long} Shifted Long */ export function op_LeftShift($this, numBits) { if (isLong(numBits)) numBits = toInt(numBits); if ((numBits &= 63) === 0) return $this; else if (numBits < 32) return fromBits($this.low << numBits, ($this.high << numBits) | ($this.low >>> (32 - numBits)), $this.unsigned); else return fromBits(0, $this.low << (numBits - 32), $this.unsigned); } ; /** * Returns this Long with bits arithmetically shifted to the right by the given amount. * @param {number|!Long} numBits Number of bits * @returns {!Long} Shifted Long */ export function op_RightShift($this, numBits) { if (isLong(numBits)) numBits = toInt(numBits); if ((numBits &= 63) === 0) return $this; else if (numBits < 32) return fromBits(($this.low >>> numBits) | ($this.high << (32 - numBits)), $this.high >> numBits, $this.unsigned); else return fromBits($this.high >> (numBits - 32), $this.high >= 0 ? 0 : -1, $this.unsigned); } ; /** * Returns this Long with bits logically shifted to the right by the given amount. * @param {number|!Long} numBits Number of bits * @returns {!Long} Shifted Long */ export function op_RightShiftUnsigned($this, numBits) { if (isLong(numBits)) numBits = toInt(numBits); numBits &= 63; if (numBits === 0) return $this; else { var high = $this.high; if (numBits < 32) { var low = $this.low; return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, $this.unsigned); } else if (numBits === 32) return fromBits(high, 0, $this.unsigned); else return fromBits(high >>> (numBits - 32), 0, $this.unsigned); } } ; /** * Converts this Long to signed. * @returns {!Long} Signed long */ export function toSigned($this) { if (!$this.unsigned) return $this; return fromBits($this.low, $this.high, false); } ; /** * Converts this Long to unsigned. * @returns {!Long} Unsigned long */ export function toUnsigned($this) { if ($this.unsigned) return $this; return fromBits($this.low, $this.high, true); } ; /** * Converts this Long to its byte representation. * @param {boolean=} le Whether little or big endian, defaults to big endian * @returns {!Array.<number>} Byte representation */ export function toBytes($this, le) { return le ? toBytesLE($this) : toBytesBE($this); } ; /** * Converts this Long to its little endian byte representation. * @returns {!Array.<number>} Little endian byte representation */ export function toBytesLE($this) { var hi = $this.high, lo = $this.low; return [ lo & 0xff, lo >>> 8 & 0xff, lo >>> 16 & 0xff, lo >>> 24, hi & 0xff, hi >>> 8 & 0xff, hi >>> 16 & 0xff, hi >>> 24 ]; } ; /** * Converts this Long to its big endian byte representation. * @returns {!Array.<number>} Big endian byte representation */ export function toBytesBE($this) { var hi = $this.high, lo = $this.low; return [ hi >>> 24, hi >>> 16 & 0xff, hi >>> 8 & 0xff, hi & 0xff, lo >>> 24, lo >>> 16 & 0xff, lo >>> 8 & 0xff, lo & 0xff ]; } ; /** * Creates a Long from its byte representation. * @param {!Array.<number>} bytes Byte representation * @param {boolean=} unsigned Whether unsigned or not, defaults to signed * @param {boolean=} le Whether little or big endian, defaults to big endian * @returns {Long} The corresponding Long value */ export function fromBytes(bytes, unsigned, le) { return le ? fromBytesLE(bytes, unsigned) : fromBytesBE(bytes, unsigned); } ; /** * Creates a Long from its little endian byte representation. * @param {!Array.<number>} bytes Little endian byte representation * @param {boolean=} unsigned Whether unsigned or not, defaults to signed * @returns {Long} The corresponding Long value */ export function fromBytesLE(bytes, unsigned) { return new Long(bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24, bytes[4] | bytes[5] << 8 | bytes[6] << 16 | bytes[7] << 24, unsigned); } ; /** * Creates a Long from its big endian byte representation. * @param {!Array.<number>} bytes Big endian byte representation * @param {boolean=} unsigned Whether unsigned or not, defaults to signed * @returns {Long} The corresponding Long value */ export function fromBytesBE(bytes, unsigned) { return new Long(bytes[4] << 24 | bytes[5] << 16 | bytes[6] << 8 | bytes[7], bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], unsigned); } ; export function unixEpochMillisecondsToTicks(ms, offset) { return op_Multiply(op_Addition(op_Addition(fromNumber(ms), 62135596800000), offset), 10000); } export function ticksToUnixEpochMilliseconds(ticks) { return toNumber(op_Subtraction(op_Division(ticks, 10000), 62135596800000)); } export function makeRangeStepFunction(step, last, unsigned) { const stepComparedWithZero = compare(step, unsigned ? UZERO : ZERO); if (stepComparedWithZero === 0) { throw new Error("The step of a range cannot be zero"); } const stepGreaterThanZero = stepComparedWithZero > 0; return (x) => { const comparedWithLast = compare(x, last); if ((stepGreaterThanZero && comparedWithLast <= 0) || (!stepGreaterThanZero && comparedWithLast >= 0)) { return [x, op_Addition(x, step)]; } else { return null; } }; } //# sourceMappingURL=Long.js.map