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