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