int.cpp 38.3 KB
Newer Older
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1
// Copyright (c) 2014-2015 Dropbox, Inc.
Kevin Modzelewski's avatar
Kevin Modzelewski committed
2
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
3 4 5
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Kevin Modzelewski's avatar
Kevin Modzelewski committed
6
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
7
//    http://www.apache.org/licenses/LICENSE-2.0
Kevin Modzelewski's avatar
Kevin Modzelewski committed
8
//
Kevin Modzelewski's avatar
Kevin Modzelewski committed
9 10 11 12 13 14
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

15 16
#include "runtime/int.h"

17
#include <cmath>
Kevin Modzelewski's avatar
Kevin Modzelewski committed
18 19
#include <sstream>

20
#include "capi/typeobject.h"
21
#include "core/ast.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
22 23 24 25
#include "core/common.h"
#include "core/options.h"
#include "core/stats.h"
#include "core/types.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
26
#include "runtime/float.h"
27
#include "runtime/inline/boxing.h"
28
#include "runtime/long.h"
Kevin Modzelewski's avatar
Kevin Modzelewski committed
29 30 31 32
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/util.h"

Travis Hance's avatar
Travis Hance committed
33 34
extern "C" PyObject* float_pow(PyObject* v, PyObject* w, PyObject* z) noexcept;

Kevin Modzelewski's avatar
Kevin Modzelewski committed
35 36
namespace pyston {

Marius Wachtler's avatar
Marius Wachtler committed
37 38 39 40
extern "C" long PyInt_GetMax() noexcept {
    return LONG_MAX; /* To initialize sys.maxint */
}

41
extern "C" unsigned long PyInt_AsUnsignedLongMask(PyObject* op) noexcept {
42 43 44 45
    if (op && PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*)op);
    if (op && PyLong_Check(op))
        return PyLong_AsUnsignedLongMask(op);
46 47 48
    Py_FatalError("unimplemented");
}

49
extern "C" long PyInt_AsLong(PyObject* op) noexcept {
50 51
    // This method should do quite a bit more, including checking tp_as_number->nb_int (or calling __int__?)

52
    if (PyInt_Check(op))
53 54 55 56 57
        return static_cast<BoxedInt*>(op)->n;

    if (op->cls == long_cls)
        return PyLong_AsLong(op);

58 59
    PyErr_SetString(PyExc_TypeError, "an integer is required");
    return -1;
60 61
}

62
extern "C" Py_ssize_t PyInt_AsSsize_t(PyObject* op) noexcept {
63 64 65 66 67 68 69 70 71 72 73 74 75 76
    if (op == NULL) {
        PyErr_SetString(PyExc_TypeError, "an integer is required");
        return -1;
    }

    if (PyInt_Check(op))
        return ((BoxedInt*)op)->n;
    if (PyLong_Check(op))
        return _PyLong_AsSsize_t(op);
#if SIZEOF_SIZE_T == SIZEOF_LONG
    return PyInt_AsLong(op);
#else
    RELEASE_ASSERT("not implemented", "");
#endif
77 78
}

79
extern "C" PyObject* PyInt_FromSize_t(size_t ival) noexcept {
80 81 82 83
    RELEASE_ASSERT(ival <= LONG_MAX, "");
    return boxInt(ival);
}

84
extern "C" PyObject* PyInt_FromSsize_t(Py_ssize_t ival) noexcept {
85
    return boxInt(ival);
86 87
}

88
extern "C" PyObject* PyInt_FromLong(long n) noexcept {
Marius Wachtler's avatar
Marius Wachtler committed
89 90 91
    return boxInt(n);
}

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
/* Convert an integer to a decimal string.  On many platforms, this
   will be significantly faster than the general arbitrary-base
   conversion machinery in _PyInt_Format, thanks to optimization
   opportunities offered by division by a compile-time constant. */
static Box* int_to_decimal_string(BoxedInt* v) noexcept {
    char buf[sizeof(long) * CHAR_BIT / 3 + 6], *p, *bufend;
    long n = v->n;
    unsigned long absn;
    p = bufend = buf + sizeof(buf);
    absn = n < 0 ? 0UL - n : n;
    do {
        *--p = '0' + (char)(absn % 10);
        absn /= 10;
    } while (absn);
    if (n < 0)
        *--p = '-';
    return PyString_FromStringAndSize(p, bufend - p);
}

111
extern "C" PyAPI_FUNC(PyObject*) _PyInt_Format(PyIntObject* v, int base, int newstyle) noexcept {
112
    BoxedInt* bint = reinterpret_cast<BoxedInt*>(v);
113
    RELEASE_ASSERT(PyInt_Check(bint), "");
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172

    /* There are no doubt many, many ways to optimize this, using code
       similar to _PyLong_Format */
    long n = bint->n;
    int negative = n < 0;
    int is_zero = n == 0;

    /* For the reasoning behind this size, see
       http://c-faq.com/misc/hexio.html. Then, add a few bytes for
       the possible sign and prefix "0[box]" */
    char buf[sizeof(n) * CHAR_BIT + 6];

    /* Start by pointing to the end of the buffer.  We fill in from
       the back forward. */
    char* p = &buf[sizeof(buf)];

    assert(base >= 2 && base <= 36);

    /* Special case base 10, for speed */
    if (base == 10)
        return int_to_decimal_string(bint);

    do {
        /* I'd use i_divmod, except it doesn't produce the results
           I want when n is negative.  So just duplicate the salient
           part here. */
        long div = n / base;
        long mod = n - div * base;

        /* convert abs(mod) to the right character in [0-9, a-z] */
        char cdigit = (char)(mod < 0 ? -mod : mod);
        cdigit += (cdigit < 10) ? '0' : 'a' - 10;
        *--p = cdigit;

        n = div;
    } while (n);

    if (base == 2) {
        *--p = 'b';
        *--p = '0';
    } else if (base == 8) {
        if (newstyle) {
            *--p = 'o';
            *--p = '0';
        } else if (!is_zero)
            *--p = '0';
    } else if (base == 16) {
        *--p = 'x';
        *--p = '0';
    } else {
        *--p = '#';
        *--p = '0' + base % 10;
        if (base > 10)
            *--p = '0' + base / 10;
    }
    if (negative)
        *--p = '-';

    return PyString_FromStringAndSize(p, &buf[sizeof(buf)] - p);
173 174
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
175 176 177 178 179 180 181 182 183
extern "C" int _PyInt_AsInt(PyObject* obj) noexcept {
    long result = PyInt_AsLong(obj);
    if (result == -1 && PyErr_Occurred())
        return -1;
    if (result > INT_MAX || result < INT_MIN) {
        PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int");
        return -1;
    }
    return (int)result;
184 185
}

186 187 188 189 190 191 192 193 194 195
#ifdef HAVE_LONG_LONG
extern "C" unsigned PY_LONG_LONG PyInt_AsUnsignedLongLongMask(register PyObject* op) noexcept {
    Py_FatalError("unimplemented");

    unsigned PY_LONG_LONG val = 0;

    return val;
}
#endif

196
extern "C" PyObject* PyInt_FromString(const char* s, char** pend, int base) noexcept {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210
    char* end;
    long x;
    Py_ssize_t slen;
    PyObject* sobj, *srepr;

    if ((base != 0 && base < 2) || base > 36) {
        PyErr_SetString(PyExc_ValueError, "int() base must be >= 2 and <= 36");
        return NULL;
    }

    while (*s && isspace(Py_CHARMASK(*s)))
        s++;
    errno = 0;
    if (base == 0 && s[0] == '0') {
Marius Wachtler's avatar
Marius Wachtler committed
211
        x = (long)PyOS_strtoul(const_cast<char*>(s), &end, base);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
212 213 214
        if (x < 0)
            return PyLong_FromString(s, pend, base);
    } else
Marius Wachtler's avatar
Marius Wachtler committed
215
        x = PyOS_strtol(const_cast<char*>(s), &end, base);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
216 217 218 219 220 221 222
    if (end == s || !isalnum(Py_CHARMASK(end[-1])))
        goto bad;
    while (*end && isspace(Py_CHARMASK(*end)))
        end++;
    if (*end != '\0') {
    bad:
        slen = strlen(s) < 200 ? strlen(s) : 200;
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237

        // Pyston addition: try to avoid doing the string repr if possible.
        bool use_fast = true;
        for (int i = 0; i < slen; i++) {
            char c = s[i];
            if (c == '\'' || c == '\\' || c == '\t' || c == '\n' || c == '\r' || c < ' ' || c >= 0x7f) {
                use_fast = false;
                break;
            }
        }
        if (use_fast) {
            PyErr_Format(PyExc_ValueError, "invalid literal for int() with base %d: '%.200s'", base, s);
            return NULL;
        }

Kevin Modzelewski's avatar
Kevin Modzelewski committed
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
        sobj = PyString_FromStringAndSize(s, slen);
        if (sobj == NULL)
            return NULL;
        srepr = PyObject_Repr(sobj);
        Py_DECREF(sobj);
        if (srepr == NULL)
            return NULL;
        PyErr_Format(PyExc_ValueError, "invalid literal for int() with base %d: %s", base, PyString_AS_STRING(srepr));
        Py_DECREF(srepr);
        return NULL;
    } else if (errno != 0)
        return PyLong_FromString(s, pend, base);
    if (pend)
        *pend = end;
    return PyInt_FromLong(x);
}

#ifdef Py_USING_UNICODE
256
extern "C" PyObject* PyInt_FromUnicode(Py_UNICODE* s, Py_ssize_t length, int base) noexcept {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
257
    PyObject* result;
258
    char* buffer = (char*)malloc(length + 1);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
259 260 261 262 263

    if (buffer == NULL)
        return PyErr_NoMemory();

    if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) {
264
        free(buffer);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
265 266 267
        return NULL;
    }
    result = PyInt_FromString(buffer, NULL, base);
268
    free(buffer);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
269 270 271 272
    return result;
}
#endif

Kevin Modzelewski's avatar
Kevin Modzelewski committed
273 274
BoxedInt* interned_ints[NUM_INTERNED_INTS];

275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
// If we don't have fast overflow-checking builtins, provide some slow variants:
#if !__has_builtin(__builtin_saddl_overflow)

#ifdef __clang__
#error "shouldn't be defining the slow versions of these for clang"
#endif

bool __builtin_saddl_overflow(i64 lhs, i64 rhs, i64* result) {
    __int128 r = (__int128)lhs + (__int128)rhs;
    if (r > (__int128)PYSTON_INT_MAX)
        return true;
    if (r < (__int128)PYSTON_INT_MIN)
        return true;
    *result = (i64)r;
    return false;
}
bool __builtin_ssubl_overflow(i64 lhs, i64 rhs, i64* result) {
    __int128 r = (__int128)lhs - (__int128)rhs;
    if (r > (__int128)PYSTON_INT_MAX)
        return true;
    if (r < (__int128)PYSTON_INT_MIN)
        return true;
    *result = (i64)r;
    return false;
}
bool __builtin_smull_overflow(i64 lhs, i64 rhs, i64* result) {
    __int128 r = (__int128)lhs * (__int128)rhs;
    if (r > (__int128)PYSTON_INT_MAX)
        return true;
    if (r < (__int128)PYSTON_INT_MIN)
        return true;
    *result = (i64)r;
    return false;
}

#endif

Kevin Modzelewski's avatar
Kevin Modzelewski committed
312 313
// Could add this to the others, but the inliner should be smart enough
// that this isn't needed:
314 315 316 317 318
extern "C" Box* add_i64_i64(i64 lhs, i64 rhs) {
    i64 result;
    if (!__builtin_saddl_overflow(lhs, rhs, &result))
        return boxInt(result);
    return longAdd(boxLong(lhs), boxLong(rhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
319 320
}

321 322 323 324 325
extern "C" Box* sub_i64_i64(i64 lhs, i64 rhs) {
    i64 result;
    if (!__builtin_ssubl_overflow(lhs, rhs, &result))
        return boxInt(result);
    return longSub(boxLong(lhs), boxLong(rhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
326 327
}

328
extern "C" Box* div_i64_i64(i64 lhs, i64 rhs) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
329
    if (rhs == 0) {
330
        raiseExcHelper(ZeroDivisionError, "integer division or modulo by zero");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
331
    }
332

333
// It's possible for division to overflow:
334 335 336
#if PYSTON_INT_MIN < -PYSTON_INT_MAX
    static_assert(PYSTON_INT_MIN == -PYSTON_INT_MAX - 1, "");

337 338
    if (lhs == PYSTON_INT_MIN && rhs == -1) {
        return longDiv(boxLong(lhs), boxLong(rhs));
339 340 341
    }
#endif

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
    i64 div_result, mod_result;
    div_result = lhs / rhs;
    /* div_result * rhs can overflow on platforms where lhs/rhs gives floor(lhs/rhs)
     * for lhs and rhs with differing signs. (This is unusual
     * behaviour, and C99 prohibits it, but it's allowed by C89;
     * for an example of overflow, take lhs = LONG_MIN, rhs = 5 or lhs =
     * LONG_MAX, rhs = -5.)  However, lhs - div_result*rhs is always
     * representable as a long, since it lies strictly between
     * -abs(rhs) and abs(rhs).  We add casts to avoid intermediate
     * overflow.
     */
    mod_result = (i64)(lhs - (unsigned long)div_result * rhs);
    /* If the signs of lhs and rhs differ, and the remainder is non-0,
     * C89 doesn't define whether div_result is now the floor or the
     * ceiling of the infinitely precise quotient.  We want the floor,
     * and we have it iff the remainder's sign matches rhs's.
     */
    if (mod_result && ((rhs ^ mod_result) < 0) /* i.e. and signs differ */) {
        mod_result += rhs;
        --div_result;
        assert(mod_result && ((rhs ^ mod_result) >= 0));
    }

    return boxInt(div_result);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
366 367 368 369
}

extern "C" i64 mod_i64_i64(i64 lhs, i64 rhs) {
    if (rhs == 0) {
370
        raiseExcHelper(ZeroDivisionError, "integer division or modulo by zero");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
371
    }
372
    // I don't think this can overflow:
Kevin Modzelewski's avatar
Kevin Modzelewski committed
373 374 375 376 377 378 379
    if (lhs < 0 && rhs > 0)
        return ((lhs + 1) % rhs) + (rhs - 1);
    if (lhs > 0 && rhs < 0)
        return ((lhs - 1) % rhs) + (rhs + 1);
    return lhs % rhs;
}

380
extern "C" Box* pow_i64_i64(i64 lhs, i64 rhs, Box* mod) {
381
    i64 orig_rhs = rhs;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
382
    i64 rtn = 1, curpow = lhs;
383

Kevin Modzelewski's avatar
Kevin Modzelewski committed
384
    if (rhs < 0)
385 386
        // already checked, rhs is a integer,
        // and mod will be None in this case.
Kevin Modzelewski's avatar
Kevin Modzelewski committed
387 388
        return boxFloat(pow_float_float(lhs, rhs));

389 390
    // let longPow do the checks.
    return longPow(boxLong(lhs), boxLong(rhs), mod);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
391 392
}

393 394 395 396 397
extern "C" Box* mul_i64_i64(i64 lhs, i64 rhs) {
    i64 result;
    if (!__builtin_smull_overflow(lhs, rhs, &result))
        return boxInt(result);
    return longMul(boxLong(lhs), boxLong(rhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
398 399
}

400
extern "C" Box* intAddInt(BoxedInt* lhs, BoxedInt* rhs) {
401 402
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
403
    return add_i64_i64(lhs->n, rhs->n);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
404 405
}

406
extern "C" Box* intAddFloat(BoxedInt* lhs, BoxedFloat* rhs) {
407
    assert(PyInt_Check(lhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
408 409 410 411
    assert(rhs->cls == float_cls);
    return boxFloat(lhs->n + rhs->d);
}

412
extern "C" Box* intAdd(BoxedInt* lhs, Box* rhs) {
413
    if (!PyInt_Check(lhs))
414
        raiseExcHelper(TypeError, "descriptor '__add__' requires a 'int' object but received a '%s'", getTypeName(lhs));
415

416
    if (PyInt_Check(rhs)) {
417
        BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
418
        return add_i64_i64(lhs->n, rhs_int->n);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
419
    } else if (rhs->cls == float_cls) {
420
        BoxedFloat* rhs_float = static_cast<BoxedFloat*>(rhs);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
421 422 423 424 425 426
        return boxFloat(lhs->n + rhs_float->d);
    } else {
        return NotImplemented;
    }
}

427
extern "C" Box* intAndInt(BoxedInt* lhs, BoxedInt* rhs) {
428 429
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
430 431 432
    return boxInt(lhs->n & rhs->n);
}

433
extern "C" Box* intAnd(BoxedInt* lhs, Box* rhs) {
434
    if (!PyInt_Check(lhs))
435
        raiseExcHelper(TypeError, "descriptor '__and__' requires a 'int' object but received a '%s'", getTypeName(lhs));
436

437
    if (!PyInt_Check(rhs)) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
438 439
        return NotImplemented;
    }
440
    BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
441 442 443
    return boxInt(lhs->n & rhs_int->n);
}

444
extern "C" Box* intOrInt(BoxedInt* lhs, BoxedInt* rhs) {
445 446
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
447 448 449 450
    return boxInt(lhs->n | rhs->n);
}

extern "C" Box* intOr(BoxedInt* lhs, Box* rhs) {
451
    if (!PyInt_Check(lhs))
452
        raiseExcHelper(TypeError, "descriptor '__or__' requires a 'int' object but received a '%s'", getTypeName(lhs));
453

454
    if (!PyInt_Check(rhs)) {
455 456 457 458 459 460 461
        return NotImplemented;
    }
    BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
    return boxInt(lhs->n | rhs_int->n);
}

extern "C" Box* intXorInt(BoxedInt* lhs, BoxedInt* rhs) {
462 463
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
464 465 466 467
    return boxInt(lhs->n ^ rhs->n);
}

extern "C" Box* intXor(BoxedInt* lhs, Box* rhs) {
468
    if (!PyInt_Check(lhs))
469
        raiseExcHelper(TypeError, "descriptor '__xor__' requires a 'int' object but received a '%s'", getTypeName(lhs));
470

471
    if (!PyInt_Check(rhs)) {
472 473 474 475 476 477
        return NotImplemented;
    }
    BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
    return boxInt(lhs->n ^ rhs_int->n);
}

478
extern "C" Box* intDivInt(BoxedInt* lhs, BoxedInt* rhs) {
479 480
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
481
    return div_i64_i64(lhs->n, rhs->n);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
482 483
}

484
extern "C" Box* intDivFloat(BoxedInt* lhs, BoxedFloat* rhs) {
485
    assert(PyInt_Check(lhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
486 487 488
    assert(rhs->cls == float_cls);

    if (rhs->d == 0) {
489
        raiseExcHelper(ZeroDivisionError, "float divide by zero");
Kevin Modzelewski's avatar
Kevin Modzelewski committed
490 491 492 493
    }
    return boxFloat(lhs->n / rhs->d);
}

494
extern "C" Box* intDiv(BoxedInt* lhs, Box* rhs) {
495
    if (!PyInt_Check(lhs))
496
        raiseExcHelper(TypeError, "descriptor '__div__' requires a 'int' object but received a '%s'", getTypeName(lhs));
497

498
    if (PyInt_Check(rhs)) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
499 500 501 502 503 504 505 506
        return intDivInt(lhs, static_cast<BoxedInt*>(rhs));
    } else if (rhs->cls == float_cls) {
        return intDivFloat(lhs, static_cast<BoxedFloat*>(rhs));
    } else {
        return NotImplemented;
    }
}

507
extern "C" Box* intFloordivInt(BoxedInt* lhs, BoxedInt* rhs) {
508 509
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
510 511 512 513
    return div_i64_i64(lhs->n, rhs->n);
}

extern "C" Box* intFloordivFloat(BoxedInt* lhs, BoxedFloat* rhs) {
514
    assert(PyInt_Check(lhs));
515 516 517 518 519 520 521 522 523
    assert(rhs->cls == float_cls);

    if (rhs->d == 0) {
        raiseExcHelper(ZeroDivisionError, "float divide by zero");
    }
    return boxFloat(floor(lhs->n / rhs->d));
}

extern "C" Box* intFloordiv(BoxedInt* lhs, Box* rhs) {
524
    if (!PyInt_Check(lhs))
525
        raiseExcHelper(TypeError, "descriptor '__floordiv__' requires a 'int' object but received a '%s'",
526
                       getTypeName(lhs));
527

528
    if (PyInt_Check(rhs)) {
529 530 531 532 533 534 535 536
        return intFloordivInt(lhs, static_cast<BoxedInt*>(rhs));
    } else if (rhs->cls == float_cls) {
        return intFloordivFloat(lhs, static_cast<BoxedFloat*>(rhs));
    } else {
        return NotImplemented;
    }
}

Travis Hance's avatar
Travis Hance committed
537
extern "C" Box* intTruedivInt(BoxedInt* lhs, BoxedInt* rhs) {
538 539
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
Travis Hance's avatar
Travis Hance committed
540 541 542 543

    if (rhs->n == 0) {
        raiseExcHelper(ZeroDivisionError, "division by zero");
    }
544
    return boxFloat(lhs->n / (double)rhs->n);
Travis Hance's avatar
Travis Hance committed
545 546 547
}

extern "C" Box* intTruedivFloat(BoxedInt* lhs, BoxedFloat* rhs) {
548
    assert(PyInt_Check(lhs));
Travis Hance's avatar
Travis Hance committed
549 550 551 552 553 554 555 556 557
    assert(rhs->cls == float_cls);

    if (rhs->d == 0) {
        raiseExcHelper(ZeroDivisionError, "division by zero");
    }
    return boxFloat(lhs->n / rhs->d);
}

extern "C" Box* intTruediv(BoxedInt* lhs, Box* rhs) {
558
    if (!PyInt_Check(lhs))
559
        raiseExcHelper(TypeError, "descriptor '__truediv__' requires a 'int' object but received a '%s'",
560
                       getTypeName(lhs));
561

562
    if (PyInt_Check(rhs)) {
Travis Hance's avatar
Travis Hance committed
563 564 565 566 567 568 569 570
        return intTruedivInt(lhs, static_cast<BoxedInt*>(rhs));
    } else if (rhs->cls == float_cls) {
        return intTruedivFloat(lhs, static_cast<BoxedFloat*>(rhs));
    } else {
        return NotImplemented;
    }
}

571
extern "C" Box* intLShiftInt(BoxedInt* lhs, BoxedInt* rhs) {
572 573
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
574 575 576 577

    if (rhs->n < 0)
        raiseExcHelper(ValueError, "negative shift count");

578 579 580 581 582 583 584
    bool undefined = rhs->n >= sizeof(rhs->n) * 8;
    if (!undefined) {
        int64_t res = lhs->n << rhs->n;
        if ((res >> rhs->n) == lhs->n)
            return boxInt(lhs->n << rhs->n);
    }
    return longLshift(boxLong(lhs->n), rhs);
585 586
}

587
extern "C" Box* intLShift(BoxedInt* lhs, Box* rhs) {
588
    if (!PyInt_Check(lhs))
589
        raiseExcHelper(TypeError, "descriptor '__lshift__' requires a 'int' object but received a '%s'",
590
                       getTypeName(lhs));
591

592 593 594
    if (rhs->cls == long_cls)
        return longLshift(boxLong(lhs->n), rhs);

595
    if (!PyInt_Check(rhs)) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
596 597
        return NotImplemented;
    }
598
    BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
599
    return intLShiftInt(lhs, rhs_int);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
600 601
}

602
extern "C" Box* intModInt(BoxedInt* lhs, BoxedInt* rhs) {
603 604
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
605 606 607
    return boxInt(mod_i64_i64(lhs->n, rhs->n));
}

608
extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) {
609
    if (!PyInt_Check(lhs))
610
        raiseExcHelper(TypeError, "descriptor '__mod__' requires a 'int' object but received a '%s'", getTypeName(lhs));
611

612
    if (!PyInt_Check(rhs)) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
613 614
        return NotImplemented;
    }
615
    BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
616 617 618
    return boxInt(mod_i64_i64(lhs->n, rhs_int->n));
}

619
extern "C" Box* intDivmod(BoxedInt* lhs, Box* rhs) {
620
    if (!PyInt_Check(lhs))
621
        raiseExcHelper(TypeError, "descriptor '__divmod__' requires a 'int' object but received a '%s'",
622
                       getTypeName(lhs));
623

624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
    Box* divResult = intDiv(lhs, rhs);

    if (divResult == NotImplemented) {
        return NotImplemented;
    }

    Box* modResult = intMod(lhs, rhs);

    if (modResult == NotImplemented) {
        return NotImplemented;
    }

    Box* arg[2] = { divResult, modResult };
    return createTuple(2, arg);
}


641
extern "C" Box* intMulInt(BoxedInt* lhs, BoxedInt* rhs) {
642 643
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
644
    return mul_i64_i64(lhs->n, rhs->n);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
645 646
}

647
extern "C" Box* intMulFloat(BoxedInt* lhs, BoxedFloat* rhs) {
648
    assert(PyInt_Check(lhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
649 650 651 652
    assert(rhs->cls == float_cls);
    return boxFloat(lhs->n * rhs->d);
}

653
extern "C" Box* intMul(BoxedInt* lhs, Box* rhs) {
654
    if (!PyInt_Check(lhs))
655
        raiseExcHelper(TypeError, "descriptor '__mul__' requires a 'int' object but received a '%s'", getTypeName(lhs));
656

657
    if (PyInt_Check(rhs)) {
658
        BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
659
        return intMulInt(lhs, rhs_int);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
660
    } else if (rhs->cls == float_cls) {
661
        BoxedFloat* rhs_float = static_cast<BoxedFloat*>(rhs);
662
        return intMulFloat(lhs, rhs_float);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
663 664 665 666 667
    } else {
        return NotImplemented;
    }
}

668 669 670 671
static void _addFuncPow(const char* name, ConcreteCompilerType* rtn_type, void* float_func, void* int_func) {
    std::vector<ConcreteCompilerType*> v_ifu{ BOXED_INT, BOXED_FLOAT, UNKNOWN };
    std::vector<ConcreteCompilerType*> v_uuu{ UNKNOWN, UNKNOWN, UNKNOWN };

672 673 674 675
    FunctionMetadata* md = new FunctionMetadata(3, false, false);
    md->addVersion(float_func, UNKNOWN, v_ifu);
    md->addVersion(int_func, UNKNOWN, v_uuu);
    int_cls->giveAttr(name, new BoxedFunction(md, { None }));
676 677 678
}

extern "C" Box* intPowLong(BoxedInt* lhs, BoxedLong* rhs, Box* mod) {
679 680
    assert(PyInt_Check(lhs));
    assert(PyLong_Check(rhs));
681 682
    BoxedLong* lhs_long = boxLong(lhs->n);
    return longPow(lhs_long, rhs, mod);
683 684
}

685
extern "C" Box* intPowFloat(BoxedInt* lhs, BoxedFloat* rhs, Box* mod) {
686
    assert(PyInt_Check(lhs));
687
    assert(rhs->cls == float_cls);
688 689 690 691 692

    if (mod != None) {
        raiseExcHelper(TypeError, "pow() 3rd argument not allowed unless all arguments are integers");
    }
    return boxFloat(pow_float_float(lhs->n, rhs->d));
693 694
}

695
extern "C" Box* intPow(BoxedInt* lhs, Box* rhs, Box* mod) {
696
    if (!PyInt_Check(lhs))
697
        raiseExcHelper(TypeError, "descriptor '__pow__' requires a 'int' object but received a '%s'", getTypeName(lhs));
698

699
    if (PyLong_Check(rhs))
700
        return intPowLong(lhs, static_cast<BoxedLong*>(rhs), mod);
701
    else if (PyFloat_Check(rhs))
702
        return intPowFloat(lhs, static_cast<BoxedFloat*>(rhs), mod);
703
    else if (!PyInt_Check(rhs))
Kevin Modzelewski's avatar
Kevin Modzelewski committed
704
        return NotImplemented;
705 706 707 708 709 710 711 712

    BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
    BoxedInt* mod_int = static_cast<BoxedInt*>(mod);

    if (mod != None) {
        if (rhs_int->n < 0)
            raiseExcHelper(TypeError, "pow() 2nd argument "
                                      "cannot be negative when 3rd argument specified");
713
        if (!PyInt_Check(mod)) {
714 715 716 717
            return NotImplemented;
        } else if (mod_int->n == 0) {
            raiseExcHelper(ValueError, "pow() 3rd argument cannot be 0");
        }
Kevin Modzelewski's avatar
Kevin Modzelewski committed
718
    }
719 720

    Box* rtn = pow_i64_i64(lhs->n, rhs_int->n, mod);
721
    if (PyLong_Check(rtn))
722 723
        return longInt(rtn);
    return rtn;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
724 725
}

726
extern "C" Box* intRShiftInt(BoxedInt* lhs, BoxedInt* rhs) {
727 728
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
729 730 731 732

    if (rhs->n < 0)
        raiseExcHelper(ValueError, "negative shift count");

733 734 735
    return boxInt(lhs->n >> rhs->n);
}

736
extern "C" Box* intRShift(BoxedInt* lhs, Box* rhs) {
737
    if (!PyInt_Check(lhs))
738
        raiseExcHelper(TypeError, "descriptor '__rshift__' requires a 'int' object but received a '%s'",
739
                       getTypeName(lhs));
740

741 742 743
    if (rhs->cls == long_cls)
        return longRshift(boxLong(lhs->n), rhs);

744
    if (!PyInt_Check(rhs)) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
745 746
        return NotImplemented;
    }
747
    BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
748
    return intRShiftInt(lhs, rhs_int);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
749 750
}

751
extern "C" Box* intSubInt(BoxedInt* lhs, BoxedInt* rhs) {
752 753
    assert(PyInt_Check(lhs));
    assert(PyInt_Check(rhs));
754
    return sub_i64_i64(lhs->n, rhs->n);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
755 756
}

757
extern "C" Box* intSubFloat(BoxedInt* lhs, BoxedFloat* rhs) {
758
    assert(PyInt_Check(lhs));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
759 760 761 762
    assert(rhs->cls == float_cls);
    return boxFloat(lhs->n - rhs->d);
}

763
extern "C" Box* intSub(BoxedInt* lhs, Box* rhs) {
764
    if (!PyInt_Check(lhs))
765
        raiseExcHelper(TypeError, "descriptor '__sub__' requires a 'int' object but received a '%s'", getTypeName(lhs));
766

767
    if (PyInt_Check(rhs)) {
768
        BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
769
        return intSubInt(lhs, rhs_int);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
770
    } else if (rhs->cls == float_cls) {
771
        BoxedFloat* rhs_float = static_cast<BoxedFloat*>(rhs);
772
        return intSubFloat(lhs, rhs_float);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
773 774 775 776 777 778
    } else {
        return NotImplemented;
    }
}

extern "C" Box* intInvert(BoxedInt* v) {
779
    if (!PyInt_Check(v))
780
        raiseExcHelper(TypeError, "descriptor '__invert__' requires a 'int' object but received a '%s'",
781
                       getTypeName(v));
782

Kevin Modzelewski's avatar
Kevin Modzelewski committed
783 784 785 786
    return boxInt(~v->n);
}

extern "C" Box* intPos(BoxedInt* v) {
787
    if (!PyInt_Check(v))
788
        raiseExcHelper(TypeError, "descriptor '__pos__' requires a 'int' object but received a '%s'", getTypeName(v));
789 790 791 792

    if (v->cls == int_cls)
        return v;
    return boxInt(v->n);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
793 794 795
}

extern "C" Box* intNeg(BoxedInt* v) {
796
    if (!PyInt_Check(v))
797
        raiseExcHelper(TypeError, "descriptor '__neg__' requires a 'int' object but received a '%s'", getTypeName(v));
798

799

800
// It's possible for this to overflow:
801 802 803 804 805 806 807 808
#if PYSTON_INT_MIN < -PYSTON_INT_MAX
    static_assert(PYSTON_INT_MIN == -PYSTON_INT_MAX - 1, "");

    if (v->n == PYSTON_INT_MIN) {
        return longNeg(boxLong(v->n));
    }
#endif

Kevin Modzelewski's avatar
Kevin Modzelewski committed
809 810 811 812
    return boxInt(-v->n);
}

extern "C" Box* intNonzero(BoxedInt* v) {
813
    if (!PyInt_Check(v))
814
        raiseExcHelper(TypeError, "descriptor '__nonzero__' requires a 'int' object but received a '%s'",
815
                       getTypeName(v));
816

Kevin Modzelewski's avatar
Kevin Modzelewski committed
817 818 819 820
    return boxBool(v->n != 0);
}

extern "C" BoxedString* intRepr(BoxedInt* v) {
821
    if (!PyInt_Check(v))
822
        raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'int' object but received a '%s'", getTypeName(v));
823

Kevin Modzelewski's avatar
Kevin Modzelewski committed
824 825
    char buf[80];
    int len = snprintf(buf, 80, "%ld", v->n);
826
    return static_cast<BoxedString*>(boxString(llvm::StringRef(buf, len)));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
827 828 829
}

extern "C" Box* intHash(BoxedInt* self) {
830
    if (!PyInt_Check(self))
831
        raiseExcHelper(TypeError, "descriptor '__hash__' requires a 'int' object but received a '%s'",
832
                       getTypeName(self));
833 834 835 836

    if (self->cls == int_cls)
        return self;
    return boxInt(self->n);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
837 838
}

839 840 841 842 843 844 845 846
extern "C" Box* intBin(BoxedInt* self) {
    if (!PyInt_Check(self))
        raiseExcHelper(TypeError, "descriptor '__bin__' requires a 'int' object but received a '%s'",
                       getTypeName(self));

    return _PyInt_Format(reinterpret_cast<PyIntObject*>(self), 2, 0);
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
847
extern "C" Box* intHex(BoxedInt* self) {
848
    if (!PyInt_Check(self))
Kevin Modzelewski's avatar
Kevin Modzelewski committed
849
        raiseExcHelper(TypeError, "descriptor '__hex__' requires a 'int' object but received a '%s'",
850
                       getTypeName(self));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
851 852

    char buf[80];
853 854 855 856 857 858
    int len = 0;
    bool is_negative = self->n < 0;
    if (is_negative)
        len = snprintf(buf, sizeof(buf), "-0x%lx", std::abs(self->n));
    else
        len = snprintf(buf, sizeof(buf), "0x%lx", self->n);
859
    return boxString(llvm::StringRef(buf, len));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
860 861 862
}

extern "C" Box* intOct(BoxedInt* self) {
863
    if (!PyInt_Check(self))
Kevin Modzelewski's avatar
Kevin Modzelewski committed
864
        raiseExcHelper(TypeError, "descriptor '__oct__' requires a 'int' object but received a '%s'",
865
                       getTypeName(self));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
866 867

    char buf[80];
868 869 870 871 872 873
    int len = 0;
    bool is_negative = self->n < 0;
    if (is_negative)
        len = snprintf(buf, sizeof(buf), "-%#lo", std::abs(self->n));
    else
        len = snprintf(buf, sizeof(buf), "%#lo", self->n);
874
    return boxString(llvm::StringRef(buf, len));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
875 876
}

877
extern "C" Box* intTrunc(BoxedInt* self) {
878
    if (!PyInt_Check(self))
879 880 881
        raiseExcHelper(TypeError, "descriptor '__trunc__' requires a 'int' object but received a '%s'",
                       getTypeName(self));

882 883 884 885 886 887
    if (self->cls == int_cls)
        return self;
    return boxInt(self->n);
}

extern "C" Box* intInt(BoxedInt* self) {
888
    if (!PyInt_Check(self))
889 890 891 892 893 894
        raiseExcHelper(TypeError, "descriptor '__int__' requires a 'int' object but received a '%s'",
                       getTypeName(self));

    if (self->cls == int_cls)
        return self;
    return boxInt(self->n);
895 896
}

897 898 899 900 901 902
extern "C" Box* intIndex(BoxedInt* v) {
    if (PyInt_CheckExact(v))
        return v;
    return boxInt(v->n);
}

903 904 905 906 907 908 909
template <ExceptionStyle S> static Box* _intNew(Box* val, Box* _base) noexcept(S == CAPI) {
    int base = 10;

    if (_base) {
        if (S == CAPI) {
            if (!PyInt_Check(_base)) {
                PyErr_SetString(PyExc_TypeError, "an integer is required");
910
                return NULL;
911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926
            }

            if (val == None) {
                PyErr_SetString(PyExc_TypeError, "int() missing string argument");
                return NULL;
            }

            if (!PyString_Check(val) && !PyUnicode_Check(val)) {
                PyErr_SetString(PyExc_TypeError, "int() can't convert non-string with explicit base");
                return NULL;
            }
        } else {
            if (!PyInt_Check(_base))
                raiseExcHelper(TypeError, "an integer is required");

            if (val == None)
927
                raiseExcHelper(TypeError, "int() missing string argument");
928 929 930

            if (!PyString_Check(val) && !PyUnicode_Check(val))
                raiseExcHelper(TypeError, "int() can't convert non-string with explicit base");
931
        }
932 933 934 935 936
        base = static_cast<BoxedInt*>(_base)->n;
    } else {
        if (val == None)
            return PyInt_FromLong(0L);

937 938 939 940 941 942 943 944 945 946 947
        Box* r = PyNumber_Int(val);
        if (!r) {
            if (S == CAPI) {
                return NULL;
            } else
                throwCAPIException();
        }
        return r;
    }

    if (PyString_Check(val)) {
948
        BoxedString* s = static_cast<BoxedString*>(val);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
949

950 951 952
        if (s->size() != strlen(s->data())) {
            Box* srepr = PyObject_Repr(val);
            if (S == CAPI) {
953
                PyErr_Format(PyExc_ValueError, "invalid literal for int() with base %d: %s", base,
954 955 956
                             PyString_AS_STRING(srepr));
                return NULL;
            } else {
957
                raiseExcHelper(ValueError, "invalid literal for int() with base %d: %s", base,
958 959 960
                               PyString_AS_STRING(srepr));
            }
        }
961
        Box* r = PyInt_FromString(s->data(), NULL, base);
962 963 964 965 966 967
        if (!r) {
            if (S == CAPI)
                return NULL;
            else
                throwCAPIException();
        }
968
        return r;
969 970 971
    } else {
        // only for unicode and its subtype. Other type will be filtered out in above.
        Box* r = PyInt_FromUnicode(PyUnicode_AS_UNICODE(val), PyUnicode_GET_SIZE(val), base);
972 973 974 975 976 977
        if (!r) {
            if (S == CAPI)
                return NULL;
            else
                throwCAPIException();
        }
Kevin Modzelewski's avatar
Kevin Modzelewski committed
978
        return r;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
979
    }
980 981
}

982
template <ExceptionStyle S> Box* intNew(Box* _cls, Box* val, Box* base) noexcept(S == CAPI) {
983
    if (!PyType_Check(_cls)) {
984 985 986 987 988 989
        if (S == CAPI) {
            PyErr_Format(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls));
            return NULL;
        } else
            raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls));
    }
990 991

    BoxedClass* cls = static_cast<BoxedClass*>(_cls);
992 993 994 995 996 997 998 999 1000
    if (!isSubclass(cls, int_cls)) {
        if (S == CAPI) {
            PyErr_Format(TypeError, "int.__new__(%s): %s is not a subtype of int", getNameOfClass(cls),
                         getNameOfClass(cls));
            return NULL;
        } else
            raiseExcHelper(TypeError, "int.__new__(%s): %s is not a subtype of int", getNameOfClass(cls),
                           getNameOfClass(cls));
    }
1001 1002

    if (cls == int_cls)
1003 1004 1005 1006 1007 1008 1009
        return _intNew<S>(val, base);

    BoxedInt* n = (BoxedInt*)_intNew<S>(val, base);
    if (!n) {
        assert(S == CAPI);
        return NULL;
    }
1010

Marius Wachtler's avatar
Marius Wachtler committed
1011 1012 1013
    if (n->cls == long_cls) {
        if (cls == int_cls)
            return n;
1014 1015

        if (S == CAPI) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1016
            PyErr_SetString(OverflowError, "Python int too large to convert to C long");
1017 1018 1019
            return NULL;
        } else
            raiseExcHelper(OverflowError, "Python int too large to convert to C long");
Marius Wachtler's avatar
Marius Wachtler committed
1020
    }
1021
    return new (cls) BoxedInt(n->n);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1022 1023
}

1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
static const unsigned char BitLengthTable[32]
    = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };

static int bits_in_ulong(unsigned long d) noexcept {
    int d_bits = 0;
    while (d >= 32) {
        d_bits += 6;
        d >>= 6;
    }
    d_bits += (int)BitLengthTable[d];
    return d_bits;
}

extern "C" Box* intBitLength(BoxedInt* v) {
1038
    if (!PyInt_Check(v))
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
        raiseExcHelper(TypeError, "descriptor 'bit_length' requires a 'int' object but received a '%s'",
                       getTypeName(v));

    unsigned long n;
    if (v->n < 0)
        /* avoid undefined behaviour when v->n == -LONG_MAX-1 */
        n = 0U - (unsigned long)v->n;
    else
        n = (unsigned long)v->n;

    return PyInt_FromLong(bits_in_ulong(n));
}

1052
static void _addFuncIntFloatUnknown(const char* name, void* int_func, void* float_func, void* boxed_func) {
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1053 1054
    std::vector<ConcreteCompilerType*> v_ii, v_if, v_iu;
    assert(BOXED_INT);
1055
    v_ii.push_back(UNKNOWN);
1056
    v_ii.push_back(BOXED_INT);
1057
    v_if.push_back(UNKNOWN);
1058
    v_if.push_back(BOXED_FLOAT);
1059 1060 1061
    // Only the unknown version can accept non-ints (ex if you access the function directly ex via int.__add__)
    v_iu.push_back(UNKNOWN);
    v_iu.push_back(UNKNOWN);
1062

1063 1064 1065 1066 1067
    FunctionMetadata* md = new FunctionMetadata(2, false, false);
    md->addVersion(int_func, UNKNOWN, v_ii);
    md->addVersion(float_func, BOXED_FLOAT, v_if);
    md->addVersion(boxed_func, UNKNOWN, v_iu);
    int_cls->giveAttr(name, new BoxedFunction(md));
1068 1069 1070 1071 1072
}

static void _addFuncIntUnknown(const char* name, ConcreteCompilerType* rtn_type, void* int_func, void* boxed_func) {
    std::vector<ConcreteCompilerType*> v_ii, v_iu;
    assert(BOXED_INT);
1073
    v_ii.push_back(UNKNOWN);
1074
    v_ii.push_back(BOXED_INT);
1075
    v_iu.push_back(UNKNOWN);
1076
    v_iu.push_back(UNKNOWN);
1077

1078 1079 1080 1081
    FunctionMetadata* md = new FunctionMetadata(2, false, false);
    md->addVersion(int_func, rtn_type, v_ii);
    md->addVersion(boxed_func, UNKNOWN, v_iu);
    int_cls->giveAttr(name, new BoxedFunction(md));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1082 1083
}

1084
static Box* intIntGetset(Box* b, void*) {
Travis Hance's avatar
Travis Hance committed
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
    if (b->cls == int_cls) {
        return b;
    } else {
        assert(PyInt_Check(b));
        return boxInt(static_cast<BoxedInt*>(b)->n);
    }
}

static Box* int0(Box*, void*) {
    return boxInt(0);
}

1097 1098 1099 1100
static Box* int1(Box*, void*) {
    return boxInt(1);
}

1101 1102 1103 1104 1105 1106 1107
static int64_t int_hash(BoxedInt* o) noexcept {
    int64_t n = o->n;
    if (n == -1)
        return -2;
    return n;
}

1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
static PyObject* int_richcompare(PyObject* v, PyObject* w, int op) noexcept {
    if (!PyInt_Check(v) || !PyInt_Check(w)) {
        Py_INCREF(Py_NotImplemented);
        return Py_NotImplemented;
    }

    int64_t lhs = static_cast<BoxedInt*>(v)->n;
    int64_t rhs = static_cast<BoxedInt*>(w)->n;

    switch (op) {
        case Py_EQ:
            return boxBool(lhs == rhs);
        case Py_NE:
            return boxBool(lhs != rhs);
        case Py_LT:
            return boxBool(lhs < rhs);
        case Py_LE:
            return boxBool(lhs <= rhs);
        case Py_GT:
            return boxBool(lhs > rhs);
        case Py_GE:
            return boxBool(lhs >= rhs);
        default:
            RELEASE_ASSERT(0, "%d", op);
    }
}

1135 1136 1137 1138
static PyObject* int_getnewargs(BoxedInt* v) noexcept {
    return Py_BuildValue("(l)", v->n);
}

Kevin Modzelewski's avatar
Kevin Modzelewski committed
1139
void setupInt() {
1140 1141 1142
    static PyNumberMethods int_as_number;
    int_cls->tp_as_number = &int_as_number;

1143
    for (int i = 0; i < NUM_INTERNED_INTS; i++) {
1144
        interned_ints[i] = new BoxedInt(i);
1145
        gc::registerPermanentRoot(interned_ints[i]);
1146 1147
    }

1148 1149
    int_cls->giveAttr("__getnewargs__", new BoxedFunction(FunctionMetadata::create((void*)int_getnewargs, UNKNOWN, 1,
                                                                                   ParamNames::empty(), CAPI)));
1150

1151 1152
    _addFuncIntFloatUnknown("__add__", (void*)intAddInt, (void*)intAddFloat, (void*)intAdd);
    _addFuncIntUnknown("__and__", BOXED_INT, (void*)intAndInt, (void*)intAnd);
1153 1154
    _addFuncIntUnknown("__or__", BOXED_INT, (void*)intOrInt, (void*)intOr);
    _addFuncIntUnknown("__xor__", BOXED_INT, (void*)intXorInt, (void*)intXor);
1155 1156
    _addFuncIntFloatUnknown("__sub__", (void*)intSubInt, (void*)intSubFloat, (void*)intSub);
    _addFuncIntFloatUnknown("__div__", (void*)intDivInt, (void*)intDivFloat, (void*)intDiv);
1157
    _addFuncIntFloatUnknown("__floordiv__", (void*)intFloordivInt, (void*)intFloordivFloat, (void*)intFloordiv);
1158
    _addFuncIntFloatUnknown("__truediv__", (void*)intTruedivInt, (void*)intTruedivFloat, (void*)intTruediv);
1159 1160
    _addFuncIntFloatUnknown("__mul__", (void*)intMulInt, (void*)intMulFloat, (void*)intMul);
    _addFuncIntUnknown("__mod__", BOXED_INT, (void*)intModInt, (void*)intMod);
1161
    _addFuncPow("__pow__", BOXED_INT, (void*)intPowFloat, (void*)intPow);
1162 1163
    // Note: CPython implements int comparisons using tp_compare
    int_cls->tp_richcompare = int_richcompare;
1164

1165
    _addFuncIntUnknown("__lshift__", UNKNOWN, (void*)intLShiftInt, (void*)intLShift);
1166
    _addFuncIntUnknown("__rshift__", UNKNOWN, (void*)intRShiftInt, (void*)intRShift);
1167

1168 1169 1170 1171 1172
    int_cls->giveAttr("__invert__", new BoxedFunction(FunctionMetadata::create((void*)intInvert, BOXED_INT, 1)));
    int_cls->giveAttr("__pos__", new BoxedFunction(FunctionMetadata::create((void*)intPos, BOXED_INT, 1)));
    int_cls->giveAttr("__neg__", new BoxedFunction(FunctionMetadata::create((void*)intNeg, UNKNOWN, 1)));
    int_cls->giveAttr("__nonzero__", new BoxedFunction(FunctionMetadata::create((void*)intNonzero, BOXED_BOOL, 1)));
    int_cls->giveAttr("__repr__", new BoxedFunction(FunctionMetadata::create((void*)intRepr, STR, 1)));
1173
    int_cls->tp_hash = (hashfunc)int_hash;
1174
    int_cls->giveAttr("__divmod__", new BoxedFunction(FunctionMetadata::create((void*)intDivmod, UNKNOWN, 2)));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1175

1176 1177 1178
    int_cls->giveAttr("__bin__", new BoxedFunction(FunctionMetadata::create((void*)intBin, STR, 1)));
    int_cls->giveAttr("__hex__", new BoxedFunction(FunctionMetadata::create((void*)intHex, STR, 1)));
    int_cls->giveAttr("__oct__", new BoxedFunction(FunctionMetadata::create((void*)intOct, STR, 1)));
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1179

1180 1181 1182
    int_cls->giveAttr("__trunc__", new BoxedFunction(FunctionMetadata::create((void*)intTrunc, BOXED_INT, 1)));
    int_cls->giveAttr("__index__", new BoxedFunction(FunctionMetadata::create((void*)intIndex, BOXED_INT, 1)));
    int_cls->giveAttr("__int__", new BoxedFunction(FunctionMetadata::create((void*)intInt, BOXED_INT, 1)));
1183

1184 1185 1186
    auto int_new = FunctionMetadata::create((void*)intNew<CXX>, UNKNOWN, 3, false, false,
                                            ParamNames({ "", "x", "base" }, "", ""), CXX);
    int_new->addVersion((void*)intNew<CAPI>, UNKNOWN, CAPI);
1187 1188
    int_cls->giveAttr("__new__", new BoxedFunction(int_new, { None, NULL }));

Kevin Modzelewski's avatar
Kevin Modzelewski committed
1189

1190
    int_cls->giveAttr("bit_length", new BoxedFunction(FunctionMetadata::create((void*)intBitLength, BOXED_INT, 1)));
1191

1192
    int_cls->giveAttr("real", new (pyston_getset_cls) BoxedGetsetDescriptor(intIntGetset, NULL, NULL));
Travis Hance's avatar
Travis Hance committed
1193
    int_cls->giveAttr("imag", new (pyston_getset_cls) BoxedGetsetDescriptor(int0, NULL, NULL));
1194
    int_cls->giveAttr("conjugate", new BoxedFunction(FunctionMetadata::create((void*)intIntGetset, BOXED_INT, 1)));
1195
    int_cls->giveAttr("numerator", new (pyston_getset_cls) BoxedGetsetDescriptor(intIntGetset, NULL, NULL));
1196
    int_cls->giveAttr("denominator", new (pyston_getset_cls) BoxedGetsetDescriptor(int1, NULL, NULL));
Travis Hance's avatar
Travis Hance committed
1197

1198
    add_operators(int_cls);
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1199
    int_cls->freeze();
1200 1201

    int_cls->tp_repr = (reprfunc)int_to_decimal_string;
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1202 1203 1204 1205 1206
}

void teardownInt() {
}
}