Skip to content

Commit fa421b8

Browse files
stepanchegcopybara-github
authored andcommitted
Starlark: specialize &, |, ^, ~ for 64-bit integers
Follow-up to #12498 (64-bit integer operations without round-trip to BigInteger). Closes #12517. PiperOrigin-RevId: 344873802
1 parent 96e9c84 commit fa421b8

File tree

2 files changed

+45
-17
lines changed

2 files changed

+45
-17
lines changed

src/main/java/net/starlark/java/eval/StarlarkInt.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -611,10 +611,12 @@ public static StarlarkInt shiftLeft(StarlarkInt x, StarlarkInt y) throws EvalExc
611611

612612
/** Returns x ^ y. */
613613
public static StarlarkInt xor(StarlarkInt x, StarlarkInt y) {
614-
if (x instanceof Int32 && y instanceof Int32) {
615-
long xl = ((Int32) x).v;
616-
long yl = ((Int32) y).v;
614+
try {
615+
long xl = x.toLongFast();
616+
long yl = y.toLongFast();
617617
return StarlarkInt.of(xl ^ yl);
618+
} catch (Overflow unused) {
619+
/* fall through */
618620
}
619621

620622
BigInteger xbig = x.toBigInteger();
@@ -625,10 +627,12 @@ public static StarlarkInt xor(StarlarkInt x, StarlarkInt y) {
625627

626628
/** Returns x | y. */
627629
public static StarlarkInt or(StarlarkInt x, StarlarkInt y) {
628-
if (x instanceof Int32 && y instanceof Int32) {
629-
long xl = ((Int32) x).v;
630-
long yl = ((Int32) y).v;
630+
try {
631+
long xl = x.toLongFast();
632+
long yl = y.toLongFast();
631633
return StarlarkInt.of(xl | yl);
634+
} catch (Overflow unused) {
635+
/* fall through */
632636
}
633637

634638
BigInteger xbig = x.toBigInteger();
@@ -639,10 +643,12 @@ public static StarlarkInt or(StarlarkInt x, StarlarkInt y) {
639643

640644
/** Returns x & y. */
641645
public static StarlarkInt and(StarlarkInt x, StarlarkInt y) {
642-
if (x instanceof Int32 && y instanceof Int32) {
643-
long xl = ((Int32) x).v;
644-
long yl = ((Int32) y).v;
646+
try {
647+
long xl = x.toLongFast();
648+
long yl = y.toLongFast();
645649
return StarlarkInt.of(xl & yl);
650+
} catch (Overflow unused) {
651+
/* fall through */
646652
}
647653

648654
BigInteger xbig = x.toBigInteger();
@@ -653,9 +659,11 @@ public static StarlarkInt and(StarlarkInt x, StarlarkInt y) {
653659

654660
/** Returns ~x. */
655661
public static StarlarkInt bitnot(StarlarkInt x) {
656-
if (x instanceof Int32) {
657-
long xl = ((Int32) x).v;
662+
try {
663+
long xl = x.toLongFast();
658664
return StarlarkInt.of(~xl);
665+
} catch (Overflow unused) {
666+
/* fall through */
659667
}
660668

661669
BigInteger xbig = x.toBigInteger();

src/test/java/net/starlark/java/eval/testdata/int.star

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,6 @@ assert_eq(++4, 4)
173173
assert_eq(+-4, 0 - 4)
174174
assert_eq(-+-4, 4)
175175

176-
---
177-
1 // 0 ### integer division by zero
178-
---
179-
1 % 0 ### integer modulo by zero
180-
---
181-
182176
# bitwise
183177

184178
def f():
@@ -196,6 +190,32 @@ def f():
196190
assert_eq(x, 1)
197191

198192
f()
193+
194+
assert_eq(minint & -1, minint)
195+
assert_eq(maxint & -1, maxint)
196+
assert_eq(minlong & -1, minlong)
197+
assert_eq(maxlong & -1, maxlong)
198+
199+
assert_eq(minint | -1, -1)
200+
assert_eq(maxint | -1, -1)
201+
assert_eq(minlong | -1, -1)
202+
assert_eq(maxlong | -1, -1)
203+
204+
assert_eq(minint ^ -1, maxint)
205+
assert_eq(maxint ^ -1, minint)
206+
assert_eq(minlong ^ -1, maxlong)
207+
assert_eq(maxlong ^ -1, minlong)
208+
209+
assert_eq(~minint, maxint)
210+
assert_eq(~maxint, minint)
211+
assert_eq(~minlong, maxlong)
212+
assert_eq(~maxlong, minlong)
213+
214+
---
215+
1 // 0 ### integer division by zero
216+
---
217+
1 % 0 ### integer modulo by zero
218+
199219
---
200220
assert_eq(1 | 2, 3)
201221
assert_eq(3 | 6, 7)

0 commit comments

Comments
 (0)