Commit 97d42bce authored by Robert Bradshaw's avatar Robert Bradshaw Committed by GitHub

Merge pull request #2234 from jdemeyer/longint

Allow access to long/int internals (and other builtin types).
parents a59bda8c 4bd2c9b8
......@@ -54,6 +54,16 @@ non_portable_builtins_map = {
'raw_input' : ('PY_MAJOR_VERSION >= 3', 'input'),
}
ctypedef_builtins_map = {
# types of builtins in "ctypedef class" statements which we don't
# import either because the names conflict with C types or because
# the type simply is not exposed.
'py_int' : '&PyInt_Type',
'py_long' : '&PyLong_Type',
'py_float' : '&PyFloat_Type',
'wrapper_descriptor' : '&PyWrapperDescr_Type',
}
basicsize_builtins_map = {
# builtins whose type has a different tp_basicsize than sizeof(...)
'PyTypeObject': 'PyHeapTypeObject',
......
......@@ -2995,6 +2995,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
condition = replacement = None
if module_name not in ('__builtin__', 'builtins'):
module_name = '"%s"' % module_name
elif type.name in Code.ctypedef_builtins_map:
# Fast path for special builtins, don't actually import
ctypename = Code.ctypedef_builtins_map[type.name]
code.putln('%s = %s;' % (type.typeptr_cname, ctypename))
return
else:
module_name = '__Pyx_BUILTIN_MODULE_NAME'
if type.name in Code.non_portable_builtins_map:
......
......@@ -2,14 +2,13 @@
# This is not part of Python's published API.
cdef extern from "longintrepr.h":
# Add explicit cast to avoid compiler warnings
cdef _PyLong_New "(PyObject*)_PyLong_New"(Py_ssize_t s)
ctypedef unsigned int digit
ctypedef int sdigit # Python >= 2.7 only
ctypedef struct PyLongObject:
digit* ob_digit
ctypedef class __builtin__.py_long [object PyLongObject]:
cdef digit* ob_digit
cdef py_long _PyLong_New(Py_ssize_t s)
cdef long PyLong_SHIFT
cdef digit PyLong_BASE
......
......@@ -48,15 +48,15 @@ def lshift(long a, unsigned long n):
if high == 0:
ret = _PyLong_New(index + 1)
(<PyLongObject*>ret).ob_digit[index] = low
ret.ob_digit[index] = low
else:
ret = _PyLong_New(index + 2)
(<PyLongObject*>ret).ob_digit[index] = low
(<PyLongObject*>ret).ob_digit[index + 1] = high
ret.ob_digit[index] = low
ret.ob_digit[index + 1] = high
while index >= 1:
index -= 1
(<PyLongObject*>ret).ob_digit[index] = 0
ret.ob_digit[index] = 0
if a < 0:
Py_SIZE_PTR(ret)[0] *= -1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment