Sasha Smundak | 9ff3db4 | 2021-04-09 13:28:12 -0700 | [diff] [blame] | 1 | // 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). |
alandonovan | c6daab6 | 2020-06-17 14:27:56 -0400 | [diff] [blame] | 4 | package starlark |
| 5 | |
| 6 | // generic Int implementation as a union |
| 7 | |
| 8 | import "math/big" |
| 9 | |
| 10 | type 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. |
| 22 | func (i Int) get() (small int64, big *big.Int) { |
alandonovan | 50ca820 | 2020-06-19 10:36:48 -0400 | [diff] [blame] | 23 | return i.impl.small_, i.impl.big_ |
alandonovan | c6daab6 | 2020-06-17 14:27:56 -0400 | [diff] [blame] | 24 | } |
| 25 | |
| 26 | // Precondition: math.MinInt32 <= x && x <= math.MaxInt32 |
| 27 | func makeSmallInt(x int64) Int { |
| 28 | return Int{intImpl{small_: x}} |
| 29 | } |
| 30 | |
| 31 | // Precondition: x cannot be represented as int32. |
| 32 | func makeBigInt(x *big.Int) Int { |
| 33 | return Int{intImpl{big_: x}} |
| 34 | } |