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