@@ -40,74 +40,81 @@ import scala.annotation.tailrec
40
40
/** Emulates a Long on the JavaScript platform. */
41
41
@ inline
42
42
final class RuntimeLong (val lo : Int , val hi : Int ) {
43
- a =>
44
-
45
43
import RuntimeLong ._
46
44
47
- // Universal equality
45
+ // java.lang.Object
48
46
49
47
@ inline
50
48
override def equals (that : Any ): Boolean = that match {
51
- case b : RuntimeLong => inline_equals(b )
52
- case _ => false
49
+ case that : RuntimeLong => RuntimeLong .equals( this , that )
50
+ case _ => false
53
51
}
54
52
55
53
@ inline override def hashCode (): Int = lo ^ hi
56
54
57
- // String operations
58
-
59
55
@ inline override def toString (): String =
60
- RuntimeLong .toString(lo, hi)
61
-
62
- // Conversions
63
-
64
- @ inline def toByte : Byte = lo.toByte
65
- @ inline def toShort : Short = lo.toShort
66
- @ inline def toChar : Char = lo.toChar
67
- @ inline def toInt : Int = lo
68
- @ inline def toLong : Long = this .asInstanceOf [Long ]
69
- @ inline def toFloat : Float = RuntimeLong .toFloat(lo, hi)
70
- @ inline def toDouble : Double = RuntimeLong .toDouble(lo, hi)
56
+ RuntimeLong .toString(this )
71
57
72
58
// java.lang.Number
73
59
74
- @ inline def byteValue (): Byte = toByte
75
- @ inline def shortValue (): Short = toShort
76
- @ inline def intValue (): Int = toInt
77
- @ inline def longValue (): Long = toLong
78
- @ inline def floatValue (): Float = toFloat
79
- @ inline def doubleValue (): Double = toDouble
60
+ @ inline def byteValue (): Byte = lo. toByte
61
+ @ inline def shortValue (): Short = lo. toShort
62
+ @ inline def intValue (): Int = lo
63
+ @ inline def longValue (): Long = this . asInstanceOf [ Long ]
64
+ @ inline def floatValue (): Float = RuntimeLong . toFloat( this )
65
+ @ inline def doubleValue (): Double = RuntimeLong . toDouble( this )
80
66
81
67
// java.lang.Comparable, including bridges
82
68
83
69
@ inline
84
70
def compareTo (that : Object ): Int =
85
- compareTo( that.asInstanceOf [RuntimeLong ])
71
+ RuntimeLong .compare( this , that.asInstanceOf [RuntimeLong ])
86
72
87
73
@ inline
88
74
def compareTo (that : java.lang.Long ): Int =
89
- compareTo(that.asInstanceOf [RuntimeLong ])
75
+ RuntimeLong .compare(this , that.asInstanceOf [RuntimeLong ])
76
+
77
+ // A few operator-friendly methods used by the division algorithms
78
+
79
+ @ inline private def << (b : Int ): RuntimeLong = RuntimeLong .shl(this , b)
80
+ @ inline private def >>> (b : Int ): RuntimeLong = RuntimeLong .shr(this , b)
81
+ @ inline private def + (b : RuntimeLong ): RuntimeLong = RuntimeLong .add(this , b)
82
+ @ inline private def - (b : RuntimeLong ): RuntimeLong = RuntimeLong .sub(this , b)
83
+ }
84
+
85
+ object RuntimeLong {
86
+ private final val TwoPow32 = 4294967296.0
87
+ private final val TwoPow63 = 9223372036854775808.0
88
+
89
+ /** The magical mask that allows to test whether an unsigned long is a safe
90
+ * double.
91
+ * @see isUnsignedSafeDouble
92
+ */
93
+ private final val UnsignedSafeDoubleHiMask = 0xffe00000
94
+
95
+ private final val AskQuotient = 0
96
+ private final val AskRemainder = 1
97
+ private final val AskToString = 2
98
+
99
+ /** The hi part of a (lo, hi) return value. */
100
+ private [this ] var hiReturn : Int = _
90
101
91
102
// Comparisons
92
103
93
104
@ inline
94
- def compareTo ( b : RuntimeLong ): Int =
105
+ def compare ( a : RuntimeLong , b : RuntimeLong ): Int =
95
106
RuntimeLong .compare(a.lo, a.hi, b.lo, b.hi)
96
107
97
108
@ inline
98
- private def inline_equals ( b : RuntimeLong ): Boolean =
109
+ def equals ( a : RuntimeLong , b : RuntimeLong ): Boolean =
99
110
a.lo == b.lo && a.hi == b.hi
100
111
101
112
@ inline
102
- def equals (b : RuntimeLong ): Boolean =
103
- inline_equals(b)
104
-
105
- @ inline
106
- def notEquals (b : RuntimeLong ): Boolean =
107
- ! inline_equals(b)
113
+ def notEquals (a : RuntimeLong , b : RuntimeLong ): Boolean =
114
+ ! equals(a, b)
108
115
109
116
@ inline
110
- def < ( b : RuntimeLong ): Boolean = {
117
+ def lt ( a : RuntimeLong , b : RuntimeLong ): Boolean = {
111
118
/* We should use `inlineUnsignedInt_<(a.lo, b.lo)`, but that first extracts
112
119
* a.lo and b.lo into local variables, which cause the if/else not to be
113
120
* a valid JavaScript expression anymore. This causes useless explosion of
@@ -121,7 +128,7 @@ final class RuntimeLong(val lo: Int, val hi: Int) {
121
128
}
122
129
123
130
@ inline
124
- def <= ( b : RuntimeLong ): Boolean = {
131
+ def le ( a : RuntimeLong , b : RuntimeLong ): Boolean = {
125
132
/* Manually inline `inlineUnsignedInt_<=(a.lo, b.lo)`.
126
133
* See the comment in `<` for the rationale.
127
134
*/
@@ -132,7 +139,7 @@ final class RuntimeLong(val lo: Int, val hi: Int) {
132
139
}
133
140
134
141
@ inline
135
- def > ( b : RuntimeLong ): Boolean = {
142
+ def gt ( a : RuntimeLong , b : RuntimeLong ): Boolean = {
136
143
/* Manually inline `inlineUnsignedInt_>a.lo, b.lo)`.
137
144
* See the comment in `<` for the rationale.
138
145
*/
@@ -143,7 +150,7 @@ final class RuntimeLong(val lo: Int, val hi: Int) {
143
150
}
144
151
145
152
@ inline
146
- def >= ( b : RuntimeLong ): Boolean = {
153
+ def ge ( a : RuntimeLong , b : RuntimeLong ): Boolean = {
147
154
/* Manually inline `inlineUnsignedInt_>=(a.lo, b.lo)`.
148
155
* See the comment in `<` for the rationale.
149
156
*/
@@ -156,26 +163,26 @@ final class RuntimeLong(val lo: Int, val hi: Int) {
156
163
// Bitwise operations
157
164
158
165
@ inline
159
- def unary_~ : RuntimeLong = // scalastyle:ignore
160
- new RuntimeLong (~ lo, ~ hi)
166
+ def not ( a : RuntimeLong ) : RuntimeLong =
167
+ new RuntimeLong (~ a. lo, ~ a. hi)
161
168
162
169
@ inline
163
- def | ( b : RuntimeLong ): RuntimeLong =
170
+ def or ( a : RuntimeLong , b : RuntimeLong ): RuntimeLong =
164
171
new RuntimeLong (a.lo | b.lo, a.hi | b.hi)
165
172
166
173
@ inline
167
- def & ( b : RuntimeLong ): RuntimeLong =
174
+ def and ( a : RuntimeLong , b : RuntimeLong ): RuntimeLong =
168
175
new RuntimeLong (a.lo & b.lo, a.hi & b.hi)
169
176
170
177
@ inline
171
- def ^ ( b : RuntimeLong ): RuntimeLong =
178
+ def xor ( a : RuntimeLong , b : RuntimeLong ): RuntimeLong =
172
179
new RuntimeLong (a.lo ^ b.lo, a.hi ^ b.hi)
173
180
174
181
// Shifts
175
182
176
183
/** Shift left */
177
184
@ inline
178
- def << ( n : Int ): RuntimeLong = {
185
+ def shl ( a : RuntimeLong , n : Int ): RuntimeLong = {
179
186
/* This should *reasonably* be:
180
187
* val n1 = n & 63
181
188
* if (n1 < 32)
@@ -241,43 +248,43 @@ final class RuntimeLong(val lo: Int, val hi: Int) {
241
248
*
242
249
* Finally we have:
243
250
*/
244
- val lo = this .lo
251
+ val lo = a .lo
245
252
new RuntimeLong (
246
253
if ((n & 32 ) == 0 ) lo << n else 0 ,
247
- if ((n & 32 ) == 0 ) (lo >>> 1 >>> (31 - n)) | (hi << n) else lo << n)
254
+ if ((n & 32 ) == 0 ) (lo >>> 1 >>> (31 - n)) | (a. hi << n) else lo << n)
248
255
}
249
256
250
257
/** Logical shift right */
251
258
@ inline
252
- def >>> ( n : Int ): RuntimeLong = {
259
+ def shr ( a : RuntimeLong , n : Int ): RuntimeLong = {
253
260
// This derives in a similar way as in <<
254
- val hi = this .hi
261
+ val hi = a .hi
255
262
new RuntimeLong (
256
- if ((n & 32 ) == 0 ) (lo >>> n) | (hi << 1 << (31 - n)) else hi >>> n,
263
+ if ((n & 32 ) == 0 ) (a. lo >>> n) | (hi << 1 << (31 - n)) else hi >>> n,
257
264
if ((n & 32 ) == 0 ) hi >>> n else 0 )
258
265
}
259
266
260
267
/** Arithmetic shift right */
261
268
@ inline
262
- def >> ( n : Int ): RuntimeLong = {
269
+ def sar ( a : RuntimeLong , n : Int ): RuntimeLong = {
263
270
// This derives in a similar way as in <<
264
- val hi = this .hi
271
+ val hi = a .hi
265
272
new RuntimeLong (
266
- if ((n & 32 ) == 0 ) (lo >>> n) | (hi << 1 << (31 - n)) else hi >> n,
273
+ if ((n & 32 ) == 0 ) (a. lo >>> n) | (hi << 1 << (31 - n)) else hi >> n,
267
274
if ((n & 32 ) == 0 ) hi >> n else hi >> 31 )
268
275
}
269
276
270
277
// Arithmetic operations
271
278
272
279
@ inline
273
- def unary_- : RuntimeLong = { // scalastyle:ignore
274
- val lo = this .lo
275
- val hi = this .hi
280
+ def neg ( a : RuntimeLong ) : RuntimeLong = {
281
+ val lo = a .lo
282
+ val hi = a .hi
276
283
new RuntimeLong (inline_lo_unary_-(lo), inline_hi_unary_-(lo, hi))
277
284
}
278
285
279
286
@ inline
280
- def + ( b : RuntimeLong ): RuntimeLong = {
287
+ def add ( a : RuntimeLong , b : RuntimeLong ): RuntimeLong = {
281
288
val alo = a.lo
282
289
val ahi = a.hi
283
290
val bhi = b.hi
@@ -287,7 +294,7 @@ final class RuntimeLong(val lo: Int, val hi: Int) {
287
294
}
288
295
289
296
@ inline
290
- def - ( b : RuntimeLong ): RuntimeLong = {
297
+ def sub ( a : RuntimeLong , b : RuntimeLong ): RuntimeLong = {
291
298
val alo = a.lo
292
299
val ahi = a.hi
293
300
val bhi = b.hi
@@ -297,7 +304,7 @@ final class RuntimeLong(val lo: Int, val hi: Int) {
297
304
}
298
305
299
306
@ inline
300
- def * ( b : RuntimeLong ): RuntimeLong = {
307
+ def mul ( a : RuntimeLong , b : RuntimeLong ): RuntimeLong = {
301
308
/* The following algorithm is based on the decomposition in 32-bit and then
302
309
* 16-bit subproducts of the unsigned interpretation of operands.
303
310
*
@@ -523,54 +530,23 @@ final class RuntimeLong(val lo: Int, val hi: Int) {
523
530
new RuntimeLong (lo, hi)
524
531
}
525
532
526
- @ inline
527
- def / (b : RuntimeLong ): RuntimeLong =
528
- RuntimeLong .divide(a, b)
529
-
530
- /** `java.lang.Long.divideUnsigned(a, b)` */
531
- @ inline
532
- def divideUnsigned (b : RuntimeLong ): RuntimeLong =
533
- RuntimeLong .divideUnsigned(a, b)
534
-
535
- @ inline
536
- def % (b : RuntimeLong ): RuntimeLong =
537
- RuntimeLong .remainder(a, b)
538
-
539
- /** `java.lang.Long.remainderUnsigned(a, b)` */
540
- @ inline
541
- def remainderUnsigned (b : RuntimeLong ): RuntimeLong =
542
- RuntimeLong .remainderUnsigned(a, b)
543
-
544
- /** Computes `longBitsToDouble(this)`.
533
+ /** Computes `longBitsToDouble(a)`.
545
534
*
546
535
* `fpBitsDataView` must be a scratch `js.typedarray.DataView` whose
547
536
* underlying buffer is at least 8 bytes long.
548
537
*/
549
538
@ inline
550
- def bitsToDouble (fpBitsDataView : scala.scalajs.js.typedarray.DataView ): Double = {
551
- fpBitsDataView.setInt32(0 , lo, littleEndian = true )
552
- fpBitsDataView.setInt32(4 , hi, littleEndian = true )
539
+ def bitsToDouble (a : RuntimeLong ,
540
+ fpBitsDataView : scala.scalajs.js.typedarray.DataView ): Double = {
541
+
542
+ fpBitsDataView.setInt32(0 , a.lo, littleEndian = true )
543
+ fpBitsDataView.setInt32(4 , a.hi, littleEndian = true )
553
544
fpBitsDataView.getFloat64(0 , littleEndian = true )
554
545
}
555
546
556
- }
557
-
558
- object RuntimeLong {
559
- private final val TwoPow32 = 4294967296.0
560
- private final val TwoPow63 = 9223372036854775808.0
561
-
562
- /** The magical mask that allows to test whether an unsigned long is a safe
563
- * double.
564
- * @see isUnsignedSafeDouble
565
- */
566
- private final val UnsignedSafeDoubleHiMask = 0xffe00000
567
-
568
- private final val AskQuotient = 0
569
- private final val AskRemainder = 1
570
- private final val AskToString = 2
571
-
572
- /** The hi part of a (lo, hi) return value. */
573
- private [this ] var hiReturn : Int = _
547
+ @ inline
548
+ def toString (a : RuntimeLong ): String =
549
+ toString(a.lo, a.hi)
574
550
575
551
private def toString (lo : Int , hi : Int ): String = {
576
552
if (isInt32(lo, hi)) {
@@ -608,6 +584,14 @@ object RuntimeLong {
608
584
}
609
585
}
610
586
587
+ @ inline
588
+ def toInt (a : RuntimeLong ): Int =
589
+ a.lo
590
+
591
+ @ inline
592
+ def toDouble (a : RuntimeLong ): Double =
593
+ toDouble(a.lo, a.hi)
594
+
611
595
private def toDouble (lo : Int , hi : Int ): Double = {
612
596
if (hi < 0 ) {
613
597
// We do asUint() on the hi part specifically for MinValue
@@ -618,6 +602,10 @@ object RuntimeLong {
618
602
}
619
603
}
620
604
605
+ @ inline
606
+ def toFloat (a : RuntimeLong ): Float =
607
+ toFloat(a.lo, a.hi)
608
+
621
609
private def toFloat (lo : Int , hi : Int ): Float = {
622
610
/* This implementation is based on the property that, *if* the conversion
623
611
* `x.toDouble` is lossless, then the result of `x.toFloat` is equivalent
0 commit comments