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