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