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