1package goja
2
3// ported from https://gist.github.com/orlp/3551590
4
5var highest_bit_set = [256]byte{
6	0, 1, 2, 2, 3, 3, 3, 3,
7	4, 4, 4, 4, 4, 4, 4, 4,
8	5, 5, 5, 5, 5, 5, 5, 5,
9	5, 5, 5, 5, 5, 5, 5, 5,
10	6, 6, 6, 6, 6, 6, 6, 6,
11	6, 6, 6, 6, 6, 6, 6, 6,
12	6, 6, 6, 6, 6, 6, 6, 6,
13	6, 6, 6, 6, 6, 6, 6, 255, // anything past 63 is a guaranteed overflow with base > 1
14	255, 255, 255, 255, 255, 255, 255, 255,
15	255, 255, 255, 255, 255, 255, 255, 255,
16	255, 255, 255, 255, 255, 255, 255, 255,
17	255, 255, 255, 255, 255, 255, 255, 255,
18	255, 255, 255, 255, 255, 255, 255, 255,
19	255, 255, 255, 255, 255, 255, 255, 255,
20	255, 255, 255, 255, 255, 255, 255, 255,
21	255, 255, 255, 255, 255, 255, 255, 255,
22	255, 255, 255, 255, 255, 255, 255, 255,
23	255, 255, 255, 255, 255, 255, 255, 255,
24	255, 255, 255, 255, 255, 255, 255, 255,
25	255, 255, 255, 255, 255, 255, 255, 255,
26	255, 255, 255, 255, 255, 255, 255, 255,
27	255, 255, 255, 255, 255, 255, 255, 255,
28	255, 255, 255, 255, 255, 255, 255, 255,
29	255, 255, 255, 255, 255, 255, 255, 255,
30	255, 255, 255, 255, 255, 255, 255, 255,
31	255, 255, 255, 255, 255, 255, 255, 255,
32	255, 255, 255, 255, 255, 255, 255, 255,
33	255, 255, 255, 255, 255, 255, 255, 255,
34	255, 255, 255, 255, 255, 255, 255, 255,
35	255, 255, 255, 255, 255, 255, 255, 255,
36	255, 255, 255, 255, 255, 255, 255, 255,
37	255, 255, 255, 255, 255, 255, 255, 255,
38}
39
40func ipow(base, exp int64) (result int64) {
41	result = 1
42
43	switch highest_bit_set[byte(exp)] {
44	case 255: // we use 255 as an overflow marker and return 0 on overflow/underflow
45		if base == 1 {
46			return 1
47		}
48
49		if base == -1 {
50			return 1 - 2*(exp&1)
51		}
52
53		return 0
54	case 6:
55		if exp&1 != 0 {
56			result *= base
57		}
58		exp >>= 1
59		base *= base
60		fallthrough
61	case 5:
62		if exp&1 != 0 {
63			result *= base
64		}
65		exp >>= 1
66		base *= base
67		fallthrough
68	case 4:
69		if exp&1 != 0 {
70			result *= base
71		}
72		exp >>= 1
73		base *= base
74		fallthrough
75	case 3:
76		if exp&1 != 0 {
77			result *= base
78		}
79		exp >>= 1
80		base *= base
81		fallthrough
82	case 2:
83		if exp&1 != 0 {
84			result *= base
85		}
86		exp >>= 1
87		base *= base
88		fallthrough
89	case 1:
90		if exp&1 != 0 {
91			result *= base
92		}
93		fallthrough
94	default:
95		return result
96	}
97}
98