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