Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Struct } from "./utils";
- function operator(target, name, descriptor) {
- const oldValue = descriptor.value;
- descriptor.value = function() {
- if (arguments.length != oldValue.length)
- throw Error("Not enough arguments for function " + name);
- for (let arg of arguments)
- if (!(arg instanceof Int64))
- arguments[i] = new Int64(arg);
- return oldValue.apply(this, arguments);
- };
- return descriptor;
- }
- export default class Int64 {
- constructor() {
- this.bytes = new Uint8Array(8);
- switch (typeof v) {
- case 'number':
- v = '0x' + Math.floor(v).toString(16);
- case 'string':
- if (v.startsWith('0x'))
- v = v.substr(2);
- if (v.length % 2 == 1)
- v = '0' + v;
- var bigEndian = unhexlify(v, 8);
- bytes.set(Array.from(bigEndian).reverse());
- break;
- case 'object':
- if (v instanceof Int64) {
- bytes.set(v.bytes());
- } else {
- if (v.length != 8)
- throw TypeError('Array must have excactly 8 elements.');
- bytes.set(v);
- }
- break;
- case 'undefined':
- break;
- default:
- throw TypeError('Int64 constructor requires an argument.');
- }
- }
- asDouble() {
- // Check for NaN
- if (bytes[7] == 0xff && (bytes[6] == 0xff || bytes[6] == 0xfe))
- throw new RangeError("Integer can not be represented by a double");
- return Struct.unpack(Struct.float64, bytes);
- }
- asJSValue() {
- if ((bytes[7] == 0 && bytes[6] == 0) || (bytes[7] == 0xff && bytes[6] == 0xff))
- throw new RangeError("Integer can not be represented by a JSValue");
- // For NaN-boxing, JSC adds 2^48 to a double value's bit pattern.
- this.assignSub(this, 0x1000000000000);
- const res = Struct.unpack(Struct.float64, bytes);
- this.assignAdd(this, 0x1000000000000);
- return res;
- }
- bytes() {
- return Array.from(bytes);
- }
- byteAt(i) {
- return bytes[i];
- }
- toString() {
- return '0x' + hexlify(Array.from(bytes).reverse());
- }
- @operator
- assignNeg() {
- for (let i = 0; i < 8; i++)
- bytes[i] = ~this.byteAt(i);
- return this.assignAdd(this, Int64.One);
- }
- neg() {
- return new Int64(this).assignNeg();
- }
- @operator
- assignAdd(b) {
- let carry = 0;
- for (let i = 0; i < 8; i++) {
- const cur = this.byteAt(i) + b.byteAt(i) + carry;
- carry = cur > 0xff | 0;
- bytes[i] = cur;
- }
- return this;
- }
- add(op) {
- return new Int64(this).assignAdd(op);
- }
- @operator
- assignSub(b) {
- let carry = 0;
- for (let i = 0; i < 8; i++) {
- const cur = this.byteAt(i) - b.byteAt(i) - carry;
- carry = cur < 0 | 0;
- bytes[i] = cur;
- }
- return this;
- }
- sub(op) {
- return new Int64(this).assignSub(op);
- }
- static fromDouble(d) {
- const bytes = Struct.pack(Struct.float64, d);
- return new Int64(bytes);
- }
- }
- Int64.Zero = new Int64(0);
- Int64.One = new Int64(1);
Add Comment
Please, Sign In to add comment