blob: 8eed77d12c4e0772ecd350bd5dbc35e6cd54a06f [file] [log] [blame]
Sasha Smundak9ff3db42021-04-09 13:28:12 -07001// Always use this implementation, even for Posix-compliant platforms
2// (upstream code uses the implementation in int_posix64.go, but we
3// do not want to depend on golang.olg/x.sys/unix package).
alandonovanc6daab62020-06-17 14:27:56 -04004package starlark
5
6// generic Int implementation as a union
7
8import "math/big"
9
10type intImpl struct {
11 // We use only the signed 32-bit range of small to ensure
12 // that small+small and small*small do not overflow.
13 small_ int64 // minint32 <= small <= maxint32
14 big_ *big.Int // big != nil <=> value is not representable as int32
15}
16
17// --- low-level accessors ---
18
19// get returns the small and big components of the Int.
20// small is defined only if big is nil.
21// small is sign-extended to 64 bits for ease of subsequent arithmetic.
22func (i Int) get() (small int64, big *big.Int) {
alandonovan50ca8202020-06-19 10:36:48 -040023 return i.impl.small_, i.impl.big_
alandonovanc6daab62020-06-17 14:27:56 -040024}
25
26// Precondition: math.MinInt32 <= x && x <= math.MaxInt32
27func makeSmallInt(x int64) Int {
28 return Int{intImpl{small_: x}}
29}
30
31// Precondition: x cannot be represented as int32.
32func makeBigInt(x *big.Int) Int {
33 return Int{intImpl{big_: x}}
34}