Guest User

Untitled

a guest
Dec 17th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.36 KB | None | 0 0
  1. import { Struct } from "./utils";
  2.  
  3. function operator(target, name, descriptor) {
  4. const oldValue = descriptor.value;
  5. descriptor.value = function() {
  6. if (arguments.length != oldValue.length)
  7. throw Error("Not enough arguments for function " + name);
  8.  
  9. for (let arg of arguments)
  10. if (!(arg instanceof Int64))
  11. arguments[i] = new Int64(arg);
  12.  
  13. return oldValue.apply(this, arguments);
  14. };
  15. return descriptor;
  16. }
  17.  
  18. export default class Int64 {
  19. constructor() {
  20. this.bytes = new Uint8Array(8);
  21.  
  22. switch (typeof v) {
  23. case 'number':
  24. v = '0x' + Math.floor(v).toString(16);
  25. case 'string':
  26. if (v.startsWith('0x'))
  27. v = v.substr(2);
  28. if (v.length % 2 == 1)
  29. v = '0' + v;
  30.  
  31. var bigEndian = unhexlify(v, 8);
  32. bytes.set(Array.from(bigEndian).reverse());
  33. break;
  34. case 'object':
  35. if (v instanceof Int64) {
  36. bytes.set(v.bytes());
  37. } else {
  38. if (v.length != 8)
  39. throw TypeError('Array must have excactly 8 elements.');
  40. bytes.set(v);
  41. }
  42. break;
  43. case 'undefined':
  44. break;
  45. default:
  46. throw TypeError('Int64 constructor requires an argument.');
  47. }
  48. }
  49.  
  50. asDouble() {
  51. // Check for NaN
  52. if (bytes[7] == 0xff && (bytes[6] == 0xff || bytes[6] == 0xfe))
  53. throw new RangeError("Integer can not be represented by a double");
  54.  
  55. return Struct.unpack(Struct.float64, bytes);
  56. }
  57.  
  58. asJSValue() {
  59. if ((bytes[7] == 0 && bytes[6] == 0) || (bytes[7] == 0xff && bytes[6] == 0xff))
  60. throw new RangeError("Integer can not be represented by a JSValue");
  61.  
  62. // For NaN-boxing, JSC adds 2^48 to a double value's bit pattern.
  63. this.assignSub(this, 0x1000000000000);
  64. const res = Struct.unpack(Struct.float64, bytes);
  65. this.assignAdd(this, 0x1000000000000);
  66.  
  67. return res;
  68. }
  69.  
  70. bytes() {
  71. return Array.from(bytes);
  72. }
  73.  
  74. byteAt(i) {
  75. return bytes[i];
  76. }
  77.  
  78. toString() {
  79. return '0x' + hexlify(Array.from(bytes).reverse());
  80. }
  81.  
  82. @operator
  83. assignNeg() {
  84. for (let i = 0; i < 8; i++)
  85. bytes[i] = ~this.byteAt(i);
  86.  
  87. return this.assignAdd(this, Int64.One);
  88. }
  89.  
  90. neg() {
  91. return new Int64(this).assignNeg();
  92. }
  93.  
  94. @operator
  95. assignAdd(b) {
  96. let carry = 0;
  97. for (let i = 0; i < 8; i++) {
  98. const cur = this.byteAt(i) + b.byteAt(i) + carry;
  99. carry = cur > 0xff | 0;
  100. bytes[i] = cur;
  101. }
  102. return this;
  103. }
  104.  
  105. add(op) {
  106. return new Int64(this).assignAdd(op);
  107. }
  108.  
  109. @operator
  110. assignSub(b) {
  111. let carry = 0;
  112. for (let i = 0; i < 8; i++) {
  113. const cur = this.byteAt(i) - b.byteAt(i) - carry;
  114. carry = cur < 0 | 0;
  115. bytes[i] = cur;
  116. }
  117. return this;
  118. }
  119.  
  120. sub(op) {
  121. return new Int64(this).assignSub(op);
  122. }
  123.  
  124. static fromDouble(d) {
  125. const bytes = Struct.pack(Struct.float64, d);
  126. return new Int64(bytes);
  127. }
  128. }
  129.  
  130. Int64.Zero = new Int64(0);
  131. Int64.One = new Int64(1);
Add Comment
Please, Sign In to add comment