better error message
[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:
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.putln(
4910             "/*finally:*/ {")
4911         cases_used = []
4912         error_label_used = 0
4913         for i, new_label in enumerate(new_labels):
4914             if new_label in code.labels_used:
4915                 cases_used.append(i)
4916                 if new_label == new_error_label:
4917                     error_label_used = 1
4918                     error_label_case = i
4919         if cases_used:
4920             code.putln(
4921                     "int __pyx_why;")
4922             if error_label_used and self.preserve_exception:
4923                 code.putln(
4924                     "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4925                 code.putln(
4926                     "int %s;" % Naming.exc_lineno_name)
4927                 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4928                 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4929                 code.putln(exc_var_init_zero)
4930             else:
4931                 exc_var_init_zero = None
4932             code.use_label(catch_label)
4933             code.putln(
4934                     "__pyx_why = 0; goto %s;" % catch_label)
4935             for i in cases_used:
4936                 new_label = new_labels[i]
4937                 #if new_label and new_label != "<try>":
4938                 if new_label == new_error_label and self.preserve_exception:
4939                     self.put_error_catcher(code, 
4940                         new_error_label, i+1, catch_label, temps_to_clean_up)
4941                 else:
4942                     code.put('%s: ' % new_label)
4943                     if exc_var_init_zero:
4944                         code.putln(exc_var_init_zero)
4945                     code.putln("__pyx_why = %s; goto %s;" % (
4946                             i+1,
4947                             catch_label))
4948             code.put_label(catch_label)
4949         code.set_all_labels(old_labels)
4950         if error_label_used:
4951             code.new_error_label()
4952             finally_error_label = code.error_label
4953         self.finally_clause.generate_execution_code(code)
4954         if error_label_used:
4955             if finally_error_label in code.labels_used and self.preserve_exception:
4956                 over_label = code.new_label()
4957                 code.put_goto(over_label);
4958                 code.put_label(finally_error_label)
4959                 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4960                 for var in Naming.exc_vars:
4961                     code.putln("Py_XDECREF(%s);" % var)
4962                 code.putln("}")
4963                 code.put_goto(old_error_label)
4964                 code.put_label(over_label)
4965             code.error_label = old_error_label
4966         if cases_used:
4967             code.putln(
4968                 "switch (__pyx_why) {")
4969             for i in cases_used:
4970                 old_label = old_labels[i]
4971                 if old_label == old_error_label and self.preserve_exception:
4972                     self.put_error_uncatcher(code, i+1, old_error_label)
4973                 else:
4974                     code.use_label(old_label)
4975                     code.putln(
4976                         "case %s: goto %s;" % (
4977                             i+1,
4978                             old_label))
4979             code.putln(
4980                 "}")
4981         code.putln(
4982             "}")
4983
4984     def generate_function_definitions(self, env, code):
4985         self.body.generate_function_definitions(env, code)
4986         self.finally_clause.generate_function_definitions(env, code)
4987
4988     def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4989         code.globalstate.use_utility_code(restore_exception_utility_code)
4990         code.putln(
4991             "%s: {" %
4992                 error_label)
4993         code.putln(
4994                 "__pyx_why = %s;" %
4995                     i)
4996         for temp_name, type in temps_to_clean_up:
4997             code.put_xdecref_clear(temp_name, type)
4998         code.putln(
4999                 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5000                     Naming.exc_vars)
5001         code.putln(
5002                 "%s = %s;" % (
5003                     Naming.exc_lineno_name, Naming.lineno_cname))
5004         code.put_goto(catch_label)
5005         code.putln("}")
5006             
5007     def put_error_uncatcher(self, code, i, error_label):
5008         code.globalstate.use_utility_code(restore_exception_utility_code)
5009         code.putln(
5010             "case %s: {" %
5011                 i)
5012         code.putln(
5013                 "__Pyx_ErrRestore(%s, %s, %s);" %
5014                     Naming.exc_vars)
5015         code.putln(
5016                 "%s = %s;" % (
5017                     Naming.lineno_cname, Naming.exc_lineno_name))
5018         for var in Naming.exc_vars:
5019             code.putln(
5020                 "%s = 0;" %
5021                     var)
5022         code.put_goto(error_label)
5023         code.putln(
5024             "}")
5025
5026     def annotate(self, code):
5027         self.body.annotate(code)
5028         self.finally_clause.annotate(code)
5029
5030
5031 class GILStatNode(TryFinallyStatNode):
5032     #  'with gil' or 'with nogil' statement
5033     #
5034     #   state   string   'gil' or 'nogil'
5035
5036 #    child_attrs = []
5037     
5038     preserve_exception = 0
5039
5040     def __init__(self, pos, state, body):
5041         self.state = state
5042         TryFinallyStatNode.__init__(self, pos,
5043             body = body,
5044             finally_clause = GILExitNode(pos, state = state))
5045
5046     def analyse_expressions(self, env):
5047         env.use_utility_code(force_init_threads_utility_code)
5048         was_nogil = env.nogil
5049         env.nogil = 1
5050         TryFinallyStatNode.analyse_expressions(self, env)
5051         env.nogil = was_nogil
5052
5053     nogil_check = None
5054
5055     def generate_execution_code(self, code):
5056         code.mark_pos(self.pos)
5057         if self.state == 'gil':
5058             code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
5059         else:
5060             code.putln("{ PyThreadState *_save;")
5061             code.putln("Py_UNBLOCK_THREADS")
5062         TryFinallyStatNode.generate_execution_code(self, code)
5063         code.putln("}")
5064
5065
5066 class GILExitNode(StatNode):
5067     #  Used as the 'finally' block in a GILStatNode
5068     #
5069     #  state   string   'gil' or 'nogil'
5070
5071     child_attrs = []
5072
5073     def analyse_expressions(self, env):
5074         pass
5075
5076     def generate_execution_code(self, code):
5077         if self.state == 'gil':
5078             code.putln("PyGILState_Release();")
5079         else:
5080             code.putln("Py_BLOCK_THREADS")
5081
5082
5083 class CImportStatNode(StatNode):
5084     #  cimport statement
5085     #
5086     #  module_name   string           Qualified name of module being imported
5087     #  as_name       string or None   Name specified in "as" clause, if any
5088
5089     child_attrs = []
5090     
5091     def analyse_declarations(self, env):
5092         if not env.is_module_scope:
5093             error(self.pos, "cimport only allowed at module level")
5094             return
5095         module_scope = env.find_module(self.module_name, self.pos)
5096         if "." in self.module_name:
5097             names = [EncodedString(name) for name in self.module_name.split(".")]
5098             top_name = names[0]
5099             top_module_scope = env.context.find_submodule(top_name)
5100             module_scope = top_module_scope
5101             for name in names[1:]:
5102                 submodule_scope = module_scope.find_submodule(name)
5103                 module_scope.declare_module(name, submodule_scope, self.pos)
5104                 module_scope = submodule_scope
5105             if self.as_name:
5106                 env.declare_module(self.as_name, module_scope, self.pos)
5107             else:
5108                 env.declare_module(top_name, top_module_scope, self.pos)
5109         else:
5110             name = self.as_name or self.module_name
5111             env.declare_module(name, module_scope, self.pos)
5112
5113     def analyse_expressions(self, env):
5114         pass
5115     
5116     def generate_execution_code(self, code):
5117         pass
5118     
5119
5120 class FromCImportStatNode(StatNode):
5121     #  from ... cimport statement
5122     #
5123     #  module_name     string                        Qualified name of module
5124     #  imported_names  [(pos, name, as_name, kind)]  Names to be imported
5125     
5126     child_attrs = []
5127
5128     def analyse_declarations(self, env):
5129         if not env.is_module_scope:
5130             error(self.pos, "cimport only allowed at module level")
5131             return
5132         module_scope = env.find_module(self.module_name, self.pos)
5133         env.add_imported_module(module_scope)
5134         for pos, name, as_name, kind in self.imported_names:
5135             if name == "*":
5136                 for local_name, entry in module_scope.entries.items():
5137                     env.add_imported_entry(local_name, entry, pos)
5138             else:
5139                 entry = module_scope.lookup(name)
5140                 if entry:
5141                     if kind and not self.declaration_matches(entry, kind):
5142                         entry.redeclared(pos)
5143                 else:
5144                     if kind == 'struct' or kind == 'union':
5145                         entry = module_scope.declare_struct_or_union(name,
5146                             kind = kind, scope = None, typedef_flag = 0, pos = pos)
5147                     elif kind == 'class':
5148                         entry = module_scope.declare_c_class(name, pos = pos,
5149                             module_name = self.module_name)
5150                     else:
5151                         submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5152                         if submodule_scope.parent_module is module_scope:
5153                             env.declare_module(as_name or name, submodule_scope, self.pos)
5154                         else:
5155                             error(pos, "Name '%s' not declared in module '%s'"
5156                                 % (name, self.module_name))
5157                         
5158                 if entry:
5159                     local_name = as_name or name
5160                     env.add_imported_entry(local_name, entry, pos)
5161     
5162     def declaration_matches(self, entry, kind):
5163         if not entry.is_type:
5164             return 0
5165         type = entry.type
5166         if kind == 'class':
5167             if not type.is_extension_type:
5168                 return 0
5169         else:
5170             if not type.is_struct_or_union:
5171                 return 0
5172             if kind != type.kind:
5173                 return 0
5174         return 1
5175
5176     def analyse_expressions(self, env):
5177         pass
5178     
5179     def generate_execution_code(self, code):
5180         pass
5181
5182
5183 class FromImportStatNode(StatNode):
5184     #  from ... import statement
5185     #
5186     #  module           ImportNode
5187     #  items            [(string, NameNode)]
5188     #  interned_items   [(string, NameNode, ExprNode)]
5189     #  item             PyTempNode            used internally
5190     #  import_star      boolean               used internally
5191
5192     child_attrs = ["module"]
5193     import_star = 0
5194     
5195     def analyse_declarations(self, env):
5196         for name, target in self.items:
5197             if name == "*":
5198                 if not env.is_module_scope:
5199                     error(self.pos, "import * only allowed at module level")
5200                     return
5201                 env.has_import_star = 1
5202                 self.import_star = 1
5203             else:
5204                 target.analyse_target_declaration(env)
5205     
5206     def analyse_expressions(self, env):
5207         import ExprNodes
5208         self.module.analyse_expressions(env)
5209         self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5210         self.interned_items = []
5211         for name, target in self.items:
5212             if name == '*':
5213                 for _, entry in env.entries.items():
5214                     if not entry.is_type and entry.type.is_extension_type:
5215                         env.use_utility_code(ExprNodes.type_test_utility_code)
5216                         break
5217             else:
5218                 entry =  env.lookup(target.name)
5219                 if (entry.is_type and 
5220                     entry.type.name == name and
5221                     entry.type.module_name == self.module.module_name.value):
5222                     continue # already cimported
5223                 target.analyse_target_expression(env, None)
5224                 if target.type is py_object_type:
5225                     coerced_item = None
5226                 else:
5227                     coerced_item = self.item.coerce_to(target.type, env)
5228                 self.interned_items.append(
5229                     (name, target, coerced_item))
5230     
5231     def generate_execution_code(self, code):
5232         self.module.generate_evaluation_code(code)
5233         if self.import_star:
5234             code.putln(
5235                 'if (%s(%s) < 0) %s;' % (
5236                     Naming.import_star,
5237                     self.module.py_result(),
5238                     code.error_goto(self.pos)))
5239         item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5240         self.item.set_cname(item_temp)
5241         for name, target, coerced_item in self.interned_items:
5242             cname = code.intern_identifier(name)
5243             code.putln(
5244                 '%s = PyObject_GetAttr(%s, %s); %s' % (
5245                     item_temp,
5246                     self.module.py_result(),
5247                     cname,
5248                     code.error_goto_if_null(item_temp, self.pos)))
5249             code.put_gotref(item_temp)
5250             if coerced_item is None:
5251                 target.generate_assignment_code(self.item, code)
5252             else:
5253                 coerced_item.allocate_temp_result(code)
5254                 coerced_item.generate_result_code(code)
5255                 target.generate_assignment_code(coerced_item, code)
5256             code.put_decref_clear(item_temp, py_object_type)
5257         code.funcstate.release_temp(item_temp)
5258         self.module.generate_disposal_code(code)
5259         self.module.free_temps(code)
5260
5261
5262
5263 #------------------------------------------------------------------------------------
5264 #
5265 #  Runtime support code
5266 #
5267 #------------------------------------------------------------------------------------
5268
5269 utility_function_predeclarations = \
5270 """
5271 /* inline attribute */
5272 #ifndef CYTHON_INLINE
5273   #if defined(__GNUC__)
5274     #define CYTHON_INLINE __inline__
5275   #elif defined(_MSC_VER)
5276     #define CYTHON_INLINE __inline
5277   #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5278     #define CYTHON_INLINE inline
5279   #else
5280     #define CYTHON_INLINE 
5281   #endif
5282 #endif
5283
5284 /* unused attribute */
5285 #ifndef CYTHON_UNUSED
5286 # if defined(__GNUC__)
5287 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5288 #     define CYTHON_UNUSED __attribute__ ((__unused__)) 
5289 #   else
5290 #     define CYTHON_UNUSED
5291 #   endif
5292 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5293 #   define CYTHON_UNUSED __attribute__ ((__unused__)) 
5294 # else
5295 #   define CYTHON_UNUSED 
5296 # endif
5297 #endif
5298
5299 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*/
5300
5301 """
5302
5303 if Options.gcc_branch_hints:
5304     branch_prediction_macros = \
5305     """
5306 #ifdef __GNUC__
5307 /* Test for GCC > 2.95 */
5308 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) 
5309 #define likely(x)   __builtin_expect(!!(x), 1)
5310 #define unlikely(x) __builtin_expect(!!(x), 0)
5311 #else /* __GNUC__ > 2 ... */
5312 #define likely(x)   (x)
5313 #define unlikely(x) (x)
5314 #endif /* __GNUC__ > 2 ... */
5315 #else /* __GNUC__ */
5316 #define likely(x)   (x)
5317 #define unlikely(x) (x)
5318 #endif /* __GNUC__ */
5319     """
5320 else:
5321     branch_prediction_macros = \
5322     """
5323 #define likely(x)   (x)
5324 #define unlikely(x) (x)
5325     """
5326
5327 #get_name_predeclaration = \
5328 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5329
5330 #get_name_interned_predeclaration = \
5331 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5332
5333 #------------------------------------------------------------------------------------
5334
5335 printing_utility_code = UtilityCode(
5336 proto = """
5337 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5338 #if PY_MAJOR_VERSION >= 3
5339 static PyObject* %s = 0;
5340 static PyObject* %s = 0;
5341 #endif
5342 """ % (Naming.print_function, Naming.print_function_kwargs),
5343 cleanup = """
5344 #if PY_MAJOR_VERSION >= 3
5345 Py_CLEAR(%s);
5346 Py_CLEAR(%s);
5347 #endif
5348 """ % (Naming.print_function, Naming.print_function_kwargs),
5349 impl = r"""
5350 #if PY_MAJOR_VERSION < 3
5351 static PyObject *__Pyx_GetStdout(void) {
5352     PyObject *f = PySys_GetObject((char *)"stdout");
5353     if (!f) {
5354         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5355     }
5356     return f;
5357 }
5358
5359 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5360     PyObject* v;
5361     int i;
5362
5363     if (!f) {
5364         if (!(f = __Pyx_GetStdout()))
5365             return -1;
5366     }
5367     for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5368         if (PyFile_SoftSpace(f, 1)) {
5369             if (PyFile_WriteString(" ", f) < 0)
5370                 return -1;
5371         }
5372         v = PyTuple_GET_ITEM(arg_tuple, i);
5373         if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5374             return -1;
5375         if (PyString_Check(v)) {
5376             char *s = PyString_AsString(v);
5377             Py_ssize_t len = PyString_Size(v);
5378             if (len > 0 &&
5379                 isspace(Py_CHARMASK(s[len-1])) &&
5380                 s[len-1] != ' ')
5381                     PyFile_SoftSpace(f, 0);
5382         }
5383     }
5384     if (newline) {
5385         if (PyFile_WriteString("\n", f) < 0)
5386             return -1;
5387         PyFile_SoftSpace(f, 0);
5388     }
5389     return 0;
5390 }
5391
5392 #else /* Python 3 has a print function */
5393
5394 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5395     PyObject* kwargs = 0;
5396     PyObject* result = 0;
5397     PyObject* end_string;
5398     if (unlikely(!%(PRINT_FUNCTION)s)) {
5399         %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5400         if (!%(PRINT_FUNCTION)s)
5401             return -1;
5402     }
5403     if (stream) {
5404         kwargs = PyDict_New();
5405         if (unlikely(!kwargs))
5406             return -1;
5407         if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5408             goto bad;
5409         if (!newline) {
5410             end_string = PyUnicode_FromStringAndSize(" ", 1);
5411             if (unlikely(!end_string))
5412                 goto bad;
5413             if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5414                 Py_DECREF(end_string);
5415                 goto bad;
5416             }
5417             Py_DECREF(end_string);
5418         }
5419     } else if (!newline) {
5420         if (unlikely(!%(PRINT_KWARGS)s)) {
5421             %(PRINT_KWARGS)s = PyDict_New();
5422             if (unlikely(!%(PRINT_KWARGS)s))
5423                 return -1;
5424             end_string = PyUnicode_FromStringAndSize(" ", 1);
5425             if (unlikely(!end_string))
5426                 return -1;
5427             if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5428                 Py_DECREF(end_string);
5429                 return -1;
5430             }
5431             Py_DECREF(end_string);
5432         }
5433         kwargs = %(PRINT_KWARGS)s;
5434     }
5435     result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5436     if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5437         Py_DECREF(kwargs);
5438     if (!result)
5439         return -1;
5440     Py_DECREF(result);
5441     return 0;
5442 bad:
5443     if (kwargs != %(PRINT_KWARGS)s)
5444         Py_XDECREF(kwargs);
5445     return -1;
5446 }
5447
5448 #endif
5449 """ % {'BUILTINS'       : Naming.builtins_cname,
5450        'PRINT_FUNCTION' : Naming.print_function,
5451        'PRINT_KWARGS'   : Naming.print_function_kwargs}
5452 )
5453
5454
5455 printing_one_utility_code = UtilityCode(
5456 proto = """
5457 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5458 """,
5459 impl = r"""
5460 #if PY_MAJOR_VERSION < 3
5461
5462 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5463     if (!f) {
5464         if (!(f = __Pyx_GetStdout()))
5465             return -1;
5466     }
5467     if (PyFile_SoftSpace(f, 0)) {
5468         if (PyFile_WriteString(" ", f) < 0)
5469             return -1;
5470     }
5471     if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5472         return -1;
5473     if (PyFile_WriteString("\n", f) < 0)
5474         return -1;
5475     return 0;
5476     /* the line below is just to avoid compiler
5477      * compiler warnings about unused functions */
5478     return __Pyx_Print(f, NULL, 0);
5479 }
5480
5481 #else /* Python 3 has a print function */
5482
5483 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5484     int res;
5485     PyObject* arg_tuple = PyTuple_New(1);
5486     if (unlikely(!arg_tuple))
5487         return -1;
5488     Py_INCREF(o);
5489     PyTuple_SET_ITEM(arg_tuple, 0, o);
5490     res = __Pyx_Print(stream, arg_tuple, 1);
5491     Py_DECREF(arg_tuple);
5492     return res;
5493 }
5494
5495 #endif
5496 """,
5497 requires=[printing_utility_code])
5498
5499
5500
5501 #------------------------------------------------------------------------------------
5502
5503 # Exception raising code
5504 #
5505 # Exceptions are raised by __Pyx_Raise() and stored as plain
5506 # type/value/tb in PyThreadState->curexc_*.  When being caught by an
5507 # 'except' statement, curexc_* is moved over to exc_* by
5508 # __Pyx_GetException()
5509
5510 restore_exception_utility_code = UtilityCode(
5511 proto = """
5512 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5513 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5514 """,
5515 impl = """
5516 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5517     PyObject *tmp_type, *tmp_value, *tmp_tb;
5518     PyThreadState *tstate = PyThreadState_GET();
5519
5520     tmp_type = tstate->curexc_type;
5521     tmp_value = tstate->curexc_value;
5522     tmp_tb = tstate->curexc_traceback;
5523     tstate->curexc_type = type;
5524     tstate->curexc_value = value;
5525     tstate->curexc_traceback = tb;
5526     Py_XDECREF(tmp_type);
5527     Py_XDECREF(tmp_value);
5528     Py_XDECREF(tmp_tb);
5529 }
5530
5531 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5532     PyThreadState *tstate = PyThreadState_GET();
5533     *type = tstate->curexc_type;
5534     *value = tstate->curexc_value;
5535     *tb = tstate->curexc_traceback;
5536
5537     tstate->curexc_type = 0;
5538     tstate->curexc_value = 0;
5539     tstate->curexc_traceback = 0;
5540 }
5541
5542 """)
5543
5544 # The following function is based on do_raise() from ceval.c. There
5545 # are separate versions for Python2 and Python3 as exception handling
5546 # has changed quite a lot between the two versions.
5547
5548 raise_utility_code = UtilityCode(
5549 proto = """
5550 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5551 """,
5552 impl = """
5553 #if PY_MAJOR_VERSION < 3
5554 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5555     Py_XINCREF(type);
5556     Py_XINCREF(value);
5557     Py_XINCREF(tb);
5558     /* First, check the traceback argument, replacing None with NULL. */
5559     if (tb == Py_None) {
5560         Py_DECREF(tb);
5561         tb = 0;
5562     }
5563     else if (tb != NULL && !PyTraceBack_Check(tb)) {
5564         PyErr_SetString(PyExc_TypeError,
5565             "raise: arg 3 must be a traceback or None");
5566         goto raise_error;
5567     }
5568     /* Next, replace a missing value with None */
5569     if (value == NULL) {
5570         value = Py_None;
5571         Py_INCREF(value);
5572     }
5573     #if PY_VERSION_HEX < 0x02050000
5574     if (!PyClass_Check(type))
5575     #else
5576     if (!PyType_Check(type))
5577     #endif
5578     {
5579         /* Raising an instance.  The value should be a dummy. */
5580         if (value != Py_None) {
5581             PyErr_SetString(PyExc_TypeError,
5582                 "instance exception may not have a separate value");
5583             goto raise_error;
5584         }
5585         /* Normalize to raise <class>, <instance> */
5586         Py_DECREF(value);
5587         value = type;
5588         #if PY_VERSION_HEX < 0x02050000
5589             if (PyInstance_Check(type)) {
5590                 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5591                 Py_INCREF(type);
5592             }
5593             else {
5594                 type = 0;
5595                 PyErr_SetString(PyExc_TypeError,
5596                     "raise: exception must be an old-style class or instance");
5597                 goto raise_error;
5598             }
5599         #else
5600             type = (PyObject*) Py_TYPE(type);
5601             Py_INCREF(type);
5602             if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5603                 PyErr_SetString(PyExc_TypeError,
5604                     "raise: exception class must be a subclass of BaseException");
5605                 goto raise_error;
5606             }
5607         #endif
5608     }
5609
5610     __Pyx_ErrRestore(type, value, tb);
5611     return;
5612 raise_error:
5613     Py_XDECREF(value);
5614     Py_XDECREF(type);
5615     Py_XDECREF(tb);
5616     return;
5617 }
5618
5619 #else /* Python 3+ */
5620
5621 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5622     if (tb == Py_None) {
5623         tb = 0;
5624     } else if (tb && !PyTraceBack_Check(tb)) {
5625         PyErr_SetString(PyExc_TypeError,
5626             "raise: arg 3 must be a traceback or None");
5627         goto bad;
5628     }
5629     if (value == Py_None)
5630         value = 0;
5631
5632     if (PyExceptionInstance_Check(type)) {
5633         if (value) {
5634             PyErr_SetString(PyExc_TypeError,
5635                 "instance exception may not have a separate value");
5636             goto bad;
5637         }
5638         value = type;
5639         type = (PyObject*) Py_TYPE(value);
5640     } else if (!PyExceptionClass_Check(type)) {
5641         PyErr_SetString(PyExc_TypeError,
5642             "raise: exception class must be a subclass of BaseException");
5643         goto bad;
5644     }
5645
5646     PyErr_SetObject(type, value);
5647
5648     if (tb) {
5649         PyThreadState *tstate = PyThreadState_GET();
5650         PyObject* tmp_tb = tstate->curexc_traceback;
5651         if (tb != tmp_tb) {
5652             Py_INCREF(tb);
5653             tstate->curexc_traceback = tb;
5654             Py_XDECREF(tmp_tb);
5655         }
5656     }
5657
5658 bad:
5659     return;
5660 }
5661 #endif
5662 """,
5663 requires=[restore_exception_utility_code])
5664
5665 #------------------------------------------------------------------------------------
5666
5667 get_exception_utility_code = UtilityCode(
5668 proto = """
5669 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5670 """,
5671 impl = """
5672 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5673     PyObject *local_type, *local_value, *local_tb;
5674     PyObject *tmp_type, *tmp_value, *tmp_tb;
5675     PyThreadState *tstate = PyThreadState_GET();
5676     local_type = tstate->curexc_type;
5677     local_value = tstate->curexc_value;
5678     local_tb = tstate->curexc_traceback;
5679     tstate->curexc_type = 0;
5680     tstate->curexc_value = 0;
5681     tstate->curexc_traceback = 0;
5682     PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5683     if (unlikely(tstate->curexc_type))
5684         goto bad;
5685     #if PY_MAJOR_VERSION >= 3
5686     if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5687         goto bad;
5688     #endif
5689     *type = local_type;
5690     *value = local_value;
5691     *tb = local_tb;
5692     Py_INCREF(local_type);
5693     Py_INCREF(local_value);
5694     Py_INCREF(local_tb);
5695     tmp_type = tstate->exc_type;
5696     tmp_value = tstate->exc_value;
5697     tmp_tb = tstate->exc_traceback;
5698     tstate->exc_type = local_type;
5699     tstate->exc_value = local_value;
5700     tstate->exc_traceback = local_tb;
5701     /* Make sure tstate is in a consistent state when we XDECREF
5702        these objects (XDECREF may run arbitrary code). */
5703     Py_XDECREF(tmp_type);
5704     Py_XDECREF(tmp_value);
5705     Py_XDECREF(tmp_tb);
5706     return 0;
5707 bad:
5708     *type = 0;
5709     *value = 0;
5710     *tb = 0;
5711     Py_XDECREF(local_type);
5712     Py_XDECREF(local_value);
5713     Py_XDECREF(local_tb);
5714     return -1;
5715 }
5716
5717 """)
5718
5719 #------------------------------------------------------------------------------------
5720
5721 get_exception_tuple_utility_code = UtilityCode(proto="""
5722 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5723 """,
5724 # I doubt that calling __Pyx_GetException() here is correct as it moves
5725 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5726 # exception handlers later on from receiving it.
5727 impl = """
5728 static PyObject *__Pyx_GetExceptionTuple(void) {
5729     PyObject *type = NULL, *value = NULL, *tb = NULL;
5730     if (__Pyx_GetException(&type, &value, &tb) == 0) {
5731         PyObject* exc_info = PyTuple_New(3);
5732         if (exc_info) {
5733             Py_INCREF(type);
5734             Py_INCREF(value);
5735             Py_INCREF(tb);
5736             PyTuple_SET_ITEM(exc_info, 0, type);
5737             PyTuple_SET_ITEM(exc_info, 1, value);
5738             PyTuple_SET_ITEM(exc_info, 2, tb);
5739             return exc_info;
5740         }
5741     }
5742     return NULL;
5743 }
5744 """,
5745 requires=[get_exception_utility_code])
5746
5747 #------------------------------------------------------------------------------------
5748
5749 reset_exception_utility_code = UtilityCode(
5750 proto = """
5751 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5752 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5753 """,
5754 impl = """
5755 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5756     PyThreadState *tstate = PyThreadState_GET();
5757     *type = tstate->exc_type;
5758     *value = tstate->exc_value;
5759     *tb = tstate->exc_traceback;
5760     Py_XINCREF(*type);
5761     Py_XINCREF(*value);
5762     Py_XINCREF(*tb);
5763 }
5764
5765 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5766     PyObject *tmp_type, *tmp_value, *tmp_tb;
5767     PyThreadState *tstate = PyThreadState_GET();
5768     tmp_type = tstate->exc_type;
5769     tmp_value = tstate->exc_value;
5770     tmp_tb = tstate->exc_traceback;
5771     tstate->exc_type = type;
5772     tstate->exc_value = value;
5773     tstate->exc_traceback = tb;
5774     Py_XDECREF(tmp_type);
5775     Py_XDECREF(tmp_value);
5776     Py_XDECREF(tmp_tb);
5777 }
5778 """)
5779
5780 #------------------------------------------------------------------------------------
5781
5782 arg_type_test_utility_code = UtilityCode(
5783 proto = """
5784 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5785     const char *name, int exact); /*proto*/
5786 """,
5787 impl = """
5788 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5789     const char *name, int exact)
5790 {
5791     if (!type) {
5792         PyErr_Format(PyExc_SystemError, "Missing type object");
5793         return 0;
5794     }
5795     if (none_allowed && obj == Py_None) return 1;
5796     else if (exact) {
5797         if (Py_TYPE(obj) == type) return 1;
5798     }
5799     else {
5800         if (PyObject_TypeCheck(obj, type)) return 1;
5801     }
5802     PyErr_Format(PyExc_TypeError,
5803         "Argument '%s' has incorrect type (expected %s, got %s)",
5804         name, type->tp_name, Py_TYPE(obj)->tp_name);
5805     return 0;
5806 }
5807 """)
5808
5809 #------------------------------------------------------------------------------------
5810 #
5811 #  __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5812 #  many or too few positional arguments were found.  This handles
5813 #  Py_ssize_t formatting correctly.
5814
5815 raise_argtuple_invalid_utility_code = UtilityCode(
5816 proto = """
5817 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5818     Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5819 """,
5820 impl = """
5821 static void __Pyx_RaiseArgtupleInvalid(
5822     const char* func_name,
5823     int exact,
5824     Py_ssize_t num_min,
5825     Py_ssize_t num_max,
5826     Py_ssize_t num_found)
5827 {
5828     Py_ssize_t num_expected;
5829     const char *number, *more_or_less;
5830
5831     if (num_found < num_min) {
5832         num_expected = num_min;
5833         more_or_less = "at least";
5834     } else {
5835         num_expected = num_max;
5836         more_or_less = "at most";
5837     }
5838     if (exact) {
5839         more_or_less = "exactly";
5840     }
5841     number = (num_expected == 1) ? "" : "s";
5842     PyErr_Format(PyExc_TypeError,
5843         #if PY_VERSION_HEX < 0x02050000
5844             "%s() takes %s %d positional argument%s (%d given)",
5845         #else
5846             "%s() takes %s %zd positional argument%s (%zd given)",
5847         #endif
5848         func_name, more_or_less, num_expected, number, num_found);
5849 }
5850 """)
5851
5852 raise_keyword_required_utility_code = UtilityCode(
5853 proto = """
5854 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5855 """,
5856 impl = """
5857 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5858     const char* func_name,
5859     PyObject* kw_name)
5860 {
5861     PyErr_Format(PyExc_TypeError,
5862         #if PY_MAJOR_VERSION >= 3
5863         "%s() needs keyword-only argument %U", func_name, kw_name);
5864         #else
5865         "%s() needs keyword-only argument %s", func_name,
5866         PyString_AS_STRING(kw_name));
5867         #endif
5868 }
5869 """)
5870
5871 raise_double_keywords_utility_code = UtilityCode(
5872 proto = """
5873 static void __Pyx_RaiseDoubleKeywordsError(
5874     const char* func_name, PyObject* kw_name); /*proto*/
5875 """,
5876 impl = """
5877 static void __Pyx_RaiseDoubleKeywordsError(
5878     const char* func_name,
5879     PyObject* kw_name)
5880 {
5881     PyErr_Format(PyExc_TypeError,
5882         #if PY_MAJOR_VERSION >= 3
5883         "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5884         #else
5885         "%s() got multiple values for keyword argument '%s'", func_name,
5886         PyString_AS_STRING(kw_name));
5887         #endif
5888 }
5889 """)
5890
5891 #------------------------------------------------------------------------------------
5892 #
5893 #  __Pyx_CheckKeywordStrings raises an error if non-string keywords
5894 #  were passed to a function, or if any keywords were passed to a
5895 #  function that does not accept them.
5896
5897 keyword_string_check_utility_code = UtilityCode(
5898 proto = """
5899 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5900     const char* function_name, int kw_allowed); /*proto*/
5901 """,
5902 impl = """
5903 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5904     PyObject *kwdict,
5905     const char* function_name,
5906     int kw_allowed)
5907 {
5908     PyObject* key = 0;
5909     Py_ssize_t pos = 0;
5910     while (PyDict_Next(kwdict, &pos, &key, 0)) {
5911         #if PY_MAJOR_VERSION < 3
5912         if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5913         #else
5914         if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5915         #endif
5916             goto invalid_keyword_type;
5917     }
5918     if ((!kw_allowed) && unlikely(key))
5919         goto invalid_keyword;
5920     return 1;
5921 invalid_keyword_type:
5922     PyErr_Format(PyExc_TypeError,
5923         "%s() keywords must be strings", function_name);
5924     return 0;
5925 invalid_keyword:
5926     PyErr_Format(PyExc_TypeError,
5927     #if PY_MAJOR_VERSION < 3
5928         "%s() got an unexpected keyword argument '%s'",
5929         function_name, PyString_AsString(key));
5930     #else
5931         "%s() got an unexpected keyword argument '%U'",
5932         function_name, key);
5933     #endif
5934     return 0;
5935 }
5936 """)
5937
5938 #------------------------------------------------------------------------------------
5939 #
5940 #  __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5941 #  arguments from the kwds dict into kwds2.  If kwds2 is NULL, unknown
5942 #  keywords will raise an invalid keyword error.
5943 #
5944 #  Three kinds of errors are checked: 1) non-string keywords, 2)
5945 #  unexpected keywords and 3) overlap with positional arguments.
5946 #
5947 #  If num_posargs is greater 0, it denotes the number of positional
5948 #  arguments that were passed and that must therefore not appear
5949 #  amongst the keywords as well.
5950 #
5951 #  This method does not check for required keyword arguments.
5952 #
5953
5954 parse_keywords_utility_code = UtilityCode(
5955 proto = """
5956 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5957     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5958     const char* function_name); /*proto*/
5959 """,
5960 impl = """
5961 static int __Pyx_ParseOptionalKeywords(
5962     PyObject *kwds,
5963     PyObject **argnames[],
5964     PyObject *kwds2,
5965     PyObject *values[],
5966     Py_ssize_t num_pos_args,
5967     const char* function_name)
5968 {
5969     PyObject *key = 0, *value = 0;
5970     Py_ssize_t pos = 0;
5971     PyObject*** name;
5972     PyObject*** first_kw_arg = argnames + num_pos_args;
5973
5974     while (PyDict_Next(kwds, &pos, &key, &value)) {
5975         name = first_kw_arg;
5976         while (*name && (**name != key)) name++;
5977         if (*name) {
5978             values[name-argnames] = value;
5979         } else {
5980             #if PY_MAJOR_VERSION < 3
5981             if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5982             #else
5983             if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5984             #endif
5985                 goto invalid_keyword_type;
5986             } else {
5987                 for (name = first_kw_arg; *name; name++) {
5988                     #if PY_MAJOR_VERSION >= 3
5989                     if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5990                         PyUnicode_Compare(**name, key) == 0) break;
5991                     #else
5992                     if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5993                         _PyString_Eq(**name, key)) break;
5994                     #endif
5995                 }
5996                 if (*name) {
5997                     values[name-argnames] = value;
5998                 } else {
5999                     /* unexpected keyword found */
6000                     for (name=argnames; name != first_kw_arg; name++) {
6001                         if (**name == key) goto arg_passed_twice;
6002                         #if PY_MAJOR_VERSION >= 3
6003                         if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6004                             PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6005                         #else
6006                         if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6007                             _PyString_Eq(**name, key)) goto arg_passed_twice;
6008                         #endif
6009                     }
6010                     if (kwds2) {
6011                         if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6012                     } else {
6013                         goto invalid_keyword;
6014                     }
6015                 }
6016             }
6017         }
6018     }
6019     return 0;
6020 arg_passed_twice:
6021     __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6022     goto bad;
6023 invalid_keyword_type:
6024     PyErr_Format(PyExc_TypeError,
6025         "%s() keywords must be strings", function_name);
6026     goto bad;
6027 invalid_keyword:
6028     PyErr_Format(PyExc_TypeError,
6029     #if PY_MAJOR_VERSION < 3
6030         "%s() got an unexpected keyword argument '%s'",
6031         function_name, PyString_AsString(key));
6032     #else
6033         "%s() got an unexpected keyword argument '%U'",
6034         function_name, key);
6035     #endif
6036 bad:
6037     return -1;
6038 }
6039 """)
6040
6041 #------------------------------------------------------------------------------------
6042
6043 traceback_utility_code = UtilityCode(
6044 proto = """
6045 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6046 """,
6047 impl = """
6048 #include "compile.h"
6049 #include "frameobject.h"
6050 #include "traceback.h"
6051
6052 static void __Pyx_AddTraceback(const char *funcname) {
6053     PyObject *py_srcfile = 0;
6054     PyObject *py_funcname = 0;
6055     PyObject *py_globals = 0;
6056     PyCodeObject *py_code = 0;
6057     PyFrameObject *py_frame = 0;
6058
6059     #if PY_MAJOR_VERSION < 3
6060     py_srcfile = PyString_FromString(%(FILENAME)s);
6061     #else
6062     py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6063     #endif
6064     if (!py_srcfile) goto bad;
6065     if (%(CLINENO)s) {
6066         #if PY_MAJOR_VERSION < 3
6067         py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6068         #else
6069         py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6070         #endif
6071     }
6072     else {
6073         #if PY_MAJOR_VERSION < 3
6074         py_funcname = PyString_FromString(funcname);
6075         #else
6076         py_funcname = PyUnicode_FromString(funcname);
6077         #endif
6078     }
6079     if (!py_funcname) goto bad;
6080     py_globals = PyModule_GetDict(%(GLOBALS)s);
6081     if (!py_globals) goto bad;
6082     py_code = PyCode_New(
6083         0,            /*int argcount,*/
6084         #if PY_MAJOR_VERSION >= 3
6085         0,            /*int kwonlyargcount,*/
6086         #endif
6087         0,            /*int nlocals,*/
6088         0,            /*int stacksize,*/
6089         0,            /*int flags,*/
6090         %(EMPTY_BYTES)s, /*PyObject *code,*/
6091         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6092         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6093         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6094         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6095         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6096         py_srcfile,   /*PyObject *filename,*/
6097         py_funcname,  /*PyObject *name,*/
6098         %(LINENO)s,   /*int firstlineno,*/
6099         %(EMPTY_BYTES)s  /*PyObject *lnotab*/
6100     );
6101     if (!py_code) goto bad;
6102     py_frame = PyFrame_New(
6103         PyThreadState_GET(), /*PyThreadState *tstate,*/
6104         py_code,             /*PyCodeObject *code,*/
6105         py_globals,          /*PyObject *globals,*/
6106         0                    /*PyObject *locals*/
6107     );
6108     if (!py_frame) goto bad;
6109     py_frame->f_lineno = %(LINENO)s;
6110     PyTraceBack_Here(py_frame);
6111 bad:
6112     Py_XDECREF(py_srcfile);
6113     Py_XDECREF(py_funcname);
6114     Py_XDECREF(py_code);
6115     Py_XDECREF(py_frame);
6116 }
6117 """ % {
6118     'FILENAME': Naming.filename_cname,
6119     'LINENO':  Naming.lineno_cname,
6120     'CFILENAME': Naming.cfilenm_cname,
6121     'CLINENO':  Naming.clineno_cname,
6122     'GLOBALS': Naming.module_cname,
6123     'EMPTY_TUPLE' : Naming.empty_tuple,
6124     'EMPTY_BYTES' : Naming.empty_bytes,
6125 })
6126
6127 #------------------------------------------------------------------------------------
6128
6129 unraisable_exception_utility_code = UtilityCode(
6130 proto = """
6131 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6132 """,
6133 impl = """
6134 static void __Pyx_WriteUnraisable(const char *name) {
6135     PyObject *old_exc, *old_val, *old_tb;
6136     PyObject *ctx;
6137     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6138     #if PY_MAJOR_VERSION < 3
6139     ctx = PyString_FromString(name);
6140     #else
6141     ctx = PyUnicode_FromString(name);
6142     #endif
6143     __Pyx_ErrRestore(old_exc, old_val, old_tb);
6144     if (!ctx) {
6145         PyErr_WriteUnraisable(Py_None);
6146     } else {
6147         PyErr_WriteUnraisable(ctx);
6148         Py_DECREF(ctx);
6149     }
6150 }
6151 """,
6152 requires=[restore_exception_utility_code])
6153
6154 #------------------------------------------------------------------------------------
6155
6156 set_vtable_utility_code = UtilityCode(
6157 proto = """
6158 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6159 """,
6160 impl = """
6161 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6162 #if PY_VERSION_HEX < 0x03010000
6163     PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6164 #else
6165     PyObject *ob = PyCapsule_New(vtable, 0, 0);
6166 #endif
6167     if (!ob)
6168         goto bad;
6169     if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6170         goto bad;
6171     Py_DECREF(ob);
6172     return 0;
6173 bad:
6174     Py_XDECREF(ob);
6175     return -1;
6176 }
6177 """)
6178
6179 #------------------------------------------------------------------------------------
6180
6181 get_vtable_utility_code = UtilityCode(
6182 proto = """
6183 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6184 """,
6185 impl = r"""
6186 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6187     PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6188     if (!ob)
6189         goto bad;
6190 #if PY_VERSION_HEX < 0x03010000
6191     *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6192 #else
6193     *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6194 #endif
6195     if (!*(void **)vtabptr)
6196         goto bad;
6197     Py_DECREF(ob);
6198     return 0;
6199 bad:
6200     Py_XDECREF(ob);
6201     return -1;
6202 }
6203 """)
6204
6205 #------------------------------------------------------------------------------------
6206
6207 init_string_tab_utility_code = UtilityCode(
6208 proto = """
6209 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6210 """,
6211 impl = """
6212 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6213     while (t->p) {
6214         #if PY_MAJOR_VERSION < 3
6215         if (t->is_unicode) {
6216             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6217         } else if (t->intern) {
6218             *t->p = PyString_InternFromString(t->s);
6219         } else {
6220             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6221         }
6222         #else  /* Python 3+ has unicode identifiers */
6223         if (t->is_unicode | t->is_str) {
6224             if (t->intern) {
6225                 *t->p = PyUnicode_InternFromString(t->s);
6226             } else if (t->encoding) {
6227                 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6228             } else {
6229                 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6230             }
6231         } else {
6232             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6233         }
6234         #endif
6235         if (!*t->p)
6236             return -1;
6237         ++t;
6238     }
6239     return 0;
6240 }
6241 """)
6242
6243 #------------------------------------------------------------------------------------
6244
6245 force_init_threads_utility_code = UtilityCode(
6246 proto="""
6247 #ifndef __PYX_FORCE_INIT_THREADS
6248   #if PY_VERSION_HEX < 0x02040200
6249     #define __PYX_FORCE_INIT_THREADS 1
6250   #else
6251     #define __PYX_FORCE_INIT_THREADS 0
6252   #endif
6253 #endif
6254 """)
6255
6256 #------------------------------------------------------------------------------------
6257
6258 # Note that cPython ignores PyTrace_EXCEPTION, 
6259 # but maybe some other profilers don't. 
6260
6261 profile_utility_code = UtilityCode(proto="""
6262 #ifndef CYTHON_PROFILE
6263   #define CYTHON_PROFILE 1
6264 #endif
6265
6266 #ifndef CYTHON_PROFILE_REUSE_FRAME
6267   #define CYTHON_PROFILE_REUSE_FRAME 0
6268 #endif
6269
6270 #if CYTHON_PROFILE
6271
6272   #include "compile.h"
6273   #include "frameobject.h"
6274   #include "traceback.h"
6275
6276   #if CYTHON_PROFILE_REUSE_FRAME
6277     #define CYTHON_FRAME_MODIFIER static
6278     #define CYTHON_FRAME_DEL
6279   #else
6280     #define CYTHON_FRAME_MODIFIER
6281     #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6282   #endif
6283
6284   #define __Pyx_TraceDeclarations                                  \\
6285   static PyCodeObject *%(FRAME_CODE)s = NULL;                      \\
6286   CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL;           \\
6287   int __Pyx_use_tracing = 0;                                                         
6288
6289   #define __Pyx_TraceCall(funcname, srcfile, firstlineno)                            \\
6290   if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) {      \\
6291       __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno);  \\
6292   }
6293
6294   #define __Pyx_TraceException()                                                           \\
6295   if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6296       PyObject *exc_info = __Pyx_GetExceptionTuple();                                      \\
6297       if (exc_info) {                                                                      \\
6298           PyThreadState_GET()->c_profilefunc(                                              \\
6299               PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info);  \\
6300           Py_DECREF(exc_info);                                                             \\
6301       }                                                                                    \\
6302   }
6303
6304   #define __Pyx_TraceReturn(result)                                                  \\
6305   if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) {  \\
6306       PyThreadState_GET()->c_profilefunc(                                            \\
6307           PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result);     \\
6308       CYTHON_FRAME_DEL;                                                               \\
6309   }
6310
6311   static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6312   static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6313
6314 #else
6315
6316   #define __Pyx_TraceDeclarations
6317   #define __Pyx_TraceCall(funcname, srcfile, firstlineno) 
6318   #define __Pyx_TraceException() 
6319   #define __Pyx_TraceReturn(result) 
6320
6321 #endif /* CYTHON_PROFILE */
6322 """ 
6323 % {
6324     "FRAME": Naming.frame_cname,
6325     "FRAME_CODE": Naming.frame_code_cname,
6326 },
6327 impl = """
6328
6329 #if CYTHON_PROFILE
6330
6331 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6332                                    PyFrameObject** frame,
6333                                    const char *funcname,
6334                                    const char *srcfile,
6335                                    int firstlineno) {
6336     if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6337         if (*code == NULL) {
6338             *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6339             if (*code == NULL) return 0;
6340         }
6341         *frame = PyFrame_New(
6342             PyThreadState_GET(),            /*PyThreadState *tstate*/
6343             *code,                          /*PyCodeObject *code*/
6344             PyModule_GetDict(%(MODULE)s),      /*PyObject *globals*/
6345             0                               /*PyObject *locals*/
6346         );
6347         if (*frame == NULL) return 0;
6348     }
6349     else {
6350         (*frame)->f_tstate = PyThreadState_GET();
6351     }
6352     return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6353 }
6354
6355 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6356     PyObject *py_srcfile = 0;
6357     PyObject *py_funcname = 0;
6358     PyCodeObject *py_code = 0;
6359
6360     #if PY_MAJOR_VERSION < 3
6361     py_funcname = PyString_FromString(funcname);
6362     py_srcfile = PyString_FromString(srcfile);
6363     #else
6364     py_funcname = PyUnicode_FromString(funcname);
6365     py_srcfile = PyUnicode_FromString(srcfile);
6366     #endif
6367     if (!py_funcname | !py_srcfile) goto bad;
6368
6369     py_code = PyCode_New(
6370         0,                /*int argcount,*/
6371         #if PY_MAJOR_VERSION >= 3
6372         0,                /*int kwonlyargcount,*/
6373         #endif
6374         0,                /*int nlocals,*/
6375         0,                /*int stacksize,*/
6376         0,                /*int flags,*/
6377         %(EMPTY_BYTES)s,  /*PyObject *code,*/
6378         %(EMPTY_TUPLE)s,  /*PyObject *consts,*/
6379         %(EMPTY_TUPLE)s,  /*PyObject *names,*/
6380         %(EMPTY_TUPLE)s,  /*PyObject *varnames,*/
6381         %(EMPTY_TUPLE)s,  /*PyObject *freevars,*/
6382         %(EMPTY_TUPLE)s,  /*PyObject *cellvars,*/
6383         py_srcfile,       /*PyObject *filename,*/
6384         py_funcname,      /*PyObject *name,*/
6385         firstlineno,      /*int firstlineno,*/
6386         %(EMPTY_BYTES)s   /*PyObject *lnotab*/
6387     );
6388
6389 bad: 
6390     Py_XDECREF(py_srcfile);
6391     Py_XDECREF(py_funcname);
6392     
6393     return py_code;
6394 }
6395
6396 #endif /* CYTHON_PROFILE */
6397 """ % {
6398     'EMPTY_TUPLE' : Naming.empty_tuple,
6399     'EMPTY_BYTES' : Naming.empty_bytes,
6400     "MODULE": Naming.module_cname,
6401 })