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