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