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