Cython has moved to github.
cython-devel
view Cython/Compiler/PyrexTypes.py @ 2118:97069bd04411
Ticket #355 - ctypedef class ordering
| author | Robert Bradshaw <robertwb@math.washington.edu> |
|---|---|
| date | Thu Sep 10 19:33:50 2009 -0700 (2 years ago) |
| parents | 5f8653965c34 |
| children | 8d333cfc54df |
line source
1 #
2 # Pyrex - Types
3 #
5 from Cython.Utils import UtilityCode
6 import StringEncoding
7 import Naming
8 import copy
10 class BaseType(object):
11 #
12 # Base class for all Pyrex types including pseudo-types.
14 def cast_code(self, expr_code):
15 return "((%s)%s)" % (self.declaration_code(""), expr_code)
17 def specalization_name(self):
18 return self.declaration_code("").replace(" ", "__")
20 def base_declaration_code(self, base_code, entity_code):
21 if entity_code:
22 return "%s %s" % (base_code, entity_code)
23 else:
24 return base_code
26 class PyrexType(BaseType):
27 #
28 # Base class for all Pyrex types.
29 #
30 # is_pyobject boolean Is a Python object type
31 # is_extension_type boolean Is a Python extension type
32 # is_numeric boolean Is a C numeric type
33 # is_int boolean Is a C integer type
34 # is_float boolean Is a C floating point type
35 # is_complex boolean Is a C complex type
36 # is_void boolean Is the C void type
37 # is_array boolean Is a C array type
38 # is_ptr boolean Is a C pointer type
39 # is_null_ptr boolean Is the type of NULL
40 # is_cfunction boolean Is a C function type
41 # is_struct_or_union boolean Is a C struct or union type
42 # is_struct boolean Is a C struct type
43 # is_enum boolean Is a C enum type
44 # is_typedef boolean Is a typedef type
45 # is_string boolean Is a C char * type
46 # is_unicode boolean Is a UTF-8 encoded C char * type
47 # is_returncode boolean Is used only to signal exceptions
48 # is_error boolean Is the dummy error type
49 # is_buffer boolean Is buffer access type
50 # has_attributes boolean Has C dot-selectable attributes
51 # default_value string Initial value
52 # pymemberdef_typecode string Type code for PyMemberDef struct
53 #
54 # declaration_code(entity_code,
55 # for_display = 0, dll_linkage = None, pyrex = 0)
56 # Returns a code fragment for the declaration of an entity
57 # of this type, given a code fragment for the entity.
58 # * If for_display, this is for reading by a human in an error
59 # message; otherwise it must be valid C code.
60 # * If dll_linkage is not None, it must be 'DL_EXPORT' or
61 # 'DL_IMPORT', and will be added to the base type part of
62 # the declaration.
63 # * If pyrex = 1, this is for use in a 'cdef extern'
64 # statement of a Pyrex include file.
65 #
66 # assignable_from(src_type)
67 # Tests whether a variable of this type can be
68 # assigned a value of type src_type.
69 #
70 # same_as(other_type)
71 # Tests whether this type represents the same type
72 # as other_type.
73 #
74 # as_argument_type():
75 # Coerces array type into pointer type for use as
76 # a formal argument type.
77 #
79 is_pyobject = 0
80 is_extension_type = 0
81 is_builtin_type = 0
82 is_numeric = 0
83 is_int = 0
84 is_float = 0
85 is_complex = 0
86 is_void = 0
87 is_array = 0
88 is_ptr = 0
89 is_null_ptr = 0
90 is_cfunction = 0
91 is_struct_or_union = 0
92 is_struct = 0
93 is_enum = 0
94 is_typedef = 0
95 is_string = 0
96 is_unicode = 0
97 is_returncode = 0
98 is_error = 0
99 is_buffer = 0
100 has_attributes = 0
101 default_value = ""
102 pymemberdef_typecode = None
104 def resolve(self):
105 # If a typedef, returns the base type.
106 return self
108 def literal_code(self, value):
109 # Returns a C code fragment representing a literal
110 # value of this type.
111 return str(value)
113 def __str__(self):
114 return self.declaration_code("", for_display = 1).strip()
116 def same_as(self, other_type, **kwds):
117 return self.same_as_resolved_type(other_type.resolve(), **kwds)
119 def same_as_resolved_type(self, other_type):
120 return self == other_type or other_type is error_type
122 def subtype_of(self, other_type):
123 return self.subtype_of_resolved_type(other_type.resolve())
125 def subtype_of_resolved_type(self, other_type):
126 return self.same_as(other_type)
128 def assignable_from(self, src_type):
129 return self.assignable_from_resolved_type(src_type.resolve())
131 def assignable_from_resolved_type(self, src_type):
132 return self.same_as(src_type)
134 def as_argument_type(self):
135 return self
137 def is_complete(self):
138 # A type is incomplete if it is an unsized array,
139 # a struct whose attributes are not defined, etc.
140 return 1
142 def is_simple_buffer_dtype(self):
143 return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or
144 self.is_extension_type or self.is_ptr)
146 def struct_nesting_depth(self):
147 # Returns the number levels of nested structs. This is
148 # used for constructing a stack for walking the run-time
149 # type information of the struct.
150 return 1
152 class CTypedefType(BaseType):
153 #
154 # Pseudo-type defined with a ctypedef statement in a
155 # 'cdef extern from' block. Delegates most attribute
156 # lookups to the base type. ANYTHING NOT DEFINED
157 # HERE IS DELEGATED!
158 #
159 # qualified_name string
160 # typedef_cname string
161 # typedef_base_type PyrexType
162 # typedef_is_external bool
164 is_typedef = 1
165 typedef_is_external = 0
167 def __init__(self, cname, base_type, is_external=0):
168 self.typedef_cname = cname
169 self.typedef_base_type = base_type
170 self.typedef_is_external = is_external
172 # Make typecodes in external typedefs use typesize-neutral macros
173 if is_external:
174 typecode = None
175 if base_type.is_int:
176 if base_type.signed == 0:
177 typecode = "__Pyx_T_UNSIGNED_INT"
178 else:
179 typecode = "__Pyx_T_SIGNED_INT"
180 elif base_type.is_float and not rank_to_type_name[base_type.rank] == "long double":
181 typecode = "__Pyx_T_FLOATING"
182 if typecode:
183 self.pymemberdef_typecode = "%s(%s)" % (typecode, cname)
185 def resolve(self):
186 return self.typedef_base_type.resolve()
188 def declaration_code(self, entity_code,
189 for_display = 0, dll_linkage = None, pyrex = 0):
190 name = self.declaration_name(for_display, pyrex)
191 return self.base_declaration_code(name, entity_code)
193 def declaration_name(self, for_display = 0, pyrex = 0):
194 if pyrex or for_display:
195 return self.qualified_name
196 else:
197 return self.typedef_cname
199 def as_argument_type(self):
200 return self
202 def cast_code(self, expr_code):
203 # If self is really an array (rather than pointer), we can't cast.
204 # For example, the gmp mpz_t.
205 if self.typedef_base_type.is_ptr:
206 return self.typedef_base_type.cast_code(expr_code)
207 else:
208 return BaseType.cast_code(self, expr_code)
210 def __repr__(self):
211 return "<CTypedefType %s>" % self.typedef_cname
213 def __str__(self):
214 return self.declaration_name(for_display = 1)
216 def __getattr__(self, name):
217 return getattr(self.typedef_base_type, name)
219 class BufferType(BaseType):
220 #
221 # Delegates most attribute
222 # lookups to the base type. ANYTHING NOT DEFINED
223 # HERE IS DELEGATED!
225 # dtype PyrexType
226 # ndim int
227 # mode str
228 # negative_indices bool
229 # cast bool
230 # is_buffer bool
231 # writable bool
233 is_buffer = 1
234 writable = True
235 def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
236 self.base = base
237 self.dtype = dtype
238 self.ndim = ndim
239 self.buffer_ptr_type = CPtrType(dtype)
240 self.mode = mode
241 self.negative_indices = negative_indices
242 self.cast = cast
244 def as_argument_type(self):
245 return self
247 def __getattr__(self, name):
248 return getattr(self.base, name)
250 def __repr__(self):
251 return "<BufferType %r>" % self.base
253 def public_decl(base, dll_linkage):
254 if dll_linkage:
255 return "%s(%s)" % (dll_linkage, base)
256 else:
257 return base
259 class PyObjectType(PyrexType):
260 #
261 # Base class for all Python object types (reference-counted).
262 #
263 # buffer_defaults dict or None Default options for bu
265 is_pyobject = 1
266 default_value = "0"
267 pymemberdef_typecode = "T_OBJECT"
268 buffer_defaults = None
270 def __str__(self):
271 return "Python object"
273 def __repr__(self):
274 return "<PyObjectType>"
276 def assignable_from(self, src_type):
277 return 1 # Conversion will be attempted
279 def declaration_code(self, entity_code,
280 for_display = 0, dll_linkage = None, pyrex = 0):
281 if pyrex or for_display:
282 return self.base_declaration_code("object", entity_code)
283 else:
284 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
286 def as_pyobject(self, cname):
287 if (not self.is_complete()) or self.is_extension_type:
288 return "(PyObject *)" + cname
289 else:
290 return cname
292 class BuiltinObjectType(PyObjectType):
294 is_builtin_type = 1
295 has_attributes = 1
296 base_type = None
297 module_name = '__builtin__'
299 alternative_name = None # used for str/bytes duality
301 def __init__(self, name, cname):
302 self.name = name
303 if name == 'str':
304 self.alternative_name = 'bytes'
305 elif name == 'bytes':
306 self.alternative_name = 'str'
307 self.cname = cname
308 self.typeptr_cname = "&" + cname
310 def set_scope(self, scope):
311 self.scope = scope
312 if scope:
313 scope.parent_type = self
315 def __str__(self):
316 return "%s object" % self.name
318 def __repr__(self):
319 return "<%s>"% self.cname
321 def assignable_from(self, src_type):
322 if isinstance(src_type, BuiltinObjectType):
323 return src_type.name == self.name or (
324 src_type.name == self.alternative_name and
325 src_type.name is not None)
326 else:
327 return not src_type.is_extension_type
329 def typeobj_is_available(self):
330 return True
332 def attributes_known(self):
333 return True
335 def subtype_of(self, type):
336 return type.is_pyobject and self.assignable_from(type)
338 def type_test_code(self, arg):
339 type_name = self.name
340 if type_name == 'str':
341 check = 'PyString_CheckExact'
342 elif type_name == 'set':
343 check = 'PyAnySet_CheckExact'
344 elif type_name == 'frozenset':
345 check = 'PyFrozenSet_CheckExact'
346 elif type_name == 'bool':
347 check = 'PyBool_Check'
348 else:
349 check = 'Py%s_CheckExact' % type_name.capitalize()
350 return 'likely(%s(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (check, arg, arg, self.name, arg)
352 def declaration_code(self, entity_code,
353 for_display = 0, dll_linkage = None, pyrex = 0):
354 if pyrex or for_display:
355 return self.base_declaration_code(self.name, entity_code)
356 else:
357 return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
360 class PyExtensionType(PyObjectType):
361 #
362 # A Python extension type.
363 #
364 # name string
365 # scope CClassScope Attribute namespace
366 # visibility string
367 # typedef_flag boolean
368 # base_type PyExtensionType or None
369 # module_name string or None Qualified name of defining module
370 # objstruct_cname string Name of PyObject struct
371 # objtypedef_cname string Name of PyObject struct typedef
372 # typeobj_cname string or None C code fragment referring to type object
373 # typeptr_cname string or None Name of pointer to external type object
374 # vtabslot_cname string Name of C method table member
375 # vtabstruct_cname string Name of C method table struct
376 # vtabptr_cname string Name of pointer to C method table
377 # vtable_cname string Name of C method table definition
379 is_extension_type = 1
380 has_attributes = 1
382 objtypedef_cname = None
384 def __init__(self, name, typedef_flag, base_type):
385 self.name = name
386 self.scope = None
387 self.typedef_flag = typedef_flag
388 self.base_type = base_type
389 self.module_name = None
390 self.objstruct_cname = None
391 self.typeobj_cname = None
392 self.typeptr_cname = None
393 self.vtabslot_cname = None
394 self.vtabstruct_cname = None
395 self.vtabptr_cname = None
396 self.vtable_cname = None
398 def set_scope(self, scope):
399 self.scope = scope
400 if scope:
401 scope.parent_type = self
403 def subtype_of_resolved_type(self, other_type):
404 if other_type.is_extension_type:
405 return self is other_type or (
406 self.base_type and self.base_type.subtype_of(other_type))
407 else:
408 return other_type is py_object_type
410 def typeobj_is_available(self):
411 # Do we have a pointer to the type object?
412 return self.typeptr_cname
414 def typeobj_is_imported(self):
415 # If we don't know the C name of the type object but we do
416 # know which module it's defined in, it will be imported.
417 return self.typeobj_cname is None and self.module_name is not None
419 def declaration_code(self, entity_code,
420 for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
421 if pyrex or for_display:
422 return self.base_declaration_code(self.name, entity_code)
423 else:
424 if self.typedef_flag:
425 base_format = "%s"
426 else:
427 base_format = "struct %s"
428 base = public_decl(base_format % self.objstruct_cname, dll_linkage)
429 if deref:
430 return "%s %s" % (base, entity_code)
431 else:
432 return "%s *%s" % (base, entity_code)
434 def type_test_code(self, py_arg):
435 return "__Pyx_TypeTest(%s, %s)" % (py_arg, self.typeptr_cname)
437 def attributes_known(self):
438 return self.scope is not None
440 def __str__(self):
441 return self.name
443 def __repr__(self):
444 return "<PyExtensionType %s%s>" % (self.scope.class_name,
445 ("", " typedef")[self.typedef_flag])
448 class CType(PyrexType):
449 #
450 # Base class for all C types (non-reference-counted).
451 #
452 # to_py_function string C function for converting to Python object
453 # from_py_function string C function for constructing from Python object
454 #
456 to_py_function = None
457 from_py_function = None
458 exception_value = None
459 exception_check = 1
461 def create_to_py_utility_code(self, env):
462 return self.to_py_function is not None
464 def create_from_py_utility_code(self, env):
465 return self.from_py_function is not None
467 def error_condition(self, result_code):
468 conds = []
469 if self.is_string:
470 conds.append("(!%s)" % result_code)
471 elif self.exception_value is not None:
472 conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
473 if self.exception_check:
474 conds.append("PyErr_Occurred()")
475 if len(conds) > 0:
476 return " && ".join(conds)
477 else:
478 return 0
481 class CVoidType(CType):
482 is_void = 1
484 def __repr__(self):
485 return "<CVoidType>"
487 def declaration_code(self, entity_code,
488 for_display = 0, dll_linkage = None, pyrex = 0):
489 base = public_decl("void", dll_linkage)
490 return self.base_declaration_code(base, entity_code)
492 def is_complete(self):
493 return 0
496 class CNumericType(CType):
497 #
498 # Base class for all C numeric types.
499 #
500 # rank integer Relative size
501 # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
502 #
504 is_numeric = 1
505 default_value = "0"
507 sign_words = ("unsigned ", "", "signed ")
509 def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
510 self.rank = rank
511 self.signed = signed
512 self.pymemberdef_typecode = pymemberdef_typecode
514 def sign_and_name(self):
515 s = self.sign_words[self.signed]
516 n = rank_to_type_name[self.rank]
517 return s + n
519 def __repr__(self):
520 return "<CNumericType %s>" % self.sign_and_name()
522 def declaration_code(self, entity_code,
523 for_display = 0, dll_linkage = None, pyrex = 0):
524 base = public_decl(self.sign_and_name(), dll_linkage)
525 if for_display:
526 base = base.replace('PY_LONG_LONG', 'long long')
527 return self.base_declaration_code(base, entity_code)
530 type_conversion_predeclarations = ""
531 type_conversion_functions = ""
533 c_int_from_py_function = UtilityCode(
534 proto="""
535 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
536 """,
537 impl="""
538 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
539 if (sizeof(%(type)s) < sizeof(long)) {
540 long val = __Pyx_PyInt_AsLong(x);
541 if (unlikely(val != (long)(%(type)s)val)) {
542 if (unlikely(val == -1 && PyErr_Occurred()))
543 return (%(type)s)-1;""" + \
544 "%(IntValSignTest)s" + \
545 """
546 PyErr_SetString(PyExc_OverflowError,
547 "value too large to convert to %(type)s");
548 return (%(type)s)-1;
549 }
550 return (%(type)s)val;
551 }
552 return (%(type)s)__Pyx_PyInt_As%(SignWord)sLong(x);
553 }
554 """)
555 intval_signtest = """
556 if (unlikely(%(var)s < 0)) {
557 PyErr_SetString(PyExc_OverflowError,
558 "can't convert negative value to %(type)s");
559 return (%(type)s)-1;
560 }"""
562 c_long_from_py_function = UtilityCode(
563 proto="""
564 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
565 """,
566 impl="""
567 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
568 #if PY_VERSION_HEX < 0x03000000
569 if (likely(PyInt_CheckExact(x) || PyInt_Check(x))) {
570 long val = PyInt_AS_LONG(x);""" + \
571 "%(IntValSignTest)s" + \
572 """
573 return (%(type)s)val;
574 } else
575 #endif
576 if (likely(PyLong_CheckExact(x) || PyLong_Check(x))) {""" +\
577 "%(PyLongSignTest)s" + \
578 """
579 return %(PyLongConvert)s(x);
580 } else {
581 %(type)s val;
582 PyObject *tmp = __Pyx_PyNumber_Int(x);
583 if (!tmp) return (%(type)s)-1;
584 val = __Pyx_PyInt_As%(SignWord)s%(TypeName)s(tmp);
585 Py_DECREF(tmp);
586 return val;
587 }
588 }
589 """)
590 pylong_signtest = """
591 if (unlikely(Py_SIZE(%(var)s) < 0)) {
592 PyErr_SetString(PyExc_OverflowError,
593 "can't convert negative value to %(type)s");
594 return (%(type)s)-1;
595 }"""
599 class CIntType(CNumericType):
601 is_int = 1
602 typedef_flag = 0
603 to_py_function = "PyInt_FromLong"
604 from_py_function = "__Pyx_PyInt_AsInt"
605 exception_value = -1
607 def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
608 CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
609 self.is_returncode = is_returncode
610 if self.from_py_function == "__Pyx_PyInt_AsInt":
611 self.from_py_function = self.get_type_conversion()
613 def get_type_conversion(self):
614 ctype = self.declaration_code('')
615 bits = ctype.split(" ", 1)
616 if len(bits) == 1:
617 sign_word, type_name = "", bits[0]
618 else:
619 sign_word, type_name = bits
620 type_name = type_name.replace("PY_LONG_LONG","long long")
621 SignWord = sign_word.title()
622 TypeName = type_name.title().replace(" ", "")
623 data = {'IntValSignTest' : "",
624 'PyLongSignTest' : "",
625 'PyLongConvert' : "",
626 }
627 if not self.signed:
628 data['IntValSignTest'] = intval_signtest % {'var':"val", 'type':ctype}
629 data['PyLongSignTest'] = pylong_signtest % {'var':"x", 'type':ctype}
630 if "Long" in TypeName:
631 data['PyLongConvert'] = \
632 "PyLong_As" + SignWord.replace("Signed", "") + TypeName
633 # the replaces below are just for generating well indented C code
634 data['IntValSignTest'] = "\n".join(
635 [ln.replace(" "*4, "", 1) for ln in data['IntValSignTest'].split('\n')]
636 )
637 utility_code = c_long_from_py_function
638 else:
639 utility_code = c_int_from_py_function
640 utility_code.specialize(self,
641 SignWord=SignWord,
642 TypeName=TypeName,
643 **data)
644 func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName)
645 return func_name
647 def assignable_from_resolved_type(self, src_type):
648 return src_type.is_int or src_type.is_enum or src_type is error_type
651 class CBIntType(CIntType):
653 to_py_function = "__Pyx_PyBool_FromLong"
654 from_py_function = "__Pyx_PyObject_IsTrue"
655 exception_check = 0
658 class CAnonEnumType(CIntType):
660 is_enum = 1
662 def sign_and_name(self):
663 return 'int'
666 class CUIntType(CIntType):
668 to_py_function = "PyLong_FromUnsignedLong"
669 exception_value = -1
672 class CLongType(CIntType):
674 to_py_function = "PyInt_FromLong"
677 class CULongType(CUIntType):
679 to_py_function = "PyLong_FromUnsignedLong"
682 class CLongLongType(CIntType):
684 to_py_function = "PyLong_FromLongLong"
687 class CULongLongType(CUIntType):
689 to_py_function = "PyLong_FromUnsignedLongLong"
692 class CPySSizeTType(CIntType):
694 to_py_function = "PyInt_FromSsize_t"
695 from_py_function = "__Pyx_PyIndex_AsSsize_t"
697 def sign_and_name(self):
698 return rank_to_type_name[self.rank]
701 class CSizeTType(CUIntType):
703 to_py_function = "__Pyx_PyInt_FromSize_t"
704 from_py_function = "__Pyx_PyInt_AsSize_t"
706 def sign_and_name(self):
707 return rank_to_type_name[self.rank]
710 class CFloatType(CNumericType):
712 is_float = 1
713 to_py_function = "PyFloat_FromDouble"
714 from_py_function = "__pyx_PyFloat_AsDouble"
716 def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''):
717 CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
718 self.math_h_modifier = math_h_modifier
720 def assignable_from_resolved_type(self, src_type):
721 return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type
724 class CComplexType(CNumericType):
726 is_complex = 1
727 to_py_function = "__pyx_PyObject_from_complex"
728 has_attributes = 1
729 scope = None
731 def __init__(self, real_type):
732 self.real_type = real_type
733 CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
734 self.binops = {}
735 self.from_parts = "%s_from_parts" % self.specalization_name()
737 def __cmp__(self, other):
738 if isinstance(self, CComplexType) and isinstance(other, CComplexType):
739 return cmp(self.real_type, other.real_type)
740 else:
741 return 1
743 def __hash__(self):
744 return ~hash(self.real_type)
746 def sign_and_name(self):
747 return Naming.type_prefix + self.real_type.specalization_name() + "_complex"
749 def assignable_from_resolved_type(self, src_type):
750 return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
751 or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type)
752 or src_type is error_type)
754 def attributes_known(self):
755 if self.scope is None:
756 import Symtab
757 self.scope = Symtab.StructOrUnionScope(self.specalization_name())
758 self.scope.declare_var("real", self.real_type, None, "real")
759 self.scope.declare_var("imag", self.real_type, None, "imag")
760 return True
762 def create_declaration_utility_code(self, env):
763 # This must always be run, because a single CComplexType instance can be shared
764 # across multiple compilations (the one created in the module scope)
765 env.use_utility_code(complex_generic_utility_code)
766 env.use_utility_code(
767 complex_arithmatic_utility_code.specialize(self,
768 math_h_modifier = self.real_type.math_h_modifier,
769 real_type = self.real_type.declaration_code('')))
770 return True
772 def create_from_py_utility_code(self, env):
773 self.real_type.create_from_py_utility_code(env)
774 env.use_utility_code(
775 complex_conversion_utility_code.specialize(self,
776 math_h_modifier = self.real_type.math_h_modifier,
777 real_type = self.real_type.declaration_code(''),
778 type_convert = self.real_type.from_py_function))
779 self.from_py_function = "__pyx_PyObject_As_" + self.specalization_name()
780 return True
782 def lookup_op(self, nargs, op):
783 try:
784 return self.binops[nargs, op]
785 except KeyError:
786 pass
787 try:
788 op_name = complex_ops[nargs, op]
789 self.binops[nargs, op] = func_name = "%s_%s" % (self.specalization_name(), op_name)
790 return func_name
791 except KeyError:
792 return None
794 def unary_op(self, op):
795 return self.lookup_op(1, op)
797 def binary_op(self, op):
798 return self.lookup_op(2, op)
800 complex_ops = {
801 (1, '-'): 'neg',
802 (1, 'zero'): 'is_zero',
803 (2, '+'): 'add',
804 (2, '-') : 'sub',
805 (2, '*'): 'mul',
806 (2, '/'): 'div',
807 (2, '=='): 'eq',
808 }
810 complex_generic_utility_code = UtilityCode(
811 proto="""
812 #if __PYX_USE_C99_COMPLEX
813 #define __Pyx_REAL_PART(z) __real__(z)
814 #define __Pyx_IMAG_PART(z) __imag__(z)
815 #else
816 #define __Pyx_REAL_PART(z) ((z).real)
817 #define __Pyx_IMAG_PART(z) ((z).imag)
818 #endif
820 #define __pyx_PyObject_from_complex(z) PyComplex_FromDoubles((double)__Pyx_REAL_PART(z), (double)__Pyx_IMAG_PART(z))
821 """)
823 complex_conversion_utility_code = UtilityCode(
824 proto="""
825 static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o); /* proto */
826 """,
827 impl="""
828 static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o) {
829 if (PyComplex_CheckExact(o)) {
830 return %(type_name)s_from_parts(
831 (%(real_type)s)((PyComplexObject *)o)->cval.real,
832 (%(real_type)s)((PyComplexObject *)o)->cval.imag);
833 }
834 else {
835 Py_complex cval = PyComplex_AsCComplex(o);
836 return %(type_name)s_from_parts((%(real_type)s)cval.real, (%(real_type)s)cval.imag);
837 }
838 }
839 """)
841 complex_arithmatic_utility_code = UtilityCode(
842 proto="""
843 #if __PYX_USE_C99_COMPLEX
845 typedef %(real_type)s _Complex %(type_name)s;
846 static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
847 return x + y*(%(type)s)_Complex_I;
848 }
850 #define %(type_name)s_is_zero(a) ((a) == 0)
851 #define %(type_name)s_eq(a, b) ((a) == (b))
852 #define %(type_name)s_add(a, b) ((a)+(b))
853 #define %(type_name)s_sub(a, b) ((a)-(b))
854 #define %(type_name)s_mul(a, b) ((a)*(b))
855 #define %(type_name)s_div(a, b) ((a)/(b))
856 #define %(type_name)s_neg(a) (-(a))
858 #else
860 typedef struct { %(real_type)s real, imag; } %(type_name)s;
861 static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
862 %(type)s c; c.real = x; c.imag = y; return c;
863 }
865 static INLINE int %(type_name)s_is_zero(%(type)s a) {
866 return (a.real == 0) & (a.imag == 0);
867 }
869 static INLINE int %(type_name)s_eq(%(type)s a, %(type)s b) {
870 return (a.real == b.real) & (a.imag == b.imag);
871 }
873 static INLINE %(type)s %(type_name)s_add(%(type)s a, %(type)s b) {
874 %(type)s z;
875 z.real = a.real + b.real;
876 z.imag = a.imag + b.imag;
877 return z;
878 }
880 static INLINE %(type)s %(type_name)s_sub(%(type)s a, %(type)s b) {
881 %(type)s z;
882 z.real = a.real - b.real;
883 z.imag = a.imag - b.imag;
884 return z;
885 }
887 static INLINE %(type)s %(type_name)s_mul(%(type)s a, %(type)s b) {
888 %(type)s z;
889 z.real = a.real * b.real - a.imag * b.imag;
890 z.imag = a.real * b.imag + a.imag * b.real;
891 return z;
892 }
894 static INLINE %(type)s %(type_name)s_div(%(type)s a, %(type)s b) {
895 %(type)s z;
896 %(real_type)s denom = b.real*b.real + b.imag*b.imag;
897 z.real = (a.real * b.real + a.imag * b.imag) / denom;
898 z.imag = (a.imag * b.real - a.real * b.imag) / denom;
899 return z;
900 }
902 static INLINE %(type)s %(type_name)s_neg(%(type)s a) {
903 %(type)s z;
904 z.real = -a.real;
905 z.imag = -a.imag;
906 return z;
907 }
909 #endif
910 """)
913 class CArrayType(CType):
914 # base_type CType Element type
915 # size integer or None Number of elements
917 is_array = 1
919 def __init__(self, base_type, size):
920 self.base_type = base_type
921 self.size = size
922 if base_type is c_char_type:
923 self.is_string = 1
925 def __repr__(self):
926 return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
928 def same_as_resolved_type(self, other_type):
929 return ((other_type.is_array and
930 self.base_type.same_as(other_type.base_type))
931 or other_type is error_type)
933 def assignable_from_resolved_type(self, src_type):
934 # Can't assign to a variable of an array type
935 return 0
937 def element_ptr_type(self):
938 return c_ptr_type(self.base_type)
940 def declaration_code(self, entity_code,
941 for_display = 0, dll_linkage = None, pyrex = 0):
942 if self.size is not None:
943 dimension_code = self.size
944 else:
945 dimension_code = ""
946 if entity_code.startswith("*"):
947 entity_code = "(%s)" % entity_code
948 return self.base_type.declaration_code(
949 "%s[%s]" % (entity_code, dimension_code),
950 for_display, dll_linkage, pyrex)
952 def as_argument_type(self):
953 return c_ptr_type(self.base_type)
955 def is_complete(self):
956 return self.size is not None
959 class CPtrType(CType):
960 # base_type CType Referenced type
962 is_ptr = 1
963 default_value = "0"
965 def __init__(self, base_type):
966 self.base_type = base_type
968 def __repr__(self):
969 return "<CPtrType %s>" % repr(self.base_type)
971 def same_as_resolved_type(self, other_type):
972 return ((other_type.is_ptr and
973 self.base_type.same_as(other_type.base_type))
974 or other_type is error_type)
976 def declaration_code(self, entity_code,
977 for_display = 0, dll_linkage = None, pyrex = 0):
978 #print "CPtrType.declaration_code: pointer to", self.base_type ###
979 return self.base_type.declaration_code(
980 "*%s" % entity_code,
981 for_display, dll_linkage, pyrex)
983 def assignable_from_resolved_type(self, other_type):
984 if other_type is error_type:
985 return 1
986 if other_type.is_null_ptr:
987 return 1
988 if self.base_type.is_cfunction:
989 if other_type.is_ptr:
990 other_type = other_type.base_type.resolve()
991 if other_type.is_cfunction:
992 return self.base_type.pointer_assignable_from_resolved_type(other_type)
993 else:
994 return 0
995 if other_type.is_array or other_type.is_ptr:
996 return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
997 return 0
1000 class CNullPtrType(CPtrType):
1002 is_null_ptr = 1
1005 class CFuncType(CType):
1006 # return_type CType
1007 # args [CFuncTypeArg]
1008 # has_varargs boolean
1009 # exception_value string
1010 # exception_check boolean True if PyErr_Occurred check needed
1011 # calling_convention string Function calling convention
1012 # nogil boolean Can be called without gil
1013 # with_gil boolean Acquire gil around function body
1015 is_cfunction = 1
1016 original_sig = None
1018 def __init__(self, return_type, args, has_varargs = 0,
1019 exception_value = None, exception_check = 0, calling_convention = "",
1020 nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0):
1021 self.return_type = return_type
1022 self.args = args
1023 self.has_varargs = has_varargs
1024 self.optional_arg_count = optional_arg_count
1025 self.exception_value = exception_value
1026 self.exception_check = exception_check
1027 self.calling_convention = calling_convention
1028 self.nogil = nogil
1029 self.with_gil = with_gil
1030 self.is_overridable = is_overridable
1032 def __repr__(self):
1033 arg_reprs = map(repr, self.args)
1034 if self.has_varargs:
1035 arg_reprs.append("...")
1036 return "<CFuncType %s %s[%s]>" % (
1037 repr(self.return_type),
1038 self.calling_convention_prefix(),
1039 ",".join(arg_reprs))
1041 def calling_convention_prefix(self):
1042 cc = self.calling_convention
1043 if cc:
1044 return cc + " "
1045 else:
1046 return ""
1048 def same_c_signature_as(self, other_type, as_cmethod = 0):
1049 return self.same_c_signature_as_resolved_type(
1050 other_type.resolve(), as_cmethod)
1052 def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
1053 #print "CFuncType.same_c_signature_as_resolved_type:", \
1054 # self, other_type, "as_cmethod =", as_cmethod ###
1055 if other_type is error_type:
1056 return 1
1057 if not other_type.is_cfunction:
1058 return 0
1059 if self.is_overridable != other_type.is_overridable:
1060 return 0
1061 nargs = len(self.args)
1062 if nargs != len(other_type.args):
1063 return 0
1064 # When comparing C method signatures, the first argument
1065 # is exempt from compatibility checking (the proper check
1066 # is performed elsewhere).
1067 for i in range(as_cmethod, nargs):
1068 if not self.args[i].type.same_as(
1069 other_type.args[i].type):
1070 return 0
1071 if self.has_varargs != other_type.has_varargs:
1072 return 0
1073 if self.optional_arg_count != other_type.optional_arg_count:
1074 return 0
1075 if not self.return_type.same_as(other_type.return_type):
1076 return 0
1077 if not self.same_calling_convention_as(other_type):
1078 return 0
1079 return 1
1081 def compatible_signature_with(self, other_type, as_cmethod = 0):
1082 return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
1084 def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
1085 #print "CFuncType.same_c_signature_as_resolved_type:", \
1086 # self, other_type, "as_cmethod =", as_cmethod ###
1087 if other_type is error_type:
1088 return 1
1089 if not other_type.is_cfunction:
1090 return 0
1091 if not self.is_overridable and other_type.is_overridable:
1092 return 0
1093 nargs = len(self.args)
1094 if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
1095 return 0
1096 if self.optional_arg_count < other_type.optional_arg_count:
1097 return 0
1098 # When comparing C method signatures, the first argument
1099 # is exempt from compatibility checking (the proper check
1100 # is performed elsewhere).
1101 for i in range(as_cmethod, len(other_type.args)):
1102 if not self.args[i].type.same_as(
1103 other_type.args[i].type):
1104 return 0
1105 if self.has_varargs != other_type.has_varargs:
1106 return 0
1107 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1108 return 0
1109 if not self.same_calling_convention_as(other_type):
1110 return 0
1111 if self.nogil != other_type.nogil:
1112 return 0
1113 self.original_sig = other_type.original_sig or other_type
1114 if as_cmethod:
1115 self.args[0] = other_type.args[0]
1116 return 1
1119 def narrower_c_signature_than(self, other_type, as_cmethod = 0):
1120 return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
1122 def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
1123 if other_type is error_type:
1124 return 1
1125 if not other_type.is_cfunction:
1126 return 0
1127 nargs = len(self.args)
1128 if nargs != len(other_type.args):
1129 return 0
1130 for i in range(as_cmethod, nargs):
1131 if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
1132 return 0
1133 else:
1134 self.args[i].needs_type_test = other_type.args[i].needs_type_test \
1135 or not self.args[i].type.same_as(other_type.args[i].type)
1136 if self.has_varargs != other_type.has_varargs:
1137 return 0
1138 if self.optional_arg_count != other_type.optional_arg_count:
1139 return 0
1140 if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1141 return 0
1142 return 1
1144 def same_calling_convention_as(self, other):
1145 ## XXX Under discussion ...
1146 ## callspec_words = ("__stdcall", "__cdecl", "__fastcall")
1147 ## cs1 = self.calling_convention
1148 ## cs2 = other.calling_convention
1149 ## if (cs1 in callspec_words or
1150 ## cs2 in callspec_words):
1151 ## return cs1 == cs2
1152 ## else:
1153 ## return True
1154 sc1 = self.calling_convention == '__stdcall'
1155 sc2 = other.calling_convention == '__stdcall'
1156 return sc1 == sc2
1158 def same_exception_signature_as(self, other_type):
1159 return self.same_exception_signature_as_resolved_type(
1160 other_type.resolve())
1162 def same_exception_signature_as_resolved_type(self, other_type):
1163 return self.exception_value == other_type.exception_value \
1164 and self.exception_check == other_type.exception_check
1166 def same_as_resolved_type(self, other_type, as_cmethod = 0):
1167 return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
1168 and self.same_exception_signature_as_resolved_type(other_type) \
1169 and self.nogil == other_type.nogil
1171 def pointer_assignable_from_resolved_type(self, other_type):
1172 return self.same_c_signature_as_resolved_type(other_type) \
1173 and self.same_exception_signature_as_resolved_type(other_type) \
1174 and not (self.nogil and not other_type.nogil)
1176 def declaration_code(self, entity_code,
1177 for_display = 0, dll_linkage = None, pyrex = 0,
1178 with_calling_convention = 1):
1179 arg_decl_list = []
1180 for arg in self.args[:len(self.args)-self.optional_arg_count]:
1181 arg_decl_list.append(
1182 arg.type.declaration_code("", for_display, pyrex = pyrex))
1183 if self.is_overridable:
1184 arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
1185 if self.optional_arg_count:
1186 arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
1187 if self.has_varargs:
1188 arg_decl_list.append("...")
1189 arg_decl_code = ", ".join(arg_decl_list)
1190 if not arg_decl_code and not pyrex:
1191 arg_decl_code = "void"
1192 trailer = ""
1193 if (pyrex or for_display) and not self.return_type.is_pyobject:
1194 if self.exception_value and self.exception_check:
1195 trailer = " except? %s" % self.exception_value
1196 elif self.exception_value:
1197 trailer = " except %s" % self.exception_value
1198 elif self.exception_check == '+':
1199 trailer = " except +"
1200 else:
1201 " except *" # ignored
1202 if self.nogil:
1203 trailer += " nogil"
1204 if not with_calling_convention:
1205 cc = ''
1206 else:
1207 cc = self.calling_convention_prefix()
1208 if (not entity_code and cc) or entity_code.startswith("*"):
1209 entity_code = "(%s%s)" % (cc, entity_code)
1210 cc = ""
1211 return self.return_type.declaration_code(
1212 "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
1213 for_display, dll_linkage, pyrex)
1215 def function_header_code(self, func_name, arg_code):
1216 return "%s%s(%s)" % (self.calling_convention_prefix(),
1217 func_name, arg_code)
1219 def signature_string(self):
1220 s = self.declaration_code("")
1221 return s
1223 def signature_cast_string(self):
1224 s = self.declaration_code("(*)", with_calling_convention=False)
1225 return '(%s)' % s
1228 class CFuncTypeArg(object):
1229 # name string
1230 # cname string
1231 # type PyrexType
1232 # pos source file position
1234 def __init__(self, name, type, pos, cname=None):
1235 self.name = name
1236 if cname is not None:
1237 self.cname = cname
1238 else:
1239 self.cname = Naming.var_prefix + name
1240 self.type = type
1241 self.pos = pos
1242 self.not_none = False
1243 self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
1245 def __repr__(self):
1246 return "%s:%s" % (self.name, repr(self.type))
1248 def declaration_code(self, for_display = 0):
1249 return self.type.declaration_code(self.cname, for_display)
1252 class CStructOrUnionType(CType):
1253 # name string
1254 # cname string
1255 # kind string "struct" or "union"
1256 # scope StructOrUnionScope, or None if incomplete
1257 # typedef_flag boolean
1258 # packed boolean
1260 is_struct_or_union = 1
1261 has_attributes = 1
1263 def __init__(self, name, kind, scope, typedef_flag, cname, packed=False):
1264 self.name = name
1265 self.cname = cname
1266 self.kind = kind
1267 self.scope = scope
1268 self.typedef_flag = typedef_flag
1269 self.is_struct = kind == 'struct'
1270 if self.is_struct:
1271 self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
1272 self.exception_check = True
1273 self._convert_code = None
1274 self.packed = packed
1276 def create_to_py_utility_code(self, env):
1277 if env.outer_scope is None:
1278 return False
1279 if self._convert_code is None:
1280 import Code
1281 code = Code.CCodeWriter()
1282 Code.GlobalState(code)
1283 header = "static PyObject* %s(%s)" % (self.to_py_function, self.declaration_code('s'))
1284 code.putln("%s {" % header)
1285 code.putln("PyObject* res;")
1286 code.putln("PyObject* member;")
1287 code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
1288 for member in self.scope.var_entries:
1289 if member.type.to_py_function and member.type.create_to_py_utility_code(env):
1290 interned_name = env.get_string_const(member.name, identifier=True)
1291 env.add_py_string(interned_name)
1292 code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
1293 member.type.to_py_function, member.cname))
1294 code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % interned_name.pystring_cname)
1295 code.putln("Py_DECREF(member);")
1296 else:
1297 self.to_py_function = None
1298 return False
1299 code.putln("return res;")
1300 code.putln("bad:")
1301 code.putln("Py_XDECREF(member);")
1302 code.putln("Py_DECREF(res);")
1303 code.putln("return NULL;")
1304 code.putln("}")
1305 proto = header + ";"
1306 # This is a bit of a hack, we need a forward declaration
1307 # due to the way things are ordered in the module...
1308 entry = env.lookup(self.name)
1309 if entry.visibility != 'extern':
1310 proto = self.declaration_code('') + ';\n' + proto
1311 self._convert_code = UtilityCode(proto=proto, impl=code.buffer.getvalue())
1313 env.use_utility_code(self._convert_code)
1314 return True
1316 def __repr__(self):
1317 return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
1318 ("", " typedef")[self.typedef_flag])
1320 def declaration_code(self, entity_code,
1321 for_display = 0, dll_linkage = None, pyrex = 0):
1322 if pyrex:
1323 return self.base_declaration_code(self.name, entity_code)
1324 else:
1325 if for_display:
1326 base = self.name
1327 elif self.typedef_flag:
1328 base = self.cname
1329 else:
1330 base = "%s %s" % (self.kind, self.cname)
1331 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1333 def __cmp__(self, other):
1334 try:
1335 if self.name == other.name:
1336 return 0
1337 else:
1338 return 1
1339 except AttributeError:
1340 return 1
1342 def is_complete(self):
1343 return self.scope is not None
1345 def attributes_known(self):
1346 return self.is_complete()
1348 def can_be_complex(self):
1349 # Does the struct consist of exactly two identical floats?
1350 fields = self.scope.var_entries
1351 if len(fields) != 2: return False
1352 a, b = fields
1353 return (a.type.is_float and b.type.is_float and
1354 a.type.declaration_code("") ==
1355 b.type.declaration_code(""))
1357 def struct_nesting_depth(self):
1358 child_depths = [x.type.struct_nesting_depth()
1359 for x in self.scope.var_entries]
1360 return max(child_depths) + 1
1362 class CEnumType(CType):
1363 # name string
1364 # cname string or None
1365 # typedef_flag boolean
1367 is_enum = 1
1368 signed = 1
1369 rank = -1 # Ranks below any integer type
1370 to_py_function = "PyInt_FromLong"
1371 from_py_function = "PyInt_AsLong"
1373 def __init__(self, name, cname, typedef_flag):
1374 self.name = name
1375 self.cname = cname
1376 self.values = []
1377 self.typedef_flag = typedef_flag
1379 def __str__(self):
1380 return self.name
1382 def __repr__(self):
1383 return "<CEnumType %s %s%s>" % (self.name, self.cname,
1384 ("", " typedef")[self.typedef_flag])
1386 def declaration_code(self, entity_code,
1387 for_display = 0, dll_linkage = None, pyrex = 0):
1388 if pyrex:
1389 return self.base_declaration_code(self.cname, entity_code)
1390 else:
1391 if self.typedef_flag:
1392 base = self.cname
1393 else:
1394 base = "enum %s" % self.cname
1395 return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1398 class CStringType(object):
1399 # Mixin class for C string types.
1401 is_string = 1
1402 is_unicode = 0
1404 to_py_function = "__Pyx_PyBytes_FromString"
1405 from_py_function = "__Pyx_PyBytes_AsString"
1406 exception_value = "NULL"
1408 def literal_code(self, value):
1409 assert isinstance(value, str)
1410 return '"%s"' % StringEncoding.escape_byte_string(value)
1413 class CUTF8CharArrayType(CStringType, CArrayType):
1414 # C 'char []' type.
1416 pymemberdef_typecode = "T_STRING_INPLACE"
1417 is_unicode = 1
1419 to_py_function = "PyUnicode_DecodeUTF8"
1420 exception_value = "NULL"
1422 def __init__(self, size):
1423 CArrayType.__init__(self, c_char_type, size)
1425 class CCharArrayType(CStringType, CArrayType):
1426 # C 'char []' type.
1428 pymemberdef_typecode = "T_STRING_INPLACE"
1430 def __init__(self, size):
1431 CArrayType.__init__(self, c_char_type, size)
1434 class CCharPtrType(CStringType, CPtrType):
1435 # C 'char *' type.
1437 pymemberdef_typecode = "T_STRING"
1439 def __init__(self):
1440 CPtrType.__init__(self, c_char_type)
1443 class UnspecifiedType(PyrexType):
1444 # Used as a placeholder until the type can be determined.
1446 def declaration_code(self, entity_code,
1447 for_display = 0, dll_linkage = None, pyrex = 0):
1448 return "<unspecified>"
1450 def same_as_resolved_type(self, other_type):
1451 return False
1454 class ErrorType(PyrexType):
1455 # Used to prevent propagation of error messages.
1457 is_error = 1
1458 exception_value = "0"
1459 exception_check = 0
1460 to_py_function = "dummy"
1461 from_py_function = "dummy"
1463 def create_to_py_utility_code(self, env):
1464 return True
1466 def create_from_py_utility_code(self, env):
1467 return True
1469 def declaration_code(self, entity_code,
1470 for_display = 0, dll_linkage = None, pyrex = 0):
1471 return "<error>"
1473 def same_as_resolved_type(self, other_type):
1474 return 1
1476 def error_condition(self, result_code):
1477 return "dummy"
1480 rank_to_type_name = (
1481 "char", # 0
1482 "short", # 1
1483 "int", # 2
1484 "long", # 3
1485 "Py_ssize_t", # 4
1486 "size_t", # 5
1487 "PY_LONG_LONG", # 6
1488 "float", # 7
1489 "double", # 8
1490 "long double", # 9
1491 )
1493 py_object_type = PyObjectType()
1495 c_void_type = CVoidType()
1496 c_void_ptr_type = CPtrType(c_void_type)
1497 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
1499 c_uchar_type = CIntType(0, 0, "T_UBYTE")
1500 c_ushort_type = CIntType(1, 0, "T_USHORT")
1501 c_uint_type = CUIntType(2, 0, "T_UINT")
1502 c_ulong_type = CULongType(3, 0, "T_ULONG")
1503 c_ulonglong_type = CULongLongType(6, 0, "T_ULONGLONG")
1505 c_char_type = CIntType(0, 1, "T_CHAR")
1506 c_short_type = CIntType(1, 1, "T_SHORT")
1507 c_int_type = CIntType(2, 1, "T_INT")
1508 c_long_type = CLongType(3, 1, "T_LONG")
1509 c_longlong_type = CLongLongType(6, 1, "T_LONGLONG")
1510 c_bint_type = CBIntType(2, 1, "T_INT")
1512 c_schar_type = CIntType(0, 2, "T_CHAR")
1513 c_sshort_type = CIntType(1, 2, "T_SHORT")
1514 c_sint_type = CIntType(2, 2, "T_INT")
1515 c_slong_type = CLongType(3, 2, "T_LONG")
1516 c_slonglong_type = CLongLongType(6, 2, "T_LONGLONG")
1518 c_py_ssize_t_type = CPySSizeTType(4, 2, "T_PYSSIZET")
1519 c_size_t_type = CSizeTType(5, 0, "T_SIZET")
1521 c_float_type = CFloatType(7, "T_FLOAT", math_h_modifier='f')
1522 c_double_type = CFloatType(8, "T_DOUBLE")
1523 c_longdouble_type = CFloatType(9, math_h_modifier='l')
1525 c_double_complex_type = CComplexType(c_double_type)
1527 c_null_ptr_type = CNullPtrType(c_void_type)
1528 c_char_array_type = CCharArrayType(None)
1529 c_char_ptr_type = CCharPtrType()
1530 c_utf8_char_array_type = CUTF8CharArrayType(None)
1531 c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
1532 c_int_ptr_type = CPtrType(c_int_type)
1533 c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
1534 c_size_t_ptr_type = CPtrType(c_size_t_type)
1536 c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1)
1538 c_anon_enum_type = CAnonEnumType(-1, 1)
1540 # the Py_buffer type is defined in Builtin.py
1541 c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
1542 c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
1544 error_type = ErrorType()
1545 unspecified_type = UnspecifiedType()
1547 sign_and_rank_to_type = {
1548 #(signed, rank)
1549 (0, 0): c_uchar_type,
1550 (0, 1): c_ushort_type,
1551 (0, 2): c_uint_type,
1552 (0, 3): c_ulong_type,
1553 (0, 6): c_ulonglong_type,
1555 (1, 0): c_char_type,
1556 (1, 1): c_short_type,
1557 (1, 2): c_int_type,
1558 (1, 3): c_long_type,
1559 (1, 6): c_longlong_type,
1561 (2, 0): c_schar_type,
1562 (2, 1): c_sshort_type,
1563 (2, 2): c_sint_type,
1564 (2, 3): c_slong_type,
1565 (2, 6): c_slonglong_type,
1567 (0, 4): c_py_ssize_t_type,
1568 (1, 4): c_py_ssize_t_type,
1569 (2, 4): c_py_ssize_t_type,
1570 (0, 5): c_size_t_type,
1571 (1, 5): c_size_t_type,
1572 (2, 5): c_size_t_type,
1574 (1, 7): c_float_type,
1575 (1, 8): c_double_type,
1576 (1, 9): c_longdouble_type,
1577 # In case we're mixing unsigned ints and floats...
1578 (0, 7): c_float_type,
1579 (0, 8): c_double_type,
1580 (0, 9): c_longdouble_type,
1581 }
1583 modifiers_and_name_to_type = {
1584 #(signed, longness, name)
1585 (0, 0, "char"): c_uchar_type,
1586 (0, -1, "int"): c_ushort_type,
1587 (0, 0, "int"): c_uint_type,
1588 (0, 1, "int"): c_ulong_type,
1589 (0, 2, "int"): c_ulonglong_type,
1590 (1, 0, "void"): c_void_type,
1591 (1, 0, "char"): c_char_type,
1592 (1, -1, "int"): c_short_type,
1593 (1, 0, "int"): c_int_type,
1594 (1, 1, "int"): c_long_type,
1595 (1, 2, "int"): c_longlong_type,
1596 (1, 0, "float"): c_float_type,
1597 (1, 0, "double"): c_double_type,
1598 (1, 1, "double"): c_longdouble_type,
1599 (1, 0, "object"): py_object_type,
1600 (1, 0, "bint"): c_bint_type,
1601 (2, 0, "char"): c_schar_type,
1602 (2, -1, "int"): c_sshort_type,
1603 (2, 0, "int"): c_sint_type,
1604 (2, 1, "int"): c_slong_type,
1605 (2, 2, "int"): c_slonglong_type,
1607 (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
1608 (0, 0, "size_t") : c_size_t_type,
1610 (1, 0, "long"): c_long_type,
1611 (1, 0, "short"): c_short_type,
1612 (1, 0, "longlong"): c_longlong_type,
1613 (1, 0, "bint"): c_bint_type,
1614 }
1616 def widest_numeric_type(type1, type2):
1617 # Given two numeric types, return the narrowest type
1618 # encompassing both of them.
1619 if type1 == type2:
1620 return type1
1621 if type1.is_complex:
1622 if type2.is_complex:
1623 return CComplexType(widest_numeric_type(type1.real_type, type2.real_type))
1624 else:
1625 return CComplexType(widest_numeric_type(type1.real_type, type2))
1626 elif type2.is_complex:
1627 return CComplexType(widest_numeric_type(type1, type2.real_type))
1628 if type1.is_enum and type2.is_enum:
1629 return c_int_type
1630 elif type1 is type2:
1631 return type1
1632 elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
1633 if type2.rank > type1.rank:
1634 return type2
1635 else:
1636 return type1
1637 else:
1638 return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
1639 return widest_type
1641 def simple_c_type(signed, longness, name):
1642 # Find type descriptor for simple type given name and modifiers.
1643 # Returns None if arguments don't make sense.
1644 return modifiers_and_name_to_type.get((signed, longness, name))
1646 def parse_basic_type(name):
1647 base = None
1648 if name.startswith('p_'):
1649 base = parse_basic_type(name[2:])
1650 elif name.startswith('p'):
1651 base = parse_basic_type(name[1:])
1652 elif name.endswith('*'):
1653 base = parse_basic_type(name[:-1])
1654 if base:
1655 return CPtrType(base)
1656 elif name.startswith('u'):
1657 return simple_c_type(0, 0, name[1:])
1658 else:
1659 return simple_c_type(1, 0, name)
1661 def c_array_type(base_type, size):
1662 # Construct a C array type.
1663 if base_type is c_char_type:
1664 return CCharArrayType(size)
1665 elif base_type is error_type:
1666 return error_type
1667 else:
1668 return CArrayType(base_type, size)
1670 def c_ptr_type(base_type):
1671 # Construct a C pointer type.
1672 if base_type is c_char_type:
1673 return c_char_ptr_type
1674 elif base_type is error_type:
1675 return error_type
1676 else:
1677 return CPtrType(base_type)
1679 def Node_to_type(node, env):
1680 from ExprNodes import NameNode, AttributeNode, StringNode, error
1681 if isinstance(node, StringNode):
1682 node = NameNode(node.pos, name=node.value)
1683 if isinstance(node, NameNode) and node.name in rank_to_type_name:
1684 return simple_c_type(1, 0, node.name)
1685 elif isinstance(node, (AttributeNode, NameNode)):
1686 node.analyze_types(env)
1687 if not node.entry.is_type:
1688 pass
1689 else:
1690 error(node.pos, "Bad type")
1692 def same_type(type1, type2):
1693 return type1.same_as(type2)
1695 def assignable_from(type1, type2):
1696 return type1.assignable_from(type2)
1698 def typecast(to_type, from_type, expr_code):
1699 # Return expr_code cast to a C type which can be
1700 # assigned to to_type, assuming its existing C type
1701 # is from_type.
1702 if to_type is from_type or \
1703 (not to_type.is_pyobject and assignable_from(to_type, from_type)):
1704 return expr_code
1705 else:
1706 #print "typecast: to", to_type, "from", from_type ###
1707 return to_type.cast_code(expr_code)
1710 type_conversion_predeclarations = """
1711 /* Type Conversion Predeclarations */
1713 #if PY_MAJOR_VERSION < 3
1714 #define __Pyx_PyBytes_FromString PyString_FromString
1715 #define __Pyx_PyBytes_FromStringAndSize PyString_FromStringAndSize
1716 #define __Pyx_PyBytes_AsString PyString_AsString
1717 #else
1718 #define __Pyx_PyBytes_FromString PyBytes_FromString
1719 #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
1720 #define __Pyx_PyBytes_AsString PyBytes_AsString
1721 #endif
1723 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
1724 static INLINE int __Pyx_PyObject_IsTrue(PyObject*);
1725 static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
1727 #if !defined(T_PYSSIZET)
1728 #if PY_VERSION_HEX < 0x02050000
1729 #define T_PYSSIZET T_INT
1730 #elif !defined(T_LONGLONG)
1731 #define T_PYSSIZET \\
1732 ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
1733 ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1))
1734 #else
1735 #define T_PYSSIZET \\
1736 ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\
1737 ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : \\
1738 ((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))
1739 #endif
1740 #endif
1743 #if !defined(T_ULONGLONG)
1744 #define __Pyx_T_UNSIGNED_INT(x) \\
1745 ((sizeof(x) == sizeof(unsigned char)) ? T_UBYTE : \\
1746 ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
1747 ((sizeof(x) == sizeof(unsigned int)) ? T_UINT : \\
1748 ((sizeof(x) == sizeof(unsigned long)) ? T_ULONG : -1))))
1749 #else
1750 #define __Pyx_T_UNSIGNED_INT(x) \\
1751 ((sizeof(x) == sizeof(unsigned char)) ? T_UBYTE : \\
1752 ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
1753 ((sizeof(x) == sizeof(unsigned int)) ? T_UINT : \\
1754 ((sizeof(x) == sizeof(unsigned long)) ? T_ULONG : \\
1755 ((sizeof(x) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))))
1756 #endif
1757 #if !defined(T_LONGLONG)
1758 #define __Pyx_T_SIGNED_INT(x) \\
1759 ((sizeof(x) == sizeof(char)) ? T_BYTE : \\
1760 ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
1761 ((sizeof(x) == sizeof(int)) ? T_INT : \\
1762 ((sizeof(x) == sizeof(long)) ? T_LONG : -1))))
1763 #else
1764 #define __Pyx_T_SIGNED_INT(x) \\
1765 ((sizeof(x) == sizeof(char)) ? T_BYTE : \\
1766 ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
1767 ((sizeof(x) == sizeof(int)) ? T_INT : \\
1768 ((sizeof(x) == sizeof(long)) ? T_LONG : \\
1769 ((sizeof(x) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))))
1770 #endif
1772 #define __Pyx_T_FLOATING(x) \\
1773 ((sizeof(x) == sizeof(float)) ? T_FLOAT : \\
1774 ((sizeof(x) == sizeof(double)) ? T_DOUBLE : -1))
1776 #if !defined(T_SIZET)
1777 #if !defined(T_ULONGLONG)
1778 #define T_SIZET \\
1779 ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
1780 ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1))
1781 #else
1782 #define T_SIZET \\
1783 ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\
1784 ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : \\
1785 ((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))
1786 #endif
1787 #endif
1789 static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
1790 static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
1791 static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
1793 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
1795 """ + type_conversion_predeclarations
1797 type_conversion_functions = """
1798 /* Type Conversion Functions */
1800 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
1801 if (x == Py_True) return 1;
1802 else if ((x == Py_False) | (x == Py_None)) return 0;
1803 else return PyObject_IsTrue(x);
1804 }
1806 static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
1807 PyNumberMethods *m;
1808 const char *name = NULL;
1809 PyObject *res = NULL;
1810 #if PY_VERSION_HEX < 0x03000000
1811 if (PyInt_Check(x) || PyLong_Check(x))
1812 #else
1813 if (PyLong_Check(x))
1814 #endif
1815 return Py_INCREF(x), x;
1816 m = Py_TYPE(x)->tp_as_number;
1817 #if PY_VERSION_HEX < 0x03000000
1818 if (m && m->nb_int) {
1819 name = "int";
1820 res = PyNumber_Int(x);
1821 }
1822 else if (m && m->nb_long) {
1823 name = "long";
1824 res = PyNumber_Long(x);
1825 }
1826 #else
1827 if (m && m->nb_int) {
1828 name = "int";
1829 res = PyNumber_Long(x);
1830 }
1831 #endif
1832 if (res) {
1833 #if PY_VERSION_HEX < 0x03000000
1834 if (!PyInt_Check(res) && !PyLong_Check(res)) {
1835 #else
1836 if (!PyLong_Check(res)) {
1837 #endif
1838 PyErr_Format(PyExc_TypeError,
1839 "__%s__ returned non-%s (type %.200s)",
1840 name, name, Py_TYPE(res)->tp_name);
1841 Py_DECREF(res);
1842 return NULL;
1843 }
1844 }
1845 else if (!PyErr_Occurred()) {
1846 PyErr_SetString(PyExc_TypeError,
1847 "an integer is required");
1848 }
1849 return res;
1850 }
1852 static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
1853 Py_ssize_t ival;
1854 PyObject* x = PyNumber_Index(b);
1855 if (!x) return -1;
1856 ival = PyInt_AsSsize_t(x);
1857 Py_DECREF(x);
1858 return ival;
1859 }
1861 static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
1862 #if PY_VERSION_HEX < 0x02050000
1863 if (ival <= LONG_MAX)
1864 return PyInt_FromLong((long)ival);
1865 else {
1866 unsigned char *bytes = (unsigned char *) &ival;
1867 int one = 1; int little = (int)*(unsigned char*)&one;
1868 return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
1869 }
1870 #else
1871 return PyInt_FromSize_t(ival);
1872 #endif
1873 }
1875 static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
1876 unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
1877 if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
1878 return (size_t)-1;
1879 } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
1880 PyErr_SetString(PyExc_OverflowError,
1881 "value too large to convert to size_t");
1882 return (size_t)-1;
1883 }
1884 return (size_t)val;
1885 }
1887 """ + type_conversion_functions
