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