merged in latest cython-release
[cython.git] / Cython / Compiler / Nodes.py
1
2 #
3 #   Pyrex - Parse tree nodes
4 #
5
6 import sys, os, time, copy
7
8 try:
9     set
10 except NameError:
11     # Python 2.3
12     from sets import Set as set
13
14 import Code
15 import Builtin
16 from Errors import error, warning, InternalError
17 import Naming
18 import PyrexTypes
19 import TypeSlots
20 from PyrexTypes import py_object_type, error_type, CFuncType
21 from Symtab import ModuleScope, LocalScope, ClosureScope, \
22     StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
23 from Cython.Utils import open_new_file, replace_suffix
24 from Code import UtilityCode
25 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
26 import Options
27 import ControlFlow
28 import DebugFlags
29
30 absolute_path_length = 0
31
32 def relative_position(pos):
33     """
34     We embed the relative filename in the generated C file, since we
35     don't want to have to regnerate and compile all the source code
36     whenever the Python install directory moves (which could happen,
37     e.g,. when distributing binaries.)
38     
39     INPUT:
40         a position tuple -- (absolute filename, line number column position)
41
42     OUTPUT:
43         relative filename
44         line number
45
46     AUTHOR: William Stein
47     """
48     global absolute_path_length
49     if absolute_path_length==0:
50         absolute_path_length = len(os.path.abspath(os.getcwd())) 
51     return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
52
53 def embed_position(pos, docstring):
54     if not Options.embed_pos_in_docstring:
55         return docstring
56     pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
57     if docstring is None:
58         # unicode string
59         return EncodedString(pos_line)
60
61     # make sure we can encode the filename in the docstring encoding
62     # otherwise make the docstring a unicode string
63     encoding = docstring.encoding
64     if encoding is not None:
65         try:
66             encoded_bytes = pos_line.encode(encoding)
67         except UnicodeEncodeError:
68             encoding = None
69
70     if not docstring:
71         # reuse the string encoding of the original docstring
72         doc = EncodedString(pos_line)
73     else:
74         doc = EncodedString(pos_line + u'\n' + docstring)
75     doc.encoding = encoding
76     return doc
77
78
79 from Code import CCodeWriter
80 from types import FunctionType
81
82 def write_func_call(func):
83     def f(*args, **kwds):
84         if len(args) > 1 and isinstance(args[1], CCodeWriter):
85             # here we annotate the code with this function call
86             # but only if new code is generated
87             node, code = args[:2]
88             marker = '                    /* %s -> %s.%s %s */' % (
89                     ' ' * code.call_level,
90                     node.__class__.__name__, 
91                     func.__name__, 
92                     node.pos[1:])
93             pristine = code.buffer.stream.tell()
94             code.putln(marker)
95             start = code.buffer.stream.tell()
96             code.call_level += 4
97             res = func(*args, **kwds)
98             code.call_level -= 4
99             if start == code.buffer.stream.tell():
100                 code.buffer.stream.seek(pristine)
101             else:
102                 marker = marker.replace('->', '<-')
103                 code.putln(marker)
104             return res
105         else:
106             return func(*args, **kwds)
107     return f
108
109 class VerboseCodeWriter(type):
110     # Set this as a metaclass to trace function calls in code.
111     # This slows down code generation and makes much larger files. 
112     def __new__(cls, name, bases, attrs):
113         attrs = dict(attrs)
114         for mname, m in attrs.items():
115             if isinstance(m, FunctionType):
116                 attrs[mname] = write_func_call(m)
117         return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
118
119
120 class Node(object):
121     #  pos         (string, int, int)   Source file position
122     #  is_name     boolean              Is a NameNode
123     #  is_literal  boolean              Is a ConstNode
124
125     if DebugFlags.debug_trace_code_generation:
126         __metaclass__ = VerboseCodeWriter
127     
128     is_name = 0
129     is_literal = 0
130     temps = None
131
132     # All descandants should set child_attrs to a list of the attributes
133     # containing nodes considered "children" in the tree. Each such attribute
134     # can either contain a single node or a list of nodes. See Visitor.py.
135     child_attrs = None
136     
137     def __init__(self, pos, **kw):
138         self.pos = pos
139         self.__dict__.update(kw)
140     
141     gil_message = "Operation"
142
143     nogil_check = None
144
145     def gil_error(self, env=None):
146         error(self.pos, "%s not allowed without gil" % self.gil_message)
147     
148     cpp_message = "Operation"
149     
150     def cpp_check(self, env):
151         if not env.is_cpp():
152             self.cpp_error()
153
154     def cpp_error(self):
155         error(self.pos, "%s only allowed in c++" % self.cpp_message)
156
157     def clone_node(self):
158         """Clone the node. This is defined as a shallow copy, except for member lists
159            amongst the child attributes (from get_child_accessors) which are also
160            copied. Lists containing child nodes are thus seen as a way for the node
161            to hold multiple children directly; the list is not treated as a seperate
162            level in the tree."""
163         result = copy.copy(self)
164         for attrname in result.child_attrs:
165             value = getattr(result, attrname)
166             if isinstance(value, list):
167                 setattr(result, attrname, [x for x in value])
168         return result
169     
170     
171     #
172     #  There are 4 phases of parse tree processing, applied in order to
173     #  all the statements in a given scope-block:
174     #
175     #  (0) analyse_control_flow
176     #        Create the control flow tree into which state can be asserted and
177     #        queried.
178     #
179     #  (1) analyse_declarations
180     #        Make symbol table entries for all declarations at the current
181     #        level, both explicit (def, cdef, etc.) and implicit (assignment
182     #        to an otherwise undeclared name).
183     #
184     #  (2) analyse_expressions
185     #         Determine the result types of expressions and fill in the
186     #         'type' attribute of each ExprNode. Insert coercion nodes into the
187     #         tree where needed to convert to and from Python objects. 
188     #         Allocate temporary locals for intermediate results. Fill
189     #         in the 'result_code' attribute of each ExprNode with a C code
190     #         fragment.
191     #
192     #  (3) generate_code
193     #         Emit C code for all declarations, statements and expressions.
194     #         Recursively applies the 3 processing phases to the bodies of
195     #         functions.
196     #
197     
198     def analyse_control_flow(self, env):
199         pass
200     
201     def analyse_declarations(self, env):
202         pass
203     
204     def analyse_expressions(self, env):
205         raise InternalError("analyse_expressions not implemented for %s" % \
206             self.__class__.__name__)
207     
208     def generate_code(self, code):
209         raise InternalError("generate_code not implemented for %s" % \
210             self.__class__.__name__)
211             
212     def annotate(self, code):
213         # mro does the wrong thing
214         if isinstance(self, BlockNode):
215             self.body.annotate(code)
216             
217     def end_pos(self):
218         try:
219             return self._end_pos
220         except AttributeError:
221             pos = self.pos
222             if not self.child_attrs:
223                 self._end_pos = pos
224                 return pos
225             for attr in self.child_attrs:
226                 child = getattr(self, attr)
227                 # Sometimes lists, sometimes nodes
228                 if child is None:
229                     pass
230                 elif isinstance(child, list):
231                     for c in child:
232                         pos = max(pos, c.end_pos())
233                 else:
234                     pos = max(pos, child.end_pos())
235             self._end_pos = pos
236             return pos
237
238     def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
239         if cutoff == 0:
240             return "<...nesting level cutoff...>"
241         if encountered is None:
242             encountered = set()
243         if id(self) in encountered:
244             return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
245         encountered.add(id(self))
246         
247         def dump_child(x, level):
248             if isinstance(x, Node):
249                 return x.dump(level, filter_out, cutoff-1, encountered)
250             elif isinstance(x, list):
251                 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
252             else:
253                 return repr(x)
254             
255         
256         attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
257         if len(attrs) == 0:
258             return "<%s (%d)>" % (self.__class__.__name__, id(self))
259         else:
260             indent = "  " * level
261             res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
262             for key, value in attrs:
263                 res += "%s  %s: %s\n" % (indent, key, dump_child(value, level + 1))
264             res += "%s>" % indent
265             return res
266
267 class CompilerDirectivesNode(Node):
268     """
269     Sets compiler directives for the children nodes
270     """
271     #  directives     {string:value}  A dictionary holding the right value for
272     #                                 *all* possible directives.
273     #  body           Node
274     child_attrs = ["body"]
275
276     def analyse_control_flow(self, env):
277         old = env.directives
278         env.directives = self.directives
279         self.body.analyse_control_flow(env)
280         env.directives = old
281
282     def analyse_declarations(self, env):
283         old = env.directives
284         env.directives = self.directives
285         self.body.analyse_declarations(env)
286         env.directives = old
287     
288     def analyse_expressions(self, env):
289         old = env.directives
290         env.directives = self.directives
291         self.body.analyse_expressions(env)
292         env.directives = old
293
294     def generate_function_definitions(self, env, code):
295         env_old = env.directives
296         code_old = code.globalstate.directives
297         code.globalstate.directives = self.directives
298         self.body.generate_function_definitions(env, code)
299         env.directives = env_old
300         code.globalstate.directives = code_old
301             
302     def generate_execution_code(self, code):
303         old = code.globalstate.directives
304         code.globalstate.directives = self.directives
305         self.body.generate_execution_code(code)
306         code.globalstate.directives = old
307             
308     def annotate(self, code):
309         old = code.globalstate.directives
310         code.globalstate.directives = self.directives
311         self.body.annotate(code)
312         code.globalstate.directives = old
313         
314 class BlockNode(object):
315     #  Mixin class for nodes representing a declaration block.
316
317     def generate_cached_builtins_decls(self, env, code):
318         entries = env.global_scope().undeclared_cached_builtins
319         for entry in entries:
320             code.globalstate.add_cached_builtin_decl(entry)
321         del entries[:]
322         
323
324 class StatListNode(Node):
325     # stats     a list of StatNode
326     
327     child_attrs = ["stats"]
328
329     def create_analysed(pos, env, *args, **kw):
330         node = StatListNode(pos, *args, **kw)
331         return node # No node-specific analysis necesarry
332     create_analysed = staticmethod(create_analysed)
333     
334     def analyse_control_flow(self, env):
335         for stat in self.stats:
336             stat.analyse_control_flow(env)
337
338     def analyse_declarations(self, env):
339         #print "StatListNode.analyse_declarations" ###
340         for stat in self.stats:
341             stat.analyse_declarations(env)
342     
343     def analyse_expressions(self, env):
344         #print "StatListNode.analyse_expressions" ###
345         for stat in self.stats:
346             stat.analyse_expressions(env)
347     
348     def generate_function_definitions(self, env, code):
349         #print "StatListNode.generate_function_definitions" ###
350         for stat in self.stats:
351             stat.generate_function_definitions(env, code)
352             
353     def generate_execution_code(self, code):
354         #print "StatListNode.generate_execution_code" ###
355         for stat in self.stats:
356             code.mark_pos(stat.pos)
357             stat.generate_execution_code(code)
358             
359     def annotate(self, code):
360         for stat in self.stats:
361             stat.annotate(code)
362     
363
364 class StatNode(Node):
365     #
366     #  Code generation for statements is split into the following subphases:
367     #
368     #  (1) generate_function_definitions
369     #        Emit C code for the definitions of any structs,
370     #        unions, enums and functions defined in the current
371     #        scope-block.
372     #
373     #  (2) generate_execution_code
374     #        Emit C code for executable statements.
375     #
376     
377     def generate_function_definitions(self, env, code):
378         pass
379     
380     def generate_execution_code(self, code):
381         raise InternalError("generate_execution_code not implemented for %s" % \
382             self.__class__.__name__)
383
384
385 class CDefExternNode(StatNode):
386     #  include_file   string or None
387     #  body           StatNode
388     
389     child_attrs = ["body"]
390     
391     def analyse_declarations(self, env):
392         if self.include_file:
393             env.add_include_file(self.include_file)
394         old_cinclude_flag = env.in_cinclude
395         env.in_cinclude = 1
396         self.body.analyse_declarations(env)
397         env.in_cinclude = old_cinclude_flag
398     
399     def analyse_expressions(self, env):
400         pass
401     
402     def generate_execution_code(self, code):
403         pass
404
405     def annotate(self, code):
406         self.body.annotate(code)
407         
408
409 class CDeclaratorNode(Node):
410     # Part of a C declaration.
411     #
412     # Processing during analyse_declarations phase:
413     #
414     #   analyse
415     #      Returns (name, type) pair where name is the
416     #      CNameDeclaratorNode of the name being declared 
417     #      and type is the type it is being declared as.
418     #
419     #  calling_convention  string   Calling convention of CFuncDeclaratorNode
420     #                               for which this is a base 
421
422     child_attrs = []
423
424     calling_convention = ""
425
426
427 class CNameDeclaratorNode(CDeclaratorNode):
428     #  name    string             The Pyrex name being declared
429     #  cname   string or None     C name, if specified
430     #  default ExprNode or None   the value assigned on declaration
431     
432     child_attrs = ['default']
433     
434     default = None
435     
436     def analyse(self, base_type, env, nonempty = 0):
437         if nonempty and self.name == '':
438             # May have mistaken the name for the type. 
439             if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
440                 error(self.pos, "Missing argument name")
441             elif base_type.is_void:
442                 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
443             else:
444                 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
445                 base_type = py_object_type
446         self.type = base_type
447         return self, base_type
448         
449 class CPtrDeclaratorNode(CDeclaratorNode):
450     # base     CDeclaratorNode
451     
452     child_attrs = ["base"]
453
454     def analyse(self, base_type, env, nonempty = 0):
455         if base_type.is_pyobject:
456             error(self.pos,
457                 "Pointer base type cannot be a Python object")
458         ptr_type = PyrexTypes.c_ptr_type(base_type)
459         return self.base.analyse(ptr_type, env, nonempty = nonempty)
460
461 class CReferenceDeclaratorNode(CDeclaratorNode):
462     # base     CDeclaratorNode
463
464     child_attrs = ["base"]
465
466     def analyse(self, base_type, env, nonempty = 0):
467         if base_type.is_pyobject:
468             error(self.pos,
469                   "Reference base type cannot be a Python object")
470         ref_type = PyrexTypes.c_ref_type(base_type)
471         return self.base.analyse(ref_type, env, nonempty = nonempty)
472
473 class CArrayDeclaratorNode(CDeclaratorNode):
474     # base        CDeclaratorNode
475     # dimension   ExprNode
476
477     child_attrs = ["base", "dimension"]
478     
479     def analyse(self, base_type, env, nonempty = 0):
480         if base_type.is_cpp_class:
481             from ExprNodes import TupleNode
482             if isinstance(self.dimension, TupleNode):
483                 args = self.dimension.args
484             else:
485                 args = self.dimension,
486             values = [v.analyse_as_type(env) for v in args]
487             if None in values:
488                 ix = values.index(None)
489                 error(args[ix].pos, "Template parameter not a type.")
490                 return error_type
491             base_type = base_type.specialize_here(self.pos, values)
492             return self.base.analyse(base_type, env, nonempty = nonempty)
493         if self.dimension:
494             self.dimension.analyse_const_expression(env)
495             if not self.dimension.type.is_int:
496                 error(self.dimension.pos, "Array dimension not integer")
497             size = self.dimension.get_constant_c_result_code()
498             if size is not None:
499                 try:
500                     size = int(size)
501                 except ValueError:
502                     # runtime constant?
503                     pass
504         else:
505             size = None
506         if not base_type.is_complete():
507             error(self.pos,
508                 "Array element type '%s' is incomplete" % base_type)
509         if base_type.is_pyobject:
510             error(self.pos,
511                 "Array element cannot be a Python object")
512         if base_type.is_cfunction:
513             error(self.pos,
514                 "Array element cannot be a function")
515         array_type = PyrexTypes.c_array_type(base_type, size)
516         return self.base.analyse(array_type, env, nonempty = nonempty)
517
518
519 class CFuncDeclaratorNode(CDeclaratorNode):
520     # base             CDeclaratorNode
521     # args             [CArgDeclNode]
522     # has_varargs      boolean
523     # exception_value  ConstNode
524     # exception_check  boolean    True if PyErr_Occurred check needed
525     # nogil            boolean    Can be called without gil
526     # with_gil         boolean    Acquire gil around function body
527     
528     child_attrs = ["base", "args", "exception_value"]
529
530     overridable = 0
531     optional_arg_count = 0
532
533     def analyse(self, return_type, env, nonempty = 0):
534         if nonempty:
535             nonempty -= 1
536         func_type_args = []
537         for arg_node in self.args:
538             name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
539             name = name_declarator.name
540             if name_declarator.cname:
541                 error(self.pos, 
542                     "Function argument cannot have C name specification")
543             # Turn *[] argument into **
544             if type.is_array:
545                 type = PyrexTypes.c_ptr_type(type.base_type)
546             # Catch attempted C-style func(void) decl
547             if type.is_void:
548                 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
549             func_type_args.append(
550                 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
551             if arg_node.default:
552                 self.optional_arg_count += 1
553             elif self.optional_arg_count:
554                 error(self.pos, "Non-default argument follows default argument")
555         
556         if self.optional_arg_count:
557             scope = StructOrUnionScope()
558             arg_count_member = '%sn' % Naming.pyrex_prefix
559             scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
560             for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
561                 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
562             struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
563             self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
564                                         kind = 'struct',
565                                         scope = scope,
566                                         typedef_flag = 0,
567                                         pos = self.pos,
568                                         cname = struct_cname)
569             self.op_args_struct.defined_in_pxd = 1
570             self.op_args_struct.used = 1
571         
572         exc_val = None
573         exc_check = 0
574         if self.exception_check == '+':
575             env.add_include_file('stdexcept')
576         if return_type.is_pyobject \
577             and (self.exception_value or self.exception_check) \
578             and self.exception_check != '+':
579                 error(self.pos,
580                     "Exception clause not allowed for function returning Python object")
581         else:
582             if self.exception_value:
583                 self.exception_value.analyse_const_expression(env)
584                 if self.exception_check == '+':
585                     self.exception_value.analyse_types(env)
586                     exc_val_type = self.exception_value.type
587                     if not exc_val_type.is_error and \
588                           not exc_val_type.is_pyobject and \
589                           not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
590                         error(self.exception_value.pos,
591                             "Exception value must be a Python exception or cdef function with no arguments.")
592                     exc_val = self.exception_value
593                 else:
594                     if self.exception_value.analyse_const_expression(env):
595                         exc_val = self.exception_value.get_constant_c_result_code()
596                         if exc_val is None:
597                             raise InternalError("get_constant_c_result_code not implemented for %s" %
598                                 self.exception_value.__class__.__name__)
599                         if not return_type.assignable_from(self.exception_value.type):
600                             error(self.exception_value.pos,
601                                   "Exception value incompatible with function return type")
602             exc_check = self.exception_check
603         if return_type.is_array:
604             error(self.pos,
605                 "Function cannot return an array")
606         if return_type.is_cfunction:
607             error(self.pos,
608                 "Function cannot return a function")
609         func_type = PyrexTypes.CFuncType(
610             return_type, func_type_args, self.has_varargs, 
611             optional_arg_count = self.optional_arg_count,
612             exception_value = exc_val, exception_check = exc_check,
613             calling_convention = self.base.calling_convention,
614             nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
615         if self.optional_arg_count:
616             func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
617         callspec = env.directives['callspec']
618         if callspec:
619             current = func_type.calling_convention
620             if current and current != callspec:
621                 error(self.pos, "cannot have both '%s' and '%s' "
622                       "calling conventions" % (current, callspec))
623             func_type.calling_convention = callspec
624         return self.base.analyse(func_type, env)
625
626
627 class CArgDeclNode(Node):
628     # Item in a function declaration argument list.
629     #
630     # base_type      CBaseTypeNode
631     # declarator     CDeclaratorNode
632     # not_none       boolean            Tagged with 'not None'
633     # or_none        boolean            Tagged with 'or None'
634     # accept_none    boolean            Resolved boolean for not_none/or_none
635     # default        ExprNode or None
636     # default_value  PyObjectConst      constant for default value
637     # annotation     ExprNode or None   Py3 function arg annotation
638     # is_self_arg    boolean            Is the "self" arg of an extension type method
639     # is_type_arg    boolean            Is the "class" arg of an extension type classmethod
640     # is_kw_only     boolean            Is a keyword-only argument
641
642     child_attrs = ["base_type", "declarator", "default"]
643
644     is_self_arg = 0
645     is_type_arg = 0
646     is_generic = 1
647     type = None
648     name_declarator = None
649     default_value = None
650     annotation = None
651
652     def analyse(self, env, nonempty = 0):
653         #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
654         if self.type is None:
655             # The parser may missinterpret names as types...
656             # We fix that here.
657             if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
658                 if nonempty:
659                     self.declarator.name = self.base_type.name
660                     self.base_type.name = None
661                     self.base_type.is_basic_c_type = False
662                 could_be_name = True
663             else:
664                 could_be_name = False
665             base_type = self.base_type.analyse(env, could_be_name = could_be_name)
666             if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
667                 self.declarator.name = self.base_type.arg_name
668             # The parser is unable to resolve the ambiguity of [] as part of the 
669             # type (e.g. in buffers) or empty declarator (as with arrays). 
670             # This is only arises for empty multi-dimensional arrays.
671             if (base_type.is_array 
672                     and isinstance(self.base_type, TemplatedTypeNode) 
673                     and isinstance(self.declarator, CArrayDeclaratorNode)):
674                 declarator = self.declarator
675                 while isinstance(declarator.base, CArrayDeclaratorNode):
676                     declarator = declarator.base
677                 declarator.base = self.base_type.array_declarator
678                 base_type = base_type.base_type
679             return self.declarator.analyse(base_type, env, nonempty = nonempty)
680         else:
681             return self.name_declarator, self.type
682
683     def calculate_default_value_code(self, code):
684         if self.default_value is None:
685             if self.default:
686                 if self.default.is_literal:
687                     # will not output any code, just assign the result_code
688                     self.default.generate_evaluation_code(code)
689                     return self.type.cast_code(self.default.result())
690                 self.default_value = code.get_argument_default_const(self.type)
691         return self.default_value
692
693     def annotate(self, code):
694         if self.default:
695             self.default.annotate(code)
696
697
698 class CBaseTypeNode(Node):
699     # Abstract base class for C base type nodes.
700     #
701     # Processing during analyse_declarations phase:
702     #
703     #   analyse
704     #     Returns the type.
705     
706     pass
707     
708     def analyse_as_type(self, env):
709         return self.analyse(env)
710     
711 class CAnalysedBaseTypeNode(Node):
712     # type            type
713     
714     child_attrs = []
715     
716     def analyse(self, env, could_be_name = False):
717         return self.type
718
719 class CSimpleBaseTypeNode(CBaseTypeNode):
720     # name             string
721     # module_path      [string]     Qualifying name components
722     # is_basic_c_type  boolean
723     # signed           boolean
724     # longness         integer
725     # complex          boolean
726     # is_self_arg      boolean      Is self argument of C method
727     # ##is_type_arg      boolean      Is type argument of class method
728
729     child_attrs = []
730     arg_name = None   # in case the argument name was interpreted as a type
731     
732     def analyse(self, env, could_be_name = False):
733         # Return type descriptor.
734         #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
735         type = None
736         if self.is_basic_c_type:
737             type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
738             if not type:
739                 error(self.pos, "Unrecognised type modifier combination")
740         elif self.name == "object" and not self.module_path:
741             type = py_object_type
742         elif self.name is None:
743             if self.is_self_arg and env.is_c_class_scope:
744                 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
745                 type = env.parent_type
746             ## elif self.is_type_arg and env.is_c_class_scope:
747             ##     type = Builtin.type_type
748             else:
749                 type = py_object_type
750         else:
751             if self.module_path:
752                 scope = env.find_imported_module(self.module_path, self.pos)
753             else:
754                 scope = env
755             if scope:
756                 if scope.is_c_class_scope:
757                     scope = scope.global_scope()
758                 entry = scope.lookup(self.name)
759                 if entry and entry.is_type:
760                     type = entry.type
761                 elif could_be_name:
762                     if self.is_self_arg and env.is_c_class_scope:
763                         type = env.parent_type
764                     ## elif self.is_type_arg and env.is_c_class_scope:
765                     ##     type = Builtin.type_type
766                     else:
767                         type = py_object_type
768                     self.arg_name = self.name
769                 else:
770                     if self.templates:
771                         if not self.name in self.templates:
772                             error(self.pos, "'%s' is not a type identifier" % self.name)
773                         type = PyrexTypes.TemplatePlaceholderType(self.name)
774                     else:
775                         error(self.pos, "'%s' is not a type identifier" % self.name)
776         if self.complex:
777             if not type.is_numeric or type.is_complex:
778                 error(self.pos, "can only complexify c numeric types")
779             type = PyrexTypes.CComplexType(type)
780             type.create_declaration_utility_code(env)
781         if type:
782             return type
783         else:
784             return PyrexTypes.error_type
785
786 class CNestedBaseTypeNode(CBaseTypeNode):
787     # For C++ classes that live inside other C++ classes. 
788
789     # name             string
790     # base_type        CBaseTypeNode
791
792     child_attrs = ['base_type']
793
794     def analyse(self, env, could_be_name = None):
795         base_type = self.base_type.analyse(env)
796         if base_type is PyrexTypes.error_type:
797             return PyrexTypes.error_type
798         if not base_type.is_cpp_class:
799             error(self.pos, "'%s' is not a valid type scope" % base_type)
800             return PyrexTypes.error_type
801         type_entry = base_type.scope.lookup_here(self.name)
802         if not type_entry or not type_entry.is_type:
803             error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
804             return PyrexTypes.error_type
805         return type_entry.type
806
807 class TemplatedTypeNode(CBaseTypeNode):
808     #  After parsing:
809     #  positional_args  [ExprNode]        List of positional arguments
810     #  keyword_args     DictNode          Keyword arguments
811     #  base_type_node   CBaseTypeNode
812
813     #  After analysis:
814     #  type             PyrexTypes.BufferType or PyrexTypes.CppClassType  ...containing the right options
815
816
817     child_attrs = ["base_type_node", "positional_args",
818                    "keyword_args", "dtype_node"]
819
820     dtype_node = None
821
822     name = None
823     
824     def analyse(self, env, could_be_name = False, base_type = None):
825         if base_type is None:
826             base_type = self.base_type_node.analyse(env)
827         if base_type.is_error: return base_type
828         
829         if base_type.is_cpp_class:
830             # Templated class
831             if self.keyword_args and self.keyword_args.key_value_pairs:
832                 error(self.pos, "c++ templates cannot take keyword arguments");
833                 self.type = PyrexTypes.error_type
834             else:
835                 template_types = []
836                 for template_node in self.positional_args:
837                     type = template_node.analyse_as_type(env)
838                     if type is None:
839                         error(template_node.pos, "unknown type in template argument")
840                         return error_type
841                     template_types.append(type)
842                 self.type = base_type.specialize_here(self.pos, template_types)
843         
844         elif base_type.is_pyobject:
845             # Buffer
846             import Buffer
847
848             options = Buffer.analyse_buffer_options(
849                 self.pos,
850                 env,
851                 self.positional_args,
852                 self.keyword_args,
853                 base_type.buffer_defaults)
854
855             if sys.version_info[0] < 3:
856                 # Py 2.x enforces byte strings as keyword arguments ...
857                 options = dict([ (name.encode('ASCII'), value)
858                                  for name, value in options.iteritems() ])
859
860             self.type = PyrexTypes.BufferType(base_type, **options)
861         
862         else:
863             # Array
864             empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
865             if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
866                 error(self.pos, "invalid array declaration")
867                 self.type = PyrexTypes.error_type
868             else:
869                 # It would be nice to merge this class with CArrayDeclaratorNode, 
870                 # but arrays are part of the declaration, not the type...
871                 if not self.positional_args:
872                     dimension = None
873                 else:
874                     dimension = self.positional_args[0]
875                 self.array_declarator = CArrayDeclaratorNode(self.pos, 
876                     base = empty_declarator, 
877                     dimension = dimension)
878                 self.type = self.array_declarator.analyse(base_type, env)[1]
879         
880         return self.type
881
882 class CComplexBaseTypeNode(CBaseTypeNode):
883     # base_type   CBaseTypeNode
884     # declarator  CDeclaratorNode
885     
886     child_attrs = ["base_type", "declarator"]
887
888     def analyse(self, env, could_be_name = False):
889         base = self.base_type.analyse(env, could_be_name)
890         _, type = self.declarator.analyse(base, env)
891         return type
892
893
894 class CVarDefNode(StatNode):
895     #  C variable definition or forward/extern function declaration.
896     #
897     #  visibility    'private' or 'public' or 'extern'
898     #  base_type     CBaseTypeNode
899     #  declarators   [CDeclaratorNode]
900     #  in_pxd        boolean
901     #  api           boolean
902     #  properties    [entry]
903
904     #  decorators    [cython.locals(...)] or None 
905     #  directive_locals { string : NameNode } locals defined by cython.locals(...)
906
907     child_attrs = ["base_type", "declarators"]
908     properties = ()
909     
910     decorators = None
911     directive_locals = {}
912     
913     def analyse_declarations(self, env, dest_scope = None):
914         if not dest_scope:
915             dest_scope = env
916         self.dest_scope = dest_scope
917         base_type = self.base_type.analyse(env)
918
919         # If the field is an external typedef, we cannot be sure about the type,
920         # so do conversion ourself rather than rely on the CPython mechanism (through
921         # a property; made in AnalyseDeclarationsTransform).
922         if (dest_scope.is_c_class_scope
923             and self.visibility in ('public', 'readonly')):
924             self.properties = []
925             need_property = True
926         else:
927             need_property = False
928         visibility = self.visibility
929             
930         for declarator in self.declarators:
931             name_declarator, type = declarator.analyse(base_type, env)
932             if not type.is_complete():
933                 if not (self.visibility == 'extern' and type.is_array):
934                     error(declarator.pos,
935                         "Variable type '%s' is incomplete" % type)
936             if self.visibility == 'extern' and type.is_pyobject:
937                 error(declarator.pos,
938                     "Python object cannot be declared extern")
939             name = name_declarator.name
940             cname = name_declarator.cname
941             if name == '':
942                 error(declarator.pos, "Missing name in declaration.")
943                 return
944             if type.is_cfunction:
945                 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
946                     cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
947                     api = self.api)
948                 if entry is not None:
949                     entry.directive_locals = self.directive_locals
950             else:
951                 if self.directive_locals:
952                     s.error("Decorators can only be followed by functions")
953                 if self.in_pxd and self.visibility != 'extern':
954                     error(self.pos, 
955                         "Only 'extern' C variable declaration allowed in .pxd file")
956                 entry = dest_scope.declare_var(name, type, declarator.pos,
957                             cname = cname, visibility = visibility, is_cdef = 1)
958                 if need_property:
959                     self.properties.append(entry)
960     
961
962 class CStructOrUnionDefNode(StatNode):
963     #  name          string
964     #  cname         string or None
965     #  kind          "struct" or "union"
966     #  typedef_flag  boolean
967     #  visibility    "public" or "private"
968     #  in_pxd        boolean
969     #  attributes    [CVarDefNode] or None
970     #  entry         Entry
971     #  packed        boolean
972     
973     child_attrs = ["attributes"]
974
975     def analyse_declarations(self, env):
976         scope = None
977         if self.visibility == 'extern' and self.packed:
978             error(self.pos, "Cannot declare extern struct as 'packed'")
979         if self.attributes is not None:
980             scope = StructOrUnionScope(self.name)
981         self.entry = env.declare_struct_or_union(
982             self.name, self.kind, scope, self.typedef_flag, self.pos,
983             self.cname, visibility = self.visibility, packed = self.packed)
984         if self.attributes is not None:
985             if self.in_pxd and not env.in_cinclude:
986                 self.entry.defined_in_pxd = 1
987             for attr in self.attributes:
988                 attr.analyse_declarations(env, scope)
989             if self.visibility != 'extern':
990                 need_typedef_indirection = False
991                 for attr in scope.var_entries:
992                     type = attr.type
993                     while type.is_array:
994                         type = type.base_type
995                     if type == self.entry.type:
996                         error(attr.pos, "Struct cannot contain itself as a member.")
997                     if self.typedef_flag:
998                         while type.is_ptr:
999                             type = type.base_type
1000                         if type == self.entry.type:
1001                             need_typedef_indirection = True
1002                 if need_typedef_indirection:
1003                     # C can't handle typedef structs that refer to themselves. 
1004                     struct_entry = self.entry
1005                     self.entry = env.declare_typedef(
1006                         self.name, struct_entry.type, self.pos,
1007                         cname = self.cname, visibility='ignore')
1008                     struct_entry.type.typedef_flag = False
1009                     # FIXME: this might be considered a hack ;-)
1010                     struct_entry.cname = struct_entry.type.cname = \
1011                                          '_' + self.entry.type.typedef_cname
1012     
1013     def analyse_expressions(self, env):
1014         pass
1015     
1016     def generate_execution_code(self, code):
1017         pass
1018
1019
1020 class CppClassNode(CStructOrUnionDefNode):
1021
1022     #  name          string
1023     #  cname         string or None
1024     #  visibility    "extern"
1025     #  in_pxd        boolean
1026     #  attributes    [CVarDefNode] or None
1027     #  entry         Entry
1028     #  base_classes  [string]
1029     #  templates     [string] or None
1030
1031     def analyse_declarations(self, env):
1032         scope = None
1033         if self.attributes is not None:
1034             scope = CppClassScope(self.name, env)
1035         base_class_types = []
1036         for base_class_name in self.base_classes:
1037             base_class_entry = env.lookup(base_class_name)
1038             if base_class_entry is None:
1039                 error(self.pos, "'%s' not found" % base_class_name)
1040             elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1041                 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1042             else:
1043                 base_class_types.append(base_class_entry.type)
1044         if self.templates is None:
1045             template_types = None
1046         else:
1047             template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1048         self.entry = env.declare_cpp_class(
1049             self.name, scope, self.pos,
1050             self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1051         self.entry.is_cpp_class = 1
1052         if self.attributes is not None:
1053             if self.in_pxd and not env.in_cinclude:
1054                 self.entry.defined_in_pxd = 1
1055             for attr in self.attributes:
1056                 attr.analyse_declarations(scope)
1057
1058 class CEnumDefNode(StatNode):
1059     #  name           string or None
1060     #  cname          string or None
1061     #  items          [CEnumDefItemNode]
1062     #  typedef_flag   boolean
1063     #  visibility     "public" or "private"
1064     #  in_pxd         boolean
1065     #  entry          Entry
1066     
1067     child_attrs = ["items"]
1068     
1069     def analyse_declarations(self, env):
1070         self.entry = env.declare_enum(self.name, self.pos,
1071             cname = self.cname, typedef_flag = self.typedef_flag,
1072             visibility = self.visibility)
1073         if self.items is not None:
1074             if self.in_pxd and not env.in_cinclude:
1075                 self.entry.defined_in_pxd = 1
1076             for item in self.items:
1077                 item.analyse_declarations(env, self.entry)
1078
1079     def analyse_expressions(self, env):
1080         pass
1081
1082     def generate_execution_code(self, code):
1083         if self.visibility == 'public':
1084             temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1085             for item in self.entry.enum_values:
1086                 code.putln("%s = PyInt_FromLong(%s); %s" % (
1087                         temp,
1088                         item.cname,
1089                         code.error_goto_if_null(temp, item.pos)))
1090                 code.put_gotref(temp)
1091                 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1092                         Naming.module_cname, 
1093                         item.name, 
1094                         temp,
1095                         code.error_goto(item.pos)))
1096                 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1097             code.funcstate.release_temp(temp)
1098
1099
1100 class CEnumDefItemNode(StatNode):
1101     #  name     string
1102     #  cname    string or None
1103     #  value    ExprNode or None
1104     
1105     child_attrs = ["value"]
1106
1107     def analyse_declarations(self, env, enum_entry):
1108         if self.value:
1109             self.value.analyse_const_expression(env)
1110             if not self.value.type.is_int:
1111                 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1112                 self.value.analyse_const_expression(env)
1113         entry = env.declare_const(self.name, enum_entry.type, 
1114             self.value, self.pos, cname = self.cname,
1115             visibility = enum_entry.visibility)
1116         enum_entry.enum_values.append(entry)
1117
1118
1119 class CTypeDefNode(StatNode):
1120     #  base_type    CBaseTypeNode
1121     #  declarator   CDeclaratorNode
1122     #  visibility   "public" or "private"
1123     #  in_pxd       boolean
1124
1125     child_attrs = ["base_type", "declarator"]
1126     
1127     def analyse_declarations(self, env):
1128         base = self.base_type.analyse(env)
1129         name_declarator, type = self.declarator.analyse(base, env)
1130         name = name_declarator.name
1131         cname = name_declarator.cname
1132         entry = env.declare_typedef(name, type, self.pos,
1133             cname = cname, visibility = self.visibility)
1134         if self.in_pxd and not env.in_cinclude:
1135             entry.defined_in_pxd = 1
1136     
1137     def analyse_expressions(self, env):
1138         pass
1139     def generate_execution_code(self, code):
1140         pass
1141
1142
1143 class FuncDefNode(StatNode, BlockNode):
1144     #  Base class for function definition nodes.
1145     #
1146     #  return_type     PyrexType
1147     #  #filename        string        C name of filename string const
1148     #  entry           Symtab.Entry
1149     #  needs_closure   boolean        Whether or not this function has inner functions/classes/yield
1150     #  directive_locals { string : NameNode } locals defined by cython.locals(...)
1151     
1152     py_func = None
1153     assmt = None
1154     needs_closure = False
1155     modifiers = []
1156     
1157     def analyse_default_values(self, env):
1158         genv = env.global_scope()
1159         default_seen = 0
1160         for arg in self.args:
1161             if arg.default:
1162                 default_seen = 1
1163                 if arg.is_generic:
1164                     arg.default.analyse_types(env)
1165                     arg.default = arg.default.coerce_to(arg.type, genv)
1166                 else:
1167                     error(arg.pos,
1168                         "This argument cannot have a default value")
1169                     arg.default = None
1170             elif arg.kw_only:
1171                 default_seen = 1
1172             elif default_seen:
1173                 error(arg.pos, "Non-default argument following default argument")
1174
1175     def need_gil_acquisition(self, lenv):
1176         return 0
1177         
1178     def create_local_scope(self, env):
1179         genv = env
1180         while genv.is_py_class_scope or genv.is_c_class_scope:
1181             genv = env.outer_scope
1182         if self.needs_closure:
1183             lenv = ClosureScope(name=self.entry.name,
1184                                 outer_scope = genv,
1185                                 scope_name=self.entry.cname)
1186         else:
1187             lenv = LocalScope(name=self.entry.name,
1188                               outer_scope=genv,
1189                               parent_scope=env)
1190         lenv.return_type = self.return_type
1191         type = self.entry.type
1192         if type.is_cfunction:
1193             lenv.nogil = type.nogil and not type.with_gil
1194         self.local_scope = lenv
1195         lenv.directives = env.directives
1196         return lenv
1197                 
1198     def generate_function_definitions(self, env, code):
1199         import Buffer
1200
1201         lenv = self.local_scope
1202         if lenv.is_closure_scope:
1203             outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1204                                             Naming.outer_scope_cname)
1205         else:
1206             outer_scope_cname = Naming.outer_scope_cname
1207         lenv.mangle_closure_cnames(outer_scope_cname)
1208         # Generate closure function definitions
1209         self.body.generate_function_definitions(lenv, code)
1210         # generate lambda function definitions
1211         for node in lenv.lambda_defs:
1212             node.generate_function_definitions(lenv, code)
1213
1214         is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1215                              self.entry.scope.is_c_class_scope)
1216         is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1217                                  self.entry.scope.is_c_class_scope)
1218         is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1219         if is_buffer_slot:
1220             if 'cython_unused' not in self.modifiers:
1221                 self.modifiers = self.modifiers + ['cython_unused']
1222         
1223         profile = code.globalstate.directives['profile']
1224         if profile:
1225             if lenv.nogil:
1226                 error(self.pos, "Cannot profile nogil function.")
1227             code.globalstate.use_utility_code(profile_utility_code)
1228
1229         # Generate C code for header and body of function
1230         code.enter_cfunc_scope()
1231         code.return_from_error_cleanup_label = code.new_label()
1232             
1233         # ----- Top-level constants used by this function
1234         code.mark_pos(self.pos)
1235         self.generate_cached_builtins_decls(lenv, code)
1236         # ----- Function header
1237         code.putln("")
1238         with_pymethdef = self.needs_assignment_synthesis(env, code)
1239         if self.py_func:
1240             self.py_func.generate_function_header(code, 
1241                 with_pymethdef = with_pymethdef,
1242                 proto_only=True)
1243         self.generate_function_header(code,
1244             with_pymethdef = with_pymethdef)
1245         # ----- Local variable declarations
1246         if lenv.is_closure_scope:
1247             code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1248             code.putln(";")
1249         elif env.is_closure_scope:
1250             code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1251             code.putln(";")
1252         self.generate_argument_declarations(lenv, code)
1253         for entry in lenv.var_entries:
1254             if not entry.in_closure:
1255                 code.put_var_declaration(entry)
1256         init = ""
1257         if not self.return_type.is_void:
1258             if self.return_type.is_pyobject:
1259                 init = " = NULL"
1260             code.putln(
1261                 "%s%s;" % 
1262                     (self.return_type.declaration_code(Naming.retval_cname),
1263                      init))
1264         tempvardecl_code = code.insertion_point()
1265         self.generate_keyword_list(code)
1266         if profile:
1267             code.put_trace_declarations()
1268         # ----- Extern library function declarations
1269         lenv.generate_library_function_declarations(code)
1270         # ----- GIL acquisition
1271         acquire_gil = self.acquire_gil
1272         if acquire_gil:
1273             env.use_utility_code(force_init_threads_utility_code)
1274             code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1275         # ----- set up refnanny
1276         if not lenv.nogil:
1277             code.put_setup_refcount_context(self.entry.name)
1278         # ----- Automatic lead-ins for certain special functions
1279         if is_getbuffer_slot:
1280             self.getbuffer_init(code)
1281         # ----- Create closure scope object
1282         if self.needs_closure:
1283             code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1284                 Naming.cur_scope_cname,
1285                 lenv.scope_class.type.declaration_code(''),
1286                 lenv.scope_class.type.typeptr_cname, 
1287                 lenv.scope_class.type.typeptr_cname,
1288                 Naming.empty_tuple))
1289             code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1290             if is_getbuffer_slot:
1291                 self.getbuffer_error_cleanup(code)
1292             if not lenv.nogil:
1293                 code.put_finish_refcount_context()
1294             # FIXME: what if the error return value is a Python value?
1295             code.putln("return %s;" % self.error_value())
1296             code.putln("}")
1297             code.put_gotref(Naming.cur_scope_cname)
1298             # Note that it is unsafe to decref the scope at this point.
1299         if env.is_closure_scope:
1300             code.putln("%s = (%s)%s;" % (
1301                             outer_scope_cname,
1302                             env.scope_class.type.declaration_code(''),
1303                             Naming.self_cname))
1304             if self.needs_closure:
1305                 # inner closures own a reference to their outer parent
1306                 code.put_incref(outer_scope_cname, env.scope_class.type)
1307                 code.put_giveref(outer_scope_cname)
1308         # ----- Trace function call
1309         if profile:
1310             # this looks a bit late, but if we don't get here due to a
1311             # fatal error before hand, it's not really worth tracing
1312             code.put_trace_call(self.entry.name, self.pos)
1313         # ----- Fetch arguments
1314         self.generate_argument_parsing_code(env, code)
1315         # If an argument is assigned to in the body, we must 
1316         # incref it to properly keep track of refcounts.
1317         for entry in lenv.arg_entries:
1318             if entry.type.is_pyobject:
1319                 if entry.assignments and not entry.in_closure:
1320                     code.put_var_incref(entry)
1321         # ----- Initialise local variables 
1322         for entry in lenv.var_entries:
1323             if entry.type.is_pyobject and entry.init_to_none and entry.used:
1324                 code.put_init_var_to_py_none(entry)
1325         # ----- Initialise local buffer auxiliary variables
1326         for entry in lenv.var_entries + lenv.arg_entries:
1327             if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1328                 code.putln("%s.buf = NULL;" %
1329                            entry.buffer_aux.buffer_info_var.cname)
1330         # ----- Check and convert arguments
1331         self.generate_argument_type_tests(code)
1332         # ----- Acquire buffer arguments
1333         for entry in lenv.arg_entries:
1334             if entry.type.is_buffer:
1335                 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1336
1337         # -------------------------
1338         # ----- Function body -----
1339         # -------------------------
1340         self.body.generate_execution_code(code)
1341
1342         # ----- Default return value
1343         code.putln("")
1344         if self.return_type.is_pyobject:
1345             #if self.return_type.is_extension_type:
1346             #    lhs = "(PyObject *)%s" % Naming.retval_cname
1347             #else:
1348             lhs = Naming.retval_cname
1349             code.put_init_to_py_none(lhs, self.return_type)
1350         else:
1351             val = self.return_type.default_value
1352             if val:
1353                 code.putln("%s = %s;" % (Naming.retval_cname, val))
1354         # ----- Error cleanup
1355         if code.error_label in code.labels_used:
1356             code.put_goto(code.return_label)
1357             code.put_label(code.error_label)
1358             for cname, type in code.funcstate.all_managed_temps():
1359                 code.put_xdecref(cname, type)
1360
1361             # Clean up buffers -- this calls a Python function
1362             # so need to save and restore error state
1363             buffers_present = len(lenv.buffer_entries) > 0
1364             if buffers_present:
1365                 code.globalstate.use_utility_code(restore_exception_utility_code)
1366                 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1367                 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1368                 for entry in lenv.buffer_entries:                    
1369                     Buffer.put_release_buffer_code(code, entry)
1370                     #code.putln("%s = 0;" % entry.cname)
1371                 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1372
1373             err_val = self.error_value()
1374             exc_check = self.caller_will_check_exceptions()
1375             if err_val is not None or exc_check:
1376                 # TODO: Fix exception tracing (though currently unused by cProfile). 
1377                 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1378                 # code.put_trace_exception()
1379                 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1380             else:
1381                 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1382                             % self.entry.qualified_name, 0)
1383                 code.putln(
1384                     '__Pyx_WriteUnraisable("%s");' % 
1385                         self.entry.qualified_name)
1386                 env.use_utility_code(unraisable_exception_utility_code)
1387                 env.use_utility_code(restore_exception_utility_code)
1388             default_retval = self.return_type.default_value
1389             if err_val is None and default_retval:
1390                 err_val = default_retval
1391             if err_val is not None:
1392                 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1393
1394             if is_getbuffer_slot:
1395                 self.getbuffer_error_cleanup(code)
1396
1397             # If we are using the non-error cleanup section we should
1398             # jump past it if we have an error. The if-test below determine
1399             # whether this section is used.
1400             if buffers_present or is_getbuffer_slot:
1401                 code.put_goto(code.return_from_error_cleanup_label)
1402
1403
1404         # ----- Non-error return cleanup
1405         code.put_label(code.return_label)
1406         for entry in lenv.buffer_entries:
1407             if entry.used:
1408                 Buffer.put_release_buffer_code(code, entry)
1409         if is_getbuffer_slot:
1410             self.getbuffer_normal_cleanup(code)
1411         # ----- Return cleanup for both error and no-error return
1412         code.put_label(code.return_from_error_cleanup_label)
1413         if not Options.init_local_none:
1414             for entry in lenv.var_entries:
1415                 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1416                     entry.xdecref_cleanup = 1
1417         
1418         for entry in lenv.var_entries:
1419             if entry.type.is_pyobject:
1420                 if entry.used and not entry.in_closure:
1421                     code.put_var_decref(entry)
1422                 elif entry.in_closure and self.needs_closure:
1423                     code.put_giveref(entry.cname)
1424         # Decref any increfed args
1425         for entry in lenv.arg_entries:
1426             if entry.type.is_pyobject:
1427                 if entry.in_closure:
1428                     code.put_var_giveref(entry)
1429                 elif entry.assignments:
1430                     code.put_var_decref(entry)
1431         if self.needs_closure:
1432             code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1433                 
1434         # ----- Return
1435         # This code is duplicated in ModuleNode.generate_module_init_func
1436         if not lenv.nogil:
1437             default_retval = self.return_type.default_value
1438             err_val = self.error_value()
1439             if err_val is None and default_retval:
1440                 err_val = default_retval
1441             if self.return_type.is_pyobject:
1442                 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1443
1444         if self.entry.is_special and self.entry.name == "__hash__":
1445             # Returning -1 for __hash__ is supposed to signal an error
1446             # We do as Python instances and coerce -1 into -2. 
1447             code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1448                     Naming.retval_cname, Naming.retval_cname))
1449
1450         if profile:
1451             if self.return_type.is_pyobject:
1452                 code.put_trace_return(Naming.retval_cname)
1453             else:
1454                 code.put_trace_return("Py_None")
1455         if not lenv.nogil:
1456             code.put_finish_refcount_context()
1457         
1458         if acquire_gil:
1459             code.putln("PyGILState_Release(_save);")
1460
1461         if not self.return_type.is_void:
1462             code.putln("return %s;" % Naming.retval_cname)
1463             
1464         code.putln("}")
1465         # ----- Go back and insert temp variable declarations
1466         tempvardecl_code.put_temp_declarations(code.funcstate)
1467         # ----- Python version
1468         code.exit_cfunc_scope()
1469         if self.py_func:
1470             self.py_func.generate_function_definitions(env, code)
1471         self.generate_wrapper_functions(code)
1472
1473     def declare_argument(self, env, arg):
1474         if arg.type.is_void:
1475             error(arg.pos, "Invalid use of 'void'")
1476         elif not arg.type.is_complete() and not arg.type.is_array:
1477             error(arg.pos,
1478                 "Argument type '%s' is incomplete" % arg.type)
1479         return env.declare_arg(arg.name, arg.type, arg.pos)
1480     
1481     def generate_arg_type_test(self, arg, code):
1482         # Generate type test for one argument.
1483         if arg.type.typeobj_is_available():
1484             code.globalstate.use_utility_code(arg_type_test_utility_code)
1485             typeptr_cname = arg.type.typeptr_cname
1486             arg_code = "((PyObject *)%s)" % arg.entry.cname
1487             code.putln(
1488                 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1489                     arg_code, 
1490                     typeptr_cname,
1491                     arg.accept_none,
1492                     arg.name,
1493                     arg.type.is_builtin_type,
1494                     code.error_goto(arg.pos)))
1495         else:
1496             error(arg.pos, "Cannot test type of extern C class "
1497                 "without type object name specification")
1498
1499     def generate_arg_none_check(self, arg, code):
1500         # Generate None check for one argument.
1501         code.globalstate.use_utility_code(arg_type_test_utility_code)
1502         code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1503         code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1504             arg.name,
1505             code.error_goto(arg.pos)))
1506         code.putln('}')
1507         
1508     def generate_wrapper_functions(self, code):
1509         pass
1510
1511     def generate_execution_code(self, code):
1512         # Evaluate and store argument default values
1513         for arg in self.args:
1514             default = arg.default
1515             if default:
1516                 if not default.is_literal:
1517                     default.generate_evaluation_code(code)
1518                     default.make_owned_reference(code)
1519                     result = default.result_as(arg.type)
1520                     code.putln(
1521                         "%s = %s;" % (
1522                             arg.calculate_default_value_code(code),
1523                             result))
1524                     if arg.type.is_pyobject:
1525                         code.put_giveref(default.result())
1526                     default.generate_post_assignment_code(code)
1527                     default.free_temps(code)
1528         # For Python class methods, create and store function object
1529         if self.assmt:
1530             self.assmt.generate_execution_code(code)
1531
1532     #
1533     # Special code for the __getbuffer__ function
1534     #
1535     def getbuffer_init(self, code):
1536         info = self.local_scope.arg_entries[1].cname
1537         # Python 3.0 betas have a bug in memoryview which makes it call
1538         # getbuffer with a NULL parameter. For now we work around this;
1539         # the following line should be removed when this bug is fixed.
1540         code.putln("if (%s == NULL) return 0;" % info) 
1541         code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1542         code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1543
1544     def getbuffer_error_cleanup(self, code):
1545         info = self.local_scope.arg_entries[1].cname
1546         code.put_gotref("%s->obj" % info)
1547         code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1548                    (info, info))
1549
1550     def getbuffer_normal_cleanup(self, code):
1551         info = self.local_scope.arg_entries[1].cname
1552         code.putln("if (%s->obj == Py_None) {" % info)
1553         code.put_gotref("Py_None")
1554         code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1555         code.putln("}")
1556
1557 class CFuncDefNode(FuncDefNode):
1558     #  C function definition.
1559     #
1560     #  modifiers     ['inline']
1561     #  visibility    'private' or 'public' or 'extern'
1562     #  base_type     CBaseTypeNode
1563     #  declarator    CDeclaratorNode
1564     #  body          StatListNode
1565     #  api           boolean
1566     #  decorators    [DecoratorNode]        list of decorators
1567     #
1568     #  with_gil      boolean    Acquire GIL around body
1569     #  type          CFuncType
1570     #  py_func       wrapper for calling from Python
1571     #  overridable   whether or not this is a cpdef function
1572     #  inline_in_pxd whether this is an inline function in a pxd file
1573     
1574     child_attrs = ["base_type", "declarator", "body", "py_func"]
1575
1576     inline_in_pxd = False
1577     decorators = None
1578     directive_locals = {}
1579
1580     def unqualified_name(self):
1581         return self.entry.name
1582         
1583     def analyse_declarations(self, env):
1584         self.directive_locals.update(env.directives['locals'])
1585         base_type = self.base_type.analyse(env)
1586         # The 2 here is because we need both function and argument names. 
1587         name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1588         if not type.is_cfunction:
1589             error(self.pos, 
1590                 "Suite attached to non-function declaration")
1591         # Remember the actual type according to the function header
1592         # written here, because the type in the symbol table entry
1593         # may be different if we're overriding a C method inherited
1594         # from the base type of an extension type.
1595         self.type = type
1596         type.is_overridable = self.overridable
1597         declarator = self.declarator
1598         while not hasattr(declarator, 'args'):
1599             declarator = declarator.base
1600         self.args = declarator.args
1601         for formal_arg, type_arg in zip(self.args, type.args):
1602             formal_arg.type = type_arg.type
1603             formal_arg.name = type_arg.name
1604             formal_arg.cname = type_arg.cname
1605         name = name_declarator.name
1606         cname = name_declarator.cname
1607         self.entry = env.declare_cfunction(
1608             name, type, self.pos, 
1609             cname = cname, visibility = self.visibility,
1610             defining = self.body is not None,
1611             api = self.api, modifiers = self.modifiers)
1612         self.entry.inline_func_in_pxd = self.inline_in_pxd
1613         self.return_type = type.return_type
1614         
1615         if self.overridable and not env.is_module_scope:
1616             if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1617                 # An error will be produced in the cdef function
1618                 self.overridable = False
1619             
1620         if self.overridable:
1621             import ExprNodes
1622             py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1623             self.py_func = DefNode(pos = self.pos, 
1624                                    name = self.entry.name,
1625                                    args = self.args,
1626                                    star_arg = None,
1627                                    starstar_arg = None,
1628                                    doc = self.doc,
1629                                    body = py_func_body,
1630                                    is_wrapper = 1)
1631             self.py_func.is_module_scope = env.is_module_scope
1632             self.py_func.analyse_declarations(env)
1633             self.entry.as_variable = self.py_func.entry
1634             # Reset scope entry the above cfunction
1635             env.entries[name] = self.entry
1636             if not env.is_module_scope or Options.lookup_module_cpdef:
1637                 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1638                 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1639         self.create_local_scope(env)
1640     
1641     def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1642         import ExprNodes
1643         args = self.type.args
1644         if omit_optional_args:
1645             args = args[:len(args) - self.type.optional_arg_count]
1646         arg_names = [arg.name for arg in args]
1647         if is_module_scope:
1648             cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1649         else:
1650             self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1651             cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1652         skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1653         c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch)
1654         return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1655     
1656     def declare_arguments(self, env):
1657         for arg in self.type.args:
1658             if not arg.name:
1659                 error(arg.pos, "Missing argument name")
1660             self.declare_argument(env, arg)
1661
1662     def need_gil_acquisition(self, lenv):
1663         return self.type.with_gil
1664
1665     def nogil_check(self, env):
1666         type = self.type
1667         with_gil = type.with_gil
1668         if type.nogil and not with_gil:
1669             if type.return_type.is_pyobject:
1670                 error(self.pos,
1671                       "Function with Python return type cannot be declared nogil")
1672             for entry in self.local_scope.var_entries:
1673                 if entry.type.is_pyobject:
1674                     error(self.pos, "Function declared nogil has Python locals or temporaries")
1675
1676     def analyse_expressions(self, env):
1677         self.local_scope.directives = env.directives
1678         if self.py_func is not None:
1679             # this will also analyse the default values
1680             self.py_func.analyse_expressions(env)
1681         else:
1682             self.analyse_default_values(env)
1683         self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1684
1685     def needs_assignment_synthesis(self, env, code=None):
1686         return False
1687
1688     def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1689         arg_decls = []
1690         type = self.type
1691         visibility = self.entry.visibility
1692         for arg in type.args[:len(type.args)-type.optional_arg_count]:
1693             arg_decls.append(arg.declaration_code())
1694         if with_dispatch and self.overridable:
1695             arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1696         if type.optional_arg_count and with_opt_args:
1697             arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1698         if type.has_varargs:
1699             arg_decls.append("...")
1700         if not arg_decls:
1701             arg_decls = ["void"]
1702         if cname is None:
1703             cname = self.entry.func_cname
1704         entity = type.function_header_code(cname, ', '.join(arg_decls))
1705         if visibility == 'public':
1706             dll_linkage = "DL_EXPORT"
1707         else:
1708             dll_linkage = None
1709         header = self.return_type.declaration_code(entity,
1710             dll_linkage = dll_linkage)
1711         if visibility == 'extern':
1712             storage_class = "%s " % Naming.extern_c_macro
1713         elif visibility == 'public':
1714             storage_class = ""
1715         else:
1716             storage_class = "static "
1717         if 'inline' in self.modifiers:
1718             self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1719         code.putln("%s%s %s {" % (
1720             storage_class,
1721             ' '.join(self.modifiers).upper(), # macro forms 
1722             header))
1723
1724     def generate_argument_declarations(self, env, code):
1725         for arg in self.args:
1726             if arg.default:
1727                 result = arg.calculate_default_value_code(code)
1728                 code.putln('%s = %s;' % (
1729                     arg.type.declaration_code(arg.cname), result))
1730
1731     def generate_keyword_list(self, code):
1732         pass
1733         
1734     def generate_argument_parsing_code(self, env, code):
1735         i = 0
1736         if self.type.optional_arg_count:
1737             code.putln('if (%s) {' % Naming.optional_args_cname)
1738             for arg in self.args:
1739                 if arg.default:
1740                     code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1741                     declarator = arg.declarator
1742                     while not hasattr(declarator, 'name'):
1743                         declarator = declarator.base
1744                     code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1745                     i += 1
1746             for _ in range(self.type.optional_arg_count):
1747                 code.putln('}')
1748             code.putln('}')
1749     
1750     def generate_argument_conversion_code(self, code):
1751         pass
1752     
1753     def generate_argument_type_tests(self, code):
1754         # Generate type tests for args whose type in a parent
1755         # class is a supertype of the declared type.
1756         for arg in self.type.args:
1757             if arg.needs_type_test:
1758                 self.generate_arg_type_test(arg, code)
1759             elif arg.type.is_pyobject and not arg.accept_none:
1760                 self.generate_arg_none_check(arg, code)
1761
1762     def error_value(self):
1763         if self.return_type.is_pyobject:
1764             return "0"
1765         else:
1766             #return None
1767             return self.entry.type.exception_value
1768             
1769     def caller_will_check_exceptions(self):
1770         return self.entry.type.exception_check
1771         
1772     def generate_wrapper_functions(self, code):
1773         # If the C signature of a function has changed, we need to generate
1774         # wrappers to put in the slots here. 
1775         k = 0
1776         entry = self.entry
1777         func_type = entry.type
1778         while entry.prev_entry is not None:
1779             k += 1
1780             entry = entry.prev_entry
1781             entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1782             code.putln()
1783             self.generate_function_header(code, 
1784                                           0,
1785                                           with_dispatch = entry.type.is_overridable, 
1786                                           with_opt_args = entry.type.optional_arg_count, 
1787                                           cname = entry.func_cname)
1788             if not self.return_type.is_void:
1789                 code.put('return ')
1790             args = self.type.args
1791             arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1792             if entry.type.is_overridable:
1793                 arglist.append(Naming.skip_dispatch_cname)
1794             elif func_type.is_overridable:
1795                 arglist.append('0')
1796             if entry.type.optional_arg_count:
1797                 arglist.append(Naming.optional_args_cname)
1798             elif func_type.optional_arg_count:
1799                 arglist.append('NULL')
1800             code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1801             code.putln('}')
1802         
1803
1804 class PyArgDeclNode(Node):
1805     # Argument which must be a Python object (used
1806     # for * and ** arguments).
1807     #
1808     # name        string
1809     # entry       Symtab.Entry
1810     # annotation  ExprNode or None   Py3 argument annotation
1811     child_attrs = []
1812
1813     def generate_function_definitions(self, env, code):
1814         self.entry.generate_function_definitions(env, code)
1815
1816 class DecoratorNode(Node):
1817     # A decorator
1818     #
1819     # decorator    NameNode or CallNode or AttributeNode
1820     child_attrs = ['decorator']
1821
1822
1823 class DefNode(FuncDefNode):
1824     # A Python function definition.
1825     #
1826     # name          string                 the Python name of the function
1827     # lambda_name   string                 the internal name of a lambda 'function'
1828     # decorators    [DecoratorNode]        list of decorators
1829     # args          [CArgDeclNode]         formal arguments
1830     # star_arg      PyArgDeclNode or None  * argument
1831     # starstar_arg  PyArgDeclNode or None  ** argument
1832     # doc           EncodedString or None
1833     # body          StatListNode
1834     # return_type_annotation
1835     #               ExprNode or None       the Py3 return type annotation
1836     #
1837     #  The following subnode is constructed internally
1838     #  when the def statement is inside a Python class definition.
1839     #
1840     #  assmt   AssignmentNode   Function construction/assignment
1841     
1842     child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1843
1844     lambda_name = None
1845     assmt = None
1846     num_kwonly_args = 0
1847     num_required_kw_args = 0
1848     reqd_kw_flags_cname = "0"
1849     is_wrapper = 0
1850     decorators = None
1851     return_type_annotation = None
1852     entry = None
1853     acquire_gil = 0
1854     self_in_stararg = 0
1855
1856     def __init__(self, pos, **kwds):
1857         FuncDefNode.__init__(self, pos, **kwds)
1858         k = rk = r = 0
1859         for arg in self.args:
1860             if arg.kw_only:
1861                 k += 1
1862                 if not arg.default:
1863                     rk += 1
1864             if not arg.default:
1865                 r += 1
1866         self.num_kwonly_args = k
1867         self.num_required_kw_args = rk
1868         self.num_required_args = r
1869         
1870     def as_cfunction(self, cfunc=None, scope=None):
1871         if self.star_arg:
1872             error(self.star_arg.pos, "cdef function cannot have star argument")
1873         if self.starstar_arg:
1874             error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1875         if cfunc is None:
1876             cfunc_args = []
1877             for formal_arg in self.args:
1878                 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1879                 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1880                                                           cname = None,
1881                                                           type = py_object_type,
1882                                                           pos = formal_arg.pos))
1883             cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1884                                               args = cfunc_args,
1885                                               has_varargs = False,
1886                                               exception_value = None,
1887                                               exception_check = False,
1888                                               nogil = False,
1889                                               with_gil = False,
1890                                               is_overridable = True)
1891             cfunc = CVarDefNode(self.pos, type=cfunc_type)
1892         else:
1893             cfunc_type = cfunc.type
1894             if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1895                 error(self.pos, "wrong number of arguments")
1896                 error(cfunc.pos, "previous declaration here")
1897             for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1898                 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1899                 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1900                     formal_arg.type = type_arg.type
1901                     formal_arg.name_declarator = name_declarator
1902         import ExprNodes
1903         if cfunc_type.exception_value is None:
1904             exception_value = None
1905         else:
1906             exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1907         declarator = CFuncDeclaratorNode(self.pos, 
1908                                          base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1909                                          args = self.args,
1910                                          has_varargs = False,
1911                                          exception_check = cfunc_type.exception_check,
1912                                          exception_value = exception_value,
1913                                          with_gil = cfunc_type.with_gil,
1914                                          nogil = cfunc_type.nogil)
1915         return CFuncDefNode(self.pos, 
1916                             modifiers = [],
1917                             base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1918                             declarator = declarator,
1919                             body = self.body,
1920                             doc = self.doc,
1921                             overridable = cfunc_type.is_overridable,
1922                             type = cfunc_type,
1923                             with_gil = cfunc_type.with_gil,
1924                             nogil = cfunc_type.nogil,
1925                             visibility = 'private',
1926                             api = False,
1927                             directive_locals = getattr(cfunc, 'directive_locals', {}))
1928     
1929     def analyse_declarations(self, env):
1930         self.is_classmethod = self.is_staticmethod = False
1931         if self.decorators:
1932             for decorator in self.decorators:
1933                 func = decorator.decorator
1934                 if func.is_name:
1935                     self.is_classmethod |= func.name == 'classmethod'
1936                     self.is_staticmethod |= func.name == 'staticmethod'
1937
1938         if self.is_classmethod and env.lookup_here('classmethod'):
1939             # classmethod() was overridden - not much we can do here ...
1940             self.is_classmethod = False
1941         if self.is_staticmethod and env.lookup_here('staticmethod'):
1942             # staticmethod() was overridden - not much we can do here ...
1943             self.is_staticmethod = False
1944
1945         self.analyse_argument_types(env)
1946         if self.name == '<lambda>':
1947             self.declare_lambda_function(env)
1948         else:
1949             self.declare_pyfunction(env)
1950         self.analyse_signature(env)
1951         self.return_type = self.entry.signature.return_type()
1952         self.create_local_scope(env)
1953
1954     def analyse_argument_types(self, env):
1955         directive_locals = self.directive_locals = env.directives['locals']
1956         allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1957         for arg in self.args:
1958             if hasattr(arg, 'name'):
1959                 type = arg.type
1960                 name_declarator = None
1961             else:
1962                 base_type = arg.base_type.analyse(env)
1963                 name_declarator, type = \
1964                     arg.declarator.analyse(base_type, env)
1965                 arg.name = name_declarator.name
1966             if arg.name in directive_locals:
1967                 type_node = directive_locals[arg.name]
1968                 other_type = type_node.analyse_as_type(env)
1969                 if other_type is None:
1970                     error(type_node.pos, "Not a type")
1971                 elif (type is not PyrexTypes.py_object_type 
1972                         and not type.same_as(other_type)):
1973                     error(arg.base_type.pos, "Signature does not agree with previous declaration")
1974                     error(type_node.pos, "Previous declaration here")
1975                 else:
1976                     type = other_type
1977             if name_declarator and name_declarator.cname:
1978                 error(self.pos,
1979                     "Python function argument cannot have C name specification")
1980             arg.type = type.as_argument_type()
1981             arg.hdr_type = None
1982             arg.needs_conversion = 0
1983             arg.needs_type_test = 0
1984             arg.is_generic = 1
1985             if arg.type.is_pyobject:
1986                 if arg.or_none:
1987                     arg.accept_none = True
1988                 elif arg.not_none:
1989                     arg.accept_none = False
1990                 elif arg.type.is_extension_type or arg.type.is_builtin_type:
1991                     if arg.default and arg.default.constant_result is None:
1992                         # special case: def func(MyType obj = None)
1993                         arg.accept_none = True
1994                     else:
1995                         # default depends on compiler directive
1996                         arg.accept_none = allow_none_for_extension_args
1997                 else:
1998                     # probably just a plain 'object'
1999                     arg.accept_none = True
2000             else:
2001                 arg.accept_none = True # won't be used, but must be there
2002                 if arg.not_none:
2003                     error(arg.pos, "Only Python type arguments can have 'not None'")
2004                 if arg.or_none:
2005                     error(arg.pos, "Only Python type arguments can have 'or None'")
2006
2007     def analyse_signature(self, env):
2008         if self.entry.is_special:
2009             self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2010         elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2011             # Use the simpler calling signature for zero- and one-argument functions.
2012             if self.entry.signature is TypeSlots.pyfunction_signature:
2013                 if len(self.args) == 0:
2014                     self.entry.signature = TypeSlots.pyfunction_noargs
2015                 elif len(self.args) == 1:
2016                     if self.args[0].default is None and not self.args[0].kw_only:
2017                         self.entry.signature = TypeSlots.pyfunction_onearg
2018             elif self.entry.signature is TypeSlots.pymethod_signature:
2019                 if len(self.args) == 1:
2020                     self.entry.signature = TypeSlots.unaryfunc
2021                 elif len(self.args) == 2:
2022                     if self.args[1].default is None and not self.args[1].kw_only:
2023                         self.entry.signature = TypeSlots.ibinaryfunc
2024
2025         sig = self.entry.signature
2026         nfixed = sig.num_fixed_args()
2027         if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2028                and len(self.args) == 0 and self.star_arg:
2029             # this is the only case where a diverging number of
2030             # arguments is not an error - when we have no explicit
2031             # 'self' parameter as in method(*args)
2032             sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2033             self.self_in_stararg = 1
2034             nfixed = 0
2035
2036         for i in range(min(nfixed, len(self.args))):
2037             arg = self.args[i]
2038             arg.is_generic = 0
2039             if sig.is_self_arg(i) and not self.is_staticmethod:
2040                 if self.is_classmethod:
2041                     arg.is_type_arg = 1
2042                     arg.hdr_type = arg.type = Builtin.type_type
2043                 else:
2044                     arg.is_self_arg = 1
2045                     arg.hdr_type = arg.type = env.parent_type
2046                 arg.needs_conversion = 0
2047             else:
2048                 arg.hdr_type = sig.fixed_arg_type(i)
2049                 if not arg.type.same_as(arg.hdr_type):
2050                     if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2051                         arg.needs_type_test = 1
2052                     else:
2053                         arg.needs_conversion = 1
2054             if arg.needs_conversion:
2055                 arg.hdr_cname = Naming.arg_prefix + arg.name
2056             else:
2057                 arg.hdr_cname = Naming.var_prefix + arg.name
2058
2059         if nfixed > len(self.args):
2060             self.bad_signature()
2061             return
2062         elif nfixed < len(self.args):
2063             if not sig.has_generic_args:
2064                 self.bad_signature()
2065             for arg in self.args:
2066                 if arg.is_generic and \
2067                         (arg.type.is_extension_type or arg.type.is_builtin_type):
2068                     arg.needs_type_test = 1
2069
2070     def bad_signature(self):
2071         sig = self.entry.signature
2072         expected_str = "%d" % sig.num_fixed_args()
2073         if sig.has_generic_args:
2074             expected_str = expected_str + " or more"
2075         name = self.name
2076         if name.startswith("__") and name.endswith("__"):
2077             desc = "Special method"
2078         else:
2079             desc = "Method"
2080         error(self.pos,
2081             "%s %s has wrong number of arguments "
2082             "(%d declared, %s expected)" % (
2083                 desc, self.name, len(self.args), expected_str))
2084
2085     def signature_has_nongeneric_args(self):
2086         argcount = len(self.args)
2087         if argcount == 0 or (
2088                 argcount == 1 and (self.args[0].is_self_arg or
2089                                    self.args[0].is_type_arg)):
2090             return 0
2091         return 1
2092
2093     def signature_has_generic_args(self):
2094         return self.entry.signature.has_generic_args
2095     
2096     def declare_pyfunction(self, env):
2097         #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2098         name = self.name
2099         entry = env.lookup_here(name)
2100         if entry and entry.type.is_cfunction and not self.is_wrapper:
2101             warning(self.pos, "Overriding cdef method with def method.", 5)
2102         entry = env.declare_pyfunction(name, self.pos)
2103         self.entry = entry
2104         prefix = env.scope_prefix
2105         entry.func_cname = \
2106             Naming.pyfunc_prefix + prefix + name
2107         entry.pymethdef_cname = \
2108             Naming.pymethdef_prefix + prefix + name
2109         if Options.docstrings:
2110             entry.doc = embed_position(self.pos, self.doc)
2111             entry.doc_cname = \
2112                 Naming.funcdoc_prefix + prefix + name
2113             if entry.is_special:
2114                 if entry.name in TypeSlots.invisible or not entry.doc:
2115                     entry.wrapperbase_cname = None
2116                 else:
2117                     entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2118         else:
2119             entry.doc = None
2120
2121     def declare_lambda_function(self, env):
2122         name = self.name
2123         prefix = env.scope_prefix
2124         func_cname = \
2125             Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2126         entry = env.declare_lambda_function(func_cname, self.pos)
2127         entry.pymethdef_cname = \
2128             Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2129         entry.qualified_name = env.qualify_name(self.lambda_name)
2130         entry.doc = None
2131         self.entry = entry
2132
2133     def declare_arguments(self, env):
2134         for arg in self.args:
2135             if not arg.name:
2136                 error(arg.pos, "Missing argument name")
2137             else:
2138                 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2139                 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2140             if arg.needs_conversion:
2141                 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2142                 if arg.type.is_pyobject:
2143                     arg.entry.init = "0"
2144                 arg.entry.init_to_none = 0
2145             else:
2146                 arg.entry = self.declare_argument(env, arg)
2147             arg.entry.used = 1
2148             arg.entry.is_self_arg = arg.is_self_arg
2149             if arg.hdr_type:
2150                 if arg.is_self_arg or arg.is_type_arg or \
2151                     (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2152                         arg.entry.is_declared_generic = 1
2153         self.declare_python_arg(env, self.star_arg)
2154         self.declare_python_arg(env, self.starstar_arg)
2155
2156     def declare_python_arg(self, env, arg):
2157         if arg:
2158             if env.directives['infer_types'] != False:
2159                 type = PyrexTypes.unspecified_type
2160             else:
2161                 type = py_object_type
2162             entry = env.declare_var(arg.name, type, arg.pos)
2163             entry.used = 1
2164             entry.init = "0"
2165             entry.init_to_none = 0
2166             entry.xdecref_cleanup = 1
2167             arg.entry = entry
2168             env.control_flow.set_state((), (arg.name, 'initialized'), True)
2169             
2170     def analyse_expressions(self, env):
2171         self.local_scope.directives = env.directives
2172         self.analyse_default_values(env)
2173         if self.needs_assignment_synthesis(env):
2174             # Shouldn't we be doing this at the module level too?
2175             self.synthesize_assignment_node(env)
2176
2177     def needs_assignment_synthesis(self, env, code=None):
2178         # Should enable for module level as well, that will require more testing...
2179         if env.is_module_scope:
2180             if code is None:
2181                 return env.directives['binding']
2182             else:
2183                 return code.globalstate.directives['binding']
2184         return env.is_py_class_scope or env.is_closure_scope
2185
2186     def synthesize_assignment_node(self, env):
2187         import ExprNodes
2188         if env.is_py_class_scope:
2189             rhs = ExprNodes.UnboundMethodNode(self.pos, 
2190                 function = ExprNodes.PyCFunctionNode(self.pos,
2191                     pymethdef_cname = self.entry.pymethdef_cname))
2192         elif env.is_closure_scope:
2193             rhs = ExprNodes.InnerFunctionNode(
2194                 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2195         else:
2196             rhs = ExprNodes.PyCFunctionNode(
2197                 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2198         self.assmt = SingleAssignmentNode(self.pos,
2199             lhs = ExprNodes.NameNode(self.pos, name = self.name),
2200             rhs = rhs)
2201         self.assmt.analyse_declarations(env)
2202         self.assmt.analyse_expressions(env)
2203             
2204     def generate_function_header(self, code, with_pymethdef, proto_only=0):
2205         arg_code_list = []
2206         sig = self.entry.signature
2207         if sig.has_dummy_arg or self.self_in_stararg:
2208             arg_code_list.append(
2209                 "PyObject *%s" % Naming.self_cname)
2210         for arg in self.args:
2211             if not arg.is_generic:
2212                 if arg.is_self_arg or arg.is_type_arg:
2213                     arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2214                 else:
2215                     arg_code_list.append(
2216                         arg.hdr_type.declaration_code(arg.hdr_cname))
2217         if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2218             arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2219         if sig.has_generic_args:
2220             arg_code_list.append(
2221                 "PyObject *%s, PyObject *%s"
2222                     % (Naming.args_cname, Naming.kwds_cname))
2223         arg_code = ", ".join(arg_code_list)
2224         dc = self.return_type.declaration_code(self.entry.func_cname)
2225         mf = " ".join(self.modifiers).upper()
2226         if mf: mf += " "
2227         header = "static %s%s(%s)" % (mf, dc, arg_code)
2228         code.putln("%s; /*proto*/" % header)
2229         if proto_only:
2230             return
2231         if (Options.docstrings and self.entry.doc and
2232                 not self.entry.scope.is_property_scope and
2233                 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2234             docstr = self.entry.doc
2235             if docstr.is_unicode:
2236                 docstr = docstr.utf8encode()
2237             code.putln(
2238                 'static char %s[] = "%s";' % (
2239                     self.entry.doc_cname,
2240                     split_string_literal(escape_byte_string(docstr))))
2241             if self.entry.is_special:
2242                 code.putln(
2243                     "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2244         if with_pymethdef:
2245             code.put(
2246                 "static PyMethodDef %s = " % 
2247                     self.entry.pymethdef_cname)
2248             code.put_pymethoddef(self.entry, ";", allow_skip=False)
2249         code.putln("%s {" % header)
2250
2251     def generate_argument_declarations(self, env, code):
2252         for arg in self.args:
2253             if arg.is_generic: # or arg.needs_conversion:
2254                 if arg.needs_conversion:
2255                     code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2256                 elif not arg.entry.in_closure:
2257                     code.put_var_declaration(arg.entry)
2258
2259     def generate_keyword_list(self, code):
2260         if self.signature_has_generic_args() and \
2261                 self.signature_has_nongeneric_args():
2262             code.put(
2263                 "static PyObject **%s[] = {" %
2264                     Naming.pykwdlist_cname)
2265             for arg in self.args:
2266                 if arg.is_generic:
2267                     pystring_cname = code.intern_identifier(arg.name)
2268                     code.put('&%s,' % pystring_cname)
2269             code.putln("0};")
2270
2271     def generate_argument_parsing_code(self, env, code):
2272         # Generate PyArg_ParseTuple call for generic
2273         # arguments, if any.
2274         if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2275             # get rid of unused argument warning
2276             code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2277
2278         old_error_label = code.new_error_label()
2279         our_error_label = code.error_label
2280         end_label = code.new_label("argument_unpacking_done")
2281
2282         has_kwonly_args = self.num_kwonly_args > 0
2283         has_star_or_kw_args = self.star_arg is not None \
2284             or self.starstar_arg is not None or has_kwonly_args
2285
2286         for arg in self.args:
2287             if not arg.type.is_pyobject:
2288                 done = arg.type.create_from_py_utility_code(env)
2289                 if not done: pass # will fail later
2290
2291         if not self.signature_has_generic_args():
2292             if has_star_or_kw_args:
2293                 error(self.pos, "This method cannot have * or keyword arguments")
2294             self.generate_argument_conversion_code(code)
2295
2296         elif not self.signature_has_nongeneric_args():
2297             # func(*args) or func(**kw) or func(*args, **kw)
2298             self.generate_stararg_copy_code(code)
2299
2300         else:
2301             positional_args = []
2302             kw_only_args = []
2303             for arg in self.args:
2304                 arg_entry = arg.entry
2305                 if arg.is_generic:
2306                     if arg.default:
2307                         if not arg.is_self_arg and not arg.is_type_arg:
2308                             if arg.kw_only:
2309                                 kw_only_args.append(arg)
2310                             else:
2311                                 positional_args.append(arg)
2312                     elif arg.kw_only:
2313                         kw_only_args.append(arg)
2314                     elif not arg.is_self_arg and not arg.is_type_arg:
2315                         positional_args.append(arg)
2316
2317             self.generate_tuple_and_keyword_parsing_code(
2318                 positional_args, kw_only_args, end_label, code)
2319
2320         code.error_label = old_error_label
2321         if code.label_used(our_error_label):
2322             if not code.label_used(end_label):
2323                 code.put_goto(end_label)
2324             code.put_label(our_error_label)
2325             if has_star_or_kw_args:
2326                 self.generate_arg_decref(self.star_arg, code)
2327                 if self.starstar_arg:
2328                     if self.starstar_arg.entry.xdecref_cleanup:
2329                         code.put_var_xdecref(self.starstar_arg.entry)
2330                     else:
2331                         code.put_var_decref(self.starstar_arg.entry)
2332             code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2333             # The arguments are put into the closure one after the
2334             # other, so when type errors are found, all references in
2335             # the closure instance must be properly ref-counted to
2336             # facilitate generic closure instance deallocation.  In
2337             # the case of an argument type error, it's best to just
2338             # DECREF+clear the already handled references, as this
2339             # frees their references as early as possible.
2340             for arg in self.args:
2341                 if arg.type.is_pyobject and arg.entry.in_closure:
2342                     code.put_var_xdecref_clear(arg.entry)
2343             if self.needs_closure:
2344                 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2345             code.put_finish_refcount_context()
2346             code.putln("return %s;" % self.error_value())
2347         if code.label_used(end_label):
2348             code.put_label(end_label)
2349
2350     def generate_arg_assignment(self, arg, item, code):
2351         if arg.type.is_pyobject:
2352             if arg.is_generic:
2353                 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2354             entry = arg.entry
2355             code.putln("%s = %s;" % (entry.cname, item))
2356             if entry.in_closure:
2357                 code.put_var_incref(entry)
2358         else:
2359             func = arg.type.from_py_function
2360             if func:
2361                 code.putln("%s = %s(%s); %s" % (
2362                     arg.entry.cname,
2363                     func,
2364                     item,
2365                     code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2366             else:
2367                 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2368     
2369     def generate_arg_xdecref(self, arg, code):
2370         if arg:
2371             code.put_var_xdecref(arg.entry)
2372     
2373     def generate_arg_decref(self, arg, code):
2374         if arg:
2375             code.put_var_decref(arg.entry)
2376
2377     def generate_stararg_copy_code(self, code):
2378         if not self.star_arg:
2379             code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2380             code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2381                        Naming.args_cname)
2382             code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2383                     self.name, Naming.args_cname, self.error_value()))
2384             code.putln("}")
2385
2386         code.globalstate.use_utility_code(keyword_string_check_utility_code)
2387
2388         if self.starstar_arg:
2389             if self.star_arg:
2390                 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2391             else:
2392                 kwarg_check = "%s" % Naming.kwds_cname
2393         else:
2394             kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2395                 Naming.kwds_cname, Naming.kwds_cname)
2396         code.putln(
2397             "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2398                 kwarg_check, Naming.kwds_cname, self.name,
2399                 bool(self.starstar_arg), self.error_value()))
2400
2401         if self.starstar_arg:
2402             code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2403                     self.starstar_arg.entry.cname,
2404                     Naming.kwds_cname,
2405                     Naming.kwds_cname))
2406             code.putln("if (unlikely(!%s)) return %s;" % (
2407                     self.starstar_arg.entry.cname, self.error_value()))
2408             self.starstar_arg.entry.xdecref_cleanup = 0
2409             code.put_gotref(self.starstar_arg.entry.cname)
2410
2411         if self.self_in_stararg:
2412             # need to create a new tuple with 'self' inserted as first item
2413             code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2414                     self.star_arg.entry.cname,
2415                     Naming.args_cname,
2416                     self.star_arg.entry.cname))
2417             if self.starstar_arg:
2418                 code.putln("{")
2419                 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2420                 code.putln("return %s;" % self.error_value())
2421                 code.putln("}")
2422             else:
2423                 code.putln("return %s;" % self.error_value())
2424             code.put_gotref(self.star_arg.entry.cname)
2425             code.put_incref(Naming.self_cname, py_object_type)
2426             code.put_giveref(Naming.self_cname)
2427             code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2428                 self.star_arg.entry.cname, Naming.self_cname))
2429             temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2430             code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2431                 temp, temp, Naming.args_cname, temp))
2432             code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2433                 Naming.args_cname, temp))
2434             code.put_incref("item", py_object_type)
2435             code.put_giveref("item")
2436             code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2437                 self.star_arg.entry.cname, temp))
2438             code.putln("}")
2439             code.funcstate.release_temp(temp)
2440             self.star_arg.entry.xdecref_cleanup = 0
2441         elif self.star_arg:
2442             code.put_incref(Naming.args_cname, py_object_type)
2443             code.putln("%s = %s;" % (
2444                     self.star_arg.entry.cname,
2445                     Naming.args_cname))
2446             self.star_arg.entry.xdecref_cleanup = 0
2447
2448     def generate_tuple_and_keyword_parsing_code(self, positional_args,
2449                                                 kw_only_args, success_label, code):
2450         argtuple_error_label = code.new_label("argtuple_error")
2451
2452         min_positional_args = self.num_required_args - self.num_required_kw_args
2453         if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2454             min_positional_args -= 1
2455         max_positional_args = len(positional_args)
2456         has_fixed_positional_count = not self.star_arg and \
2457             min_positional_args == max_positional_args
2458
2459         code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2460         code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2461         if self.num_required_kw_args:
2462             code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2463
2464         if self.starstar_arg or self.star_arg:
2465             self.generate_stararg_init_code(max_positional_args, code)
2466
2467         # --- optimised code when we receive keyword arguments
2468         if self.num_required_kw_args:
2469             likely_hint = "likely"
2470         else:
2471             likely_hint = "unlikely"
2472         code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2473         self.generate_keyword_unpacking_code(
2474             min_positional_args, max_positional_args,
2475             has_fixed_positional_count,
2476             positional_args, kw_only_args, argtuple_error_label, code)
2477
2478         # --- optimised code when we do not receive any keyword arguments
2479         if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2480             # Python raises arg tuple related errors first, so we must
2481             # check the length here
2482             if min_positional_args == max_positional_args and not self.star_arg:
2483                 compare = '!='
2484             else:
2485                 compare = '<'
2486             code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2487                     Naming.args_cname, compare, min_positional_args))
2488             code.put_goto(argtuple_error_label)
2489
2490         if self.num_required_kw_args:
2491             # pure error case: keywords required but not passed
2492             if max_positional_args > min_positional_args and not self.star_arg:
2493                 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2494                         Naming.args_cname, max_positional_args))
2495                 code.put_goto(argtuple_error_label)
2496             code.putln('} else {')
2497             for i, arg in enumerate(kw_only_args):
2498                 if not arg.default:
2499                     pystring_cname = code.intern_identifier(arg.name)
2500                     # required keyword-only argument missing
2501                     code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2502                             self.name,
2503                             pystring_cname))
2504                     code.putln(code.error_goto(self.pos))
2505                     break
2506
2507         elif min_positional_args == max_positional_args:
2508             # parse the exact number of positional arguments from the
2509             # args tuple
2510             code.putln('} else {')
2511             for i, arg in enumerate(positional_args):
2512                 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2513                 self.generate_arg_assignment(arg, item, code)
2514             self.generate_arg_default_assignments(code)
2515
2516         else:
2517             # parse the positional arguments from the variable length
2518             # args tuple
2519             code.putln('} else {')
2520             self.generate_arg_default_assignments(code)
2521             code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2522             if self.star_arg:
2523                 code.putln('default:')
2524             reversed_args = list(enumerate(positional_args))[::-1]
2525             for i, arg in reversed_args:
2526                 if i >= min_positional_args-1:
2527                     if min_positional_args > 1:
2528                         code.putln('case %2d:' % (i+1)) # pure code beautification
2529                     else:
2530                         code.put('case %2d: ' % (i+1))
2531                 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2532                 self.generate_arg_assignment(arg, item, code)
2533             if min_positional_args == 0:
2534                 code.put('case  0: ')
2535             code.putln('break;')
2536             if self.star_arg:
2537                 if min_positional_args:
2538                     for i in range(min_positional_args-1, -1, -1):
2539                         code.putln('case %2d:' % i)
2540                     code.put_goto(argtuple_error_label)
2541             else:
2542                 code.put('default: ')
2543                 code.put_goto(argtuple_error_label)
2544             code.putln('}')
2545
2546         code.putln('}')
2547
2548         if code.label_used(argtuple_error_label):
2549             code.put_goto(success_label)
2550             code.put_label(argtuple_error_label)
2551             code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2552                     self.name, has_fixed_positional_count,
2553                     min_positional_args, max_positional_args,
2554                     Naming.args_cname))
2555             code.putln(code.error_goto(self.pos))
2556
2557     def generate_arg_default_assignments(self, code):
2558         for arg in self.args:
2559             if arg.is_generic and arg.default:
2560                 code.putln(
2561                     "%s = %s;" % (
2562                         arg.entry.cname,
2563                         arg.calculate_default_value_code(code)))
2564
2565     def generate_stararg_init_code(self, max_positional_args, code):
2566         if self.starstar_arg:
2567             self.starstar_arg.entry.xdecref_cleanup = 0
2568             code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2569                     self.starstar_arg.entry.cname,
2570                     self.starstar_arg.entry.cname,
2571                     self.error_value()))
2572             code.put_gotref(self.starstar_arg.entry.cname)
2573         if self.star_arg:
2574             self.star_arg.entry.xdecref_cleanup = 0
2575             code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2576                     Naming.args_cname,
2577                     max_positional_args))
2578             code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2579                     self.star_arg.entry.cname, Naming.args_cname,
2580                     max_positional_args, Naming.args_cname))
2581             code.put_gotref(self.star_arg.entry.cname)
2582             if self.starstar_arg:
2583                 code.putln("")
2584                 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2585                 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2586                 code.putln('return %s;' % self.error_value())
2587                 code.putln('}')
2588             else:
2589                 code.putln("if (unlikely(!%s)) return %s;" % (
2590                         self.star_arg.entry.cname, self.error_value()))
2591             code.putln('} else {')
2592             code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2593             code.put_incref(Naming.empty_tuple, py_object_type)
2594             code.putln('}')
2595
2596     def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2597                                         has_fixed_positional_count, positional_args,
2598                                         kw_only_args, argtuple_error_label, code):
2599         all_args = tuple(positional_args) + tuple(kw_only_args)
2600         max_args = len(all_args)
2601
2602         code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2603                    Naming.kwds_cname)
2604         # the 'values' array collects borrowed references to arguments
2605         # before doing any type coercion etc.
2606         code.putln("PyObject* values[%d] = {%s};" % (
2607             max_args, ','.join('0'*max_args)))
2608
2609         # assign borrowed Python default values to the values array,
2610         # so that they can be overwritten by received arguments below
2611         for i, arg in enumerate(all_args):
2612             if arg.default and arg.type.is_pyobject:
2613                 default_value = arg.calculate_default_value_code(code)
2614                 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2615
2616         # parse the args tuple and check that it's not too long
2617         code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2618         if self.star_arg:
2619             code.putln('default:')
2620         for i in range(max_positional_args-1, -1, -1):
2621             code.put('case %2d: ' % (i+1))
2622             code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2623                     i, Naming.args_cname, i))
2624         code.putln('case  0: break;')
2625         if not self.star_arg:
2626             code.put('default: ') # more arguments than allowed
2627             code.put_goto(argtuple_error_label)
2628         code.putln('}')
2629
2630         # now fill up the positional/required arguments with values
2631         # from the kw dict
2632         if self.num_required_args or max_positional_args > 0:
2633             last_required_arg = -1
2634             for i, arg in enumerate(all_args):
2635                 if not arg.default:
2636                     last_required_arg = i
2637             if last_required_arg < max_positional_args:
2638                 last_required_arg = max_positional_args-1
2639             num_required_args = self.num_required_args
2640             if max_positional_args > 0:
2641                 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2642             for i, arg in enumerate(all_args[:last_required_arg+1]):
2643                 if max_positional_args > 0 and i <= max_positional_args:
2644                     if self.star_arg and i == max_positional_args:
2645                         code.putln('default:')
2646                     else:
2647                         code.putln('case %2d:' % i)
2648                 pystring_cname = code.intern_identifier(arg.name)
2649                 if arg.default:
2650                     if arg.kw_only:
2651                         # handled separately below
2652                         continue
2653                     code.putln('if (kw_args > 0) {')
2654                     code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2655                         Naming.kwds_cname, pystring_cname))
2656                     code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2657                     code.putln('}')
2658                 else:
2659                     num_required_args -= 1
2660                     code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2661                         i, Naming.kwds_cname, pystring_cname))
2662                     code.putln('if (likely(values[%d])) kw_args--;' % i);
2663                     if i < min_positional_args:
2664                         if i == 0:
2665                             # special case: we know arg 0 is missing
2666                             code.put('else ')
2667                             code.put_goto(argtuple_error_label)
2668                         else:
2669                             # print the correct number of values (args or
2670                             # kwargs) that were passed into positional
2671                             # arguments up to this point
2672                             code.putln('else {')
2673                             code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2674                                     self.name, has_fixed_positional_count,
2675                                     min_positional_args, max_positional_args, i))
2676                             code.putln(code.error_goto(self.pos))
2677                             code.putln('}')
2678                     elif arg.kw_only:
2679                         code.putln('else {')
2680                         code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2681                                 self.name, pystring_cname))
2682                         code.putln(code.error_goto(self.pos))
2683                         code.putln('}')
2684             if max_positional_args > 0:
2685                 code.putln('}')
2686
2687         if kw_only_args and not self.starstar_arg:
2688             # unpack optional keyword-only arguments
2689             # checking for interned strings in a dict is faster than iterating
2690             # but it's too likely that we must iterate if we expect **kwargs
2691             optional_args = []
2692             for i, arg in enumerate(all_args[max_positional_args:]):
2693                 if not arg.kw_only or not arg.default:
2694                     continue
2695                 optional_args.append((i+max_positional_args, arg))
2696             if optional_args:
2697                 # this mimics an unrolled loop so that we can "break" out of it
2698                 code.putln('while (kw_args > 0) {')
2699                 code.putln('PyObject* value;')
2700                 for i, arg in optional_args:
2701                     pystring_cname = code.intern_identifier(arg.name)
2702                     code.putln(
2703                         'value = PyDict_GetItem(%s, %s);' % (
2704                         Naming.kwds_cname, pystring_cname))
2705                     code.putln(
2706                         'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2707                 code.putln('break;')
2708                 code.putln('}')
2709
2710         code.putln('if (unlikely(kw_args > 0)) {')
2711         # non-positional/-required kw args left in dict: default args,
2712         # kw-only args, **kwargs or error
2713         #
2714         # This is sort of a catch-all: except for checking required
2715         # arguments, this will always do the right thing for unpacking
2716         # keyword arguments, so that we can concentrate on optimising
2717         # common cases above.
2718         if max_positional_args == 0:
2719             pos_arg_count = "0"
2720         elif self.star_arg:
2721             code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2722                     Naming.args_cname, max_positional_args,
2723                     Naming.args_cname, max_positional_args))
2724             pos_arg_count = "used_pos_args"
2725         else:
2726             pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2727         code.globalstate.use_utility_code(parse_keywords_utility_code)
2728         code.put(
2729             'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2730                 Naming.kwds_cname,
2731                 Naming.pykwdlist_cname,
2732                 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2733                 pos_arg_count,
2734                 self.name))
2735         code.putln(code.error_goto(self.pos))
2736         code.putln('}')
2737
2738         # convert arg values to their final type and assign them
2739         for i, arg in enumerate(all_args):
2740             if arg.default and not arg.type.is_pyobject:
2741                 code.putln("if (values[%d]) {" % i)
2742             self.generate_arg_assignment(arg, "values[%d]" % i, code)
2743             if arg.default and not arg.type.is_pyobject:
2744                 code.putln('} else {')
2745                 code.putln(
2746                     "%s = %s;" % (
2747                         arg.entry.cname,
2748                         arg.calculate_default_value_code(code)))
2749                 code.putln('}')
2750
2751     def generate_argument_conversion_code(self, code):
2752         # Generate code to convert arguments from signature type to
2753         # declared type, if needed.  Also copies signature arguments
2754         # into closure fields.
2755         for arg in self.args:
2756             if arg.needs_conversion:
2757                 self.generate_arg_conversion(arg, code)
2758             elif arg.entry.in_closure:
2759                 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2760                 if arg.type.is_pyobject:
2761                     code.put_var_incref(arg.entry)
2762
2763     def generate_arg_conversion(self, arg, code):
2764         # Generate conversion code for one argument.
2765         old_type = arg.hdr_type
2766         new_type = arg.type
2767         if old_type.is_pyobject:
2768             if arg.default:
2769                 code.putln("if (%s) {" % arg.hdr_cname)
2770             else:
2771                 code.putln("assert(%s); {" % arg.hdr_cname)
2772             self.generate_arg_conversion_from_pyobject(arg, code)
2773             code.putln("}")
2774         elif new_type.is_pyobject:
2775             self.generate_arg_conversion_to_pyobject(arg, code)
2776         else:
2777             if new_type.assignable_from(old_type):
2778                 code.putln(
2779                     "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2780             else:
2781                 error(arg.pos,
2782                     "Cannot convert 1 argument from '%s' to '%s'" %
2783                         (old_type, new_type))
2784     
2785     def generate_arg_conversion_from_pyobject(self, arg, code):
2786         new_type = arg.type
2787         func = new_type.from_py_function
2788         # copied from CoerceFromPyTypeNode
2789         if func:
2790             lhs = arg.entry.cname
2791             rhs = "%s(%s)" % (func, arg.hdr_cname)
2792             if new_type.is_enum:
2793                 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2794             code.putln("%s = %s; %s" % (
2795                 lhs, 
2796                 rhs,
2797                 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2798         else:
2799             error(arg.pos, 
2800                 "Cannot convert Python object argument to type '%s'" 
2801                     % new_type)
2802     
2803     def generate_arg_conversion_to_pyobject(self, arg, code):
2804         old_type = arg.hdr_type
2805         func = old_type.to_py_function
2806         if func:
2807             code.putln("%s = %s(%s); %s" % (
2808                 arg.entry.cname,
2809                 func,
2810                 arg.hdr_cname,
2811                 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2812             code.put_var_gotref(arg.entry)
2813         else:
2814             error(arg.pos,
2815                 "Cannot convert argument of type '%s' to Python object"
2816                     % old_type)
2817
2818     def generate_argument_type_tests(self, code):
2819         # Generate type tests for args whose signature
2820         # type is PyObject * and whose declared type is
2821         # a subtype thereof.
2822         for arg in self.args:
2823             if arg.needs_type_test:
2824                 self.generate_arg_type_test(arg, code)
2825             elif not arg.accept_none and arg.type.is_pyobject:
2826                 self.generate_arg_none_check(arg, code)
2827
2828     def error_value(self):
2829         return self.entry.signature.error_value
2830     
2831     def caller_will_check_exceptions(self):
2832         return 1
2833             
2834 class OverrideCheckNode(StatNode):
2835     # A Node for dispatching to the def method if it
2836     # is overriden. 
2837     #
2838     #  py_func
2839     #
2840     #  args
2841     #  func_temp
2842     #  body
2843     
2844     child_attrs = ['body']
2845     
2846     body = None
2847
2848     def analyse_expressions(self, env):
2849         self.args = env.arg_entries
2850         if self.py_func.is_module_scope:
2851             first_arg = 0
2852         else:
2853             first_arg = 1
2854         import ExprNodes
2855         self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2856         call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2857         call_node = ExprNodes.SimpleCallNode(self.pos,
2858                                              function=self.func_node, 
2859                                              args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2860         self.body = ReturnStatNode(self.pos, value=call_node)
2861         self.body.analyse_expressions(env)
2862         
2863     def generate_execution_code(self, code):
2864         interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2865         # Check to see if we are an extension type
2866         if self.py_func.is_module_scope:
2867             self_arg = "((PyObject *)%s)" % Naming.module_cname
2868         else:
2869             self_arg = "((PyObject *)%s)" % self.args[0].cname
2870         code.putln("/* Check if called by wrapper */")
2871         code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2872         code.putln("/* Check if overriden in Python */")
2873         if self.py_func.is_module_scope:
2874             code.putln("else {")
2875         else:
2876             code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2877         func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2878         self.func_node.set_cname(func_node_temp)
2879         # need to get attribute manually--scope would return cdef method
2880         err = code.error_goto_if_null(func_node_temp, self.pos)
2881         code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2882             func_node_temp, self_arg, interned_attr_cname, err))
2883         code.put_gotref(func_node_temp)
2884         is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2885         is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2886             func_node_temp, self.py_func.entry.func_cname)
2887         code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2888         self.body.generate_execution_code(code)
2889         code.putln("}")
2890         code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2891         code.funcstate.release_temp(func_node_temp)
2892         code.putln("}")
2893
2894 class ClassDefNode(StatNode, BlockNode):
2895     pass
2896
2897 class PyClassDefNode(ClassDefNode):
2898     #  A Python class definition.
2899     #
2900     #  name     EncodedString   Name of the class
2901     #  doc      string or None
2902     #  body     StatNode        Attribute definition code
2903     #  entry    Symtab.Entry
2904     #  scope    PyClassScope
2905     #  decorators    [DecoratorNode]        list of decorators or None
2906     #
2907     #  The following subnodes are constructed internally:
2908     #
2909     #  dict     DictNode   Class dictionary
2910     #  classobj ClassNode  Class object
2911     #  target   NameNode   Variable to assign class object to
2912
2913     child_attrs = ["body", "dict", "classobj", "target"]
2914     decorators = None
2915     
2916     def __init__(self, pos, name, bases, doc, body, decorators = None):
2917         StatNode.__init__(self, pos)
2918         self.name = name
2919         self.doc = doc
2920         self.body = body
2921         self.decorators = decorators
2922         import ExprNodes
2923         self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2924         if self.doc and Options.docstrings:
2925             doc = embed_position(self.pos, self.doc)
2926             # FIXME: correct string node?
2927             doc_node = ExprNodes.StringNode(pos, value = doc)
2928         else:
2929             doc_node = None
2930         self.classobj = ExprNodes.ClassNode(pos, name = name,
2931             bases = bases, dict = self.dict, doc = doc_node)
2932         self.target = ExprNodes.NameNode(pos, name = name)
2933         
2934     def as_cclass(self):
2935         """
2936         Return this node as if it were declared as an extension class
2937         """
2938         bases = self.classobj.bases.args
2939         if len(bases) == 0:
2940             base_class_name = None
2941             base_class_module = None
2942         elif len(bases) == 1:
2943             base = bases[0]
2944             path = []
2945             from ExprNodes import AttributeNode, NameNode
2946             while isinstance(base, AttributeNode):
2947                 path.insert(0, base.attribute)
2948                 base = base.obj
2949             if isinstance(base, NameNode):
2950                 path.insert(0, base.name)
2951                 base_class_name = path[-1]
2952                 if len(path) > 1:
2953                     base_class_module = u'.'.join(path[:-1])
2954                 else:
2955                     base_class_module = None
2956             else:
2957                 error(self.classobj.bases.args.pos, "Invalid base class")
2958         else:
2959             error(self.classobj.bases.args.pos, "C class may only have one base class")
2960             return None
2961         
2962         return CClassDefNode(self.pos, 
2963                              visibility = 'private',
2964                              module_name = None,
2965                              class_name = self.name,
2966                              base_class_module = base_class_module,
2967                              base_class_name = base_class_name,
2968                              decorators = self.decorators,
2969                              body = self.body,
2970                              in_pxd = False,
2971                              doc = self.doc)
2972         
2973     def create_scope(self, env):
2974         genv = env
2975         while env.is_py_class_scope or env.is_c_class_scope:
2976             env = env.outer_scope
2977         cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2978         return cenv
2979     
2980     def analyse_declarations(self, env):
2981         self.target.analyse_target_declaration(env)
2982         cenv = self.create_scope(env)
2983         cenv.directives = env.directives
2984         cenv.class_obj_cname = self.target.entry.cname
2985         self.body.analyse_declarations(cenv)
2986     
2987     def analyse_expressions(self, env):
2988         self.dict.analyse_expressions(env)
2989         self.classobj.analyse_expressions(env)
2990         genv = env.global_scope()
2991         cenv = self.scope
2992         self.body.analyse_expressions(cenv)
2993         self.target.analyse_target_expression(env, self.classobj)
2994     
2995     def generate_function_definitions(self, env, code):
2996         self.body.generate_function_definitions(self.scope, code)
2997     
2998     def generate_execution_code(self, code):
2999         code.pyclass_stack.append(self)
3000         cenv = self.scope
3001         self.dict.generate_evaluation_code(code)
3002         self.classobj.generate_evaluation_code(code)
3003         cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3004         self.body.generate_execution_code(code)
3005         self.target.generate_assignment_code(self.classobj, code)
3006         self.dict.generate_disposal_code(code)
3007         self.dict.free_temps(code)
3008         code.pyclass_stack.pop()
3009
3010
3011 class CClassDefNode(ClassDefNode):
3012     #  An extension type definition.
3013     #
3014     #  visibility         'private' or 'public' or 'extern'
3015     #  typedef_flag       boolean
3016     #  api                boolean
3017     #  module_name        string or None    For import of extern type objects
3018     #  class_name         string            Unqualified name of class
3019     #  as_name            string or None    Name to declare as in this scope
3020     #  base_class_module  string or None    Module containing the base class
3021     #  base_class_name    string or None    Name of the base class
3022     #  objstruct_name     string or None    Specified C name of object struct
3023     #  typeobj_name       string or None    Specified C name of type object
3024     #  in_pxd             boolean           Is in a .pxd file
3025     #  decorators         [DecoratorNode]   list of decorators or None
3026     #  doc                string or None
3027     #  body               StatNode or None
3028     #  entry              Symtab.Entry
3029     #  base_type          PyExtensionType or None
3030     #  buffer_defaults_node DictNode or None Declares defaults for a buffer
3031     #  buffer_defaults_pos
3032
3033     child_attrs = ["body"]
3034     buffer_defaults_node = None
3035     buffer_defaults_pos = None
3036     typedef_flag = False
3037     api = False
3038     objstruct_name = None
3039     typeobj_name = None
3040     decorators = None
3041
3042     def analyse_declarations(self, env):
3043         #print "CClassDefNode.analyse_declarations:", self.class_name
3044         #print "...visibility =", self.visibility
3045         #print "...module_name =", self.module_name
3046
3047         import Buffer
3048         if self.buffer_defaults_node:
3049             buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3050                                                             env, [], self.buffer_defaults_node,
3051                                                             need_complete=False)
3052         else:
3053             buffer_defaults = None
3054
3055         if env.in_cinclude and not self.objstruct_name:
3056             error(self.pos, "Object struct name specification required for "
3057                 "C class defined in 'extern from' block")
3058         self.base_type = None
3059         # Now that module imports are cached, we need to 
3060         # import the modules for extern classes. 
3061         if self.module_name:
3062             self.module = None
3063             for module in env.cimported_modules:
3064                 if module.name == self.module_name:
3065                     self.module = module
3066             if self.module is None:
3067                 self.module = ModuleScope(self.module_name, None, env.context)
3068                 self.module.has_extern_class = 1
3069                 env.add_imported_module(self.module)
3070
3071         if self.base_class_name:
3072             if self.base_class_module:
3073                 base_class_scope = env.find_module(self.base_class_module, self.pos)
3074             else:
3075                 base_class_scope = env
3076             if self.base_class_name == 'object':
3077                 # extension classes are special and don't need to inherit from object
3078                 if base_class_scope is None or base_class_scope.lookup('object') is None:
3079                     self.base_class_name = None
3080                     self.base_class_module = None
3081                     base_class_scope = None
3082             if base_class_scope:
3083                 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3084                 if base_class_entry:
3085                     if not base_class_entry.is_type:
3086                         error(self.pos, "'%s' is not a type name" % self.base_class_name)
3087                     elif not base_class_entry.type.is_extension_type:
3088                         error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3089                     elif not base_class_entry.type.is_complete():
3090                         error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
3091                     else:
3092                         self.base_type = base_class_entry.type
3093         has_body = self.body is not None
3094         if self.module_name and self.visibility != 'extern':
3095             module_path = self.module_name.split(".")
3096             home_scope = env.find_imported_module(module_path, self.pos)
3097             if not home_scope:
3098                 return
3099         else:
3100             home_scope = env
3101
3102         if self.visibility == 'extern':
3103             if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3104                 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3105
3106         self.entry = home_scope.declare_c_class(
3107             name = self.class_name, 
3108             pos = self.pos,
3109             defining = has_body and self.in_pxd,
3110             implementing = has_body and not self.in_pxd,
3111             module_name = self.module_name,
3112             base_type = self.base_type,
3113             objstruct_cname = self.objstruct_name,
3114             typeobj_cname = self.typeobj_name,
3115             visibility = self.visibility,
3116             typedef_flag = self.typedef_flag,
3117             api = self.api,
3118             buffer_defaults = buffer_defaults)
3119         if home_scope is not env and self.visibility == 'extern':
3120             env.add_imported_entry(self.class_name, self.entry, pos)
3121         self.scope = scope = self.entry.type.scope
3122         if scope is not None:
3123             scope.directives = env.directives
3124
3125         if self.doc and Options.docstrings:
3126             scope.doc = embed_position(self.pos, self.doc)
3127             
3128         if has_body:
3129             self.body.analyse_declarations(scope)
3130             if self.in_pxd:
3131                 scope.defined = 1
3132             else:
3133                 scope.implemented = 1
3134         env.allocate_vtable_names(self.entry)
3135         
3136     def analyse_expressions(self, env):
3137         if self.body:
3138             scope = self.entry.type.scope
3139             self.body.analyse_expressions(scope)
3140     
3141     def generate_function_definitions(self, env, code):
3142         if self.body:
3143             self.body.generate_function_definitions(
3144                 self.entry.type.scope, code)
3145     
3146     def generate_execution_code(self, code):
3147         # This is needed to generate evaluation code for
3148         # default values of method arguments.
3149         if self.body:
3150             self.body.generate_execution_code(code)
3151             
3152     def annotate(self, code):
3153         if self.body:
3154             self.body.annotate(code)
3155
3156
3157 class PropertyNode(StatNode):
3158     #  Definition of a property in an extension type.
3159     #
3160     #  name   string
3161     #  doc    EncodedString or None    Doc string
3162     #  body   StatListNode
3163     
3164     child_attrs = ["body"]
3165
3166     def analyse_declarations(self, env):
3167         entry = env.declare_property(self.name, self.doc, self.pos)
3168         if entry:
3169             entry.scope.directives = env.directives
3170             self.body.analyse_declarations(entry.scope)
3171
3172     def analyse_expressions(self, env):
3173         self.body.analyse_expressions(env)
3174     
3175     def generate_function_definitions(self, env, code):
3176         self.body.generate_function_definitions(env, code)
3177
3178     def generate_execution_code(self, code):
3179         pass
3180
3181     def annotate(self, code):
3182         self.body.annotate(code)
3183
3184
3185 class GlobalNode(StatNode):
3186     # Global variable declaration.
3187     #
3188     # names    [string]
3189     
3190     child_attrs = []
3191
3192     def analyse_declarations(self, env):
3193         for name in self.names:
3194             env.declare_global(name, self.pos)
3195
3196     def analyse_expressions(self, env):
3197         pass
3198     
3199     def generate_execution_code(self, code):
3200         pass
3201
3202
3203 class ExprStatNode(StatNode):
3204     #  Expression used as a statement.
3205     #
3206     #  expr   ExprNode
3207
3208     child_attrs = ["expr"]
3209     
3210     def analyse_declarations(self, env):
3211         import ExprNodes
3212         if isinstance(self.expr, ExprNodes.GeneralCallNode):
3213             func = self.expr.function.as_cython_attribute()
3214             if func == u'declare':
3215                 args, kwds = self.expr.explicit_args_kwds()
3216                 if len(args):
3217                     error(self.expr.pos, "Variable names must be specified.")
3218                 for var, type_node in kwds.key_value_pairs:
3219                     type = type_node.analyse_as_type(env)
3220                     if type is None:
3221                         error(type_node.pos, "Unknown type")
3222                     else:
3223                         env.declare_var(var.value, type, var.pos, is_cdef = True)
3224                 self.__class__ = PassStatNode
3225     
3226     def analyse_expressions(self, env):
3227         self.expr.analyse_expressions(env)
3228     
3229     def generate_execution_code(self, code):
3230         self.expr.generate_evaluation_code(code)
3231         if not self.expr.is_temp and self.expr.result():
3232             code.putln("%s;" % self.expr.result())
3233         self.expr.generate_disposal_code(code)
3234         self.expr.free_temps(code)
3235
3236     def generate_function_definitions(self, env, code):
3237         self.expr.generate_function_definitions(env, code)
3238
3239     def annotate(self, code):
3240         self.expr.annotate(code)
3241
3242
3243 class AssignmentNode(StatNode):
3244     #  Abstract base class for assignment nodes.
3245     #
3246     #  The analyse_expressions and generate_execution_code
3247     #  phases of assignments are split into two sub-phases
3248     #  each, to enable all the right hand sides of a
3249     #  parallel assignment to be evaluated before assigning
3250     #  to any of the left hand sides.
3251
3252     def analyse_expressions(self, env):
3253         self.analyse_types(env)
3254
3255 #       def analyse_expressions(self, env):
3256 #           self.analyse_expressions_1(env)
3257 #           self.analyse_expressions_2(env)
3258
3259     def generate_execution_code(self, code):
3260         self.generate_rhs_evaluation_code(code)
3261         self.generate_assignment_code(code)
3262         
3263
3264 class SingleAssignmentNode(AssignmentNode):
3265     #  The simplest case:
3266     #
3267     #    a = b
3268     #
3269     #  lhs      ExprNode      Left hand side
3270     #  rhs      ExprNode      Right hand side
3271     #  first    bool          Is this guaranteed the first assignment to lhs?
3272     
3273     child_attrs = ["lhs", "rhs"]
3274     first = False
3275     declaration_only = False
3276
3277     def analyse_declarations(self, env):
3278         import ExprNodes
3279         
3280         # handle declarations of the form x = cython.foo()
3281         if isinstance(self.rhs, ExprNodes.CallNode):
3282             func_name = self.rhs.function.as_cython_attribute()
3283             if func_name:
3284                 args, kwds = self.rhs.explicit_args_kwds()
3285                 
3286                 if func_name in ['declare', 'typedef']:
3287                     if len(args) > 2 or kwds is not None:
3288                         error(rhs.pos, "Can only declare one type at a time.")
3289                         return
3290                     type = args[0].analyse_as_type(env)
3291                     if type is None:
3292                         error(args[0].pos, "Unknown type")
3293                         return
3294                     lhs = self.lhs
3295                     if func_name == 'declare':
3296                         if isinstance(lhs, ExprNodes.NameNode):
3297                             vars = [(lhs.name, lhs.pos)]
3298                         elif isinstance(lhs, ExprNodes.TupleNode):
3299                             vars = [(var.name, var.pos) for var in lhs.args]
3300                         else:
3301                             error(lhs.pos, "Invalid declaration")
3302                             return
3303                         for var, pos in vars:
3304                             env.declare_var(var, type, pos, is_cdef = True)
3305                         if len(args) == 2:
3306                             # we have a value
3307                             self.rhs = args[1]
3308                         else:
3309                             self.declaration_only = True
3310                     else:
3311                         self.declaration_only = True
3312                         if not isinstance(lhs, ExprNodes.NameNode):
3313                             error(lhs.pos, "Invalid declaration.")
3314                         env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3315                     
3316                 elif func_name in ['struct', 'union']:
3317                     self.declaration_only = True
3318                     if len(args) > 0 or kwds is None:
3319                         error(rhs.pos, "Struct or union members must be given by name.")
3320                         return
3321                     members = []
3322                     for member, type_node in kwds.key_value_pairs:
3323                         type = type_node.analyse_as_type(env)
3324                         if type is None:
3325                             error(type_node.pos, "Unknown type")
3326                         else:
3327                             members.append((member.value, type, member.pos))
3328                     if len(members) < len(kwds.key_value_pairs):
3329                         return
3330                     if not isinstance(self.lhs, ExprNodes.NameNode):
3331                         error(self.lhs.pos, "Invalid declaration.")
3332                     name = self.lhs.name
3333                     scope = StructOrUnionScope(name)
3334                     env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3335                     for member, type, pos in members:
3336                         scope.declare_var(member, type, pos)
3337                     
3338         if self.declaration_only:
3339             return
3340         else:
3341             self.lhs.analyse_target_declaration(env)
3342     
3343     def analyse_types(self, env, use_temp = 0):
3344         self.rhs.analyse_types(env)
3345         self.lhs.analyse_target_types(env)
3346         self.lhs.gil_assignment_check(env)
3347         self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3348         if use_temp:
3349             self.rhs = self.rhs.coerce_to_temp(env)
3350     
3351     def generate_rhs_evaluation_code(self, code):
3352         self.rhs.generate_evaluation_code(code)
3353     
3354     def generate_assignment_code(self, code):
3355         self.lhs.generate_assignment_code(self.rhs, code)
3356
3357     def generate_function_definitions(self, env, code):
3358         self.rhs.generate_function_definitions(env, code)
3359
3360     def annotate(self, code):
3361         self.lhs.annotate(code)
3362         self.rhs.annotate(code)
3363
3364
3365 class CascadedAssignmentNode(AssignmentNode):
3366     #  An assignment with multiple left hand sides:
3367     #
3368     #    a = b = c
3369     #
3370     #  lhs_list   [ExprNode]   Left hand sides
3371     #  rhs        ExprNode     Right hand sides
3372     #
3373     #  Used internally:
3374     #
3375     #  coerced_rhs_list   [ExprNode]   RHS coerced to type of each LHS
3376     
3377     child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3378     coerced_rhs_list = None
3379
3380     def analyse_declarations(self, env):
3381         for lhs in self.lhs_list:
3382             lhs.analyse_target_declaration(env)
3383     
3384     def analyse_types(self, env, use_temp = 0):
3385         self.rhs.analyse_types(env)
3386         if not self.rhs.is_simple():
3387             if use_temp:
3388                 self.rhs = self.rhs.coerce_to_temp(env)
3389             else:
3390                 self.rhs = self.rhs.coerce_to_simple(env)
3391         from ExprNodes import CloneNode
3392         self.coerced_rhs_list = []
3393         for lhs in self.lhs_list:
3394             lhs.analyse_target_types(env)
3395             lhs.gil_assignment_check(env)
3396             rhs = CloneNode(self.rhs)
3397             rhs = rhs.coerce_to(lhs.type, env)
3398             self.coerced_rhs_list.append(rhs)
3399
3400     def generate_rhs_evaluation_code(self, code):
3401         self.rhs.generate_evaluation_code(code)
3402     
3403     def generate_assignment_code(self, code):
3404         for i in range(len(self.lhs_list)):
3405             lhs = self.lhs_list[i]
3406             rhs = self.coerced_rhs_list[i]
3407             rhs.generate_evaluation_code(code)
3408             lhs.generate_assignment_code(rhs, code)
3409             # Assignment has disposed of the cloned RHS
3410         self.rhs.generate_disposal_code(code)
3411         self.rhs.free_temps(code)
3412
3413     def generate_function_definitions(self, env, code):
3414         self.rhs.generate_function_definitions(env, code)
3415
3416     def annotate(self, code):
3417         for i in range(len(self.lhs_list)):
3418             lhs = self.lhs_list[i].annotate(code)
3419             rhs = self.coerced_rhs_list[i].annotate(code)
3420         self.rhs.annotate(code)
3421         
3422
3423 class ParallelAssignmentNode(AssignmentNode):
3424     #  A combined packing/unpacking assignment:
3425     #
3426     #    a, b, c =  d, e, f
3427     #
3428     #  This has been rearranged by the parser into
3429     #
3430     #    a = d ; b = e ; c = f
3431     #
3432     #  but we must evaluate all the right hand sides
3433     #  before assigning to any of the left hand sides.
3434     #
3435     #  stats     [AssignmentNode]   The constituent assignments
3436     
3437     child_attrs = ["stats"]
3438
3439     def analyse_declarations(self, env):
3440         for stat in self.stats:
3441             stat.analyse_declarations(env)
3442     
3443     def analyse_expressions(self, env):
3444         for stat in self.stats:
3445             stat.analyse_types(env, use_temp = 1)
3446
3447 #    def analyse_expressions(self, env):
3448 #        for stat in self.stats:
3449 #            stat.analyse_expressions_1(env, use_temp = 1)
3450 #        for stat in self.stats:
3451 #            stat.analyse_expressions_2(env)
3452     
3453     def generate_execution_code(self, code):
3454         for stat in self.stats:
3455             stat.generate_rhs_evaluation_code(code)
3456         for stat in self.stats:
3457             stat.generate_assignment_code(code)
3458
3459     def generate_function_definitions(self, env, code):
3460         for stat in self.stats:
3461             stat.generate_function_definitions(env, code)
3462
3463     def annotate(self, code):
3464         for stat in self.stats:
3465             stat.annotate(code)
3466
3467
3468 class InPlaceAssignmentNode(AssignmentNode):
3469     #  An in place arithmetic operand:
3470     #
3471     #    a += b
3472     #    a -= b
3473     #    ...
3474     #
3475     #  lhs      ExprNode      Left hand side
3476     #  rhs      ExprNode      Right hand side
3477     #  op       char          one of "+-*/%^&|"
3478     #  dup     (ExprNode)     copy of lhs used for operation (auto-generated)
3479     #
3480     #  This code is a bit tricky because in order to obey Python 
3481     #  semantics the sub-expressions (e.g. indices) of the lhs must 
3482     #  not be evaluated twice. So we must re-use the values calculated 
3483     #  in evaluation phase for the assignment phase as well. 
3484     #  Fortunately, the type of the lhs node is fairly constrained 
3485     #  (it must be a NameNode, AttributeNode, or IndexNode).     
3486     
3487     child_attrs = ["lhs", "rhs"]
3488     dup = None
3489
3490     def analyse_declarations(self, env):
3491         self.lhs.analyse_target_declaration(env)
3492         
3493     def analyse_types(self, env):
3494         self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3495         self.rhs.analyse_types(env)
3496         self.lhs.analyse_target_types(env)
3497         import ExprNodes
3498         if self.lhs.type.is_pyobject:
3499             self.rhs = self.rhs.coerce_to_pyobject(env)
3500         elif self.rhs.type.is_pyobject or (self.lhs.type.is_numeric and self.rhs.type.is_numeric):
3501             self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3502         if self.lhs.type.is_pyobject:
3503             self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3504             self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3505         
3506     def generate_execution_code(self, code):
3507         import ExprNodes
3508         self.rhs.generate_evaluation_code(code)
3509         self.dup.generate_subexpr_evaluation_code(code)
3510         if self.dup.is_temp:
3511             self.dup.allocate_temp_result(code)
3512         # self.dup.generate_result_code is run only if it is not buffer access
3513         if self.operator == "**":
3514             extra = ", Py_None"
3515         else:
3516             extra = ""
3517         if self.lhs.type.is_pyobject:
3518             if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3519                 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3520             self.dup.generate_result_code(code)
3521             self.result_value_temp.allocate(code)
3522             code.putln(
3523                 "%s = %s(%s, %s%s); %s" % (
3524                     self.result_value.result(), 
3525                     self.py_operation_function(), 
3526                     self.dup.py_result(),
3527                     self.rhs.py_result(),
3528                     extra,
3529                     code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3530             code.put_gotref(self.result_value.py_result())
3531             self.result_value.generate_evaluation_code(code) # May be a type check...
3532             self.rhs.generate_disposal_code(code)
3533             self.rhs.free_temps(code)
3534             self.dup.generate_disposal_code(code)
3535             self.dup.free_temps(code)
3536             self.lhs.generate_assignment_code(self.result_value, code)
3537             self.result_value_temp.release(code)
3538         else: 
3539             c_op = self.operator
3540             if c_op == "//":
3541                 c_op = "/"
3542             elif c_op == "**":
3543                 error(self.pos, "No C inplace power operator")
3544             elif self.lhs.type.is_complex:
3545                 error(self.pos, "Inplace operators not implemented for complex types.")
3546                 
3547             # have to do assignment directly to avoid side-effects
3548             if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3549                 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3550             else:
3551                 self.dup.generate_result_code(code)
3552                 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3553             self.rhs.generate_disposal_code(code)
3554             self.rhs.free_temps(code)
3555         if self.dup.is_temp:
3556             self.dup.generate_subexpr_disposal_code(code)
3557             self.dup.free_subexpr_temps(code)
3558             
3559     def create_dup_node(self, env): 
3560         import ExprNodes
3561         self.dup = self.lhs
3562         self.dup.analyse_types(env)
3563         if isinstance(self.lhs, ExprNodes.NameNode):
3564             target_lhs = ExprNodes.NameNode(self.dup.pos,
3565                                             name = self.dup.name,
3566                                             is_temp = self.dup.is_temp,
3567                                             entry = self.dup.entry)
3568         elif isinstance(self.lhs, ExprNodes.AttributeNode):
3569             target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3570                                                  obj = ExprNodes.CloneNode(self.lhs.obj),
3571                                                  attribute = self.dup.attribute,
3572                                                  is_temp = self.dup.is_temp)
3573         elif isinstance(self.lhs, ExprNodes.IndexNode):
3574             if self.lhs.index:
3575                 index = ExprNodes.CloneNode(self.lhs.index)
3576             else:
3577                 index = None
3578             if self.lhs.indices:
3579                 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3580             else:
3581                 indices = []
3582             target_lhs = ExprNodes.IndexNode(self.dup.pos,
3583                                              base = ExprNodes.CloneNode(self.dup.base),
3584                                              index = index,
3585                                              indices = indices,
3586                                              is_temp = self.dup.is_temp)
3587         else:
3588             assert False, "Unsupported node: %s" % type(self.lhs)
3589         self.lhs = target_lhs
3590         return self.dup
3591     
3592     def py_operation_function(self):
3593         return self.py_functions[self.operator]
3594
3595     py_functions = {
3596         "|":        "PyNumber_InPlaceOr",
3597         "^":        "PyNumber_InPlaceXor",
3598         "&":        "PyNumber_InPlaceAnd",
3599         "+":        "PyNumber_InPlaceAdd",
3600         "-":        "PyNumber_InPlaceSubtract",
3601         "*":        "PyNumber_InPlaceMultiply",
3602         "/":        "__Pyx_PyNumber_InPlaceDivide",
3603         "%":        "PyNumber_InPlaceRemainder",
3604         "<<":        "PyNumber_InPlaceLshift",
3605         ">>":        "PyNumber_InPlaceRshift",
3606         "**":        "PyNumber_InPlacePower",
3607         "//":        "PyNumber_InPlaceFloorDivide",
3608     }
3609
3610     def annotate(self, code):
3611         self.lhs.annotate(code)
3612         self.rhs.annotate(code)
3613         self.dup.annotate(code)
3614     
3615     def create_binop_node(self):
3616         import ExprNodes
3617         return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3618
3619
3620 class PrintStatNode(StatNode):
3621     #  print statement
3622     #
3623     #  arg_tuple         TupleNode
3624     #  stream            ExprNode or None (stdout)
3625     #  append_newline    boolean
3626
3627     child_attrs = ["arg_tuple", "stream"]
3628
3629     def analyse_expressions(self, env):
3630         if self.stream:
3631             self.stream.analyse_expressions(env)
3632             self.stream = self.stream.coerce_to_pyobject(env)
3633         self.arg_tuple.analyse_expressions(env)
3634         self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3635         env.use_utility_code(printing_utility_code)
3636         if len(self.arg_tuple.args) == 1 and self.append_newline:
3637             env.use_utility_code(printing_one_utility_code)
3638
3639     nogil_check = Node.gil_error
3640     gil_message = "Python print statement"
3641
3642     def generate_execution_code(self, code):
3643         if self.stream:
3644             self.stream.generate_evaluation_code(code)
3645             stream_result = self.stream.py_result()
3646         else:
3647             stream_result = '0'
3648         if len(self.arg_tuple.args) == 1 and self.append_newline:
3649             arg = self.arg_tuple.args[0]
3650             arg.generate_evaluation_code(code)
3651             
3652             code.putln(
3653                 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3654                     stream_result,
3655                     arg.py_result(),
3656                     code.error_goto(self.pos)))
3657             arg.generate_disposal_code(code)
3658             arg.free_temps(code)
3659         else:
3660             self.arg_tuple.generate_evaluation_code(code)
3661             code.putln(
3662                 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3663                     stream_result,
3664                     self.arg_tuple.py_result(),
3665                     self.append_newline,
3666                     code.error_goto(self.pos)))
3667             self.arg_tuple.generate_disposal_code(code)
3668             self.arg_tuple.free_temps(code)
3669
3670         if self.stream:
3671             self.stream.generate_disposal_code(code)
3672             self.stream.free_temps(code)
3673
3674     def generate_function_definitions(self, env, code):
3675         if self.stream:
3676             self.stream.generate_function_definitions(env, code)
3677         self.arg_tuple.generate_function_definitions(env, code)
3678
3679     def annotate(self, code):
3680         if self.stream:
3681             self.stream.annotate(code)
3682         self.arg_tuple.annotate(code)
3683
3684
3685 class ExecStatNode(StatNode):
3686     #  exec statement
3687     #
3688     #  args     [ExprNode]
3689
3690     child_attrs = ["args"]
3691
3692     def analyse_expressions(self, env):
3693         for i, arg in enumerate(self.args):
3694             arg.analyse_expressions(env)
3695             arg = arg.coerce_to_pyobject(env)
3696             self.args[i] = arg
3697         env.use_utility_code(Builtin.pyexec_utility_code)
3698
3699     nogil_check = Node.gil_error
3700     gil_message = "Python exec statement"
3701
3702     def generate_execution_code(self, code):
3703         args = []
3704         for arg in self.args:
3705             arg.generate_evaluation_code(code)
3706             args.append( arg.py_result() )
3707         args = tuple(args + ['0', '0'][:3-len(args)])
3708         temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3709         code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3710                 (temp_result,) + args))
3711         for arg in self.args:
3712             arg.generate_disposal_code(code)
3713             arg.free_temps(code)
3714         code.putln(
3715             code.error_goto_if_null(temp_result, self.pos))
3716         code.put_gotref(temp_result)
3717         code.put_decref_clear(temp_result, py_object_type)
3718         code.funcstate.release_temp(temp_result)
3719
3720     def annotate(self, code):
3721         for arg in self.args:
3722             arg.annotate(code)
3723
3724
3725 class DelStatNode(StatNode):
3726     #  del statement
3727     #
3728     #  args     [ExprNode]
3729     
3730     child_attrs = ["args"]
3731
3732     def analyse_declarations(self, env):
3733         for arg in self.args:
3734             arg.analyse_target_declaration(env)
3735     
3736     def analyse_expressions(self, env):
3737         for arg in self.args:
3738             arg.analyse_target_expression(env, None)
3739             if arg.type.is_pyobject:
3740                 pass
3741             elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3742                 self.cpp_check(env)
3743             elif arg.type.is_cpp_class:
3744                 error(arg.pos, "Deletion of non-heap C++ object")
3745             else:
3746                 error(arg.pos, "Deletion of non-Python, non-C++ object")
3747             #arg.release_target_temp(env)
3748
3749     def nogil_check(self, env):
3750         for arg in self.args:
3751             if arg.type.is_pyobject:
3752                 self.gil_error()
3753
3754     gil_message = "Deleting Python object"
3755
3756     def generate_execution_code(self, code):
3757         for arg in self.args:
3758             if arg.type.is_pyobject:
3759                 arg.generate_deletion_code(code)
3760             elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3761                 arg.generate_result_code(code)
3762                 code.putln("delete %s;" % arg.result())
3763             # else error reported earlier
3764
3765     def annotate(self, code):
3766         for arg in self.args:
3767             arg.annotate(code)
3768
3769
3770 class PassStatNode(StatNode):
3771     #  pass statement
3772
3773     child_attrs = []
3774     
3775     def analyse_expressions(self, env):
3776         pass
3777     
3778     def generate_execution_code(self, code):
3779         pass
3780
3781
3782 class BreakStatNode(StatNode):
3783
3784     child_attrs = []
3785
3786     def analyse_expressions(self, env):
3787         pass
3788     
3789     def generate_execution_code(self, code):
3790         if not code.break_label:
3791             error(self.pos, "break statement not inside loop")
3792         else:
3793             code.put_goto(code.break_label)
3794
3795
3796 class ContinueStatNode(StatNode):
3797
3798     child_attrs = []
3799
3800     def analyse_expressions(self, env):
3801         pass
3802     
3803     def generate_execution_code(self, code):
3804         if code.funcstate.in_try_finally:
3805             error(self.pos, "continue statement inside try of try...finally")
3806         elif not code.continue_label:
3807             error(self.pos, "continue statement not inside loop")
3808         else:
3809             code.put_goto(code.continue_label)
3810
3811
3812 class ReturnStatNode(StatNode):
3813     #  return statement
3814     #
3815     #  value         ExprNode or None
3816     #  return_type   PyrexType
3817     
3818     child_attrs = ["value"]
3819
3820     def analyse_expressions(self, env):
3821         return_type = env.return_type
3822         self.return_type = return_type
3823         if not return_type:
3824             error(self.pos, "Return not inside a function body")
3825             return
3826         if self.value:
3827             self.value.analyse_types(env)
3828             if return_type.is_void or return_type.is_returncode:
3829                 error(self.value.pos, 
3830                     "Return with value in void function")
3831             else:
3832                 self.value = self.value.coerce_to(env.return_type, env)
3833         else:
3834             if (not return_type.is_void
3835                 and not return_type.is_pyobject
3836                 and not return_type.is_returncode):
3837                     error(self.pos, "Return value required")
3838
3839     def nogil_check(self, env):
3840         if self.return_type.is_pyobject:
3841             self.gil_error()
3842
3843     gil_message = "Returning Python object"
3844
3845     def generate_execution_code(self, code):
3846         code.mark_pos(self.pos)
3847         if not self.return_type:
3848             # error reported earlier
3849             return
3850         if self.return_type.is_pyobject:
3851             code.put_xdecref(Naming.retval_cname,
3852                              self.return_type)
3853         if self.value:
3854             self.value.generate_evaluation_code(code)
3855             self.value.make_owned_reference(code)
3856             code.putln(
3857                 "%s = %s;" % (
3858                     Naming.retval_cname,
3859                     self.value.result_as(self.return_type)))
3860             self.value.generate_post_assignment_code(code)
3861             self.value.free_temps(code)
3862         else:
3863             if self.return_type.is_pyobject:
3864                 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3865             elif self.return_type.is_returncode:
3866                 code.putln(
3867                     "%s = %s;" % (
3868                         Naming.retval_cname,
3869                         self.return_type.default_value))
3870         for cname, type in code.funcstate.temps_holding_reference():
3871             code.put_decref_clear(cname, type)
3872         code.put_goto(code.return_label)
3873
3874     def generate_function_definitions(self, env, code):
3875         if self.value is not None:
3876             self.value.generate_function_definitions(env, code)
3877         
3878     def annotate(self, code):
3879         if self.value:
3880             self.value.annotate(code)
3881
3882
3883 class RaiseStatNode(StatNode):
3884     #  raise statement
3885     #
3886     #  exc_type    ExprNode or None
3887     #  exc_value   ExprNode or None
3888     #  exc_tb      ExprNode or None
3889     
3890     child_attrs = ["exc_type", "exc_value", "exc_tb"]
3891
3892     def analyse_expressions(self, env):
3893         if self.exc_type:
3894             self.exc_type.analyse_types(env)
3895             self.exc_type = self.exc_type.coerce_to_pyobject(env)
3896         if self.exc_value:
3897             self.exc_value.analyse_types(env)
3898             self.exc_value = self.exc_value.coerce_to_pyobject(env)
3899         if self.exc_tb:
3900             self.exc_tb.analyse_types(env)
3901             self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3902         env.use_utility_code(raise_utility_code)
3903
3904     nogil_check = Node.gil_error
3905     gil_message = "Raising exception"
3906
3907     def generate_execution_code(self, code):
3908         if self.exc_type:
3909             self.exc_type.generate_evaluation_code(code)
3910             type_code = self.exc_type.py_result()
3911         else:
3912             type_code = "0"
3913         if self.exc_value:
3914             self.exc_value.generate_evaluation_code(code)
3915             value_code = self.exc_value.py_result()
3916         else:
3917             value_code = "0"
3918         if self.exc_tb:
3919             self.exc_tb.generate_evaluation_code(code)
3920             tb_code = self.exc_tb.py_result()
3921         else:
3922             tb_code = "0"
3923         code.putln(
3924             "__Pyx_Raise(%s, %s, %s);" % (
3925                 type_code,
3926                 value_code,
3927                 tb_code))
3928         for obj in (self.exc_type, self.exc_value, self.exc_tb):
3929             if obj:
3930                 obj.generate_disposal_code(code)
3931                 obj.free_temps(code)
3932         code.putln(
3933             code.error_goto(self.pos))
3934
3935     def generate_function_definitions(self, env, code):
3936         if self.exc_type is not None:
3937             self.exc_type.generate_function_definitions(env, code)
3938         if self.exc_value is not None:
3939             self.exc_value.generate_function_definitions(env, code)
3940         if self.exc_tb is not None:
3941             self.exc_tb.generate_function_definitions(env, code)
3942
3943     def annotate(self, code):
3944         if self.exc_type:
3945             self.exc_type.annotate(code)
3946         if self.exc_value:
3947             self.exc_value.annotate(code)
3948         if self.exc_tb:
3949             self.exc_tb.annotate(code)
3950
3951
3952 class ReraiseStatNode(StatNode):
3953
3954     child_attrs = []
3955
3956     def analyse_expressions(self, env):
3957         env.use_utility_code(restore_exception_utility_code)
3958
3959     nogil_check = Node.gil_error
3960     gil_message = "Raising exception"
3961
3962     def generate_execution_code(self, code):
3963         vars = code.funcstate.exc_vars
3964         if vars:
3965             for varname in vars:
3966                 code.put_giveref(varname)
3967             code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3968             for varname in vars:
3969                 code.put("%s = 0; " % varname)
3970             code.putln()
3971             code.putln(code.error_goto(self.pos))
3972         else:
3973             error(self.pos, "Reraise not inside except clause")
3974         
3975
3976 class AssertStatNode(StatNode):
3977     #  assert statement
3978     #
3979     #  cond    ExprNode
3980     #  value   ExprNode or None
3981     
3982     child_attrs = ["cond", "value"]
3983
3984     def analyse_expressions(self, env):
3985         self.cond = self.cond.analyse_boolean_expression(env)
3986         if self.value:
3987             self.value.analyse_types(env)
3988             self.value = self.value.coerce_to_pyobject(env)
3989
3990     nogil_check = Node.gil_error
3991     gil_message = "Raising exception"
3992     
3993     def generate_execution_code(self, code):
3994         code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3995         self.cond.generate_evaluation_code(code)
3996         code.putln(
3997             "if (unlikely(!%s)) {" %
3998                 self.cond.result())
3999         if self.value:
4000             self.value.generate_evaluation_code(code)
4001             code.putln(
4002                 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4003                     self.value.py_result())
4004             self.value.generate_disposal_code(code)
4005             self.value.free_temps(code)
4006         else:
4007             code.putln(
4008                 "PyErr_SetNone(PyExc_AssertionError);")
4009         code.putln(
4010                 code.error_goto(self.pos))
4011         code.putln(
4012             "}")
4013         self.cond.generate_disposal_code(code)
4014         self.cond.free_temps(code)
4015         code.putln("#endif")
4016
4017     def generate_function_definitions(self, env, code):
4018         self.cond.generate_function_definitions(env, code)
4019         if self.value is not None:
4020             self.value.generate_function_definitions(env, code)
4021
4022     def annotate(self, code):
4023         self.cond.annotate(code)
4024         if self.value:
4025             self.value.annotate(code)
4026
4027
4028 class IfStatNode(StatNode):
4029     #  if statement
4030     #
4031     #  if_clauses   [IfClauseNode]
4032     #  else_clause  StatNode or None
4033
4034     child_attrs = ["if_clauses", "else_clause"]
4035     
4036     def analyse_control_flow(self, env):
4037         env.start_branching(self.pos)
4038         for if_clause in self.if_clauses:
4039             if_clause.analyse_control_flow(env)
4040             env.next_branch(if_clause.end_pos())
4041         if self.else_clause:
4042             self.else_clause.analyse_control_flow(env)
4043         env.finish_branching(self.end_pos())
4044
4045     def analyse_declarations(self, env):
4046         for if_clause in self.if_clauses:
4047             if_clause.analyse_declarations(env)
4048         if self.else_clause:
4049             self.else_clause.analyse_declarations(env)
4050     
4051     def analyse_expressions(self, env):
4052         for if_clause in self.if_clauses:
4053             if_clause.analyse_expressions(env)
4054         if self.else_clause:
4055             self.else_clause.analyse_expressions(env)
4056
4057     def generate_execution_code(self, code):
4058         code.mark_pos(self.pos)
4059         end_label = code.new_label()
4060         for if_clause in self.if_clauses:
4061             if_clause.generate_execution_code(code, end_label)
4062         if self.else_clause:
4063             code.putln("/*else*/ {")
4064             self.else_clause.generate_execution_code(code)
4065             code.putln("}")
4066         code.put_label(end_label)
4067
4068     def generate_function_definitions(self, env, code):
4069         for clause in self.if_clauses:
4070             clause.generate_function_definitions(env, code)
4071         if self.else_clause is not None:
4072             self.else_clause.generate_function_definitions(env, code)
4073
4074     def annotate(self, code):
4075         for if_clause in self.if_clauses:
4076             if_clause.annotate(code)
4077         if self.else_clause:
4078             self.else_clause.annotate(code)
4079
4080
4081 class IfClauseNode(Node):
4082     #  if or elif clause in an if statement
4083     #
4084     #  condition   ExprNode
4085     #  body        StatNode
4086     
4087     child_attrs = ["condition", "body"]
4088
4089     def analyse_control_flow(self, env):
4090         self.body.analyse_control_flow(env)
4091         
4092     def analyse_declarations(self, env):
4093         self.condition.analyse_declarations(env)
4094         self.body.analyse_declarations(env)
4095     
4096     def analyse_expressions(self, env):
4097         self.condition = \
4098             self.condition.analyse_temp_boolean_expression(env)
4099         self.body.analyse_expressions(env)
4100
4101     def get_constant_condition_result(self):
4102         if self.condition.has_constant_result():
4103             return bool(self.condition.constant_result)
4104         else:
4105             return None
4106
4107     def generate_execution_code(self, code, end_label):
4108         self.condition.generate_evaluation_code(code)
4109         code.putln(
4110             "if (%s) {" %
4111                 self.condition.result())
4112         self.condition.generate_disposal_code(code)
4113         self.condition.free_temps(code)
4114         self.body.generate_execution_code(code)
4115         code.put_goto(end_label)
4116         code.putln("}")
4117
4118     def generate_function_definitions(self, env, code):
4119         self.condition.generate_function_definitions(env, code)
4120         self.body.generate_function_definitions(env, code)
4121
4122     def annotate(self, code):
4123         self.condition.annotate(code)
4124         self.body.annotate(code)
4125         
4126
4127 class SwitchCaseNode(StatNode):
4128     # Generated in the optimization of an if-elif-else node
4129     #
4130     # conditions    [ExprNode]
4131     # body          StatNode
4132     
4133     child_attrs = ['conditions', 'body']
4134
4135     def generate_execution_code(self, code):
4136         for cond in self.conditions:
4137             code.mark_pos(cond.pos)
4138             cond.generate_evaluation_code(code)
4139             code.putln("case %s:" % cond.result())
4140         self.body.generate_execution_code(code)
4141         code.putln("break;")
4142
4143     def generate_function_definitions(self, env, code):
4144         for cond in self.conditions:
4145             cond.generate_function_definitions(env, code)
4146         self.body.generate_function_definitions(env, code)
4147         
4148     def annotate(self, code):
4149         for cond in self.conditions:
4150             cond.annotate(code)
4151         self.body.annotate(code)
4152
4153 class SwitchStatNode(StatNode):
4154     # Generated in the optimization of an if-elif-else node
4155     #
4156     # test          ExprNode
4157     # cases         [SwitchCaseNode]
4158     # else_clause   StatNode or None
4159     
4160     child_attrs = ['test', 'cases', 'else_clause']
4161     
4162     def generate_execution_code(self, code):
4163         code.putln("switch (%s) {" % self.test.result())
4164         for case in self.cases:
4165             case.generate_execution_code(code)
4166         if self.else_clause is not None:
4167             code.putln("default:")
4168             self.else_clause.generate_execution_code(code)
4169             code.putln("break;")
4170         code.putln("}")
4171
4172     def generate_function_definitions(self, env, code):
4173         self.test.generate_function_definitions(env, code)
4174         for case in self.cases:
4175             case.generate_function_definitions(env, code)
4176         if self.else_clause is not None:
4177             self.else_clause.generate_function_definitions(env, code)
4178
4179     def annotate(self, code):
4180         self.test.annotate(code)
4181         for case in self.cases:
4182             case.annotate(code)
4183         if self.else_clause is not None:
4184             self.else_clause.annotate(code)
4185             
4186 class LoopNode(object):
4187     
4188     def analyse_control_flow(self, env):
4189         env.start_branching(self.pos)
4190         self.body.analyse_control_flow(env)
4191         env.next_branch(self.body.end_pos())
4192         if self.else_clause:
4193             self.else_clause.analyse_control_flow(env)
4194         env.finish_branching(self.end_pos())
4195
4196     
4197 class WhileStatNode(LoopNode, StatNode):
4198     #  while statement
4199     #
4200     #  condition    ExprNode
4201     #  body         StatNode
4202     #  else_clause  StatNode
4203
4204     child_attrs = ["condition", "body", "else_clause"]
4205
4206     def analyse_declarations(self, env):
4207         self.body.analyse_declarations(env)
4208         if self.else_clause:
4209             self.else_clause.analyse_declarations(env)
4210     
4211     def analyse_expressions(self, env):
4212         self.condition = \
4213             self.condition.analyse_temp_boolean_expression(env)
4214         self.body.analyse_expressions(env)
4215         if self.else_clause:
4216             self.else_clause.analyse_expressions(env)
4217     
4218     def generate_execution_code(self, code):
4219         old_loop_labels = code.new_loop_labels()
4220         code.putln(
4221             "while (1) {")
4222         self.condition.generate_evaluation_code(code)
4223         self.condition.generate_disposal_code(code)
4224         code.putln(
4225             "if (!%s) break;" %
4226                 self.condition.result())
4227         self.condition.free_temps(code)
4228         self.body.generate_execution_code(code)
4229         code.put_label(code.continue_label)
4230         code.putln("}")
4231         break_label = code.break_label
4232         code.set_loop_labels(old_loop_labels)
4233         if self.else_clause:
4234             code.putln("/*else*/ {")
4235             self.else_clause.generate_execution_code(code)
4236             code.putln("}")
4237         code.put_label(break_label)
4238
4239     def generate_function_definitions(self, env, code):
4240         self.condition.generate_function_definitions(env, code)
4241         self.body.generate_function_definitions(env, code)
4242         if self.else_clause is not None:
4243             self.else_clause.generate_function_definitions(env, code)
4244
4245     def annotate(self, code):
4246         self.condition.annotate(code)
4247         self.body.annotate(code)
4248         if self.else_clause:
4249             self.else_clause.annotate(code)
4250
4251
4252 def ForStatNode(pos, **kw):
4253     if 'iterator' in kw:
4254         return ForInStatNode(pos, **kw)
4255     else:
4256         return ForFromStatNode(pos, **kw)
4257
4258 class ForInStatNode(LoopNode, StatNode):
4259     #  for statement
4260     #
4261     #  target        ExprNode
4262     #  iterator      IteratorNode
4263     #  body          StatNode
4264     #  else_clause   StatNode
4265     #  item          NextNode       used internally
4266     
4267     child_attrs = ["target", "iterator", "body", "else_clause"]
4268     item = None
4269     
4270     def analyse_declarations(self, env):
4271         self.target.analyse_target_declaration(env)
4272         self.body.analyse_declarations(env)
4273         if self.else_clause:
4274             self.else_clause.analyse_declarations(env)
4275
4276     def analyse_expressions(self, env):
4277         import ExprNodes
4278         self.target.analyse_target_types(env)
4279         self.iterator.analyse_expressions(env)
4280         self.item = ExprNodes.NextNode(self.iterator, env)
4281         self.item = self.item.coerce_to(self.target.type, env)
4282         self.body.analyse_expressions(env)
4283         if self.else_clause:
4284             self.else_clause.analyse_expressions(env)
4285
4286     def generate_execution_code(self, code):
4287         old_loop_labels = code.new_loop_labels()
4288         self.iterator.allocate_counter_temp(code)
4289         self.iterator.generate_evaluation_code(code)
4290         code.putln(
4291             "for (;;) {")
4292         self.item.generate_evaluation_code(code)
4293         self.target.generate_assignment_code(self.item, code)
4294         self.body.generate_execution_code(code)
4295         code.put_label(code.continue_label)
4296         code.putln(
4297             "}")
4298         break_label = code.break_label
4299         code.set_loop_labels(old_loop_labels)
4300
4301         if self.else_clause:
4302             # in nested loops, the 'else' block can contain a
4303             # 'continue' statement for the outer loop, but we may need
4304             # to generate cleanup code before taking that path, so we
4305             # intercept it here
4306             orig_continue_label = code.continue_label
4307             code.continue_label = code.new_label('outer_continue')
4308
4309             code.putln("/*else*/ {")
4310             self.else_clause.generate_execution_code(code)
4311             code.putln("}")
4312
4313             if code.label_used(code.continue_label):
4314                 code.put_goto(break_label)
4315                 code.put_label(code.continue_label)
4316                 self.iterator.generate_disposal_code(code)
4317                 code.put_goto(orig_continue_label)
4318             code.set_loop_labels(old_loop_labels)
4319
4320         if code.label_used(break_label):
4321             code.put_label(break_label)
4322         self.iterator.release_counter_temp(code)
4323         self.iterator.generate_disposal_code(code)
4324         self.iterator.free_temps(code)
4325
4326     def generate_function_definitions(self, env, code):
4327         self.target.generate_function_definitions(env, code)
4328         self.iterator.generate_function_definitions(env, code)
4329         self.body.generate_function_definitions(env, code)
4330         if self.else_clause is not None:
4331             self.else_clause.generate_function_definitions(env, code)
4332
4333     def annotate(self, code):
4334         self.target.annotate(code)
4335         self.iterator.annotate(code)
4336         self.body.annotate(code)
4337         if self.else_clause:
4338             self.else_clause.annotate(code)
4339         self.item.annotate(code)
4340
4341
4342 class ForFromStatNode(LoopNode, StatNode):
4343     #  for name from expr rel name rel expr
4344     #
4345     #  target        NameNode
4346     #  bound1        ExprNode
4347     #  relation1     string
4348     #  relation2     string
4349     #  bound2        ExprNode
4350     #  step          ExprNode or None
4351     #  body          StatNode
4352     #  else_clause   StatNode or None
4353     #
4354     #  Used internally:
4355     #
4356     #  from_range         bool
4357     #  is_py_target       bool
4358     #  loopvar_node       ExprNode (usually a NameNode or temp node)
4359     #  py_loopvar_node    PyTempNode or None
4360     child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4361
4362     is_py_target = False
4363     loopvar_node = None
4364     py_loopvar_node = None
4365     from_range = False
4366
4367     gil_message = "For-loop using object bounds or target"
4368
4369     def nogil_check(self, env):
4370         for x in (self.target, self.bound1, self.bound2):
4371             if x.type.is_pyobject:
4372                 self.gil_error()
4373
4374     def analyse_declarations(self, env):
4375         self.target.analyse_target_declaration(env)
4376         self.body.analyse_declarations(env)
4377         if self.else_clause:
4378             self.else_clause.analyse_declarations(env)
4379
4380     def analyse_expressions(self, env):
4381         import ExprNodes
4382         self.target.analyse_target_types(env)
4383         self.bound1.analyse_types(env)
4384         self.bound2.analyse_types(env)
4385         if self.step is not None:
4386             if isinstance(self.step, ExprNodes.UnaryMinusNode):
4387                 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4388             self.step.analyse_types(env)
4389         
4390         target_type = self.target.type
4391         if self.target.type.is_numeric:
4392             loop_type = self.target.type
4393         else:
4394             loop_type = PyrexTypes.c_int_type
4395             if not self.bound1.type.is_pyobject:
4396                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4397             if not self.bound2.type.is_pyobject:
4398                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4399             if self.step is not None and not self.step.type.is_pyobject:
4400                 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4401         self.bound1 = self.bound1.coerce_to(loop_type, env)
4402         self.bound2 = self.bound2.coerce_to(loop_type, env)
4403         if not self.bound2.is_literal:
4404             self.bound2 = self.bound2.coerce_to_temp(env)
4405         if self.step is not None:
4406             self.step = self.step.coerce_to(loop_type, env)            
4407             if not self.step.is_literal:
4408                 self.step = self.step.coerce_to_temp(env)
4409
4410         target_type = self.target.type
4411         if not (target_type.is_pyobject or target_type.is_numeric):
4412             error(self.target.pos,
4413                 "for-from loop variable must be c numeric type or Python object")
4414         if target_type.is_numeric:
4415             self.is_py_target = False
4416             if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4417                 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4418             self.loopvar_node = self.target
4419             self.py_loopvar_node = None
4420         else:
4421             self.is_py_target = True
4422             c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4423             self.loopvar_node = c_loopvar_node
4424             self.py_loopvar_node = \
4425                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4426         self.body.analyse_expressions(env)
4427         if self.else_clause:
4428             self.else_clause.analyse_expressions(env)
4429             
4430     def generate_execution_code(self, code):
4431         old_loop_labels = code.new_loop_labels()
4432         from_range = self.from_range
4433         self.bound1.generate_evaluation_code(code)
4434         self.bound2.generate_evaluation_code(code)
4435         offset, incop = self.relation_table[self.relation1]
4436         if self.step is not None:
4437             self.step.generate_evaluation_code(code)
4438             step = self.step.result()
4439             incop = "%s=%s" % (incop[0], step)
4440         import ExprNodes
4441         if isinstance(self.loopvar_node, ExprNodes.TempNode):
4442             self.loopvar_node.allocate(code)
4443         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4444             self.py_loopvar_node.allocate(code)
4445         if from_range:
4446             loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4447         else:
4448             loopvar_name = self.loopvar_node.result()
4449         code.putln(
4450             "for (%s = %s%s; %s %s %s; %s%s) {" % (
4451                 loopvar_name,
4452                 self.bound1.result(), offset,
4453                 loopvar_name, self.relation2, self.bound2.result(),
4454                 loopvar_name, incop))
4455         if self.py_loopvar_node:
4456             self.py_loopvar_node.generate_evaluation_code(code)
4457             self.target.generate_assignment_code(self.py_loopvar_node, code)
4458         elif from_range:
4459             code.putln("%s = %s;" % (
4460                             self.target.result(), loopvar_name))
4461         self.body.generate_execution_code(code)
4462         code.put_label(code.continue_label)
4463         if self.py_loopvar_node:
4464             # This mess is to make for..from loops with python targets behave 
4465             # exactly like those with C targets with regards to re-assignment 
4466             # of the loop variable. 
4467             import ExprNodes
4468             if self.target.entry.is_pyglobal:
4469                 # We know target is a NameNode, this is the only ugly case. 
4470                 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4471                 target_node.allocate(code)
4472                 interned_cname = code.intern_identifier(self.target.entry.name)
4473                 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4474                 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4475                                 target_node.result(),
4476                                 Naming.module_cname, 
4477                                 interned_cname,
4478                                 code.error_goto_if_null(target_node.result(), self.target.pos)))
4479                 code.put_gotref(target_node.result())
4480             else:
4481                 target_node = self.target
4482             from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4483             from_py_node.temp_code = loopvar_name
4484             from_py_node.generate_result_code(code)
4485             if self.target.entry.is_pyglobal:
4486                 code.put_decref(target_node.result(), target_node.type)
4487                 target_node.release(code)
4488         code.putln("}")
4489         if self.py_loopvar_node:
4490             # This is potentially wasteful, but we don't want the semantics to 
4491             # depend on whether or not the loop is a python type. 
4492             self.py_loopvar_node.generate_evaluation_code(code)
4493             self.target.generate_assignment_code(self.py_loopvar_node, code)
4494         if from_range:
4495             code.funcstate.release_temp(loopvar_name)
4496         break_label = code.break_label
4497         code.set_loop_labels(old_loop_labels)
4498         if self.else_clause:
4499             code.putln("/*else*/ {")
4500             self.else_clause.generate_execution_code(code)
4501             code.putln("}")
4502         code.put_label(break_label)
4503         self.bound1.generate_disposal_code(code)
4504         self.bound1.free_temps(code)
4505         self.bound2.generate_disposal_code(code)
4506         self.bound2.free_temps(code)
4507         if isinstance(self.loopvar_node, ExprNodes.TempNode):
4508             self.loopvar_node.release(code)
4509         if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4510             self.py_loopvar_node.release(code)
4511         if self.step is not None:
4512             self.step.generate_disposal_code(code)
4513             self.step.free_temps(code)
4514     
4515     relation_table = {
4516         # {relop : (initial offset, increment op)}
4517         '<=': ("",   "++"),
4518         '<' : ("+1", "++"),
4519         '>=': ("",   "--"),
4520         '>' : ("-1", "--")
4521     }
4522
4523     def generate_function_definitions(self, env, code):
4524         self.target.generate_function_definitions(env, code)
4525         self.bound1.generate_function_definitions(env, code)
4526         self.bound2.generate_function_definitions(env, code)
4527         if self.step is not None:
4528             self.step.generate_function_definitions(env, code)
4529         self.body.generate_function_definitions(env, code)
4530         if self.else_clause is not None:
4531             self.else_clause.generate_function_definitions(env, code)
4532     
4533     def annotate(self, code):
4534         self.target.annotate(code)
4535         self.bound1.annotate(code)
4536         self.bound2.annotate(code)
4537         if self.step:
4538             self.step.annotate(code)
4539         self.body.annotate(code)
4540         if self.else_clause:
4541             self.else_clause.annotate(code)
4542
4543
4544 class WithStatNode(StatNode):
4545     """
4546     Represents a Python with statement.
4547     
4548     This is only used at parse tree level; and is not present in
4549     analysis or generation phases.
4550     """
4551     #  manager          The with statement manager object
4552     #  target            Node (lhs expression)
4553     #  body             StatNode
4554     child_attrs = ["manager", "target", "body"]
4555
4556 class TryExceptStatNode(StatNode):
4557     #  try .. except statement
4558     #
4559     #  body             StatNode
4560     #  except_clauses   [ExceptClauseNode]
4561     #  else_clause      StatNode or None
4562
4563     child_attrs = ["body", "except_clauses", "else_clause"]
4564     
4565     def analyse_control_flow(self, env):
4566         env.start_branching(self.pos)
4567         self.body.analyse_control_flow(env)
4568         successful_try = env.control_flow # grab this for later
4569         env.next_branch(self.body.end_pos())
4570         env.finish_branching(self.body.end_pos())
4571         
4572         env.start_branching(self.except_clauses[0].pos)
4573         for except_clause in self.except_clauses:
4574             except_clause.analyse_control_flow(env)
4575             env.next_branch(except_clause.end_pos())
4576             
4577         # the else cause it executed only when the try clause finishes
4578         env.control_flow.incoming = successful_try
4579         if self.else_clause:
4580             self.else_clause.analyse_control_flow(env)
4581         env.finish_branching(self.end_pos())
4582
4583     def analyse_declarations(self, env):
4584         self.body.analyse_declarations(env)
4585         for except_clause in self.except_clauses:
4586             except_clause.analyse_declarations(env)
4587         if self.else_clause:
4588             self.else_clause.analyse_declarations(env)
4589         env.use_utility_code(reset_exception_utility_code)
4590
4591     def analyse_expressions(self, env):
4592         self.body.analyse_expressions(env)
4593         default_clause_seen = 0
4594         for except_clause in self.except_clauses:
4595             except_clause.analyse_expressions(env)
4596             if default_clause_seen:
4597                 error(except_clause.pos, "default 'except:' must be last")
4598             if not except_clause.pattern:
4599                 default_clause_seen = 1
4600         self.has_default_clause = default_clause_seen
4601         if self.else_clause:
4602             self.else_clause.analyse_expressions(env)
4603
4604     nogil_check = Node.gil_error
4605     gil_message = "Try-except statement"
4606
4607     def generate_execution_code(self, code):
4608         old_return_label = code.return_label
4609         old_break_label = code.break_label
4610         old_continue_label = code.continue_label
4611         old_error_label = code.new_error_label()
4612         our_error_label = code.error_label
4613         except_end_label = code.new_label('exception_handled')
4614         except_error_label = code.new_label('except_error')
4615         except_return_label = code.new_label('except_return')
4616         try_return_label = code.new_label('try_return')
4617         try_break_label = code.new_label('try_break')
4618         try_continue_label = code.new_label('try_continue')
4619         try_end_label = code.new_label('try_end')
4620
4621         code.putln("{")
4622         code.putln("PyObject %s;" %
4623                    ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4624         code.putln("__Pyx_ExceptionSave(%s);" %
4625                    ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4626         for var in Naming.exc_save_vars:
4627             code.put_xgotref(var)
4628         code.putln(
4629             "/*try:*/ {")
4630         code.return_label = try_return_label
4631         code.break_label = try_break_label
4632         code.continue_label = try_continue_label
4633         self.body.generate_execution_code(code)
4634         code.putln(
4635             "}")
4636         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4637         code.error_label = except_error_label
4638         code.return_label = except_return_label
4639         if self.else_clause:
4640             code.putln(
4641                 "/*else:*/ {")
4642             self.else_clause.generate_execution_code(code)
4643             code.putln(
4644                 "}")
4645         for var in Naming.exc_save_vars:
4646             code.put_xdecref_clear(var, py_object_type)
4647         code.put_goto(try_end_label)
4648         if code.label_used(try_return_label):
4649             code.put_label(try_return_label)
4650             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4651             code.putln("__Pyx_ExceptionReset(%s);" %
4652                        ', '.join(Naming.exc_save_vars))
4653             code.put_goto(old_return_label)
4654         code.put_label(our_error_label)
4655         for temp_name, type in temps_to_clean_up:
4656             code.put_xdecref_clear(temp_name, type)
4657         for except_clause in self.except_clauses:
4658             except_clause.generate_handling_code(code, except_end_label)
4659
4660         error_label_used = code.label_used(except_error_label)
4661         if error_label_used or not self.has_default_clause:
4662             if error_label_used:
4663                 code.put_label(except_error_label)
4664             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4665             code.putln("__Pyx_ExceptionReset(%s);" %
4666                        ', '.join(Naming.exc_save_vars))
4667             code.put_goto(old_error_label)
4668
4669         for exit_label, old_label in zip(
4670             [try_break_label, try_continue_label, except_return_label],
4671             [old_break_label, old_continue_label, old_return_label]):
4672
4673             if code.label_used(exit_label):
4674                 code.put_label(exit_label)
4675                 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4676                 code.putln("__Pyx_ExceptionReset(%s);" %
4677                            ', '.join(Naming.exc_save_vars))
4678                 code.put_goto(old_label)
4679
4680         if code.label_used(except_end_label):
4681             code.put_label(except_end_label)
4682             for var in Naming.exc_save_vars: code.put_xgiveref(var)
4683             code.putln("__Pyx_ExceptionReset(%s);" %
4684                        ', '.join(Naming.exc_save_vars))
4685         code.put_label(try_end_label)
4686         code.putln("}")
4687
4688         code.return_label = old_return_label
4689         code.break_label = old_break_label
4690         code.continue_label = old_continue_label
4691         code.error_label = old_error_label
4692
4693     def generate_function_definitions(self, env, code):
4694         self.body.generate_function_definitions(env, code)
4695         for except_clause in self.except_clauses:
4696             except_clause.generate_function_definitions(env, code)
4697         if self.else_clause is not None:
4698             self.else_clause.generate_function_definitions(env, code)
4699
4700     def annotate(self, code):
4701         self.body.annotate(code)
4702         for except_node in self.except_clauses:
4703             except_node.annotate(code)
4704         if self.else_clause:
4705             self.else_clause.annotate(code)
4706
4707
4708 class ExceptClauseNode(Node):
4709     #  Part of try ... except statement.
4710     #
4711     #  pattern        [ExprNode]
4712     #  target         ExprNode or None
4713     #  body           StatNode
4714     #  excinfo_target NameNode or None   optional target for exception info
4715     #  match_flag     string             result of exception match
4716     #  exc_value      ExcValueNode       used internally
4717     #  function_name  string             qualified name of enclosing function
4718     #  exc_vars       (string * 3)       local exception variables
4719
4720     # excinfo_target is never set by the parser, but can be set by a transform
4721     # in order to extract more extensive information about the exception as a
4722     # sys.exc_info()-style tuple into a target variable
4723     
4724     child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4725
4726     exc_value = None
4727     excinfo_target = None
4728
4729     def analyse_declarations(self, env):
4730         if self.target:
4731             self.target.analyse_target_declaration(env)
4732         if self.excinfo_target is not None:
4733             self.excinfo_target.analyse_target_declaration(env)
4734         self.body.analyse_declarations(env)
4735     
4736     def analyse_expressions(self, env):
4737         import ExprNodes
4738         genv = env.global_scope()
4739         self.function_name = env.qualified_name
4740         if self.pattern:
4741             # normalise/unpack self.pattern into a list
4742             for i, pattern in enumerate(self.pattern):
4743                 pattern.analyse_expressions(env)
4744                 self.pattern[i] = pattern.coerce_to_pyobject(env)
4745
4746         if self.target:
4747             self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4748             self.target.analyse_target_expression(env, self.exc_value)
4749         if self.excinfo_target is not None:
4750             import ExprNodes
4751             self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4752                 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4753             self.excinfo_tuple.analyse_expressions(env)
4754             self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4755
4756         self.body.analyse_expressions(env)
4757
4758     def generate_handling_code(self, code, end_label):
4759         code.mark_pos(self.pos)
4760         if self.pattern:
4761             exc_tests = []
4762             for pattern in self.pattern:
4763                 pattern.generate_evaluation_code(code)
4764                 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4765
4766             match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4767             code.putln(
4768                 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4769             for pattern in self.pattern:
4770                 pattern.generate_disposal_code(code)
4771                 pattern.free_temps(code)
4772             code.putln(
4773                 "if (%s) {" %
4774                     match_flag)
4775             code.funcstate.release_temp(match_flag)
4776         else:
4777             code.putln("/*except:*/ {")
4778
4779         if not getattr(self.body, 'stats', True) and \
4780                 self.excinfo_target is None and self.target is None:
4781             # most simple case: no exception variable, empty body (pass)
4782             # => reset the exception state, done
4783             code.putln("PyErr_Restore(0,0,0);")
4784             code.put_goto(end_label)
4785             code.putln("}")
4786             return
4787         
4788         exc_vars = [code.funcstate.allocate_temp(py_object_type,
4789                                                  manage_ref=True)
4790                     for i in xrange(3)]
4791         code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4792         # We always have to fetch the exception value even if
4793         # there is no target, because this also normalises the 
4794         # exception and stores it in the thread state.
4795         code.globalstate.use_utility_code(get_exception_utility_code)
4796         exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4797         code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4798             code.error_goto(self.pos)))
4799         for x in exc_vars:
4800             code.put_gotref(x)
4801         if self.target:
4802             self.exc_value.set_var(exc_vars[1])
4803             self.exc_value.generate_evaluation_code(code)
4804             self.target.generate_assignment_code(self.exc_value, code)
4805         if self.excinfo_target is not None:
4806             for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4807                 node.set_var(tempvar)
4808             self.excinfo_tuple.generate_evaluation_code(code)
4809             self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4810
4811         old_break_label, old_continue_label = code.break_label, code.continue_label
4812         code.break_label = code.new_label('except_break')
4813         code.continue_label = code.new_label('except_continue')
4814
4815         old_exc_vars = code.funcstate.exc_vars
4816         code.funcstate.exc_vars = exc_vars
4817         self.body.generate_execution_code(code)
4818         code.funcstate.exc_vars = old_exc_vars
4819         for var in exc_vars:
4820             code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4821         code.put_goto(end_label)
4822         
4823         if code.label_used(code.break_label):
4824             code.put_label(code.break_label)
4825             for var in exc_vars:
4826                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4827             code.put_goto(old_break_label)
4828         code.break_label = old_break_label
4829
4830         if code.label_used(code.continue_label):
4831             code.put_label(code.continue_label)
4832             for var in exc_vars:
4833                 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4834             code.put_goto(old_continue_label)
4835         code.continue_label = old_continue_label
4836
4837         for temp in exc_vars:
4838             code.funcstate.release_temp(temp)
4839
4840         code.putln(
4841             "}")
4842
4843     def generate_function_definitions(self, env, code):
4844         if self.target is not None:
4845             self.target.generate_function_definitions(env, code)
4846         self.body.generate_function_definitions(env, code)
4847         
4848     def annotate(self, code):
4849         if self.pattern:
4850             for pattern in self.pattern:
4851                 pattern.annotate(code)
4852         if self.target:
4853             self.target.annotate(code)
4854         self.body.annotate(code)
4855
4856
4857 class TryFinallyStatNode(StatNode):
4858     #  try ... finally statement
4859     #
4860     #  body             StatNode
4861     #  finally_clause   StatNode
4862     #
4863     #  The plan is that we funnel all continue, break
4864     #  return and error gotos into the beginning of the
4865     #  finally block, setting a variable to remember which
4866     #  one we're doing. At the end of the finally block, we
4867     #  switch on the variable to figure out where to go.
4868     #  In addition, if we're doing an error, we save the
4869     #  exception on entry to the finally block and restore
4870     #  it on exit.
4871
4872     child_attrs = ["body", "finally_clause"]
4873     
4874     preserve_exception = 1
4875     
4876     disallow_continue_in_try_finally = 0
4877     # There doesn't seem to be any point in disallowing
4878     # continue in the try block, since we have no problem
4879     # handling it.
4880
4881     def create_analysed(pos, env, body, finally_clause):
4882         node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4883         return node
4884     create_analysed = staticmethod(create_analysed)
4885     
4886     def analyse_control_flow(self, env):
4887         env.start_branching(self.pos)
4888         self.body.analyse_control_flow(env)
4889         env.next_branch(self.body.end_pos())
4890         env.finish_branching(self.body.end_pos())
4891         self.finally_clause.analyse_control_flow(env)
4892
4893     def analyse_declarations(self, env):
4894         self.body.analyse_declarations(env)
4895         self.finally_clause.analyse_declarations(env)
4896     
4897     def analyse_expressions(self, env):
4898         self.body.analyse_expressions(env)
4899         self.finally_clause.analyse_expressions(env)
4900
4901     nogil_check = Node.gil_error
4902     gil_message = "Try-finally statement"
4903
4904     def generate_execution_code(self, code):
4905         old_error_label = code.error_label
4906         old_labels = code.all_new_labels()
4907         new_labels = code.get_all_labels()
4908         new_error_label = code.error_label
4909         catch_label = code.new_label()
4910         code.putln(
4911             "/*try:*/ {")
4912         if self.disallow_continue_in_try_finally:
4913             was_in_try_finally = code.funcstate.in_try_finally
4914             code.funcstate.in_try_finally = 1
4915         self.body.generate_execution_code(code)
4916         if self.disallow_continue_in_try_finally:
4917             code.funcstate.in_try_finally = was_in_try_finally
4918         code.putln(
4919             "}")
4920         temps_to_clean_up = code.funcstate.all_free_managed_temps()
4921         code.mark_pos(self.finally_clause.pos)
4922         code.putln(
4923             "/*finally:*/ {")
4924         cases_used = []
4925         error_label_used = 0
4926         for i, new_label in enumerate(new_labels):
4927             if new_label in code.labels_used:
4928                 cases_used.append(i)
4929                 if new_label == new_error_label:
4930                     error_label_used = 1
4931                     error_label_case = i
4932         if cases_used:
4933             code.putln(
4934                     "int __pyx_why;")
4935             if error_label_used and self.preserve_exception:
4936                 code.putln(
4937                     "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4938                 code.putln(
4939                     "int %s;" % Naming.exc_lineno_name)
4940                 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4941                 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4942                 code.putln(exc_var_init_zero)
4943             else:
4944                 exc_var_init_zero = None
4945             code.use_label(catch_label)
4946             code.putln(
4947                     "__pyx_why = 0; goto %s;" % catch_label)
4948             for i in cases_used:
4949                 new_label = new_labels[i]
4950                 #if new_label and new_label != "<try>":
4951                 if new_label == new_error_label and self.preserve_exception:
4952                     self.put_error_catcher(code, 
4953                         new_error_label, i+1, catch_label, temps_to_clean_up)
4954                 else:
4955                     code.put('%s: ' % new_label)
4956                     if exc_var_init_zero:
4957                         code.putln(exc_var_init_zero)
4958                     code.putln("__pyx_why = %s; goto %s;" % (
4959                             i+1,
4960                             catch_label))
4961             code.put_label(catch_label)
4962         code.set_all_labels(old_labels)
4963         if error_label_used:
4964             code.new_error_label()
4965             finally_error_label = code.error_label
4966         self.finally_clause.generate_execution_code(code)
4967         if error_label_used:
4968             if finally_error_label in code.labels_used and self.preserve_exception:
4969                 over_label = code.new_label()
4970                 code.put_goto(over_label);
4971                 code.put_label(finally_error_label)
4972                 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4973                 for var in Naming.exc_vars:
4974                     code.putln("Py_XDECREF(%s);" % var)
4975                 code.putln("}")
4976                 code.put_goto(old_error_label)
4977                 code.put_label(over_label)
4978             code.error_label = old_error_label
4979         if cases_used:
4980             code.putln(
4981                 "switch (__pyx_why) {")
4982             for i in cases_used:
4983                 old_label = old_labels[i]
4984                 if old_label == old_error_label and self.preserve_exception:
4985                     self.put_error_uncatcher(code, i+1, old_error_label)
4986                 else:
4987                     code.use_label(old_label)
4988                     code.putln(
4989                         "case %s: goto %s;" % (
4990                             i+1,
4991                             old_label))
4992             code.putln(
4993                 "}")
4994         code.putln(
4995             "}")
4996
4997     def generate_function_definitions(self, env, code):
4998         self.body.generate_function_definitions(env, code)
4999         self.finally_clause.generate_function_definitions(env, code)
5000
5001     def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5002         code.globalstate.use_utility_code(restore_exception_utility_code)
5003         code.putln(
5004             "%s: {" %
5005                 error_label)
5006         code.putln(
5007                 "__pyx_why = %s;" %
5008                     i)
5009         for temp_name, type in temps_to_clean_up:
5010             code.put_xdecref_clear(temp_name, type)
5011         code.putln(
5012                 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5013                     Naming.exc_vars)
5014         code.putln(
5015                 "%s = %s;" % (
5016                     Naming.exc_lineno_name, Naming.lineno_cname))
5017         code.put_goto(catch_label)
5018         code.putln("}")
5019             
5020     def put_error_uncatcher(self, code, i, error_label):
5021         code.globalstate.use_utility_code(restore_exception_utility_code)
5022         code.putln(
5023             "case %s: {" %
5024                 i)
5025         code.putln(
5026                 "__Pyx_ErrRestore(%s, %s, %s);" %
5027                     Naming.exc_vars)
5028         code.putln(
5029                 "%s = %s;" % (
5030                     Naming.lineno_cname, Naming.exc_lineno_name))
5031         for var in Naming.exc_vars:
5032             code.putln(
5033                 "%s = 0;" %
5034                     var)
5035         code.put_goto(error_label)
5036         code.putln(
5037             "}")
5038
5039     def annotate(self, code):
5040         self.body.annotate(code)
5041         self.finally_clause.annotate(code)
5042
5043
5044 class GILStatNode(TryFinallyStatNode):
5045     #  'with gil' or 'with nogil' statement
5046     #
5047     #   state   string   'gil' or 'nogil'
5048
5049 #    child_attrs = []
5050     
5051     preserve_exception = 0
5052
5053     def __init__(self, pos, state, body):
5054         self.state = state
5055         TryFinallyStatNode.__init__(self, pos,
5056             body = body,
5057             finally_clause = GILExitNode(pos, state = state))
5058
5059     def analyse_expressions(self, env):
5060         env.use_utility_code(force_init_threads_utility_code)
5061         was_nogil = env.nogil
5062         env.nogil = 1
5063         TryFinallyStatNode.analyse_expressions(self, env)
5064         env.nogil = was_nogil
5065
5066     nogil_check = None
5067
5068     def generate_execution_code(self, code):
5069         code.mark_pos(self.pos)
5070         if self.state == 'gil':
5071             code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
5072         else:
5073             code.putln("{ PyThreadState *_save;")
5074             code.putln("Py_UNBLOCK_THREADS")
5075         TryFinallyStatNode.generate_execution_code(self, code)
5076         code.putln("}")
5077
5078
5079 class GILExitNode(StatNode):
5080     #  Used as the 'finally' block in a GILStatNode
5081     #
5082     #  state   string   'gil' or 'nogil'
5083
5084     child_attrs = []
5085
5086     def analyse_expressions(self, env):
5087         pass
5088
5089     def generate_execution_code(self, code):
5090         if self.state == 'gil':
5091             code.putln("PyGILState_Release();")
5092         else:
5093             code.putln("Py_BLOCK_THREADS")
5094
5095
5096 class CImportStatNode(StatNode):
5097     #  cimport statement
5098     #
5099     #  module_name   string           Qualified name of module being imported
5100     #  as_name       string or None   Name specified in "as" clause, if any
5101
5102     child_attrs = []
5103     
5104     def analyse_declarations(self, env):
5105         if not env.is_module_scope:
5106             error(self.pos, "cimport only allowed at module level")
5107             return
5108         module_scope = env.find_module(self.module_name, self.pos)
5109         if "." in self.module_name:
5110             names = [EncodedString(name) for name in self.module_name.split(".")]
5111             top_name = names[0]
5112             top_module_scope = env.context.find_submodule(top_name)
5113             module_scope = top_module_scope
5114             for name in names[1:]:
5115                 submodule_scope = module_scope.find_submodule(name)
5116                 module_scope.declare_module(name, submodule_scope, self.pos)
5117                 module_scope = submodule_scope
5118             if self.as_name:
5119                 env.declare_module(self.as_name, module_scope, self.pos)
5120             else:
5121                 env.declare_module(top_name, top_module_scope, self.pos)
5122         else:
5123             name = self.as_name or self.module_name
5124             env.declare_module(name, module_scope, self.pos)
5125
5126     def analyse_expressions(self, env):
5127         pass
5128     
5129     def generate_execution_code(self, code):
5130         pass
5131     
5132
5133 class FromCImportStatNode(StatNode):
5134     #  from ... cimport statement
5135     #
5136     #  module_name     string                        Qualified name of module
5137     #  imported_names  [(pos, name, as_name, kind)]  Names to be imported
5138     
5139     child_attrs = []
5140
5141     def analyse_declarations(self, env):
5142         if not env.is_module_scope:
5143             error(self.pos, "cimport only allowed at module level")
5144             return
5145         module_scope = env.find_module(self.module_name, self.pos)
5146         env.add_imported_module(module_scope)
5147         for pos, name, as_name, kind in self.imported_names:
5148             if name == "*":
5149                 for local_name, entry in module_scope.entries.items():
5150                     env.add_imported_entry(local_name, entry, pos)
5151             else:
5152                 entry = module_scope.lookup(name)
5153                 if entry:
5154                     if kind and not self.declaration_matches(entry, kind):
5155                         entry.redeclared(pos)
5156                 else:
5157                     if kind == 'struct' or kind == 'union':
5158                         entry = module_scope.declare_struct_or_union(name,
5159                             kind = kind, scope = None, typedef_flag = 0, pos = pos)
5160                     elif kind == 'class':
5161                         entry = module_scope.declare_c_class(name, pos = pos,
5162                             module_name = self.module_name)
5163                     else:
5164                         submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5165                         if submodule_scope.parent_module is module_scope:
5166                             env.declare_module(as_name or name, submodule_scope, self.pos)
5167                         else:
5168                             error(pos, "Name '%s' not declared in module '%s'"
5169                                 % (name, self.module_name))
5170                         
5171                 if entry:
5172                     local_name = as_name or name
5173                     env.add_imported_entry(local_name, entry, pos)
5174     
5175     def declaration_matches(self, entry, kind):
5176         if not entry.is_type:
5177             return 0
5178         type = entry.type
5179         if kind == 'class':
5180             if not type.is_extension_type:
5181                 return 0
5182         else:
5183             if not type.is_struct_or_union:
5184                 return 0
5185             if kind != type.kind:
5186                 return 0
5187         return 1
5188
5189     def analyse_expressions(self, env):
5190         pass
5191     
5192     def generate_execution_code(self, code):
5193         pass
5194
5195
5196 class FromImportStatNode(StatNode):
5197     #  from ... import statement
5198     #
5199     #  module           ImportNode
5200     #  items            [(string, NameNode)]
5201     #  interned_items   [(string, NameNode, ExprNode)]
5202     #  item             PyTempNode            used internally
5203     #  import_star      boolean               used internally
5204
5205     child_attrs = ["module"]
5206     import_star = 0
5207     
5208     def analyse_declarations(self, env):
5209         for name, target in self.items:
5210             if name == "*":
5211                 if not env.is_module_scope:
5212                     error(self.pos, "import * only allowed at module level")
5213                     return
5214                 env.has_import_star = 1
5215                 self.import_star = 1
5216             else:
5217                 target.analyse_target_declaration(env)
5218     
5219     def analyse_expressions(self, env):
5220         import ExprNodes
5221         self.module.analyse_expressions(env)
5222         self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5223         self.interned_items = []
5224         for name, target in self.items:
5225             if name == '*':
5226                 for _, entry in env.entries.items():
5227                     if not entry.is_type and entry.type.is_extension_type:
5228                         env.use_utility_code(ExprNodes.type_test_utility_code)
5229                         break
5230             else:
5231                 entry =  env.lookup(target.name)
5232                 # check whether or not entry is already cimported
5233                 if (entry.is_type and entry.type.name == name
5234                     and hasattr(entry.type, 'module_name')):
5235                     if entry.type.module_name == self.module.module_name.value:
5236                         # cimported with absolute name
5237                         continue
5238                     try:
5239                         # cimported with relative name
5240                         module = env.find_module(self.module.module_name.value,
5241                                                  pos=None)
5242                         if entry.type.module_name == module.qualified_name:
5243                             continue
5244                     except AttributeError:
5245                         pass 
5246                 target.analyse_target_expression(env, None)
5247                 if target.type is py_object_type:
5248                     coerced_item = None
5249                 else:
5250                     coerced_item = self.item.coerce_to(target.type, env)
5251                 self.interned_items.append((name, target, coerced_item))
5252     
5253     def generate_execution_code(self, code):
5254         self.module.generate_evaluation_code(code)
5255         if self.import_star:
5256             code.putln(
5257                 'if (%s(%s) < 0) %s;' % (
5258                     Naming.import_star,
5259                     self.module.py_result(),
5260                     code.error_goto(self.pos)))
5261         item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5262         self.item.set_cname(item_temp)
5263         for name, target, coerced_item in self.interned_items:
5264             cname = code.intern_identifier(name)
5265             code.putln(
5266                 '%s = PyObject_GetAttr(%s, %s); %s' % (
5267                     item_temp,
5268                     self.module.py_result(),
5269                     cname,
5270                     code.error_goto_if_null(item_temp, self.pos)))
5271             code.put_gotref(item_temp)
5272             if coerced_item is None:
5273                 target.generate_assignment_code(self.item, code)
5274             else:
5275                 coerced_item.allocate_temp_result(code)
5276                 coerced_item.generate_result_code(code)
5277                 target.generate_assignment_code(coerced_item, code)
5278             code.put_decref_clear(item_temp, py_object_type)
5279         code.funcstate.release_temp(item_temp)
5280         self.module.generate_disposal_code(code)
5281         self.module.free_temps(code)
5282
5283
5284
5285 #------------------------------------------------------------------------------------
5286 #
5287 #  Runtime support code
5288 #
5289 #------------------------------------------------------------------------------------
5290
5291 utility_function_predeclarations = \
5292 """
5293 /* inline attribute */
5294 #ifndef CYTHON_INLINE
5295   #if defined(__GNUC__)
5296     #define CYTHON_INLINE __inline__
5297   #elif defined(_MSC_VER)
5298     #define CYTHON_INLINE __inline
5299   #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5300     #define CYTHON_INLINE inline
5301   #else
5302     #define CYTHON_INLINE 
5303   #endif
5304 #endif
5305
5306 /* unused attribute */
5307 #ifndef CYTHON_UNUSED
5308 # if defined(__GNUC__)
5309 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5310 #     define CYTHON_UNUSED __attribute__ ((__unused__)) 
5311 #   else
5312 #     define CYTHON_UNUSED
5313 #   endif
5314 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5315 #   define CYTHON_UNUSED __attribute__ ((__unused__)) 
5316 # else
5317 #   define CYTHON_UNUSED 
5318 # endif
5319 #endif
5320
5321 typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
5322
5323 """
5324
5325 if Options.gcc_branch_hints:
5326     branch_prediction_macros = \
5327     """
5328 #ifdef __GNUC__
5329 /* Test for GCC > 2.95 */
5330 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) 
5331 #define likely(x)   __builtin_expect(!!(x), 1)
5332 #define unlikely(x) __builtin_expect(!!(x), 0)
5333 #else /* __GNUC__ > 2 ... */
5334 #define likely(x)   (x)
5335 #define unlikely(x) (x)
5336 #endif /* __GNUC__ > 2 ... */
5337 #else /* __GNUC__ */
5338 #define likely(x)   (x)
5339 #define unlikely(x) (x)
5340 #endif /* __GNUC__ */
5341     """
5342 else:
5343     branch_prediction_macros = \
5344     """
5345 #define likely(x)   (x)
5346 #define unlikely(x) (x)
5347     """
5348
5349 #get_name_predeclaration = \
5350 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5351
5352 #get_name_interned_predeclaration = \
5353 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5354
5355 #------------------------------------------------------------------------------------
5356
5357 printing_utility_code = UtilityCode(
5358 proto = """
5359 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5360 #if PY_MAJOR_VERSION >= 3
5361 static PyObject* %s = 0;
5362 static PyObject* %s = 0;
5363 #endif
5364 """ % (Naming.print_function, Naming.print_function_kwargs),
5365 cleanup = """
5366 #if PY_MAJOR_VERSION >= 3
5367 Py_CLEAR(%s);
5368 Py_CLEAR(%s);
5369 #endif
5370 """ % (Naming.print_function, Naming.print_function_kwargs),
5371 impl = r"""
5372 #if PY_MAJOR_VERSION < 3
5373 static PyObject *__Pyx_GetStdout(void) {
5374     PyObject *f = PySys_GetObject((char *)"stdout");
5375     if (!f) {
5376         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5377     }
5378     return f;
5379 }
5380
5381 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5382     PyObject* v;
5383     int i;
5384
5385     if (!f) {
5386         if (!(f = __Pyx_GetStdout()))
5387             return -1;
5388     }
5389     for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5390         if (PyFile_SoftSpace(f, 1)) {
5391             if (PyFile_WriteString(" ", f) < 0)
5392                 return -1;
5393         }
5394         v = PyTuple_GET_ITEM(arg_tuple, i);
5395         if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5396             return -1;
5397         if (PyString_Check(v)) {
5398             char *s = PyString_AsString(v);
5399             Py_ssize_t len = PyString_Size(v);
5400             if (len > 0 &&
5401                 isspace(Py_CHARMASK(s[len-1])) &&
5402                 s[len-1] != ' ')
5403                     PyFile_SoftSpace(f, 0);
5404         }
5405     }
5406     if (newline) {
5407         if (PyFile_WriteString("\n", f) < 0)
5408             return -1;
5409         PyFile_SoftSpace(f, 0);
5410     }
5411     return 0;
5412 }
5413
5414 #else /* Python 3 has a print function */
5415
5416 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5417     PyObject* kwargs = 0;
5418     PyObject* result = 0;
5419     PyObject* end_string;
5420     if (unlikely(!%(PRINT_FUNCTION)s)) {
5421         %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5422         if (!%(PRINT_FUNCTION)s)
5423             return -1;
5424     }
5425     if (stream) {
5426         kwargs = PyDict_New();
5427         if (unlikely(!kwargs))
5428             return -1;
5429         if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5430             goto bad;
5431         if (!newline) {
5432             end_string = PyUnicode_FromStringAndSize(" ", 1);
5433             if (unlikely(!end_string))
5434                 goto bad;
5435             if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5436                 Py_DECREF(end_string);
5437                 goto bad;
5438             }
5439             Py_DECREF(end_string);
5440         }
5441     } else if (!newline) {
5442         if (unlikely(!%(PRINT_KWARGS)s)) {
5443             %(PRINT_KWARGS)s = PyDict_New();
5444             if (unlikely(!%(PRINT_KWARGS)s))
5445                 return -1;
5446             end_string = PyUnicode_FromStringAndSize(" ", 1);
5447             if (unlikely(!end_string))
5448                 return -1;
5449             if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5450                 Py_DECREF(end_string);
5451                 return -1;
5452             }
5453             Py_DECREF(end_string);
5454         }
5455         kwargs = %(PRINT_KWARGS)s;
5456     }
5457     result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5458     if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5459         Py_DECREF(kwargs);
5460     if (!result)
5461         return -1;
5462     Py_DECREF(result);
5463     return 0;
5464 bad:
5465     if (kwargs != %(PRINT_KWARGS)s)
5466         Py_XDECREF(kwargs);
5467     return -1;
5468 }
5469
5470 #endif
5471 """ % {'BUILTINS'       : Naming.builtins_cname,
5472        'PRINT_FUNCTION' : Naming.print_function,
5473        'PRINT_KWARGS'   : Naming.print_function_kwargs}
5474 )
5475
5476
5477 printing_one_utility_code = UtilityCode(
5478 proto = """
5479 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5480 """,
5481 impl = r"""
5482 #if PY_MAJOR_VERSION < 3
5483
5484 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5485     if (!f) {
5486         if (!(f = __Pyx_GetStdout()))
5487             return -1;
5488     }
5489     if (PyFile_SoftSpace(f, 0)) {
5490         if (PyFile_WriteString(" ", f) < 0)
5491             return -1;
5492     }
5493     if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5494         return -1;
5495     if (PyFile_WriteString("\n", f) < 0)
5496         return -1;
5497     return 0;
5498     /* the line below is just to avoid compiler
5499      * compiler warnings about unused functions */
5500     return __Pyx_Print(f, NULL, 0);
5501 }
5502
5503 #else /* Python 3 has a print function */
5504
5505 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5506     int res;
5507     PyObject* arg_tuple = PyTuple_New(1);
5508     if (unlikely(!arg_tuple))
5509         return -1;
5510     Py_INCREF(o);
5511     PyTuple_SET_ITEM(arg_tuple, 0, o);
5512     res = __Pyx_Print(stream, arg_tuple, 1);
5513     Py_DECREF(arg_tuple);
5514     return res;
5515 }
5516
5517 #endif
5518 """,
5519 requires=[printing_utility_code])
5520
5521
5522
5523 #------------------------------------------------------------------------------------
5524
5525 # Exception raising code
5526 #
5527 # Exceptions are raised by __Pyx_Raise() and stored as plain
5528 # type/value/tb in PyThreadState->curexc_*.  When being caught by an
5529 # 'except' statement, curexc_* is moved over to exc_* by
5530 # __Pyx_GetException()
5531
5532 restore_exception_utility_code = UtilityCode(
5533 proto = """
5534 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5535 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5536 """,
5537 impl = """
5538 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5539     PyObject *tmp_type, *tmp_value, *tmp_tb;
5540     PyThreadState *tstate = PyThreadState_GET();
5541
5542     tmp_type = tstate->curexc_type;
5543     tmp_value = tstate->curexc_value;
5544     tmp_tb = tstate->curexc_traceback;
5545     tstate->curexc_type = type;
5546     tstate->curexc_value = value;
5547     tstate->curexc_traceback = tb;
5548     Py_XDECREF(tmp_type);
5549     Py_XDECREF(tmp_value);
5550     Py_XDECREF(tmp_tb);
5551 }
5552
5553 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5554     PyThreadState *tstate = PyThreadState_GET();
5555     *type = tstate->curexc_type;
5556     *value = tstate->curexc_value;
5557     *tb = tstate->curexc_traceback;
5558
5559     tstate->curexc_type = 0;
5560     tstate->curexc_value = 0;
5561     tstate->curexc_traceback = 0;
5562 }
5563
5564 """)
5565
5566 # The following function is based on do_raise() from ceval.c. There
5567 # are separate versions for Python2 and Python3 as exception handling
5568 # has changed quite a lot between the two versions.
5569
5570 raise_utility_code = UtilityCode(
5571 proto = """
5572 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5573 """,
5574 impl = """
5575 #if PY_MAJOR_VERSION < 3
5576 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5577     Py_XINCREF(type);
5578     Py_XINCREF(value);
5579     Py_XINCREF(tb);
5580     /* First, check the traceback argument, replacing None with NULL. */
5581     if (tb == Py_None) {
5582         Py_DECREF(tb);
5583         tb = 0;
5584     }
5585     else if (tb != NULL && !PyTraceBack_Check(tb)) {
5586         PyErr_SetString(PyExc_TypeError,
5587             "raise: arg 3 must be a traceback or None");
5588         goto raise_error;
5589     }
5590     /* Next, replace a missing value with None */
5591     if (value == NULL) {
5592         value = Py_None;
5593         Py_INCREF(value);
5594     }
5595     #if PY_VERSION_HEX < 0x02050000
5596     if (!PyClass_Check(type))
5597     #else
5598     if (!PyType_Check(type))
5599     #endif
5600     {
5601         /* Raising an instance.  The value should be a dummy. */
5602         if (value != Py_None) {
5603             PyErr_SetString(PyExc_TypeError,
5604                 "instance exception may not have a separate value");
5605             goto raise_error;
5606         }
5607         /* Normalize to raise <class>, <instance> */
5608         Py_DECREF(value);
5609         value = type;
5610         #if PY_VERSION_HEX < 0x02050000
5611             if (PyInstance_Check(type)) {
5612                 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5613                 Py_INCREF(type);
5614             }
5615             else {
5616                 type = 0;
5617                 PyErr_SetString(PyExc_TypeError,
5618                     "raise: exception must be an old-style class or instance");
5619                 goto raise_error;
5620             }
5621         #else
5622             type = (PyObject*) Py_TYPE(type);
5623             Py_INCREF(type);
5624             if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5625                 PyErr_SetString(PyExc_TypeError,
5626                     "raise: exception class must be a subclass of BaseException");
5627                 goto raise_error;
5628             }
5629         #endif
5630     }
5631
5632     __Pyx_ErrRestore(type, value, tb);
5633     return;
5634 raise_error:
5635     Py_XDECREF(value);
5636     Py_XDECREF(type);
5637     Py_XDECREF(tb);
5638     return;
5639 }
5640
5641 #else /* Python 3+ */
5642
5643 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5644     if (tb == Py_None) {
5645         tb = 0;
5646     } else if (tb && !PyTraceBack_Check(tb)) {
5647         PyErr_SetString(PyExc_TypeError,
5648             "raise: arg 3 must be a traceback or None");
5649         goto bad;
5650     }
5651     if (value == Py_None)
5652         value = 0;
5653
5654     if (PyExceptionInstance_Check(type)) {
5655         if (value) {
5656             PyErr_SetString(PyExc_TypeError,
5657                 "instance exception may not have a separate value");
5658             goto bad;
5659         }
5660         value = type;
5661         type = (PyObject*) Py_TYPE(value);
5662     } else if (!PyExceptionClass_Check(type)) {
5663         PyErr_SetString(PyExc_TypeError,
5664             "raise: exception class must be a subclass of BaseException");
5665         goto bad;
5666     }
5667
5668     PyErr_SetObject(type, value);
5669
5670     if (tb) {
5671         PyThreadState *tstate = PyThreadState_GET();
5672         PyObject* tmp_tb = tstate->curexc_traceback;
5673         if (tb != tmp_tb) {
5674             Py_INCREF(tb);
5675             tstate->curexc_traceback = tb;
5676             Py_XDECREF(tmp_tb);
5677         }
5678     }
5679
5680 bad:
5681     return;
5682 }
5683 #endif
5684 """,
5685 requires=[restore_exception_utility_code])
5686
5687 #------------------------------------------------------------------------------------
5688
5689 get_exception_utility_code = UtilityCode(
5690 proto = """
5691 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5692 """,
5693 impl = """
5694 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5695     PyObject *local_type, *local_value, *local_tb;
5696     PyObject *tmp_type, *tmp_value, *tmp_tb;
5697     PyThreadState *tstate = PyThreadState_GET();
5698     local_type = tstate->curexc_type;
5699     local_value = tstate->curexc_value;
5700     local_tb = tstate->curexc_traceback;
5701     tstate->curexc_type = 0;
5702     tstate->curexc_value = 0;
5703     tstate->curexc_traceback = 0;
5704     PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5705     if (unlikely(tstate->curexc_type))
5706         goto bad;
5707     #if PY_MAJOR_VERSION >= 3
5708     if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5709         goto bad;
5710     #endif
5711     *type = local_type;
5712     *value = local_value;
5713     *tb = local_tb;
5714     Py_INCREF(local_type);
5715     Py_INCREF(local_value);
5716     Py_INCREF(local_tb);
5717     tmp_type = tstate->exc_type;
5718     tmp_value = tstate->exc_value;
5719     tmp_tb = tstate->exc_traceback;
5720     tstate->exc_type = local_type;
5721     tstate->exc_value = local_value;
5722     tstate->exc_traceback = local_tb;
5723     /* Make sure tstate is in a consistent state when we XDECREF
5724        these objects (XDECREF may run arbitrary code). */
5725     Py_XDECREF(tmp_type);
5726     Py_XDECREF(tmp_value);
5727     Py_XDECREF(tmp_tb);
5728     return 0;
5729 bad:
5730     *type = 0;
5731     *value = 0;
5732     *tb = 0;
5733     Py_XDECREF(local_type);
5734     Py_XDECREF(local_value);
5735     Py_XDECREF(local_tb);
5736     return -1;
5737 }
5738
5739 """)
5740
5741 #------------------------------------------------------------------------------------
5742
5743 get_exception_tuple_utility_code = UtilityCode(proto="""
5744 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5745 """,
5746 # I doubt that calling __Pyx_GetException() here is correct as it moves
5747 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5748 # exception handlers later on from receiving it.
5749 impl = """
5750 static PyObject *__Pyx_GetExceptionTuple(void) {
5751     PyObject *type = NULL, *value = NULL, *tb = NULL;
5752     if (__Pyx_GetException(&type, &value, &tb) == 0) {
5753         PyObject* exc_info = PyTuple_New(3);
5754         if (exc_info) {
5755             Py_INCREF(type);
5756             Py_INCREF(value);
5757             Py_INCREF(tb);
5758             PyTuple_SET_ITEM(exc_info, 0, type);
5759             PyTuple_SET_ITEM(exc_info, 1, value);
5760             PyTuple_SET_ITEM(exc_info, 2, tb);
5761             return exc_info;
5762         }
5763     }
5764     return NULL;
5765 }
5766 """,
5767 requires=[get_exception_utility_code])
5768
5769 #------------------------------------------------------------------------------------
5770
5771 reset_exception_utility_code = UtilityCode(
5772 proto = """
5773 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5774 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5775 """,
5776 impl = """
5777 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5778     PyThreadState *tstate = PyThreadState_GET();
5779     *type = tstate->exc_type;
5780     *value = tstate->exc_value;
5781     *tb = tstate->exc_traceback;
5782     Py_XINCREF(*type);
5783     Py_XINCREF(*value);
5784     Py_XINCREF(*tb);
5785 }
5786
5787 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5788     PyObject *tmp_type, *tmp_value, *tmp_tb;
5789     PyThreadState *tstate = PyThreadState_GET();
5790     tmp_type = tstate->exc_type;
5791     tmp_value = tstate->exc_value;
5792     tmp_tb = tstate->exc_traceback;
5793     tstate->exc_type = type;
5794     tstate->exc_value = value;
5795     tstate->exc_traceback = tb;
5796     Py_XDECREF(tmp_type);
5797     Py_XDECREF(tmp_value);
5798     Py_XDECREF(tmp_tb);
5799 }
5800 """)
5801
5802 #------------------------------------------------------------------------------------
5803
5804 arg_type_test_utility_code = UtilityCode(
5805 proto = """
5806 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5807     const char *name, int exact); /*proto*/
5808 """,
5809 impl = """
5810 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5811     const char *name, int exact)
5812 {
5813     if (!type) {
5814         PyErr_Format(PyExc_SystemError, "Missing type object");
5815         return 0;
5816     }
5817     if (none_allowed && obj == Py_None) return 1;
5818     else if (exact) {
5819         if (Py_TYPE(obj) == type) return 1;
5820     }
5821     else {
5822         if (PyObject_TypeCheck(obj, type)) return 1;
5823     }
5824     PyErr_Format(PyExc_TypeError,
5825         "Argument '%s' has incorrect type (expected %s, got %s)",
5826         name, type->tp_name, Py_TYPE(obj)->tp_name);
5827     return 0;
5828 }
5829 """)
5830
5831 #------------------------------------------------------------------------------------
5832 #
5833 #  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5834 #  many or too few positional arguments were found.  This handles
5835 #  Py_ssize_t formatting correctly.
5836
5837 raise_argtuple_invalid_utility_code = UtilityCode(
5838 proto = """
5839 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5840     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5841 """,
5842 impl = """
5843 static void __Pyx_RaiseArgtupleInvalid(
5844     const char* func_name,
5845     int exact,
5846     Py_ssize_t num_min,
5847     Py_ssize_t num_max,
5848     Py_ssize_t num_found)
5849 {
5850     Py_ssize_t num_expected;
5851     const char *number, *more_or_less;
5852
5853     if (num_found < num_min) {
5854         num_expected = num_min;
5855         more_or_less = "at least";
5856     } else {
5857         num_expected = num_max;
5858         more_or_less = "at most";
5859     }
5860     if (exact) {
5861         more_or_less = "exactly";
5862     }
5863     number = (num_expected == 1) ? "" : "s";
5864     PyErr_Format(PyExc_TypeError,
5865         #if PY_VERSION_HEX < 0x02050000
5866             "%s() takes %s %d positional argument%s (%d given)",
5867         #else
5868             "%s() takes %s %zd positional argument%s (%zd given)",
5869         #endif
5870         func_name, more_or_less, num_expected, number, num_found);
5871 }
5872 """)
5873
5874 raise_keyword_required_utility_code = UtilityCode(
5875 proto = """
5876 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5877 """,
5878 impl = """
5879 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5880     const char* func_name,
5881     PyObject* kw_name)
5882 {
5883     PyErr_Format(PyExc_TypeError,
5884         #if PY_MAJOR_VERSION >= 3
5885         "%s() needs keyword-only argument %U", func_name, kw_name);
5886         #else
5887         "%s() needs keyword-only argument %s", func_name,
5888         PyString_AS_STRING(kw_name));
5889         #endif
5890 }
5891 """)
5892
5893 raise_double_keywords_utility_code = UtilityCode(
5894 proto = """
5895 static void __Pyx_RaiseDoubleKeywordsError(
5896     const char* func_name, PyObject* kw_name); /*proto*/
5897 """,
5898 impl = """
5899 static void __Pyx_RaiseDoubleKeywordsError(
5900     const char* func_name,
5901     PyObject* kw_name)
5902 {
5903     PyErr_Format(PyExc_TypeError,
5904         #if PY_MAJOR_VERSION >= 3
5905         "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5906         #else
5907         "%s() got multiple values for keyword argument '%s'", func_name,
5908         PyString_AS_STRING(kw_name));
5909         #endif
5910 }
5911 """)
5912
5913 #------------------------------------------------------------------------------------
5914 #
5915 #  __Pyx_CheckKeywordStrings raises an error if non-string keywords
5916 #  were passed to a function, or if any keywords were passed to a
5917 #  function that does not accept them.
5918
5919 keyword_string_check_utility_code = UtilityCode(
5920 proto = """
5921 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5922     const char* function_name, int kw_allowed); /*proto*/
5923 """,
5924 impl = """
5925 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5926     PyObject *kwdict,
5927     const char* function_name,
5928     int kw_allowed)
5929 {
5930     PyObject* key = 0;
5931     Py_ssize_t pos = 0;
5932     while (PyDict_Next(kwdict, &pos, &key, 0)) {
5933         #if PY_MAJOR_VERSION < 3
5934         if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5935         #else
5936         if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5937         #endif
5938             goto invalid_keyword_type;
5939     }
5940     if ((!kw_allowed) && unlikely(key))
5941         goto invalid_keyword;
5942     return 1;
5943 invalid_keyword_type:
5944     PyErr_Format(PyExc_TypeError,
5945         "%s() keywords must be strings", function_name);
5946     return 0;
5947 invalid_keyword:
5948     PyErr_Format(PyExc_TypeError,
5949     #if PY_MAJOR_VERSION < 3
5950         "%s() got an unexpected keyword argument '%s'",
5951         function_name, PyString_AsString(key));
5952     #else
5953         "%s() got an unexpected keyword argument '%U'",
5954         function_name, key);
5955     #endif
5956     return 0;
5957 }
5958 """)
5959
5960 #------------------------------------------------------------------------------------
5961 #
5962 #  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5963 #  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
5964 #  keywords will raise an invalid keyword error.
5965 #
5966 #  Three kinds of errors are checked: 1) non-string keywords, 2)
5967 #  unexpected keywords and 3) overlap with positional arguments.
5968 #
5969 #  If num_posargs is greater 0, it denotes the number of positional
5970 #  arguments that were passed and that must therefore not appear
5971 #  amongst the keywords as well.
5972 #
5973 #  This method does not check for required keyword arguments.
5974 #
5975
5976 parse_keywords_utility_code = UtilityCode(
5977 proto = """
5978 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5979     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5980     const char* function_name); /*proto*/
5981 """,
5982 impl = """
5983 static int __Pyx_ParseOptionalKeywords(
5984     PyObject *kwds,
5985     PyObject **argnames[],
5986     PyObject *kwds2,
5987     PyObject *values[],
5988     Py_ssize_t num_pos_args,
5989     const char* function_name)
5990 {
5991     PyObject *key = 0, *value = 0;
5992     Py_ssize_t pos = 0;
5993     PyObject*** name;
5994     PyObject*** first_kw_arg = argnames + num_pos_args;
5995
5996     while (PyDict_Next(kwds, &pos, &key, &value)) {
5997         name = first_kw_arg;
5998         while (*name && (**name != key)) name++;
5999         if (*name) {
6000             values[name-argnames] = value;
6001         } else {
6002             #if PY_MAJOR_VERSION < 3
6003             if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6004             #else
6005             if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6006             #endif
6007                 goto invalid_keyword_type;
6008             } else {
6009                 for (name = first_kw_arg; *name; name++) {
6010                     #if PY_MAJOR_VERSION >= 3
6011                     if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6012                         PyUnicode_Compare(**name, key) == 0) break;
6013                     #else
6014                     if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6015                         _PyString_Eq(**name, key)) break;
6016                     #endif
6017                 }
6018                 if (*name) {
6019                     values[name-argnames] = value;
6020                 } else {
6021                     /* unexpected keyword found */
6022                     for (name=argnames; name != first_kw_arg; name++) {
6023                         if (**name == key) goto arg_passed_twice;
6024                         #if PY_MAJOR_VERSION >= 3
6025                         if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6026                             PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6027                         #else
6028                         if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6029                             _PyString_Eq(**name, key)) goto arg_passed_twice;
6030                         #endif
6031                     }
6032                     if (kwds2) {
6033                         if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6034                     } else {
6035                         goto invalid_keyword;
6036                     }
6037                 }
6038             }
6039         }
6040     }
6041     return 0;
6042 arg_passed_twice:
6043     __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6044     goto bad;
6045 invalid_keyword_type:
6046     PyErr_Format(PyExc_TypeError,
6047         "%s() keywords must be strings", function_name);
6048     goto bad;
6049 invalid_keyword:
6050     PyErr_Format(PyExc_TypeError,
6051     #if PY_MAJOR_VERSION < 3
6052         "%s() got an unexpected keyword argument '%s'",
6053         function_name, PyString_AsString(key));
6054     #else
6055         "%s() got an unexpected keyword argument '%U'",
6056         function_name, key);
6057     #endif
6058 bad:
6059     return -1;
6060 }
6061 """)
6062
6063 #------------------------------------------------------------------------------------
6064
6065 traceback_utility_code = UtilityCode(
6066 proto = """
6067 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6068 """,
6069 impl = """
6070 #include "compile.h"
6071 #include "frameobject.h"
6072 #include "traceback.h"
6073
6074 static void __Pyx_AddTraceback(const char *funcname) {
6075     PyObject *py_srcfile = 0;
6076     PyObject *py_funcname = 0;
6077     PyObject *py_globals = 0;
6078     PyCodeObject *py_code = 0;
6079     PyFrameObject *py_frame = 0;
6080
6081     #if PY_MAJOR_VERSION < 3
6082     py_srcfile = PyString_FromString(%(FILENAME)s);
6083     #else
6084     py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6085     #endif
6086     if (!py_srcfile) goto bad;
6087     if (%(CLINENO)s) {
6088         #if PY_MAJOR_VERSION < 3
6089         py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6090         #else
6091         py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6092         #endif
6093     }
6094     else {
6095         #if PY_MAJOR_VERSION < 3
6096         py_funcname = PyString_FromString(funcname);
6097         #else
6098         py_funcname = PyUnicode_FromString(funcname);
6099         #endif
6100     }
6101     if (!py_funcname) goto bad;
6102     py_globals = PyModule_GetDict(%(GLOBALS)s);
6103     if (!py_globals) goto bad;
6104     py_code = PyCode_New(
6105         0,            /*int argcount,*/
6106         #if PY_MAJOR_VERSION >= 3
6107         0,            /*int kwonlyargcount,*/
6108         #endif
6109         0,            /*int nlocals,*/
6110         0,            /*int stacksize,*/
6111         0,            /*int flags,*/
6112         %(EMPTY_BYTES)s, /*PyObject *code,*/
6113         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6114         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6115         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6116         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6117         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6118         py_srcfile,   /*PyObject *filename,*/
6119         py_funcname,  /*PyObject *name,*/
6120         %(LINENO)s,   /*int firstlineno,*/
6121         %(EMPTY_BYTES)s  /*PyObject *lnotab*/
6122     );
6123     if (!py_code) goto bad;
6124     py_frame = PyFrame_New(
6125         PyThreadState_GET(), /*PyThreadState *tstate,*/
6126         py_code,             /*PyCodeObject *code,*/
6127         py_globals,          /*PyObject *globals,*/
6128         0                    /*PyObject *locals*/
6129     );
6130     if (!py_frame) goto bad;
6131     py_frame->f_lineno = %(LINENO)s;
6132     PyTraceBack_Here(py_frame);
6133 bad:
6134     Py_XDECREF(py_srcfile);
6135     Py_XDECREF(py_funcname);
6136     Py_XDECREF(py_code);
6137     Py_XDECREF(py_frame);
6138 }
6139 """ % {
6140     'FILENAME': Naming.filename_cname,
6141     'LINENO':  Naming.lineno_cname,
6142     'CFILENAME': Naming.cfilenm_cname,
6143     'CLINENO':  Naming.clineno_cname,
6144     'GLOBALS': Naming.module_cname,
6145     'EMPTY_TUPLE' : Naming.empty_tuple,
6146     'EMPTY_BYTES' : Naming.empty_bytes,
6147 })
6148
6149 #------------------------------------------------------------------------------------
6150
6151 unraisable_exception_utility_code = UtilityCode(
6152 proto = """
6153 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6154 """,
6155 impl = """
6156 static void __Pyx_WriteUnraisable(const char *name) {
6157     PyObject *old_exc, *old_val, *old_tb;
6158     PyObject *ctx;
6159     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6160     #if PY_MAJOR_VERSION < 3
6161     ctx = PyString_FromString(name);
6162     #else
6163     ctx = PyUnicode_FromString(name);
6164     #endif
6165     __Pyx_ErrRestore(old_exc, old_val, old_tb);
6166     if (!ctx) {
6167         PyErr_WriteUnraisable(Py_None);
6168     } else {
6169         PyErr_WriteUnraisable(ctx);
6170         Py_DECREF(ctx);
6171     }
6172 }
6173 """,
6174 requires=[restore_exception_utility_code])
6175
6176 #------------------------------------------------------------------------------------
6177
6178 set_vtable_utility_code = UtilityCode(
6179 proto = """
6180 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6181 """,
6182 impl = """
6183 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6184 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6185     PyObject *ob = PyCapsule_New(vtable, 0, 0);
6186 #else
6187     PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6188 #endif
6189     if (!ob)
6190         goto bad;
6191     if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6192         goto bad;
6193     Py_DECREF(ob);
6194     return 0;
6195 bad:
6196     Py_XDECREF(ob);
6197     return -1;
6198 }
6199 """)
6200
6201 #------------------------------------------------------------------------------------
6202
6203 get_vtable_utility_code = UtilityCode(
6204 proto = """
6205 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6206 """,
6207 impl = r"""
6208 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6209     PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6210     if (!ob)
6211         goto bad;
6212 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6213     *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6214 #else
6215     *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6216 #endif
6217     if (!*(void **)vtabptr)
6218         goto bad;
6219     Py_DECREF(ob);
6220     return 0;
6221 bad:
6222     Py_XDECREF(ob);
6223     return -1;
6224 }
6225 """)
6226
6227 #------------------------------------------------------------------------------------
6228
6229 init_string_tab_utility_code = UtilityCode(
6230 proto = """
6231 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6232 """,
6233 impl = """
6234 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6235     while (t->p) {
6236         #if PY_MAJOR_VERSION < 3
6237         if (t->is_unicode) {
6238             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6239         } else if (t->intern) {
6240             *t->p = PyString_InternFromString(t->s);
6241         } else {
6242             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6243         }
6244         #else  /* Python 3+ has unicode identifiers */
6245         if (t->is_unicode | t->is_str) {
6246             if (t->intern) {
6247                 *t->p = PyUnicode_InternFromString(t->s);
6248             } else if (t->encoding) {
6249                 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6250             } else {
6251                 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6252             }
6253         } else {
6254             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6255         }
6256         #endif
6257         if (!*t->p)
6258             return -1;
6259         ++t;
6260     }
6261     return 0;
6262 }
6263 """)
6264
6265 #------------------------------------------------------------------------------------
6266
6267 force_init_threads_utility_code = UtilityCode(
6268 proto="""
6269 #ifndef __PYX_FORCE_INIT_THREADS
6270   #if PY_VERSION_HEX < 0x02040200
6271     #define __PYX_FORCE_INIT_THREADS 1
6272   #else
6273     #define __PYX_FORCE_INIT_THREADS 0
6274   #endif
6275 #endif
6276 """)
6277
6278 #------------------------------------------------------------------------------------
6279
6280 # Note that cPython ignores PyTrace_EXCEPTION, 
6281 # but maybe some other profilers don't. 
6282
6283 profile_utility_code = UtilityCode(proto="""
6284 #ifndef CYTHON_PROFILE
6285   #define CYTHON_PROFILE 1
6286 #endif
6287
6288 #ifndef CYTHON_PROFILE_REUSE_FRAME
6289   #define CYTHON_PROFILE_REUSE_FRAME 0
6290 #endif
6291
6292 #if CYTHON_PROFILE
6293
6294   #include "compile.h"
6295   #include "frameobject.h"
6296   #include "traceback.h"
6297
6298   #if CYTHON_PROFILE_REUSE_FRAME
6299     #define CYTHON_FRAME_MODIFIER static
6300     #define CYTHON_FRAME_DEL
6301   #else
6302     #define CYTHON_FRAME_MODIFIER
6303     #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6304   #endif
6305
6306   #define __Pyx_TraceDeclarations                                  \\
6307   static PyCodeObject *%(FRAME_CODE)s = NULL;                      \\
6308   CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL;           \\
6309   int __Pyx_use_tracing = 0;                                                         
6310
6311   #define __Pyx_TraceCall(funcname, srcfile, firstlineno)                            \\
6312   if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) {      \\
6313       __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno);  \\
6314   }
6315
6316   #define __Pyx_TraceException()                                                           \\
6317   if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6318       PyObject *exc_info = __Pyx_GetExceptionTuple();                                      \\
6319       if (exc_info) {                                                                      \\
6320           PyThreadState_GET()->c_profilefunc(                                              \\
6321               PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info);  \\
6322           Py_DECREF(exc_info);                                                             \\
6323       }                                                                                    \\
6324   }
6325
6326   #define __Pyx_TraceReturn(result)                                                  \\
6327   if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6328       PyThreadState_GET()->c_profilefunc(                                            \\
6329           PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result);     \\
6330       CYTHON_FRAME_DEL;                                                               \\
6331   }
6332
6333   static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6334   static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6335
6336 #else
6337
6338   #define __Pyx_TraceDeclarations
6339   #define __Pyx_TraceCall(funcname, srcfile, firstlineno) 
6340   #define __Pyx_TraceException() 
6341   #define __Pyx_TraceReturn(result) 
6342
6343 #endif /* CYTHON_PROFILE */
6344 """ 
6345 % {
6346     "FRAME": Naming.frame_cname,
6347     "FRAME_CODE": Naming.frame_code_cname,
6348 },
6349 impl = """
6350
6351 #if CYTHON_PROFILE
6352
6353 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6354                                    PyFrameObject** frame,
6355                                    const char *funcname,
6356                                    const char *srcfile,
6357                                    int firstlineno) {
6358     if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6359         if (*code == NULL) {
6360             *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6361             if (*code == NULL) return 0;
6362         }
6363         *frame = PyFrame_New(
6364             PyThreadState_GET(),            /*PyThreadState *tstate*/
6365             *code,                          /*PyCodeObject *code*/
6366             PyModule_GetDict(%(MODULE)s),      /*PyObject *globals*/
6367             0                               /*PyObject *locals*/
6368         );
6369         if (*frame == NULL) return 0;
6370     }
6371     else {
6372         (*frame)->f_tstate = PyThreadState_GET();
6373     }
6374     return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6375 }
6376
6377 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6378     PyObject *py_srcfile = 0;
6379     PyObject *py_funcname = 0;
6380     PyCodeObject *py_code = 0;
6381
6382     #if PY_MAJOR_VERSION < 3
6383     py_funcname = PyString_FromString(funcname);
6384     py_srcfile = PyString_FromString(srcfile);
6385     #else
6386     py_funcname = PyUnicode_FromString(funcname);
6387     py_srcfile = PyUnicode_FromString(srcfile);
6388     #endif
6389     if (!py_funcname | !py_srcfile) goto bad;
6390
6391     py_code = PyCode_New(
6392         0,                /*int argcount,*/
6393         #if PY_MAJOR_VERSION >= 3
6394         0,                /*int kwonlyargcount,*/
6395         #endif
6396         0,                /*int nlocals,*/
6397         0,                /*int stacksize,*/
6398         0,                /*int flags,*/
6399         %(EMPTY_BYTES)s,  /*PyObject *code,*/
6400         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6401         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6402         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6403         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6404         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6405         py_srcfile,       /*PyObject *filename,*/
6406         py_funcname,      /*PyObject *name,*/
6407         firstlineno,      /*int firstlineno,*/
6408         %(EMPTY_BYTES)s   /*PyObject *lnotab*/
6409     );
6410
6411 bad: 
6412     Py_XDECREF(py_srcfile);
6413     Py_XDECREF(py_funcname);
6414     
6415     return py_code;
6416 }
6417
6418 #endif /* CYTHON_PROFILE */
6419 """ % {
6420     'EMPTY_TUPLE' : Naming.empty_tuple,
6421     'EMPTY_BYTES' : Naming.empty_bytes,
6422     "MODULE": Naming.module_cname,
6423 })