15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Parse tree nodes 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import cython 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)cython.declare(sys=object, os=object, copy=object, 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object, 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) StructOrUnionScope=object, PyClassScope=object, 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CppClassScope=object, UtilityCode=object, EncodedString=object, 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) absolute_path_length=cython.Py_ssize_t) 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import sys, os, copy 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from itertools import chain 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import Builtin 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Errors import error, warning, InternalError, CompileError 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import Naming 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import PyrexTypes 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import TypeSlots 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from PyrexTypes import py_object_type, error_type 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Symtab import (ModuleScope, LocalScope, ClosureScope, 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) StructOrUnionScope, PyClassScope, CppClassScope, TemplateScope) 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Code import UtilityCode 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from StringEncoding import EncodedString, escape_byte_string, split_string_literal 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import Options 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import DebugFlags 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Utils import cached_function 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)absolute_path_length = 0 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def relative_position(pos): 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) We embed the relative filename in the generated C file, since we 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) don't want to have to regenerate and compile all the source code 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) whenever the Python install directory moves (which could happen, 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.g,. when distributing binaries.) 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) INPUT: 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) a position tuple -- (absolute filename, line number column position) 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OUTPUT: 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) relative filename 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) line number 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AUTHOR: William Stein 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) global absolute_path_length 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if absolute_path_length==0: 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) absolute_path_length = len(os.path.abspath(os.getcwd())) 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1]) 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def embed_position(pos, docstring): 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not Options.embed_pos_in_docstring: 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return docstring 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_line = u'File: %s (starting at line %s)' % relative_position(pos) 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if docstring is None: 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # unicode string 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return EncodedString(pos_line) 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # make sure we can encode the filename in the docstring encoding 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # otherwise make the docstring a unicode string 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) encoding = docstring.encoding 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if encoding is not None: 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try: 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_line.encode(encoding) 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except UnicodeEncodeError: 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) encoding = None 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not docstring: 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # reuse the string encoding of the original docstring 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc = EncodedString(pos_line) 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc = EncodedString(pos_line + u'\n' + docstring) 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc.encoding = encoding 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return doc 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def write_func_call(func, codewriter_class): 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def f(*args, **kwds): 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(args) > 1 and isinstance(args[1], codewriter_class): 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # here we annotate the code with this function call 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # but only if new code is generated 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node, code = args[:2] 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) marker = ' /* %s -> %s.%s %s */' % ( 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ' ' * code.call_level, 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.__class__.__name__, 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func.__name__, 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.pos[1:]) 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pristine = code.buffer.stream.tell() 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(marker) 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) start = code.buffer.stream.tell() 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.call_level += 4 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res = func(*args, **kwds) 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.call_level -= 4 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if start == code.buffer.stream.tell(): 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.buffer.stream.seek(pristine) 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) marker = marker.replace('->', '<-') 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(marker) 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return res 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return func(*args, **kwds) 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return f 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class VerboseCodeWriter(type): 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Set this as a metaclass to trace function calls in code. 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This slows down code generation and makes much larger files. 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __new__(cls, name, bases, attrs): 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from types import FunctionType 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from Code import CCodeWriter 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) attrs = dict(attrs) 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for mname, m in attrs.items(): 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(m, FunctionType): 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) attrs[mname] = write_func_call(m, CCodeWriter) 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs) 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CheckAnalysers(type): 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """Metaclass to check that type analysis functions return a node. 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) methods = set(['analyse_types', 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'analyse_expressions', 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'analyse_target_types']) 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __new__(cls, name, bases, attrs): 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from types import FunctionType 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def check(name, func): 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def call(*args, **kwargs): 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) retval = func(*args, **kwargs) 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if retval is None: 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) print name, args, kwargs 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return retval 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return call 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) attrs = dict(attrs) 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for mname, m in attrs.items(): 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(m, FunctionType) and mname in cls.methods: 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) attrs[mname] = check(mname, m) 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return super(CheckAnalysers, cls).__new__(cls, name, bases, attrs) 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class Node(object): 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # pos (string, int, int) Source file position 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_name boolean Is a NameNode 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_literal boolean Is a ConstNode 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #__metaclass__ = CheckAnalysers 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if DebugFlags.debug_trace_code_generation: 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) __metaclass__ = VerboseCodeWriter 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_name = 0 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_none = 0 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_nonecheck = 0 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_literal = 0 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_terminator = 0 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temps = None 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # All descendants should set child_attrs to a list of the attributes 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # containing nodes considered "children" in the tree. Each such attribute 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # can either contain a single node or a list of nodes. See Visitor.py. 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = None 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cf_state = None 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This may be an additional (or 'actual') type that will be checked when 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # this node is coerced to another type. This could be useful to set when 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # the actual type to which it can coerce is known, but you want to leave 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # the type a py_object_type 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coercion_type = None 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, pos, **kw): 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.pos = pos 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.__dict__.update(kw) 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Operation" 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = None 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def gil_error(self, env=None): 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "%s not allowed without gil" % self.gil_message) 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cpp_message = "Operation" 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def cpp_check(self, env): 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not env.is_cpp(): 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cpp_error() 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def cpp_error(self): 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "%s only allowed in c++" % self.cpp_message) 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def clone_node(self): 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """Clone the node. This is defined as a shallow copy, except for member lists 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) amongst the child attributes (from get_child_accessors) which are also 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) copied. Lists containing child nodes are thus seen as a way for the node 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) to hold multiple children directly; the list is not treated as a separate 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) level in the tree.""" 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = copy.copy(self) 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for attrname in result.child_attrs: 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) value = getattr(result, attrname) 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(value, list): 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) setattr(result, attrname, [x for x in value]) 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return result 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # There are 3 phases of parse tree processing, applied in order to 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # all the statements in a given scope-block: 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (0) analyse_declarations 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Make symbol table entries for all declarations at the current 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # level, both explicit (def, cdef, etc.) and implicit (assignment 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # to an otherwise undeclared name). 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (1) analyse_expressions 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Determine the result types of expressions and fill in the 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 'type' attribute of each ExprNode. Insert coercion nodes into the 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # tree where needed to convert to and from Python objects. 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Allocate temporary locals for intermediate results. Fill 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in the 'result_code' attribute of each ExprNode with a C code 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # fragment. 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (2) generate_code 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Emit C code for all declarations, statements and expressions. 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Recursively applies the 3 processing phases to the bodies of 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # functions. 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) raise InternalError("analyse_expressions not implemented for %s" % \ 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.__class__.__name__) 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_code(self, code): 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) raise InternalError("generate_code not implemented for %s" % \ 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.__class__.__name__) 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # mro does the wrong thing 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self, BlockNode): 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def end_pos(self): 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try: 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self._end_pos 2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except AttributeError: 2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos = self.pos 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.child_attrs: 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._end_pos = pos 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pos 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for attr in self.child_attrs: 2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child = getattr(self, attr) 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Sometimes lists, sometimes nodes 2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if child is None: 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif isinstance(child, list): 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for c in child: 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos = max(pos, c.end_pos()) 2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos = max(pos, child.end_pos()) 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._end_pos = pos 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pos 2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None): 2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """Debug helper method that returns a recursive string representation of this node. 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if cutoff == 0: 2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "<...nesting level cutoff...>" 2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if encountered is None: 2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) encountered = set() 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if id(self) in encountered: 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self)) 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) encountered.add(id(self)) 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def dump_child(x, level): 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(x, Node): 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return x.dump(level, filter_out, cutoff-1, encountered) 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif isinstance(x, list): 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "[%s]" % ", ".join([dump_child(item, level) for item in x]) 2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return repr(x) 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out] 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(attrs) == 0: 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "<%s (0x%x)>" % (self.__class__.__name__, id(self)) 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) indent = " " * level 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self)) 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for key, value in attrs: 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1)) 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res += "%s>" % indent 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return res 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def dump_pos(self, mark_column=False, marker='(#)'): 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """Debug helper method that returns the source code context of this node as a string. 2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.pos: 3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return u'' 3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) source_desc, line, col = self.pos 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) contents = source_desc.get_lines(encoding='ASCII', 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error_handling='ignore') 3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # line numbers start at 1 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lines = contents[max(0,line-3):line] 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current = lines[-1] 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if mark_column: 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current = current[:col] + marker + current[col:] 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lines[-1] = current.rstrip() + u' # <<<<<<<<<<<<<<\n' 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lines += contents[line:line+2] 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return u'"%s":%d:%d\n%s\n' % ( 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) source_desc.get_escaped_description(), line, col, u''.join(lines)) 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CompilerDirectivesNode(Node): 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Sets compiler directives for the children nodes 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # directives {string:value} A dictionary holding the right value for 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # *all* possible directives. 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body Node 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["body"] 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old = env.directives 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.directives = self.directives 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.directives = old 3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old = env.directives 3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.directives = self.directives 3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.directives = old 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env_old = env.directives 3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code_old = code.globalstate.directives 3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.directives = self.directives 3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.directives = env_old 3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.directives = code_old 3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old = code.globalstate.directives 3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.directives = self.directives 3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.directives = old 3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old = code.globalstate.directives 3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.directives = self.directives 3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.directives = old 3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class BlockNode(object): 3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Mixin class for nodes representing a declaration block. 3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_cached_builtins_decls(self, env, code): 3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entries = env.global_scope().undeclared_cached_builtins 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in entries: 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.add_cached_builtin_decl(entry) 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) del entries[:] 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_lambda_definitions(self, env, code): 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for node in env.lambda_defs: 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.generate_function_definitions(env, code) 3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class StatListNode(Node): 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # stats a list of StatNode 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["stats"] 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def create_analysed(pos, env, *args, **kw): 3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = StatListNode(pos, *args, **kw) 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return node # No node-specific analysis necesarry 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) create_analysed = staticmethod(create_analysed) 3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "StatListNode.analyse_declarations" ### 3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.analyse_declarations(env) 3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "StatListNode.analyse_expressions" ### 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stats = [ stat.analyse_expressions(env) 3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats ] 3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "StatListNode.generate_function_definitions" ### 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.generate_function_definitions(env, code) 3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "StatListNode.generate_execution_code" ### 3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(stat.pos) 4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.generate_execution_code(code) 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.annotate(code) 4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class StatNode(Node): 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Code generation for statements is split into the following subphases: 4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (1) generate_function_definitions 4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Emit C code for the definitions of any structs, 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # unions, enums and functions defined in the current 4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # scope-block. 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (2) generate_execution_code 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Emit C code for executable statements. 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) raise InternalError("generate_execution_code not implemented for %s" % \ 4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.__class__.__name__) 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CDefExternNode(StatNode): 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # include_file string or None 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["body"] 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.include_file: 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_include_file(self.include_file) 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_cinclude_flag = env.in_cinclude 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.in_cinclude = 1 4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.in_cinclude = old_cinclude_flag 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CDeclaratorNode(Node): 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Part of a C declaration. 4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Processing during analyse_declarations phase: 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # analyse 4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Returns (name, type) pair where name is the 4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # CNameDeclaratorNode of the name being declared 4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # and type is the type it is being declared as. 4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # calling_convention string Calling convention of CFuncDeclaratorNode 4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # for which this is a base 4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) calling_convention = "" 4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_templates(self): 4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Only C++ functions have templates. 4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CNameDeclaratorNode(CDeclaratorNode): 4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string The Cython name being declared 4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cname string or None C name, if specified 4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # default ExprNode or None the value assigned on declaration 4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['default'] 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default = None 4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, base_type, env, nonempty = 0): 4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if nonempty and self.name == '': 4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # May have mistaken the name for the type. 4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_ptr or base_type.is_array or base_type.is_buffer: 4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Missing argument name") 4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif base_type.is_void: 4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.") 4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name = base_type.declaration_code("", for_display=1, pyrex=1) 4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = py_object_type 4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_fused and env.fused_to_specific: 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = base_type.specialize(env.fused_to_specific) 4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = base_type 4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self, base_type 4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CPtrDeclaratorNode(CDeclaratorNode): 5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base CDeclaratorNode 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base"] 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, base_type, env, nonempty = 0): 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_pyobject: 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Pointer base type cannot be a Python object") 5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ptr_type = PyrexTypes.c_ptr_type(base_type) 5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.base.analyse(ptr_type, env, nonempty = nonempty) 5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CReferenceDeclaratorNode(CDeclaratorNode): 5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base CDeclaratorNode 5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base"] 5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, base_type, env, nonempty = 0): 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_pyobject: 5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Reference base type cannot be a Python object") 5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ref_type = PyrexTypes.c_ref_type(base_type) 5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.base.analyse(ref_type, env, nonempty = nonempty) 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CArrayDeclaratorNode(CDeclaratorNode): 5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base CDeclaratorNode 5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # dimension ExprNode 5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base", "dimension"] 5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, base_type, env, nonempty = 0): 5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_cpp_class or base_type.is_cfunction: 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from ExprNodes import TupleNode 5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.dimension, TupleNode): 5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = self.dimension.args 5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = self.dimension, 5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) values = [v.analyse_as_type(env) for v in args] 5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if None in values: 5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ix = values.index(None) 5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(args[ix].pos, "Template parameter not a type") 5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = error_type 5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = base_type.specialize_here(self.pos, values) 5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.base.analyse(base_type, env, nonempty = nonempty) 5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.dimension: 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dimension = self.dimension.analyse_const_expression(env) 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.dimension.type.is_int: 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.dimension.pos, "Array dimension not integer") 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size = self.dimension.get_constant_c_result_code() 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if size is not None: 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try: 5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size = int(size) 5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except ValueError: 5535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # runtime constant? 5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 5565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size = None 5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not base_type.is_complete(): 5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Array element type '%s' is incomplete" % base_type) 5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_pyobject: 5615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Array element cannot be a Python object") 5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_cfunction: 5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Array element cannot be a function") 5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) array_type = PyrexTypes.c_array_type(base_type, size) 5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.base.analyse(array_type, env, nonempty = nonempty) 5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CFuncDeclaratorNode(CDeclaratorNode): 5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base CDeclaratorNode 5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # args [CArgDeclNode] 5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # templates [TemplatePlaceholderType] 5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # has_varargs boolean 5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exception_value ConstNode 5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exception_check boolean True if PyErr_Occurred check needed 5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # nogil boolean Can be called without gil 5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # with_gil boolean Acquire gil around function body 5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_const_method boolean Whether this is a const method 5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base", "args", "exception_value"] 5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) overridable = 0 5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) optional_arg_count = 0 5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_const_method = 0 5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) templates = None 5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_templates(self): 5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.base, CArrayDeclaratorNode): 5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from ExprNodes import TupleNode, NameNode 5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_node = self.base.dimension 5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(template_node, TupleNode): 5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_nodes = template_node.args 5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif isinstance(template_node, NameNode): 5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_nodes = [template_node] 5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(template_node.pos, "Template arguments must be a list of names") 5985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.templates = [] 6005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for template in template_nodes: 6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(template, NameNode): 6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.templates.append(PyrexTypes.TemplatePlaceholderType(template.name)) 6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(template.pos, "Template arguments must be a list of names") 6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base = self.base.base 6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.templates 6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, return_type, env, nonempty = 0, directive_locals = {}): 6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if nonempty: 6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nonempty -= 1 6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_type_args = [] 6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg_node in enumerate(self.args): 6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = arg_node.analyse(env, nonempty = nonempty, 6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_self_arg = (i == 0 and env.is_c_class_scope)) 6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = name_declarator.name 6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name in directive_locals: 6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_node = directive_locals[name] 6205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) other_type = type_node.analyse_as_type(env) 6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if other_type is None: 6225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Not a type") 6235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif (type is not PyrexTypes.py_object_type 6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not type.same_as(other_type)): 6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.base.pos, "Signature does not agree with previous declaration") 6265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Previous declaration here") 6275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 6285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = other_type 6295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name_declarator.cname: 6305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 6315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Function argument cannot have C name specification") 6325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if i==0 and env.is_c_class_scope and type.is_unspecified: 6335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # fix the type of self 6345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = env.parent_type 6355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Turn *[] argument into ** 6365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.is_array: 6375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = PyrexTypes.c_ptr_type(type.base_type) 6385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Catch attempted C-style func(void) decl 6395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.is_void: 6405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.") 6415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_type_args.append( 6425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyrexTypes.CFuncTypeArg(name, type, arg_node.pos)) 6435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg_node.default: 6445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.optional_arg_count += 1 6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.optional_arg_count: 6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Non-default argument follows default argument") 6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_val = None 6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_check = 0 6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exception_check == '+': 6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_include_file('ios') # for std::ios_base::failure 6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_include_file('new') # for std::bad_alloc 6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_include_file('stdexcept') 6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_include_file('typeinfo') # for std::bad_cast 6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (return_type.is_pyobject 6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and (self.exception_value or self.exception_check) 6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and self.exception_check != '+'): 6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Exception clause not allowed for function returning Python object") 6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exception_value: 6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exception_value = self.exception_value.analyse_const_expression(env) 6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exception_check == '+': 6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_val_type = self.exception_value.type 6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (not exc_val_type.is_error 6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not exc_val_type.is_pyobject 6675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not (exc_val_type.is_cfunction 6685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not exc_val_type.return_type.is_pyobject 6695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not exc_val_type.args)): 6705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.exception_value.pos, 6715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Exception value must be a Python exception or cdef function with no arguments.") 6725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_val = self.exception_value 6735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 6745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exception_value = self.exception_value.coerce_to( 6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return_type, env).analyse_const_expression(env) 6765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_val = self.exception_value.get_constant_c_result_code() 6775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if exc_val is None: 6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) raise InternalError( 6795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "get_constant_c_result_code not implemented for %s" % 6805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exception_value.__class__.__name__) 6815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not return_type.assignable_from(self.exception_value.type): 6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.exception_value.pos, 6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Exception value incompatible with function return type") 6845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_check = self.exception_check 6855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if return_type.is_cfunction: 6865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 6875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Function cannot return a function") 6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_type = PyrexTypes.CFuncType( 6895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return_type, func_type_args, self.has_varargs, 6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) optional_arg_count = self.optional_arg_count, 6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exception_value = exc_val, exception_check = exc_check, 6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) calling_convention = self.base.calling_convention, 6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable, 6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_const_method = self.is_const_method, 6955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) templates = self.templates) 6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.optional_arg_count: 6985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func_type.is_fused: 6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This is a bit of a hack... When we need to create specialized CFuncTypes 7005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # on the fly because the cdef is defined in a pxd, we need to declare the specialized optional arg 7015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # struct 7025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_opt_arg_struct(func_type, fused_cname): 7035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_optional_arg_struct(func_type, env, fused_cname) 7045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_type.declare_opt_arg_struct = declare_opt_arg_struct 7065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_optional_arg_struct(func_type, env) 7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callspec = env.directives['callspec'] 7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if callspec: 7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current = func_type.calling_convention 7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if current and current != callspec: 7135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "cannot have both '%s' and '%s' " 7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "calling conventions" % (current, callspec)) 7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_type.calling_convention = callspec 7165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.base.analyse(func_type, env) 7175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_optional_arg_struct(self, func_type, env, fused_cname=None): 7195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 7205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Declares the optional argument struct (the struct used to hold the 7215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) values for optional arguments). For fused cdef functions, this is 7225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) deferred as analyse_declarations is called only once (on the fused 7235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cdef function). 7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 7255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = StructOrUnionScope() 7265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_count_member = '%sn' % Naming.pyrex_prefix 7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos) 7285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in func_type.args[len(func_type.args)-self.optional_arg_count:]: 7305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1) 7315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name) 7335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if fused_cname is not None: 7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct_cname = PyrexTypes.get_fused_cname(fused_cname, struct_cname) 7365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op_args_struct = env.global_scope().declare_struct_or_union( 7385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = struct_cname, 7395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kind = 'struct', 7405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = scope, 7415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef_flag = 0, 7425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos = self.pos, 7435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = struct_cname) 7445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op_args_struct.defined_in_pxd = 1 7465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) op_args_struct.used = 1 7475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_type.op_arg_struct = PyrexTypes.c_ptr_type(op_args_struct.type) 7495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CConstDeclaratorNode(CDeclaratorNode): 7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base CDeclaratorNode 7535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base"] 7555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, base_type, env, nonempty = 0): 7575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_pyobject: 7585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 7595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Const base type cannot be a Python object") 7605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const = PyrexTypes.c_const_type(base_type) 7615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.base.analyse(const, env, nonempty = nonempty) 7625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CArgDeclNode(Node): 7655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Item in a function declaration argument list. 7665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 7675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type CBaseTypeNode 7685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # declarator CDeclaratorNode 7695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # not_none boolean Tagged with 'not None' 7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # or_none boolean Tagged with 'or None' 7715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # accept_none boolean Resolved boolean for not_none/or_none 7725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # default ExprNode or None 7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # default_value PyObjectConst constant for default value 7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # annotation ExprNode or None Py3 function arg annotation 7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_self_arg boolean Is the "self" arg of an extension type method 7765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_type_arg boolean Is the "class" arg of an extension type classmethod 7775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_kw_only boolean Is a keyword-only argument 7785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_dynamic boolean Non-literal arg stored inside CyFunction 7795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base_type", "declarator", "default", "annotation"] 7815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_self_arg = 0 7835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_type_arg = 0 7845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_generic = 1 7855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kw_only = 0 7865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not_none = 0 7875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) or_none = 0 7885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = None 7895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator = None 7905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_value = None 7915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) annotation = None 7925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_dynamic = 0 7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env, nonempty = 0, is_self_arg = False): 7955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if is_self_arg: 7965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_type.is_self_arg = self.is_self_arg = True 7975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.type is None: 7985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The parser may misinterpret names as types. We fix that here. 7995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '': 8005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if nonempty: 8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.base_type.is_basic_c_type: 8025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # char, short, long called "int" 8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = self.base_type.analyse(env, could_be_name = True) 8045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_name = type.declaration_code("") 8055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 8065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_name = self.base_type.name 8075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declarator.name = EncodedString(arg_name) 8085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_type.name = None 8095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_type.is_basic_c_type = False 8105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) could_be_name = True 8115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 8125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) could_be_name = False 8135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_type.is_arg = True 8145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = self.base_type.analyse(env, could_be_name = could_be_name) 8155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name: 8165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declarator.name = self.base_type.arg_name 8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The parser is unable to resolve the ambiguity of [] as part of the 8185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # type (e.g. in buffers) or empty declarator (as with arrays). 8195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This is only arises for empty multi-dimensional arrays. 8205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (base_type.is_array 8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and isinstance(self.base_type, TemplatedTypeNode) 8225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and isinstance(self.declarator, CArrayDeclaratorNode)): 8235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator = self.declarator 8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while isinstance(declarator.base, CArrayDeclaratorNode): 8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator = declarator.base 8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator.base = self.base_type.array_declarator 8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = base_type.base_type 8285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.declarator.analyse(base_type, env, nonempty = nonempty) 8295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 8305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.name_declarator, self.type 8315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def calculate_default_value_code(self, code): 8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.default_value is None: 8345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.default: 8355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.default.is_literal: 8365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # will not output any code, just assign the result_code 8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.default.generate_evaluation_code(code) 8385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.type.cast_code(self.default.result()) 8395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.default_value = code.get_argument_default_const(self.type) 8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.default_value 8415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.default: 8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.default.annotate(code) 8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_assignment_code(self, code, target=None): 8475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default = self.default 8485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if default is None or default.is_literal: 8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if target is None: 8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target = self.calculate_default_value_code(code) 8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default.generate_evaluation_code(code) 8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default.make_owned_reference(code) 8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = default.result_as(self.type) 8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (target, result)) 8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.type.is_pyobject: 8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref(default.result()) 8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default.generate_post_assignment_code(code) 8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default.free_temps(code) 8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CBaseTypeNode(Node): 8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Abstract base class for C base type nodes. 8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Processing during analyse_declarations phase: 8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # analyse 8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Returns the type. 8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_as_type(self, env): 8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.analyse(env) 8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CAnalysedBaseTypeNode(Node): 8765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # type type 8775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 8795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env, could_be_name = False): 8815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.type 8825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CSimpleBaseTypeNode(CBaseTypeNode): 8845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string 8855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # module_path [string] Qualifying name components 8865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_basic_c_type boolean 8875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # signed boolean 8885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # longness integer 8895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # complex boolean 8905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_self_arg boolean Is self argument of C method 8915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ##is_type_arg boolean Is type argument of class method 8925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 8945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_name = None # in case the argument name was interpreted as a type 8955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_path = [] 8965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_basic_c_type = False 8975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) complex = False 8985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env, could_be_name = False): 9005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Return type descriptor. 9015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ### 9025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = None 9035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_basic_c_type: 9045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name) 9055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not type: 9065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Unrecognised type modifier combination") 9075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.name == "object" and not self.module_path: 9085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = py_object_type 9095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.name is None: 9105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_self_arg and env.is_c_class_scope: 9115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ### 9125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = env.parent_type 9135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ## elif self.is_type_arg and env.is_c_class_scope: 9145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ## type = Builtin.type_type 9155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = py_object_type 9175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.module_path: 9195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Maybe it's a nested C++ class. 9205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = env 9215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for item in self.module_path: 9225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = scope.lookup(item) 9235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry is not None and entry.is_cpp_class: 9245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = entry.type.scope 9255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = None 9275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break 9285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if scope is None: 9305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Maybe it's a cimport. 9315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = env.find_imported_module(self.module_path, self.pos) 9325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if scope: 9335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.fused_to_specific = env.fused_to_specific 9345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = env 9365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if scope: 9385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if scope.is_c_class_scope: 9395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = scope.global_scope() 9405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = scope.lookup_type(self.name) 9425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type is not None: 9435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 9445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif could_be_name: 9455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_self_arg and env.is_c_class_scope: 9465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = env.parent_type 9475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ## elif self.is_type_arg and env.is_c_class_scope: 9485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ## type = Builtin.type_type 9495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = py_object_type 9515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.arg_name = EncodedString(self.name) 9525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.templates: 9545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.name in self.templates: 9555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "'%s' is not a type identifier" % self.name) 9565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = PyrexTypes.TemplatePlaceholderType(self.name) 9575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "'%s' is not a type identifier" % self.name) 9595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.complex: 9605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not type.is_numeric or type.is_complex: 9615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "can only complexify c numeric types") 9625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = PyrexTypes.CComplexType(type) 9635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type.create_declaration_utility_code(env) 9645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif type is Builtin.complex_type: 9655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Special case: optimise builtin complex type into C's 9665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # double complex. The parser cannot do this (as for the 9675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # normal scalar types) as the user may have redeclared the 9685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 'complex' type. Testing for the exact type here works. 9695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = PyrexTypes.c_double_complex_type 9705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type.create_declaration_utility_code(env) 9715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.complex = True 9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type: 9735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return type 9745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return PyrexTypes.error_type 9765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class MemoryViewSliceTypeNode(CBaseTypeNode): 9785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = 'memoryview' 9805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['base_type_node', 'axes'] 9815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env, could_be_name = False): 9835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = self.base_type_node.analyse(env) 9855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_error: return base_type 9865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import MemoryView 9885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try: 9905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) axes_specs = MemoryView.get_axes_specs(env, self.axes) 9915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except CompileError, e: 9925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(e.position, e.message_only) 9935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = PyrexTypes.ErrorType() 9945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.type 9955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not MemoryView.validate_axes(self.pos, axes_specs): 9975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = error_type 9985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 9995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MemoryView.validate_memslice_dtype(self.pos, base_type) 10005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = PyrexTypes.MemoryViewSliceType(base_type, axes_specs) 10015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.use_memview_utilities(env) 10025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.type 10045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def use_memview_utilities(self, env): 10065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import MemoryView 10075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(MemoryView.view_utility_code) 10085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CNestedBaseTypeNode(CBaseTypeNode): 10115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # For C++ classes that live inside other C++ classes. 10125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string 10145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type CBaseTypeNode 10155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['base_type'] 10175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env, could_be_name = None): 10195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = self.base_type.analyse(env) 10205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type is PyrexTypes.error_type: 10215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return PyrexTypes.error_type 10225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not base_type.is_cpp_class: 10235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "'%s' is not a valid type scope" % base_type) 10245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return PyrexTypes.error_type 10255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_entry = base_type.scope.lookup_here(self.name) 10265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not type_entry or not type_entry.is_type: 10275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name)) 10285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return PyrexTypes.error_type 10295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return type_entry.type 10305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TemplatedTypeNode(CBaseTypeNode): 10335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # After parsing: 10345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # positional_args [ExprNode] List of positional arguments 10355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # keyword_args DictNode Keyword arguments 10365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type_node CBaseTypeNode 10375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # After analysis: 10395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options 10405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base_type_node", "positional_args", 10425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "keyword_args", "dtype_node"] 10435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dtype_node = None 10455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = None 10475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env, could_be_name = False, base_type = None): 10495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type is None: 10505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = self.base_type_node.analyse(env) 10515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_error: return base_type 10525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_cpp_class: 10545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Templated class 10555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.keyword_args and self.keyword_args.key_value_pairs: 10565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "c++ templates cannot take keyword arguments") 10575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = PyrexTypes.error_type 10585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 10595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_types = [] 10605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for template_node in self.positional_args: 10615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = template_node.analyse_as_type(env) 10625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type is None: 10635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(template_node.pos, "unknown type in template argument") 10645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return error_type 10655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_types.append(type) 10665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = base_type.specialize_here(self.pos, template_types) 10675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif base_type.is_pyobject: 10695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Buffer 10705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import Buffer 10715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) options = Buffer.analyse_buffer_options( 10735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.pos, 10745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env, 10755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.positional_args, 10765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.keyword_args, 10775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type.buffer_defaults) 10785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if sys.version_info[0] < 3: 10805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Py 2.x enforces byte strings as keyword arguments ... 10815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) options = dict([ (name.encode('ASCII'), value) 10825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name, value in options.items() ]) 10835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = PyrexTypes.BufferType(base_type, **options) 10855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 10875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Array 10885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None) 10895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs: 10905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "invalid array declaration") 10915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = PyrexTypes.error_type 10925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 10935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # It would be nice to merge this class with CArrayDeclaratorNode, 10945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # but arrays are part of the declaration, not the type... 10955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.positional_args: 10965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dimension = None 10975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 10985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dimension = self.positional_args[0] 10995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.array_declarator = CArrayDeclaratorNode(self.pos, 11005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base = empty_declarator, 11015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dimension = dimension) 11025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = self.array_declarator.analyse(base_type, env)[1] 11035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.type.is_fused and env.fused_to_specific: 11055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = self.type.specialize(env.fused_to_specific) 11065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.type 11085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CComplexBaseTypeNode(CBaseTypeNode): 11105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type CBaseTypeNode 11115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # declarator CDeclaratorNode 11125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base_type", "declarator"] 11145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env, could_be_name = False): 11165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base = self.base_type.analyse(env, could_be_name) 11175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _, type = self.declarator.analyse(base, env) 11185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return type 11195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FusedTypeNode(CBaseTypeNode): 11225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 11235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Represents a fused type in a ctypedef statement: 11245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctypedef cython.fused_type(int, long, long long) integral 11265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name str name of this fused type 11285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) types [CSimpleBaseTypeNode] is the list of types to be fused 11295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 11305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 11325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 11345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = self.analyse(env) 11355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.declare_typedef(self.name, type, self.pos) 11365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Omit the typedef declaration that self.declarator would produce 11385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.in_cinclude = True 11395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env): 11415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) types = [] 11425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for type_node in self.types: 11435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = type_node.analyse_as_type(env) 11445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not type: 11465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Not a type") 11475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 11485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type in types: 11505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Type specified multiple times") 11515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif type.is_fused: 11525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Cannot fuse a fused type") 11535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 11545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) types.append(type) 11555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # if len(self.types) == 1: 11575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # return types[0] 11585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return PyrexTypes.FusedType(types, name=self.name) 11605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CConstTypeNode(CBaseTypeNode): 11635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type CBaseTypeNode 11645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base_type"] 11665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse(self, env, could_be_name = False): 11685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base = self.base_type.analyse(env, could_be_name) 11695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base.is_pyobject: 11705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 11715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Const base type cannot be a Python object") 11725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return PyrexTypes.c_const_type(base) 11735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CVarDefNode(StatNode): 11765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # C variable definition or forward/extern function declaration. 11775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 11785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # visibility 'private' or 'public' or 'extern' 11795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type CBaseTypeNode 11805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # declarators [CDeclaratorNode] 11815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in_pxd boolean 11825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # api boolean 11835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # overridable boolean whether it is a cpdef 11845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # modifiers ['inline'] 11855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # decorators [cython.locals(...)] or None 11875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # directive_locals { string : NameNode } locals defined by cython.locals(...) 11885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base_type", "declarators"] 11905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decorators = None 11925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) directive_locals = None 11935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env, dest_scope = None): 11955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.directive_locals is None: 11965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.directive_locals = {} 11975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not dest_scope: 11985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dest_scope = env 11995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dest_scope = dest_scope 12005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.declarators: 12025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) templates = self.declarators[0].analyse_templates() 12035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 12045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) templates = None 12055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if templates is not None: 12065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.visibility != 'extern': 12075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Only extern functions allowed") 12085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.declarators) > 1: 12095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.declarators[1].pos, "Can't multiply declare template types") 12105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env = TemplateScope('func_template', env) 12115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.directives = env.outer_scope.directives 12125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for template_param in templates: 12135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_type(template_param.name, template_param, self.pos) 12145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = self.base_type.analyse(env) 12165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type.is_fused and not self.in_pxd and (env.is_c_class_scope or 12185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.is_module_scope): 12195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Fused types not allowed here") 12205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return error_type 12215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = None 12235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) visibility = self.visibility 12245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for declarator in self.declarators: 12265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (len(self.declarators) > 1 12285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not isinstance(declarator, CNameDeclaratorNode) 12295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and env.directives['warn.multiple_declarators']): 12305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(declarator.pos, 12315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). " + 12325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Each pointer declaration should be on its own line.", 1) 12335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(declarator, CFuncDeclaratorNode): 12355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = declarator.analyse(base_type, env, directive_locals=self.directive_locals) 12365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 12375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = declarator.analyse(base_type, env) 12385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not type.is_complete(): 12395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not (self.visibility == 'extern' and type.is_array or type.is_memoryviewslice): 12405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(declarator.pos, 12415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Variable type '%s' is incomplete" % type) 12425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.visibility == 'extern' and type.is_pyobject: 12435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(declarator.pos, 12445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Python object cannot be declared extern") 12455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = name_declarator.name 12465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = name_declarator.cname 12475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name == '': 12485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(declarator.pos, "Missing name in declaration.") 12495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 12505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.is_cfunction: 12515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = dest_scope.declare_cfunction(name, type, declarator.pos, 12525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = cname, visibility = self.visibility, in_pxd = self.in_pxd, 12535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api = self.api, modifiers = self.modifiers) 12545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.entry is not None: 12555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.is_overridable = self.overridable 12565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.directive_locals = copy.copy(self.directive_locals) 12575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 12585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.directive_locals: 12595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Decorators can only be followed by functions") 12605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = dest_scope.declare_var(name, type, declarator.pos, 12615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname=cname, visibility=visibility, in_pxd=self.in_pxd, 12625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api=self.api, is_cdef=1) 12635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if Options.docstrings: 12645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.doc = embed_position(self.pos, self.doc) 12655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CStructOrUnionDefNode(StatNode): 12685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string 12695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cname string or None 12705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # kind "struct" or "union" 12715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # typedef_flag boolean 12725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # visibility "public" or "private" 12735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # api boolean 12745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in_pxd boolean 12755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # attributes [CVarDefNode] or None 12765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # entry Entry 12775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # packed boolean 12785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["attributes"] 12805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare(self, env, scope=None): 12825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.visibility == 'extern' and self.packed and not scope: 12835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Cannot declare extern struct as 'packed'") 12845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = env.declare_struct_or_union( 12855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, self.kind, scope, self.typedef_flag, self.pos, 12865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cname, visibility = self.visibility, api = self.api, 12875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) packed = self.packed) 12885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 12905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = None 12915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.attributes is not None: 12925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = StructOrUnionScope(self.name) 12935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare(env, scope) 12945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.attributes is not None: 12955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.in_pxd and not env.in_cinclude: 12965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.defined_in_pxd = 1 12975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for attr in self.attributes: 12985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) attr.analyse_declarations(env, scope) 12995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.visibility != 'extern': 13005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for attr in scope.var_entries: 13015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = attr.type 13025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while type.is_array: 13035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = type.base_type 13045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type == self.entry.type: 13055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(attr.pos, "Struct cannot contain itself as a member.") 13065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 13085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 13095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 13115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 13125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CppClassNode(CStructOrUnionDefNode, BlockNode): 13155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string 13175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cname string or None 13185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # visibility "extern" 13195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in_pxd boolean 13205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # attributes [CVarDefNode] or None 13215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # entry Entry 13225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_classes [CBaseTypeNode] 13235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # templates [string] or None 13245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare(self, env): 13265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.templates is None: 13275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_types = None 13285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 13295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates] 13305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = env.declare_cpp_class( 13315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, None, self.pos, 13325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cname, base_classes = [], visibility = self.visibility, templates = template_types) 13335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 13355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = None 13365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.attributes is not None: 13375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = CppClassScope(self.name, env, templates = self.templates) 13385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def base_ok(base_class): 13395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_class.is_cpp_class or base_class.is_struct: 13405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return True 13415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 13425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Base class '%s' not a struct or class." % base_class) 13435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_types = filter(base_ok, [b.analyse(scope or env) for b in self.base_classes]) 13445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.templates is None: 13455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_types = None 13465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 13475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates] 13485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = env.declare_cpp_class( 13495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, scope, self.pos, 13505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cname, base_class_types, visibility = self.visibility, templates = template_types) 13515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.entry is None: 13525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 13535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.is_cpp_class = 1 13545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if scope is not None: 13555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.type = self.entry.type 13565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defined_funcs = [] 13575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.attributes is not None: 13585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.in_pxd and not env.in_cinclude: 13595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.defined_in_pxd = 1 13605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for attr in self.attributes: 13615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) attr.analyse_declarations(scope) 13625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(attr, CFuncDefNode): 13635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defined_funcs.append(attr) 13645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.templates is not None: 13655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) attr.template_declaration = "template <typename %s>" % ", typename ".join(self.templates) 13665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = StatListNode(self.pos, stats=defined_funcs) 13675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.scope = scope 13685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 13705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(self.entry.type.scope) 13715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 13725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 13745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(self.entry.type.scope, code) 13755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 13775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 13785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 13805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 13815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CEnumDefNode(StatNode): 13845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string or None 13855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cname string or None 13865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # items [CEnumDefItemNode] 13875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # typedef_flag boolean 13885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # visibility "public" or "private" 13895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # api boolean 13905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in_pxd boolean 13915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # entry Entry 13925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["items"] 13945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 13955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare(self, env): 13965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = env.declare_enum(self.name, self.pos, 13975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = self.cname, typedef_flag = self.typedef_flag, 13985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) visibility = self.visibility, api = self.api) 13995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 14015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.items is not None: 14025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.in_pxd and not env.in_cinclude: 14035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.defined_in_pxd = 1 14045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for item in self.items: 14055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) item.analyse_declarations(env, self.entry) 14065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 14085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 14095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 14115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.visibility == 'public' or self.api: 14125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True) 14135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for item in self.entry.enum_values: 14145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = PyInt_FromLong(%s); %s" % ( 14155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp, 14165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) item.cname, 14175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if_null(temp, item.pos))) 14185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(temp) 14195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (PyDict_SetItemString(%s, "%s", %s) < 0) %s' % ( 14205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.moddict_cname, 14215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) item.name, 14225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp, 14235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(item.pos))) 14245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(temp, PyrexTypes.py_object_type) 14255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(temp) 14265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CEnumDefItemNode(StatNode): 14295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string 14305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cname string or None 14315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # value ExprNode or None 14325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["value"] 14345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env, enum_entry): 14365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value: 14375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value = self.value.analyse_const_expression(env) 14385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.value.type.is_int: 14395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value = self.value.coerce_to(PyrexTypes.c_int_type, env) 14405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value = self.value.analyse_const_expression(env) 14415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.declare_const(self.name, enum_entry.type, 14425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value, self.pos, cname = self.cname, 14435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) visibility = enum_entry.visibility, api = enum_entry.api) 14445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) enum_entry.enum_values.append(entry) 14455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CTypeDefNode(StatNode): 14485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type CBaseTypeNode 14495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # declarator CDeclaratorNode 14505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # visibility "public" or "private" 14515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # api boolean 14525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in_pxd boolean 14535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base_type", "declarator"] 14555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 14575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base = self.base_type.analyse(env) 14585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = self.declarator.analyse(base, env) 14595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = name_declarator.name 14605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = name_declarator.cname 14615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.declare_typedef(name, type, self.pos, 14635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = cname, visibility = self.visibility, api = self.api) 14645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.is_fused: 14665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.in_cinclude = True 14675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.in_pxd and not env.in_cinclude: 14695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.defined_in_pxd = 1 14705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 14725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 14735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 14755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 14765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FuncDefNode(StatNode, BlockNode): 14795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Base class for function definition nodes. 14805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 14815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # return_type PyrexType 14825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # #filename string C name of filename string const 14835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # entry Symtab.Entry 14845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # needs_closure boolean Whether or not this function has inner functions/classes/yield 14855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # needs_outer_scope boolean Whether or not this function requires outer scope 14865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # pymethdef_required boolean Force Python method struct generation 14875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # directive_locals { string : ExprNode } locals defined by cython.locals(...) 14885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # directive_returns [ExprNode] type defined by cython.returns(...) 14895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # star_arg PyArgDeclNode or None * argument 14905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # starstar_arg PyArgDeclNode or None ** argument 14915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # has_fused_arguments boolean 14935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Whether this cdef function has fused parameters. This is needed 14945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # by AnalyseDeclarationsTransform, so it can replace CFuncDefNodes 14955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # with fused argument types with a FusedCFuncDefNode 14965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) py_func = None 14985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) needs_closure = False 14995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) needs_outer_scope = False 15005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pymethdef_required = False 15015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_generator = False 15025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_generator_body = False 15035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) modifiers = [] 15045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_fused_arguments = False 15055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) star_arg = None 15065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) starstar_arg = None 15075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_cyfunction = False 15085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_default_values(self, env): 15105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_seen = 0 15115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 15125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default: 15135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_seen = 1 15145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.is_generic: 15155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.default = arg.default.analyse_types(env) 15165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.default = arg.default.coerce_to(arg.type, env) 15175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 15185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, 15195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "This argument cannot have a default value") 15205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.default = None 15215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.kw_only: 15225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_seen = 1 15235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif default_seen: 15245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Non-default argument following default argument") 15255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def align_argument_type(self, env, arg): 15275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) directive_locals = self.directive_locals 15285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = arg.type 15295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.name in directive_locals: 15305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_node = directive_locals[arg.name] 15315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) other_type = type_node.analyse_as_type(env) 15325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if other_type is None: 15335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Not a type") 15345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif (type is not PyrexTypes.py_object_type 15355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not type.same_as(other_type)): 15365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.base_type.pos, "Signature does not agree with previous declaration") 15375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Previous declaration here") 15385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 15395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type = other_type 15405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return arg 15415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def need_gil_acquisition(self, lenv): 15435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0 15445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def create_local_scope(self, env): 15465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) genv = env 15475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while genv.is_py_class_scope or genv.is_c_class_scope: 15485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) genv = genv.outer_scope 15495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.needs_closure: 15505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv = ClosureScope(name=self.entry.name, 15515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outer_scope = genv, 15525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent_scope = env, 15535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope_name=self.entry.cname) 15545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 15555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv = LocalScope(name=self.entry.name, 15565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outer_scope=genv, 15575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent_scope=env) 15585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.return_type = self.return_type 15595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = self.entry.type 15605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.is_cfunction: 15615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.nogil = type.nogil and not type.with_gil 15625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.local_scope = lenv 15635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.directives = env.directives 15645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return lenv 15655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_body(self, env, code): 15675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 15685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 15705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import Buffer 15715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_memoryviewslice: 15725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import MemoryView 15735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv = self.local_scope 15755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if lenv.is_closure_scope and not lenv.is_passthrough: 15765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname, 15775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.outer_scope_cname) 15785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 15795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outer_scope_cname = Naming.outer_scope_cname 15805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.mangle_closure_cnames(outer_scope_cname) 15815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate closure function definitions 15825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(lenv, code) 15835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # generate lambda function definitions 15845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_lambda_definitions(lenv, code) 15855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_getbuffer_slot = (self.entry.name == "__getbuffer__" and 15875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.scope.is_c_class_scope) 15885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and 15895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.scope.is_c_class_scope) 15905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot 15915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if is_buffer_slot: 15925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if 'cython_unused' not in self.modifiers: 15935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.modifiers = self.modifiers + ['cython_unused'] 15945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) preprocessor_guard = self.get_preprocessor_guard() 15965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) profile = code.globalstate.directives['profile'] 15985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) linetrace = code.globalstate.directives['linetrace'] 15995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (linetrace or profile) and lenv.nogil: 16005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(self.pos, "Cannot profile nogil function.", 1) 16015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) profile = linetrace = False 16025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if profile or linetrace: 16035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 16045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("Profile", "Profile.c")) 16055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate C code for header and body of function 16075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.enter_cfunc_scope() 16085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.return_from_error_cleanup_label = code.new_label() 16095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Top-level constants used by this function 16115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 16125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_cached_builtins_decls(lenv, code) 16135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Function header 16145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 16155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if preprocessor_guard: 16175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(preprocessor_guard) 16185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_pymethdef = (self.needs_assignment_synthesis(env, code) or 16205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.pymethdef_required) 16215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_func: 16225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_func.generate_function_header(code, 16235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_pymethdef = with_pymethdef, 16245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) proto_only=True) 16255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_function_header(code, 16265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_pymethdef = with_pymethdef) 16275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Local variable declarations 16285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Find function scope 16295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv = env 16305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while cenv.is_py_class_scope or cenv.is_c_class_scope: 16315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv = cenv.outer_scope 16325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.needs_closure: 16335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname)) 16345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(";") 16355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.needs_outer_scope: 16365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if lenv.is_passthrough: 16375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname)) 16385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(";") 16395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname)) 16405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(";") 16415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_argument_declarations(lenv, code) 16425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.var_entries: 16445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not (entry.in_closure or entry.is_arg): 16455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_declaration(entry) 16465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Initialize the return variable __pyx_r 16485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) init = "" 16495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.return_type.is_void: 16505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 16515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) init = " = NULL" 16525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.return_type.is_memoryviewslice: 16535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) init = ' = ' + MemoryView.memslice_entry_init 16545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 16565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "%s%s;" % 16575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self.return_type.declaration_code(Naming.retval_cname), 16585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) init)) 16595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tempvardecl_code = code.insertion_point() 16615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_keyword_list(code) 16625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if profile or linetrace: 16645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_trace_declarations() 16655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Extern library function declarations 16675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.generate_library_function_declarations(code) 16685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- GIL acquisition 16705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) acquire_gil = self.acquire_gil 16715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # See if we need to acquire the GIL for variable declarations, or for 16735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # refnanny only 16745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Profiling or closures are not currently possible for cdef nogil 16765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # functions, but check them anyway 16775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) have_object_args = (self.needs_closure or self.needs_outer_scope or 16785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) profile or linetrace) 16795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in lenv.arg_entries: 16805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_pyobject: 16815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) have_object_args = True 16825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break 16835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) acquire_gil_for_var_decls_only = ( 16855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.nogil and lenv.has_with_gil_block and 16865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (have_object_args or lenv.buffer_entries)) 16875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) acquire_gil_for_refnanny_only = ( 16895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.nogil and lenv.has_with_gil_block and not 16905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) acquire_gil_for_var_decls_only) 16915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) use_refnanny = not lenv.nogil or lenv.has_with_gil_block 16935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if acquire_gil or acquire_gil_for_var_decls_only: 16955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil() 16965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif lenv.nogil and lenv.has_with_gil_block: 16975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.declare_gilstate() 16985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- set up refnanny 17005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if use_refnanny: 17015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tempvardecl_code.put_declare_refcount_context() 17025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_setup_refcount_context( 17035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.name, acquire_gil=acquire_gil_for_refnanny_only) 17045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 17055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Automatic lead-ins for certain special functions 17065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if is_getbuffer_slot: 17075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.getbuffer_init(code) 17085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Create closure scope object 17095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.needs_closure: 17105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__') 17115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) slot_func_cname = TypeSlots.get_slot_function(lenv.scope_class.type.scope, tp_slot) 17125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not slot_func_cname: 17135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) slot_func_cname = '%s->tp_new' % lenv.scope_class.type.typeptr_cname 17145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = (%s)%s(%s, %s, NULL);" % ( 17155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.cur_scope_cname, 17165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.scope_class.type.declaration_code(''), 17175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) slot_func_cname, 17185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.scope_class.type.typeptr_cname, 17195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.empty_tuple)) 17205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname) 17215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if is_getbuffer_slot: 17225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.getbuffer_error_cleanup(code) 17235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 17245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if use_refnanny: 17255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_finish_refcount_context() 17265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if acquire_gil or acquire_gil_for_var_decls_only: 17275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 17285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 17295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # FIXME: what if the error return value is a Python value? 17305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("return %s;" % self.error_value()) 17315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 17325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(Naming.cur_scope_cname) 17335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Note that it is unsafe to decref the scope at this point. 17345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.needs_outer_scope: 17355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_cyfunction: 17365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = (%s) __Pyx_CyFunction_GetClosure(%s);" % ( 17375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outer_scope_cname, 17385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv.scope_class.type.declaration_code(''), 17395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.self_cname)) 17405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 17415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = (%s) %s;" % ( 17425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outer_scope_cname, 17435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv.scope_class.type.declaration_code(''), 17445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.self_cname)) 17455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if lenv.is_passthrough: 17465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname)) 17475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.needs_closure: 17485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # inner closures own a reference to their outer parent 17495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_incref(outer_scope_cname, cenv.scope_class.type) 17505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref(outer_scope_cname) 17515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Trace function call 17525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if profile or linetrace: 17535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # this looks a bit late, but if we don't get here due to a 17545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # fatal error before hand, it's not really worth tracing 17555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_trace_call(self.entry.name, self.pos) 17565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.can_trace = True 17575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Fetch arguments 17585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_argument_parsing_code(env, code) 17595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # If an argument is assigned to in the body, we must 17605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # incref it to properly keep track of refcounts. 17615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_cdef = isinstance(self, CFuncDefNode) 17625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.arg_entries: 17635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_pyobject: 17645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((acquire_gil or len(entry.cf_assignments) > 1) and 17655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not entry.in_closure): 17665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_incref(entry) 17675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 17685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Note: defaults are always incref-ed. For def functions, we 17695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # we aquire arguments from object converstion, so we have 17705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # new references. If we are a cdef function, we need to 17715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # incref our arguments 17725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif (is_cdef and entry.type.is_memoryviewslice and 17735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) len(entry.cf_assignments) > 1): 17745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_incref_memoryviewslice(entry.cname, 17755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) have_gil=not lenv.nogil) 17765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.var_entries: 17775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.is_arg and len(entry.cf_assignments) > 1: 17785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_incref(entry) 17795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 17805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Initialise local buffer auxiliary variables 17815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.var_entries + lenv.arg_entries: 17825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_buffer and entry.buffer_aux.buflocal_nd_var.used: 17835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Buffer.put_init_vars(entry, code) 17845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 17855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Check and convert arguments 17865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_argument_type_tests(code) 17875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Acquire buffer arguments 17885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.arg_entries: 17895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_buffer: 17905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Buffer.put_acquire_arg_buffer(entry, code, self.pos) 17915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 17925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if acquire_gil_for_var_decls_only: 17935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 17945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 17955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ------------------------- 17965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Function body ----- 17975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ------------------------- 17985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_function_body(env, code) 17995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 18015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 18025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* function exit code */") 18035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Default return value 18055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.body.is_terminator: 18065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 18075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #if self.return_type.is_extension_type: 18085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # lhs = "(PyObject *)%s" % Naming.retval_cname 18095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #else: 18105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs = Naming.retval_cname 18115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_init_to_py_none(lhs, self.return_type) 18125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 18135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) val = self.return_type.default_value 18145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if val: 18155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (Naming.retval_cname, val)) 18165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Error cleanup 18175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.error_label in code.labels_used: 18185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.body.is_terminator: 18195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.return_label) 18205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.error_label) 18215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cname, type in code.funcstate.all_managed_temps(): 18225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref(cname, type, have_gil=not lenv.nogil) 18235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Clean up buffers -- this calls a Python function 18255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # so need to save and restore error state 18265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buffers_present = len(lenv.buffer_entries) > 0 18275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) memslice_entries = [e for e in lenv.entries.itervalues() 18285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if e.type.is_memoryviewslice] 18295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if buffers_present: 18305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(restore_exception_utility_code) 18315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;") 18325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);") 18335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.buffer_entries: 18345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Buffer.put_release_buffer_code(code, entry) 18355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #code.putln("%s = 0;" % entry.cname) 18365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}") 18375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_memoryviewslice: 18395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MemoryView.put_init_entry(Naming.retval_cname, code) 18405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err_val = Naming.retval_cname 18415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 18425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err_val = self.error_value() 18435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_check = self.caller_will_check_exceptions() 18455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if err_val is not None or exc_check: 18465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # TODO: Fix exception tracing (though currently unused by cProfile). 18475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # code.globalstate.use_utility_code(get_exception_tuple_utility_code) 18485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # code.put_trace_exception() 18495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if lenv.nogil and not lenv.has_with_gil_block: 18515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("{") 18525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil() 18535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_add_traceback(self.entry.qualified_name) 18555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if lenv.nogil and not lenv.has_with_gil_block: 18575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 18585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 18595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 18605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(self.entry.pos, 18615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Unraisable exception in function '%s'." % 18625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.qualified_name, 0) 18635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_unraisable(self.entry.qualified_name) 18645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_retval = self.return_type.default_value 18655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if err_val is None and default_retval: 18665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err_val = default_retval 18675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if err_val is not None: 18685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (Naming.retval_cname, err_val)) 18695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if is_getbuffer_slot: 18715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.getbuffer_error_cleanup(code) 18725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # If we are using the non-error cleanup section we should 18745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # jump past it if we have an error. The if-test below determine 18755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # whether this section is used. 18765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if buffers_present or is_getbuffer_slot or self.return_type.is_memoryviewslice: 18775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.return_from_error_cleanup_label) 18785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Non-error return cleanup 18805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.return_label) 18815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.buffer_entries: 18825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.used: 18835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Buffer.put_release_buffer_code(code, entry) 18845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if is_getbuffer_slot: 18855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.getbuffer_normal_cleanup(code) 18865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_memoryviewslice: 18885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # See if our return value is uninitialized on non-error return 18895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # import MemoryView 18905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # MemoryView.err_if_nogil_initialized_check(self.pos, env) 18915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cond = code.unlikely(self.return_type.error_condition( 18925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.retval_cname)) 18935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 18945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'if (%s) {' % cond) 18955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if env.nogil: 18965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil() 18975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 18985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'PyErr_SetString(' 18995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'PyExc_TypeError,' 19005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '"Memoryview return value is not initialized");') 19015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if env.nogil: 19025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 19035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 19045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '}') 19055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Return cleanup for both error and no-error return 19075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.return_from_error_cleanup_label) 19085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.var_entries: 19105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not entry.used or entry.in_closure: 19115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 19125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_memoryviewslice: 19145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref_memoryviewslice(entry.cname, 19155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) have_gil=not lenv.nogil) 19165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif entry.type.is_pyobject: 19175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not entry.is_arg or len(entry.cf_assignments) > 1: 19185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_decref(entry) 19195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Decref any increfed args 19215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.arg_entries: 19225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_pyobject: 19235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((acquire_gil or len(entry.cf_assignments) > 1) and 19245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not entry.in_closure): 19255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_decref(entry) 19265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif (entry.type.is_memoryviewslice and 19275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (not is_cdef or len(entry.cf_assignments) > 1)): 19285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # decref slices of def functions and acquired slices from cdef 19295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # functions, but not borrowed slices from cdef functions. 19305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref_memoryviewslice(entry.cname, 19315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) have_gil=not lenv.nogil) 19325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.needs_closure: 19335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type) 19345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Return 19365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This code is duplicated in ModuleNode.generate_module_init_func 19375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not lenv.nogil: 19385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_retval = self.return_type.default_value 19395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err_val = self.error_value() 19405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if err_val is None and default_retval: 19415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err_val = default_retval # FIXME: why is err_val not used? 19425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 19435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname)) 19445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.entry.is_special and self.entry.name == "__hash__": 19465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Returning -1 for __hash__ is supposed to signal an error 19475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # We do as Python instances and coerce -1 into -2. 19485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % ( 19495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.retval_cname, Naming.retval_cname)) 19505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if profile or linetrace: 19525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.can_trace = False 19535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 19545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_trace_return(Naming.retval_cname) 19555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 19565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_trace_return("Py_None") 19575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not lenv.nogil: 19595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # GIL holding function 19605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_finish_refcount_context() 19615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if acquire_gil or (lenv.nogil and lenv.has_with_gil_block): 19635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # release the GIL (note that with-gil blocks acquire it on exit in their EnsureGILNode) 19645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 19655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.return_type.is_void: 19675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("return %s;" % Naming.retval_cname) 19685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 19705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if preprocessor_guard: 19725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#endif /*!(%s)*/" % preprocessor_guard) 19735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Go back and insert temp variable declarations 19755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tempvardecl_code.put_temp_declarations(code.funcstate) 19765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Python version 19785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.exit_cfunc_scope() 19795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_func: 19805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_func.generate_function_definitions(env, code) 19815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_wrapper_functions(code) 19825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_argument(self, env, arg): 19845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_void: 19855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Invalid use of 'void'") 19865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif not arg.type.is_complete() and not (arg.type.is_array or arg.type.is_memoryviewslice): 19875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, 19885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Argument type '%s' is incomplete" % arg.type) 19895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return env.declare_arg(arg.name, arg.type, arg.pos) 19905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 19915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_arg_type_test(self, arg, code): 19925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate type test for one argument. 19935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.typeobj_is_available(): 19945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 19955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("ArgTypeTest", "FunctionArguments.c")) 19965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typeptr_cname = arg.type.typeptr_cname 19975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code = "((PyObject *)%s)" % arg.entry.cname 19985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 19995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % ( 20005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code, 20015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typeptr_cname, 20025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.accept_none, 20035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.name, 20045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type.is_builtin_type, 20055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(arg.pos))) 20065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 20075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Cannot test type of extern C class " 20085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "without type object name specification") 20095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_arg_none_check(self, arg, code): 20115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate None check for one argument. 20125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_memoryviewslice: 20135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = "%s.memview" % arg.entry.cname 20145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 20155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = arg.entry.cname 20165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % cname) 20185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%%.%ds' must not be None", "%s"); %s''' % ( 20195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max(200, len(arg.name)), arg.name, 20205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(arg.pos))) 20215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 20225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_wrapper_functions(self, code): 20245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 20255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 20275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Evaluate and store argument default values 20285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 20295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.is_dynamic: 20305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.generate_assignment_code(code) 20315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 20335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Special code for the __getbuffer__ function 20345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 20355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def getbuffer_init(self, code): 20365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) info = self.local_scope.arg_entries[1].cname 20375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Python 3.0 betas have a bug in memoryview which makes it call 20385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # getbuffer with a NULL parameter. For now we work around this; 20395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # the following block should be removed when this bug is fixed. 20405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (%s != NULL) {" % info) 20415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info) 20425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref("%s->obj" % info) # Do not refnanny object within structs 20435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 20445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def getbuffer_error_cleanup(self, code): 20465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) info = self.local_scope.arg_entries[1].cname 20475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (%s != NULL && %s->obj != NULL) {" 20485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) % (info, info)) 20495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref("%s->obj" % info) 20505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" 20515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) % (info, info)) 20525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 20535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def getbuffer_normal_cleanup(self, code): 20555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) info = self.local_scope.arg_entries[1].cname 20565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (%s != NULL && %s->obj == Py_None) {" % (info, info)) 20575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref("Py_None") 20585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info) 20595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 20605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def get_preprocessor_guard(self): 20625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.entry.is_special: 20635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 20645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.entry.name 20655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) slot = TypeSlots.method_name_to_slot.get(name) 20665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not slot: 20675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 20685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name == '__long__' and not self.entry.scope.lookup_here('__int__'): 20695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 20705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name in ("__getbuffer__", "__releasebuffer__") and self.entry.scope.is_c_class_scope: 20715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 20725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return slot.preprocessor_guard_code() 20735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CFuncDefNode(FuncDefNode): 20765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # C function definition. 20775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 20785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # modifiers ['inline'] 20795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # visibility 'private' or 'public' or 'extern' 20805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type CBaseTypeNode 20815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # declarator CDeclaratorNode 20825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cfunc_declarator the CFuncDeclarator of this function 20835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (this is also available through declarator or a 20845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base thereof) 20855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatListNode 20865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # api boolean 20875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # decorators [DecoratorNode] list of decorators 20885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 20895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # with_gil boolean Acquire GIL around body 20905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # type CFuncType 20915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # py_func wrapper for calling from Python 20925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # overridable whether or not this is a cpdef function 20935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # inline_in_pxd whether this is an inline function in a pxd file 20945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # template_declaration String or None Used for c++ class methods 20955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_const_method whether this is a const method 20965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["base_type", "declarator", "body", "py_func"] 20985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 20995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) inline_in_pxd = False 21005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decorators = None 21015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) directive_locals = None 21025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) directive_returns = None 21035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) override = None 21045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_declaration = None 21055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_const_method = False 21065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def unqualified_name(self): 21085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.entry.name 21095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 21115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.directive_locals is None: 21125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.directive_locals = {} 21135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.directive_locals.update(env.directives['locals']) 21145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.directive_returns is not None: 21155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = self.directive_returns.analyse_as_type(env) 21165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_type is None: 21175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.directive_returns.pos, "Not a type") 21185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = PyrexTypes.error_type 21195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 21205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = self.base_type.analyse(env) 21215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The 2 here is because we need both function and argument names. 21225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.declarator, CFuncDeclaratorNode): 21235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = self.declarator.analyse(base_type, env, 21245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nonempty = 2 * (self.body is not None), 21255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) directive_locals = self.directive_locals) 21265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 21275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None)) 21285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not type.is_cfunction: 21295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 21305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Suite attached to non-function declaration") 21315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Remember the actual type according to the function header 21325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # written here, because the type in the symbol table entry 21335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # may be different if we're overriding a C method inherited 21345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # from the base type of an extension type. 21355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type = type 21365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type.is_overridable = self.overridable 21375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator = self.declarator 21385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while not hasattr(declarator, 'args'): 21395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator = declarator.base 21405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cfunc_declarator = declarator 21425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.args = declarator.args 21435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) opt_arg_count = self.cfunc_declarator.optional_arg_count 21455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (self.visibility == 'public' or self.api) and opt_arg_count: 21465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.cfunc_declarator.pos, 21475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Function with optional arguments may not be declared " 21485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "public or api") 21495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (type.exception_check == '+' and self.visibility != 'extern'): 21515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(self.cfunc_declarator.pos, 21525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Only extern functions can throw C++ exceptions.") 21535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for formal_arg, type_arg in zip(self.args, type.args): 21555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.align_argument_type(env, type_arg) 21565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) formal_arg.type = type_arg.type 21575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) formal_arg.name = type_arg.name 21585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) formal_arg.cname = type_arg.cname 21595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._validate_type_visibility(type_arg.type, type_arg.pos, env) 21615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type_arg.type.is_fused: 21635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.has_fused_arguments = True 21645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type_arg.type.is_buffer and 'inline' in self.modifiers: 21665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1) 21675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type_arg.type.is_buffer: 21695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.type.nogil: 21705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(formal_arg.pos, 21715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Buffer may not be acquired without the GIL. " 21725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Consider using memoryview slices instead.") 21735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif 'inline' in self.modifiers: 21745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1) 21755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._validate_type_visibility(type.return_type, self.pos, env) 21775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = name_declarator.name 21795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = name_declarator.cname 21805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type.is_const_method = self.is_const_method 21825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = env.declare_cfunction( 21835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name, type, self.pos, 21845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = cname, visibility = self.visibility, api = self.api, 21855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defining = self.body is not None, modifiers = self.modifiers) 21865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.inline_func_in_pxd = self.inline_in_pxd 21875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.return_type = type.return_type 21885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_array and self.visibility != 'extern': 21895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 21905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Function cannot return an array") 21915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_cpp_class: 21925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.return_type.check_nullary_constructor(self.pos, "used as a return value") 21935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.overridable and not env.is_module_scope: 21955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.args) < 1 or not self.args[0].type.is_pyobject: 21965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # An error will be produced in the cdef function 21975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.overridable = False 21985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 21995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_cpdef_wrapper(env) 22005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.create_local_scope(env) 22015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_cpdef_wrapper(self, env): 22035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.overridable: 22045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.entry.name 22055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) py_func_body = self.call_self_node(is_module_scope = env.is_module_scope) 22065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_func = DefNode(pos = self.pos, 22075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.entry.name, 22085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = self.args, 22095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) star_arg = None, 22105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) starstar_arg = None, 22115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc = self.doc, 22125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body = py_func_body, 22135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_wrapper = 1) 22145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_func.is_module_scope = env.is_module_scope 22155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_func.analyse_declarations(env) 22165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.as_variable = self.py_func.entry 22175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.used = self.entry.as_variable.used = True 22185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Reset scope entry the above cfunction 22195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.entries[name] = self.entry 22205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (not self.entry.is_final_cmethod and 22215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (not env.is_module_scope or Options.lookup_module_cpdef)): 22225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.override = OverrideCheckNode(self.pos, py_func = self.py_func) 22235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = StatListNode(self.pos, stats=[self.override, self.body]) 22245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _validate_type_visibility(self, type, pos, env): 22265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 22275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Ensure that types used in cdef functions are public or api, or 22285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defined in a C header. 22295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 22305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public_or_api = (self.visibility == 'public' or self.api) 22315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = getattr(type, 'entry', None) 22325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if public_or_api and entry and env.is_module_scope: 22335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not (entry.visibility in ('public', 'extern') or 22345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.api or entry.in_cinclude): 22355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(pos, "Function declared public or api may not have " 22365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "private types") 22375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def call_self_node(self, omit_optional_args=0, is_module_scope=0): 22395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 22405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = self.type.args 22415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if omit_optional_args: 22425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = args[:len(args) - self.type.optional_arg_count] 22435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_names = [arg.name for arg in args] 22445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if is_module_scope: 22455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name) 22465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 22475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0]) 22485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name) 22495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) skip_dispatch = not is_module_scope or Options.lookup_module_cpdef 22505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 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) 22515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call) 22525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_arguments(self, env): 22545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.type.args: 22555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.name: 22565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Missing argument name") 22575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_argument(env, arg) 22585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def need_gil_acquisition(self, lenv): 22605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.type.with_gil 22615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def nogil_check(self, env): 22635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = self.type 22645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_gil = type.with_gil 22655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.nogil and not with_gil: 22665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.return_type.is_pyobject: 22675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 22685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Function with Python return type cannot be declared nogil") 22695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in self.local_scope.var_entries: 22705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_pyobject and not entry.in_with_gil_block: 22715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Function declared nogil has Python locals or temporaries") 22725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 22745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.local_scope.directives = env.directives 22755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_func is not None: 22765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # this will also analyse the default values 22775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_func = self.py_func.analyse_expressions(env) 22785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 22795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.analyse_default_values(env) 22805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.acquire_gil = self.need_gil_acquisition(self.local_scope) 22815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 22825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def needs_assignment_synthesis(self, env, code=None): 22845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return False 22855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None): 22875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = self.local_scope 22885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decls = [] 22895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = self.type 22905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in type.args[:len(type.args)-type.optional_arg_count]: 22915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decl = arg.declaration_code() 22925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = scope.lookup(arg.name) 22935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not entry.cf_used: 22945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decl = 'CYTHON_UNUSED %s' % arg_decl 22955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decls.append(arg_decl) 22965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if with_dispatch and self.overridable: 22975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dispatch_arg = PyrexTypes.c_int_type.declaration_code( 22985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.skip_dispatch_cname) 22995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.override: 23005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decls.append(dispatch_arg) 23015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 23025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decls.append('CYTHON_UNUSED %s' % dispatch_arg) 23035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.optional_arg_count and with_opt_args: 23045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname)) 23055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.has_varargs: 23065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decls.append("...") 23075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg_decls: 23085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_decls = ["void"] 23095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if cname is None: 23105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = self.entry.func_cname 23115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entity = type.function_header_code(cname, ', '.join(arg_decls)) 23125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.entry.visibility == 'private' and '::' not in cname: 23135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) storage_class = "static " 23145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 23155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) storage_class = "" 23165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dll_linkage = None 23175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) modifiers = code.build_function_modifiers(self.entry.func_modifiers) 23185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) header = self.return_type.declaration_code(entity, dll_linkage=dll_linkage) 23205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print (storage_class, modifiers, header) 23215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.template_declaration: 23225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(self.template_declaration) 23235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s%s%s {" % (storage_class, modifiers, header)) 23245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_declarations(self, env, code): 23265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = self.local_scope 23275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 23285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default: 23295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = scope.lookup(arg.name) 23305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.override or entry.cf_used: 23315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = arg.calculate_default_value_code(code) 23325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s = %s;' % ( 23335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type.declaration_code(arg.cname), result)) 23345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_keyword_list(self, code): 23365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 23375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_parsing_code(self, env, code): 23395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i = 0 23405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) used = 0 23415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.type.optional_arg_count: 23425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = self.local_scope 23435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (%s) {' % Naming.optional_args_cname) 23445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 23455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default: 23465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = scope.lookup(arg.name) 23475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.override or entry.cf_used: 23485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (%s->%sn > %s) {' % 23495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (Naming.optional_args_cname, 23505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.pyrex_prefix, i)) 23515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator = arg.declarator 23525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while not hasattr(declarator, 'name'): 23535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator = declarator.base 23545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s = %s->%s;' % 23555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (arg.cname, Naming.optional_args_cname, 23565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.type.opt_arg_cname(declarator.name))) 23575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) used += 1 23585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i += 1 23595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for _ in range(used): 23605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 23615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 23625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_conversion_code(self, code): 23645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 23655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_type_tests(self, code): 23675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate type tests for args whose type in a parent 23685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # class is a supertype of the declared type. 23695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.type.args: 23705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.needs_type_test: 23715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_type_test(arg, code) 23725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.type.is_pyobject and not arg.accept_none: 23735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_none_check(arg, code) 23745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def error_value(self): 23765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 23775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return "0" 23785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 23795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #return None 23805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.entry.type.exception_value 23815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def caller_will_check_exceptions(self): 23835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.entry.type.exception_check 23845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 23855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_wrapper_functions(self, code): 23865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # If the C signature of a function has changed, we need to generate 23875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # wrappers to put in the slots here. 23885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) k = 0 23895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = self.entry 23905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_type = entry.type 23915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while entry.prev_entry is not None: 23925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) k += 1 23935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = entry.prev_entry 23945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k) 23955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln() 23965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_function_header(code, 23975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 23985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_dispatch = entry.type.is_overridable, 23995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_opt_args = entry.type.optional_arg_count, 24005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = entry.func_cname) 24015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.return_type.is_void: 24025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('return ') 24035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = self.type.args 24045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]] 24055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_overridable: 24065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arglist.append(Naming.skip_dispatch_cname) 24075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif func_type.is_overridable: 24085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arglist.append('0') 24095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.optional_arg_count: 24105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arglist.append(Naming.optional_args_cname) 24115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif func_type.optional_arg_count: 24125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arglist.append('NULL') 24135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist))) 24145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 24155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class PyArgDeclNode(Node): 24185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Argument which must be a Python object (used 24195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # for * and ** arguments). 24205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 24215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string 24225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # entry Symtab.Entry 24235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # annotation ExprNode or None Py3 argument annotation 24245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 24255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_self_arg = False 24265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_type_arg = False 24275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 24295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.generate_function_definitions(env, code) 24305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class DecoratorNode(Node): 24325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # A decorator 24335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 24345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # decorator NameNode or CallNode or AttributeNode 24355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['decorator'] 24365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class DefNode(FuncDefNode): 24395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # A Python function definition. 24405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 24415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string the Python name of the function 24425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # lambda_name string the internal name of a lambda 'function' 24435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # decorators [DecoratorNode] list of decorators 24445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # args [CArgDeclNode] formal arguments 24455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # doc EncodedString or None 24465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatListNode 24475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # return_type_annotation 24485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ExprNode or None the Py3 return type annotation 24495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 24505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The following subnode is constructed internally 24515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # when the def statement is inside a Python class definition. 24525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 24535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # fused_py_func DefNode The original fused cpdef DefNode 24545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (in case this is a specialization) 24555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # specialized_cpdefs [DefNode] list of specialized cpdef DefNodes 24565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # py_cfunc_node PyCFunctionNode/InnerFunctionNode The PyCFunction to create and assign 24575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 24585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # decorator_indirection IndirectionNode Used to remove __Pyx_Method_ClassMethod for fused functions 24595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"] 24615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lambda_name = None 24635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reqd_kw_flags_cname = "0" 24645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_wrapper = 0 24655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) no_assignment_synthesis = 0 24665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decorators = None 24675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return_type_annotation = None 24685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = None 24695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) acquire_gil = 0 24705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self_in_stararg = 0 24715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) py_cfunc_node = None 24725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) requires_classobj = False 24735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defaults_struct = None # Dynamic kwrds structure name 24745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc = None 24755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fused_py_func = False 24775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) specialized_cpdefs = None 24785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) py_wrapper = None 24795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) py_wrapper_required = True 24805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_cname = None 24815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defaults_getter = None 24835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, pos, **kwds): 24855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FuncDefNode.__init__(self, pos, **kwds) 24865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) k = rk = r = 0 24875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 24885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.kw_only: 24895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) k += 1 24905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.default: 24915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rk += 1 24925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.default: 24935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) r += 1 24945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_kwonly_args = k 24955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_required_kw_args = rk 24965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_required_args = r 24975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 24985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def as_cfunction(self, cfunc=None, scope=None, overridable=True, returns=None): 24995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg: 25005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.star_arg.pos, "cdef function cannot have star argument") 25015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 25025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.starstar_arg.pos, "cdef function cannot have starstar argument") 25035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if cfunc is None: 25045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cfunc_args = [] 25055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for formal_arg in self.args: 25065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = formal_arg.analyse(scope, nonempty=1) 25075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name, 25085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = None, 25095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = py_object_type, 25105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos = formal_arg.pos)) 25115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type, 25125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = cfunc_args, 25135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_varargs = False, 25145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exception_value = None, 25155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exception_check = False, 25165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil = False, 25175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_gil = False, 25185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_overridable = overridable) 25195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cfunc = CVarDefNode(self.pos, type=cfunc_type) 25205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 25215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if scope is None: 25225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = cfunc.scope 25235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cfunc_type = cfunc.type 25245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs: 25255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "wrong number of arguments") 25265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(cfunc.pos, "previous declaration here") 25275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)): 25285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = formal_arg.analyse(scope, nonempty=1, 25295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_self_arg = (i == 0 and scope.is_c_class_scope)) 25305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type is None or type is PyrexTypes.py_object_type: 25315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) formal_arg.type = type_arg.type 25325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) formal_arg.name_declarator = name_declarator 25335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 25345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if cfunc_type.exception_value is None: 25355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exception_value = None 25365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 25375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type) 25385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator = CFuncDeclaratorNode(self.pos, 25395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base = CNameDeclaratorNode(self.pos, name=self.name, cname=None), 25405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = self.args, 25415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_varargs = False, 25425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exception_check = cfunc_type.exception_check, 25435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exception_value = exception_value, 25445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_gil = cfunc_type.with_gil, 25455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil = cfunc_type.nogil) 25465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return CFuncDefNode(self.pos, 25475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) modifiers = [], 25485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type), 25495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declarator = declarator, 25505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body = self.body, 25515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc = self.doc, 25525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) overridable = cfunc_type.is_overridable, 25535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = cfunc_type, 25545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_gil = cfunc_type.with_gil, 25555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil = cfunc_type.nogil, 25565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) visibility = 'private', 25575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api = False, 25585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) directive_locals = getattr(cfunc, 'directive_locals', {}), 25595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) directive_returns = returns) 25605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 25615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def is_cdef_func_compatible(self): 25625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """Determines if the function's signature is compatible with a 25635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cdef function. This can be used before calling 25645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) .as_cfunction() to see if that will be successful. 25655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 25665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.needs_closure: 25675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return False 25685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg or self.starstar_arg: 25695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return False 25705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return True 25715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 25725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 25735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_classmethod = self.is_staticmethod = False 25745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.decorators: 25755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for decorator in self.decorators: 25765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func = decorator.decorator 25775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func.is_name: 25785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_classmethod |= func.name == 'classmethod' 25795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_staticmethod |= func.name == 'staticmethod' 25805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 25815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_classmethod and env.lookup_here('classmethod'): 25825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # classmethod() was overridden - not much we can do here ... 25835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_classmethod = False 25845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_staticmethod and env.lookup_here('staticmethod'): 25855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # staticmethod() was overridden - not much we can do here ... 25865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_staticmethod = False 25875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 25885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.name == '__new__' and env.is_py_class_scope: 25895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_staticmethod = 1 25905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 25915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.analyse_argument_types(env) 25925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.name == '<lambda>': 25935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_lambda_function(env) 25945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 25955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_pyfunction(env) 25965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 25975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.analyse_signature(env) 25985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.return_type = self.entry.signature.return_type() 25995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.create_local_scope(env) 26005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_wrapper = DefNodeWrapper( 26025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.pos, 26035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target=self, 26045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name=self.entry.name, 26055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args=self.args, 26065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) star_arg=self.star_arg, 26075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) starstar_arg=self.starstar_arg, 26085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return_type=self.return_type) 26095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_wrapper.analyse_declarations(env) 26105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_argument_types(self, env): 26125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.directive_locals = env.directives['locals'] 26135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) allow_none_for_extension_args = env.directives['allow_none_for_extension_args'] 26145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) f2s = env.fused_to_specific 26165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.fused_to_specific = None 26175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 26195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if hasattr(arg, 'name'): 26205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator = None 26215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 26225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = arg.base_type.analyse(env) 26235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name_declarator, type = \ 26245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.declarator.analyse(base_type, env) 26255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.name = name_declarator.name 26265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type = type 26275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.is_fused: 26295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.has_fused_arguments = True 26305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.align_argument_type(env, arg) 26325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name_declarator and name_declarator.cname: 26335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 26345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Python function argument cannot have C name specification") 26355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type = arg.type.as_argument_type() 26365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.hdr_type = None 26375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.needs_conversion = 0 26385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.needs_type_test = 0 26395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.is_generic = 1 26405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_pyobject or arg.type.is_buffer or arg.type.is_memoryviewslice: 26415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.or_none: 26425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.accept_none = True 26435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.not_none: 26445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.accept_none = False 26455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif (arg.type.is_extension_type or arg.type.is_builtin_type 26465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) or arg.type.is_buffer or arg.type.is_memoryviewslice): 26475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default and arg.default.constant_result is None: 26485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # special case: def func(MyType obj = None) 26495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.accept_none = True 26505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 26515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # default depends on compiler directive 26525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.accept_none = allow_none_for_extension_args 26535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 26545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # probably just a plain 'object' 26555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.accept_none = True 26565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 26575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.accept_none = True # won't be used, but must be there 26585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.not_none: 26595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Only Python type arguments can have 'not None'") 26605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.or_none: 26615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Only Python type arguments can have 'or None'") 26625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.fused_to_specific = f2s 26645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_signature(self, env): 26665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.entry.is_special: 26675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.decorators: 26685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "special functions of cdef classes cannot have decorators") 26695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg) 26705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg): 26715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Use the simpler calling signature for zero- and one-argument functions. 26725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.entry.signature is TypeSlots.pyfunction_signature: 26735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.args) == 0: 26745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.signature = TypeSlots.pyfunction_noargs 26755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif len(self.args) == 1: 26765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.args[0].default is None and not self.args[0].kw_only: 26775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.signature = TypeSlots.pyfunction_onearg 26785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.entry.signature is TypeSlots.pymethod_signature: 26795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.args) == 1: 26805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.signature = TypeSlots.unaryfunc 26815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif len(self.args) == 2: 26825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.args[1].default is None and not self.args[1].kw_only: 26835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.signature = TypeSlots.ibinaryfunc 26845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sig = self.entry.signature 26865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nfixed = sig.num_fixed_args() 26875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if sig is TypeSlots.pymethod_signature and nfixed == 1 \ 26885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and len(self.args) == 0 and self.star_arg: 26895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # this is the only case where a diverging number of 26905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # arguments is not an error - when we have no explicit 26915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 'self' parameter as in method(*args) 26925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used 26935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.self_in_stararg = 1 26945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nfixed = 0 26955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 26965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_staticmethod and env.is_c_class_scope: 26975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nfixed = 0 26985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.self_in_stararg = True # FIXME: why for staticmethods? 26995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 27005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.signature = sig = copy.copy(sig) 27015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sig.fixed_arg_format = "*" 27025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sig.is_staticmethod = True 27035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sig.has_generic_args = True 27045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 27055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((self.is_classmethod or self.is_staticmethod) and 27065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.has_fused_arguments and env.is_c_class_scope): 27075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) del self.decorator_indirection.stats[:] 27085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 27095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in range(min(nfixed, len(self.args))): 27105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg = self.args[i] 27115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.is_generic = 0 27125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if sig.is_self_arg(i) and not self.is_staticmethod: 27135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_classmethod: 27145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.is_type_arg = 1 27155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.hdr_type = arg.type = Builtin.type_type 27165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 27175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.is_self_arg = 1 27185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.hdr_type = arg.type = env.parent_type 27195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.needs_conversion = 0 27205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 27215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.hdr_type = sig.fixed_arg_type(i) 27225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.type.same_as(arg.hdr_type): 27235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.hdr_type.is_pyobject and arg.type.is_pyobject: 27245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.needs_type_test = 1 27255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 27265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.needs_conversion = 1 27275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.needs_conversion: 27285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.hdr_cname = Naming.arg_prefix + arg.name 27295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 27305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.hdr_cname = Naming.var_prefix + arg.name 27315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 27325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if nfixed > len(self.args): 27335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bad_signature() 27345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 27355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif nfixed < len(self.args): 27365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not sig.has_generic_args: 27375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bad_signature() 27385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 27395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.is_generic and \ 27405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (arg.type.is_extension_type or arg.type.is_builtin_type): 27415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.needs_type_test = 1 27425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 27435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def bad_signature(self): 27445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sig = self.entry.signature 27455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) expected_str = "%d" % sig.num_fixed_args() 27465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if sig.has_generic_args: 27475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) expected_str += " or more" 27485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.name 27495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name.startswith("__") and name.endswith("__"): 27505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) desc = "Special method" 27515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 27525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) desc = "Method" 27535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 27545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "%s %s has wrong number of arguments " 27555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "(%d declared, %s expected)" % ( 27565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) desc, self.name, len(self.args), expected_str)) 27575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 27585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_pyfunction(self, env): 27595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "DefNode.declare_pyfunction:", self.name, "in", env ### 27605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.name 27615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.lookup_here(name) 27625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry: 27635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.is_final_cmethod and not env.parent_type.is_final_type: 27645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Only final types can have final Python (def/cpdef) methods") 27655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (entry.type.is_cfunction and not entry.is_builtin_cmethod 27665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not self.is_wrapper): 27675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(self.pos, "Overriding cdef method with def method.", 5) 27685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper) 27695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = entry 27705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefix = env.next_id(env.scope_prefix) 27715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.pyfunc_cname = Naming.pyfunc_prefix + prefix + name 27725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if Options.docstrings: 27735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.doc = embed_position(self.pos, self.doc) 27745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.doc_cname = Naming.funcdoc_prefix + prefix + name 27755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.is_special: 27765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']): 27775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.wrapperbase_cname = None 27785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 27795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name 27805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 27815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.doc = None 27825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 27835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_lambda_function(self, env): 27845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.declare_lambda_function(self.lambda_name, self.pos) 27855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.doc = None 27865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = entry 27875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.pyfunc_cname = entry.cname 27885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 27895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_arguments(self, env): 27905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 27915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.name: 27925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Missing argument name") 27935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.needs_conversion: 27945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry = env.declare_var(arg.name, arg.type, arg.pos) 27955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_pyobject: 27965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry.init = "0" 27975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 27985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry = self.declare_argument(env, arg) 27995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry.is_arg = 1 28005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry.used = 1 28015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry.is_self_arg = arg.is_self_arg 28025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_python_arg(env, self.star_arg) 28035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_python_arg(env, self.starstar_arg) 28045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_python_arg(self, env, arg): 28065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg: 28075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if env.directives['infer_types'] != False: 28085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = PyrexTypes.unspecified_type 28095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 28105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = py_object_type 28115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.declare_var(arg.name, type, arg.pos) 28125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.is_arg = 1 28135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.used = 1 28145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.init = "0" 28155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.xdecref_cleanup = 1 28165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry = entry 28175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 28195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.local_scope.directives = env.directives 28205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.analyse_default_values(env) 28215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.needs_assignment_synthesis(env) and self.decorators: 28235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for decorator in self.decorators[::-1]: 28245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decorator.decorator = decorator.decorator.analyse_expressions(env) 28255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_wrapper.prepare_argument_coercion(env) 28275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 28285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def needs_assignment_synthesis(self, env, code=None): 28305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_wrapper or self.specialized_cpdefs or self.entry.is_fused_specialized: 28315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return False 28325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_staticmethod: 28335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return True 28345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.no_assignment_synthesis: 28355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return False 28365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Should enable for module level as well, that will require more testing... 28375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.entry.is_anonymous: 28385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return True 28395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if env.is_module_scope: 28405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code is None: 28415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return env.directives['binding'] 28425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 28435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return code.globalstate.directives['binding'] 28445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return env.is_py_class_scope or env.is_closure_scope 28455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def error_value(self): 28475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.entry.signature.error_value 28485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def caller_will_check_exceptions(self): 28505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.entry.signature.exception_check 28515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 28535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.defaults_getter: 28545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.defaults_getter.generate_function_definitions(env, code) 28555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Before closure cnames are mangled 28575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_wrapper_required: 28585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # func_cname might be modified by @cname 28595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_wrapper.func_cname = self.entry.func_cname 28605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_wrapper.generate_function_definitions(env, code) 28615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FuncDefNode.generate_function_definitions(self, env, code) 28625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_header(self, code, with_pymethdef, proto_only=0): 28645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if proto_only: 28655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_wrapper_required: 28665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_wrapper.generate_function_header( 28675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code, with_pymethdef, True) 28685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 28695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list = [] 28705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.entry.signature.has_dummy_arg: 28715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self_arg = 'PyObject *%s' % Naming.self_cname 28725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.needs_outer_scope: 28735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self_arg = 'CYTHON_UNUSED ' + self_arg 28745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append(self_arg) 28755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def arg_decl_code(arg): 28775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = arg.entry 28785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.in_closure: 28795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = entry.original_cname 28805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 28815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = entry.cname 28825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decl = entry.type.declaration_code(cname) 28835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not entry.cf_used: 28845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decl = 'CYTHON_UNUSED ' + decl 28855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return decl 28865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 28885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append(arg_decl_code(arg)) 28895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg: 28905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append(arg_decl_code(self.star_arg)) 28915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 28925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append(arg_decl_code(self.starstar_arg)) 28935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code = ', '.join(arg_code_list) 28945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dc = self.return_type.declaration_code(self.entry.pyfunc_cname) 28955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 28965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decls_code = code.globalstate['decls'] 28975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) preprocessor_guard = self.get_preprocessor_guard() 28985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if preprocessor_guard: 28995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decls_code.putln(preprocessor_guard) 29005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decls_code.putln( 29015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "static %s(%s); /* proto */" % (dc, arg_code)) 29025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if preprocessor_guard: 29035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decls_code.putln("#endif") 29045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("static %s(%s) {" % (dc, arg_code)) 29055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_declarations(self, env, code): 29075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 29085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_keyword_list(self, code): 29105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 29115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_parsing_code(self, env, code): 29135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Move arguments into closure if required 29145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def put_into_closure(entry): 29155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.in_closure: 29165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s = %s;' % (entry.cname, entry.original_cname)) 29175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_incref(entry) 29185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_giveref(entry) 29195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 29205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) put_into_closure(arg.entry) 29215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.star_arg, self.starstar_arg: 29225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg: 29235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) put_into_closure(arg.entry) 29245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_type_tests(self, code): 29265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 29275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class DefNodeWrapper(FuncDefNode): 29305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # DefNode python wrapper code generator 29315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defnode = None 29335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target = None # Target DefNode 29345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, *args, **kwargs): 29365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FuncDefNode.__init__(self, *args, **kwargs) 29375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_kwonly_args = self.target.num_kwonly_args 29385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_required_kw_args = self.target.num_required_kw_args 29395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_required_args = self.target.num_required_args 29405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.self_in_stararg = self.target.self_in_stararg 29415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.signature = None 29425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 29445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_entry = self.target.entry 29455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.name 29465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefix = env.next_id(env.scope_prefix) 29475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_entry.func_cname = Naming.pywrap_prefix + prefix + name 29485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_entry.pymethdef_cname = Naming.pymethdef_prefix + prefix + name 29495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.signature = target_entry.signature 29515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def prepare_argument_coercion(self, env): 29535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This is only really required for Cython utility code at this time, 29545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # everything else can be done during code generation. But we expand 29555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # all utility code here, simply because we cannot easily distinguish 29565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # different code types. 29575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 29585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.type.is_pyobject: 29595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.type.create_from_py_utility_code(env): 29605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass # will fail later 29615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.hdr_type and not arg.hdr_type.is_pyobject: 29625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.hdr_type.create_to_py_utility_code(env): 29635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass # will fail later 29645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def signature_has_nongeneric_args(self): 29665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) argcount = len(self.args) 29675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if argcount == 0 or ( 29685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) argcount == 1 and (self.args[0].is_self_arg or 29695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.args[0].is_type_arg)): 29705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0 29715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 1 29725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def signature_has_generic_args(self): 29745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.signature.has_generic_args 29755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_body(self, code): 29775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = [] 29785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.signature.has_dummy_arg: 29795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args.append(Naming.self_cname) 29805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 29815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.hdr_type and not (arg.type.is_memoryviewslice or 29825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type.is_struct or 29835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type.is_complex): 29845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args.append(arg.type.cast_code(arg.entry.cname)) 29855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 29865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args.append(arg.entry.cname) 29875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg: 29885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args.append(self.star_arg.entry.cname) 29895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 29905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args.append(self.starstar_arg.entry.cname) 29915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = ', '.join(args) 29925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.return_type.is_void: 29935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('%s = ' % Naming.retval_cname) 29945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s(%s);' % ( 29955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.entry.pyfunc_cname, args)) 29965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 29975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 29985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv = self.target.local_scope 29995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate C code for header and body of function 30005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 30015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 30025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* Python wrapper */") 30035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) preprocessor_guard = self.target.get_preprocessor_guard() 30045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if preprocessor_guard: 30055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(preprocessor_guard) 30065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.enter_cfunc_scope() 30085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.return_from_error_cleanup_label = code.new_label() 30095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_pymethdef = (self.target.needs_assignment_synthesis(env, code) or 30115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.pymethdef_required) 30125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_function_header(code, with_pymethdef) 30135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_argument_declarations(lenv, code) 30145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tempvardecl_code = code.insertion_point() 30155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 30175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) retval_init = ' = 0' 30185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 30195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) retval_init = '' 30205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.return_type.is_void: 30215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s%s;' % ( 30225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.return_type.declaration_code(Naming.retval_cname), 30235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) retval_init)) 30245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_declare_refcount_context() 30255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_setup_refcount_context('%s (wrapper)' % self.name) 30265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_argument_parsing_code(lenv, code) 30285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_argument_type_tests(code) 30295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_function_body(code) 30305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Go back and insert temp variable declarations 30325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tempvardecl_code.put_temp_declarations(code.funcstate) 30335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 30355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 30365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* function exit code */") 30375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Error cleanup 30395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.error_label in code.labels_used: 30405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.return_label) 30415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.error_label) 30425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cname, type in code.funcstate.all_managed_temps(): 30435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref(cname, type) 30445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err_val = self.error_value() 30455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if err_val is not None: 30465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (Naming.retval_cname, err_val)) 30475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Non-error return cleanup 30495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.return_label) 30505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in lenv.var_entries: 30515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.is_arg and entry.type.is_pyobject: 30525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_decref(entry) 30535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_finish_refcount_context() 30555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.return_type.is_void: 30565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("return %s;" % Naming.retval_cname) 30575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 30585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.exit_cfunc_scope() 30595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if preprocessor_guard: 30605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#endif /*!(%s)*/" % preprocessor_guard) 30615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_header(self, code, with_pymethdef, proto_only=0): 30635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list = [] 30645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sig = self.signature 30655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if sig.has_dummy_arg or self.self_in_stararg: 30675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code = "PyObject *%s" % Naming.self_cname 30685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not sig.has_dummy_arg: 30695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code = 'CYTHON_UNUSED ' + arg_code 30705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append(arg_code) 30715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 30735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.is_generic: 30745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.is_self_arg or arg.is_type_arg: 30755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append("PyObject *%s" % arg.hdr_cname) 30765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 30775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append( 30785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.hdr_type.declaration_code(arg.hdr_cname)) 30795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = self.target.entry 30805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]: 30815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append("CYTHON_UNUSED PyObject *unused") 30825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.scope.is_c_class_scope and entry.name == "__ipow__": 30835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append("CYTHON_UNUSED PyObject *unused") 30845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if sig.has_generic_args: 30855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code_list.append( 30865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "PyObject *%s, PyObject *%s" 30875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) % (Naming.args_cname, Naming.kwds_cname)) 30885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_code = ", ".join(arg_code_list) 30895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Prevent warning: unused function '__pyx_pw_5numpy_7ndarray_1__getbuffer__' 30915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) mf = "" 30925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (entry.name in ("__getbuffer__", "__releasebuffer__") 30935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and entry.scope.is_c_class_scope): 30945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) mf = "CYTHON_UNUSED " 30955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with_pymethdef = False 30965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 30975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dc = self.return_type.declaration_code(entry.func_cname) 30985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) header = "static %s%s(%s)" % (mf, dc, arg_code) 30995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s; /*proto*/" % header) 31005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if proto_only: 31025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target.fused_py_func: 31035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # If we are the specialized version of the cpdef, we still 31045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # want the prototype for the "fused cpdef", in case we're 31055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # checking to see if our method was overridden in Python 31065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.fused_py_func.generate_function_header( 31075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code, with_pymethdef, proto_only=True) 31085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 31095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (Options.docstrings and entry.doc and 31115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not self.target.fused_py_func and 31125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not entry.scope.is_property_scope and 31135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (not entry.is_special or entry.wrapperbase_cname)): 31145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # h_code = code.globalstate['h_code'] 31155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) docstr = entry.doc 31165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if docstr.is_unicode: 31185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) docstr = docstr.utf8encode() 31195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 31215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'static char %s[] = "%s";' % ( 31225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.doc_cname, 31235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) split_string_literal(escape_byte_string(docstr)))) 31245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.is_special: 31265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('#if CYTHON_COMPILING_IN_CPYTHON') 31275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 31285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "struct wrapperbase %s;" % entry.wrapperbase_cname) 31295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('#endif') 31305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if with_pymethdef or self.target.fused_py_func: 31325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put( 31335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "static PyMethodDef %s = " % 31345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.pymethdef_cname) 31355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_pymethoddef(self.target.entry, ";", allow_skip=False) 31365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s {" % header) 31375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_declarations(self, env, code): 31395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 31405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.is_generic: 31415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.needs_conversion: 31425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("PyObject *%s = 0;" % arg.hdr_cname) 31435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 31445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_declaration(arg.entry) 31455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in env.var_entries: 31465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.is_arg: 31475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_declaration(entry) 31485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_parsing_code(self, env, code): 31505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate fast equivalent of PyArg_ParseTuple call for 31515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # generic arguments, if any, including args/kwargs 31525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_error_label = code.new_error_label() 31535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) our_error_label = code.error_label 31545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_label = code.new_label("argument_unpacking_done") 31555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_kwonly_args = self.num_kwonly_args > 0 31575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_star_or_kw_args = self.star_arg is not None \ 31585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) or self.starstar_arg is not None or has_kwonly_args 31595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 31615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.type.is_pyobject: 31625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.type.create_from_py_utility_code(env): 31635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass # will fail later 31645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.signature_has_generic_args(): 31665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if has_star_or_kw_args: 31675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "This method cannot have * or keyword arguments") 31685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_argument_conversion_code(code) 31695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif not self.signature_has_nongeneric_args(): 31715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # func(*args) or func(**kw) or func(*args, **kw) 31725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_stararg_copy_code(code) 31735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 31755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_tuple_and_keyword_parsing_code(self.args, end_label, code) 31765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_label = old_error_label 31785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(our_error_label): 31795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not code.label_used(end_label): 31805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(end_label) 31815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(our_error_label) 31825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if has_star_or_kw_args: 31835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_decref(self.star_arg, code) 31845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 31855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg.entry.xdecref_cleanup: 31865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_xdecref_clear(self.starstar_arg.entry) 31875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 31885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_decref_clear(self.starstar_arg.entry) 31895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_add_traceback(self.target.entry.qualified_name) 31905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_finish_refcount_context() 31915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("return %s;" % self.error_value()) 31925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(end_label): 31935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(end_label) 31945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_arg_xdecref(self, arg, code): 31965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg: 31975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_xdecref_clear(arg.entry) 31985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 31995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_arg_decref(self, arg, code): 32005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg: 32015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_decref_clear(arg.entry) 32025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 32035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_stararg_copy_code(self, code): 32045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.star_arg: 32055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 32065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c")) 32075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" % 32085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.args_cname) 32095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % ( 32105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, Naming.args_cname, self.error_value())) 32115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 32125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 32135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 32145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg: 32155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kwarg_check = "unlikely(%s)" % Naming.kwds_cname 32165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 32175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kwarg_check = "%s" % Naming.kwds_cname 32185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 32195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % ( 32205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.kwds_cname, Naming.kwds_cname) 32215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 32225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("KeywordStringCheck", "FunctionArguments.c")) 32235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 32245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % ( 32255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kwarg_check, Naming.kwds_cname, self.name, 32265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool(self.starstar_arg), self.error_value())) 32275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 32285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 32295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % ( 32305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.starstar_arg.entry.cname, 32315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.kwds_cname, 32325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.kwds_cname)) 32335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (unlikely(!%s)) return %s;" % ( 32345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.starstar_arg.entry.cname, self.error_value())) 32355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.starstar_arg.entry.xdecref_cleanup = 0 32365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(self.starstar_arg.entry.cname) 32375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 32385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.self_in_stararg and not self.target.is_staticmethod: 32395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # need to create a new tuple with 'self' inserted as first item 32405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % ( 32415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.cname, 32425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.args_cname, 32435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.cname)) 32445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 32455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("{") 32465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type) 32475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("return %s;" % self.error_value()) 32485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 32495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 32505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("return %s;" % self.error_value()) 32515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(self.star_arg.entry.cname) 32525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_incref(Naming.self_cname, py_object_type) 32535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref(Naming.self_cname) 32545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % ( 32555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.cname, Naming.self_cname)) 32565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False) 32575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % ( 32585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp, temp, Naming.args_cname, temp)) 32595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % ( 32605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.args_cname, temp)) 32615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_incref("item", py_object_type) 32625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref("item") 32635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % ( 32645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.cname, temp)) 32655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 32665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(temp) 32675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.xdecref_cleanup = 0 32685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.star_arg: 32695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_incref(Naming.args_cname, py_object_type) 32705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % ( 32715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.cname, 32725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.args_cname)) 32735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.xdecref_cleanup = 0 32745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 32755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_tuple_and_keyword_parsing_code(self, args, success_label, code): 32765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) argtuple_error_label = code.new_label("argtuple_error") 32775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 32785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) positional_args = [] 32795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) required_kw_only_args = [] 32805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) optional_kw_only_args = [] 32815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in args: 32825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.is_generic: 32835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default: 32845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.is_self_arg and not arg.is_type_arg: 32855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.kw_only: 32865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) optional_kw_only_args.append(arg) 32875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 32885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) positional_args.append(arg) 32895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.kw_only: 32905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) required_kw_only_args.append(arg) 32915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif not arg.is_self_arg and not arg.is_type_arg: 32925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) positional_args.append(arg) 32935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 32945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # sort required kw-only args before optional ones to avoid special 32955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cases in the unpacking code 32965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kw_only_args = required_kw_only_args + optional_kw_only_args 32975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 32985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) min_positional_args = self.num_required_args - self.num_required_kw_args 32995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(args) > 0 and (args[0].is_self_arg or args[0].is_type_arg): 33005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) min_positional_args -= 1 33015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max_positional_args = len(positional_args) 33025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_fixed_positional_count = not self.star_arg and \ 33035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) min_positional_args == max_positional_args 33045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_kw_only_args = bool(kw_only_args) 33055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 33065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.num_required_kw_args: 33075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 33085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("RaiseKeywordRequired", "FunctionArguments.c")) 33095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 33105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg or self.star_arg: 33115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_stararg_init_code(max_positional_args, code) 33125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 33135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('{') 33145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) all_args = tuple(positional_args) + tuple(kw_only_args) 33155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("static PyObject **%s[] = {%s,0};" % ( 33165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.pykwdlist_cname, 33175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ','.join([ '&%s' % code.intern_identifier(arg.name) 33185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in all_args ]))) 33195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 33205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Before being converted and assigned to the target variables, 33215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # borrowed references to all unpacked argument values are 33225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # collected into a local PyObject* array called "values", 33235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # regardless if they were taken from default arguments, 33245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # positional arguments or keyword arguments. Note that 33255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # C-typed default arguments are handled at conversion time, 33265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # so their array value is NULL in the end if no argument 33275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # was passed for them. 33285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_argument_values_setup_code(all_args, code) 33295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 33305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # --- optimised code when we receive keyword arguments 33315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (%s(%s)) {" % ( 33325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self.num_required_kw_args > 0) and "likely" or "unlikely", 33335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.kwds_cname)) 33345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_keyword_unpacking_code( 33355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) min_positional_args, max_positional_args, 33365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_fixed_positional_count, has_kw_only_args, 33375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) all_args, argtuple_error_label, code) 33385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 33395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # --- optimised code when we do not receive any keyword arguments 33405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args: 33415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Python raises arg tuple related errors first, so we must 33425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # check the length here 33435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if min_positional_args == max_positional_args and not self.star_arg: 33445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) compare = '!=' 33455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 33465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) compare = '<' 33475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % ( 33485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.args_cname, compare, min_positional_args)) 33495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(argtuple_error_label) 33505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 33515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.num_required_kw_args: 33525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # pure error case: keywords required but not passed 33535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if max_positional_args > min_positional_args and not self.star_arg: 33545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % ( 33555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.args_cname, max_positional_args)) 33565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(argtuple_error_label) 33575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('} else {') 33585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(kw_only_args): 33595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.default: 33605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pystring_cname = code.intern_identifier(arg.name) 33615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # required keyword-only argument missing 33625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % ( 33635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, 33645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pystring_cname)) 33655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(code.error_goto(self.pos)) 33665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break 33675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 33685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 33695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # optimised tuple unpacking code 33705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('} else {') 33715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if min_positional_args == max_positional_args: 33725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # parse the exact number of positional arguments from 33735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # the args tuple 33745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(positional_args): 33755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (i, Naming.args_cname, i)) 33765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 33775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # parse the positional arguments from the variable length 33785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # args tuple and reject illegal argument tuple sizes 33795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname) 33805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg: 33815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('default:') 33825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reversed_args = list(enumerate(positional_args))[::-1] 33835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in reversed_args: 33845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if i >= min_positional_args-1: 33855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('case %2d: ' % (i+1)) 33865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (i, Naming.args_cname, i)) 33875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if min_positional_args == 0: 33885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('case 0: ') 33895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('break;') 33905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg: 33915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if min_positional_args: 33925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in range(min_positional_args-1, -1, -1): 33935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('case %2d:' % i) 33945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(argtuple_error_label) 33955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 33965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('default: ') 33975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(argtuple_error_label) 33985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 33995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') # end of the conditional unpacking blocks 34015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Convert arg values to their final type and assign them. 34035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Also inject non-Python default arguments, which do cannot 34045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # live in the values[] array. 34055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(all_args): 34065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_assignment(arg, "values[%d]" % i, code) 34075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') # end of the whole argument unpacking block 34095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(argtuple_error_label): 34115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(success_label) 34125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(argtuple_error_label) 34135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 34145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c")) 34155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % ( 34165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, has_fixed_positional_count, 34175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) min_positional_args, max_positional_args, 34185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.args_cname)) 34195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(code.error_goto(self.pos)) 34205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_arg_assignment(self, arg, item, code): 34225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_pyobject: 34235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Python default arguments were already stored in 'item' at the very beginning 34245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.is_generic: 34255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item) 34265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = arg.entry 34275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (entry.cname, item)) 34285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 34295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func = arg.type.from_py_function 34305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func: 34315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default: 34325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # C-typed default arguments must be handled here 34335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (%s) {' % item) 34345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = "%s(%s)" % (func, item) 34355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_enum: 34365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = arg.type.cast_code(rhs) 34375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s; %s" % ( 34385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry.cname, 34395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs, 34405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos))) 34415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default: 34425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('} else {') 34435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 34445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "%s = %s;" % ( 34455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry.cname, 34465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.calculate_default_value_code(code))) 34475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_memoryviewslice: 34485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_incref_memoryviewslice(arg.entry.cname, 34495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) have_gil=True) 34505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 34515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 34525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type) 34535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_stararg_init_code(self, max_positional_args, code): 34555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 34565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.starstar_arg.entry.xdecref_cleanup = 0 34575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % ( 34585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.starstar_arg.entry.cname, 34595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.starstar_arg.entry.cname, 34605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.error_value())) 34615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(self.starstar_arg.entry.cname) 34625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg: 34635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.xdecref_cleanup = 0 34645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % ( 34655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.args_cname, 34665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max_positional_args)) 34675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % ( 34685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.star_arg.entry.cname, Naming.args_cname, 34695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max_positional_args, Naming.args_cname)) 34705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname) 34715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.starstar_arg: 34725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type) 34735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_finish_refcount_context() 34745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('return %s;' % self.error_value()) 34755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 34765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(self.star_arg.entry.cname) 34775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('} else {') 34785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple)) 34795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_incref(Naming.empty_tuple, py_object_type) 34805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 34815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_values_setup_code(self, args, code): 34835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max_args = len(args) 34845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # the 'values' array collects borrowed references to arguments 34855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # before doing any type coercion etc. 34865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("PyObject* values[%d] = {%s};" % ( 34875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max_args, ','.join('0'*max_args))) 34885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target.defaults_struct: 34905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s *%s = __Pyx_CyFunction_Defaults(%s, %s);' % ( 34915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.defaults_struct, Naming.dynamic_args_cname, 34925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.defaults_struct, Naming.self_cname)) 34935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 34945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # assign borrowed Python default values to the values array, 34955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # so that they can be overwritten by received arguments below 34965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(args): 34975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default and arg.type.is_pyobject: 34985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_value = arg.calculate_default_value_code(code) 34995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value))) 35005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 35015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args, 35025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_fixed_positional_count, has_kw_only_args, 35035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) all_args, argtuple_error_label, code): 35045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('Py_ssize_t kw_args;') 35055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('const Py_ssize_t pos_args = PyTuple_GET_SIZE(%s);' % Naming.args_cname) 35065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # copy the values from the args tuple and check that it's not too long 35075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('switch (pos_args) {') 35085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg: 35095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('default:') 35105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in range(max_positional_args-1, -1, -1): 35115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('case %2d: ' % (i+1)) 35125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % ( 35135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i, Naming.args_cname, i)) 35145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('case 0: break;') 35155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.star_arg: 35165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('default: ') # more arguments than allowed 35175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(argtuple_error_label) 35185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 35195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 35205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The code above is very often (but not always) the same as 35215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # the optimised non-kwargs tuple unpacking code, so we keep 35225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # the code block above at the very top, before the following 35235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 'external' PyDict_Size() call, to make it easy for the C 35245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # compiler to merge the two separate tuple unpacking 35255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # implementations into one when they turn out to be identical. 35265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 35275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # If we received kwargs, fill up the positional/required 35285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # arguments with values from the kw dict 35295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('kw_args = PyDict_Size(%s);' % Naming.kwds_cname) 35305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.num_required_args or max_positional_args > 0: 35315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_required_arg = -1 35325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(all_args): 35335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.default: 35345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_required_arg = i 35355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if last_required_arg < max_positional_args: 35365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_required_arg = max_positional_args-1 35375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if max_positional_args > 0: 35385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('switch (pos_args) {') 35395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(all_args[:last_required_arg+1]): 35405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if max_positional_args > 0 and i <= max_positional_args: 35415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.star_arg and i == max_positional_args: 35425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('default:') 35435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 35445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('case %2d:' % i) 35455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pystring_cname = code.intern_identifier(arg.name) 35465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default: 35475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.kw_only: 35485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # optional kw-only args are handled separately below 35495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 35505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (kw_args > 0) {') 35515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # don't overwrite default argument 35525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % ( 35535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.kwds_cname, pystring_cname)) 35545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (value) { values[%d] = value; kw_args--; }' % i) 35555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 35565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 35575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (likely((values[%d] = PyDict_GetItem(%s, %s)) != 0)) kw_args--;' % ( 35585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i, Naming.kwds_cname, pystring_cname)) 35595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if i < min_positional_args: 35605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if i == 0: 35615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # special case: we know arg 0 is missing 35625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('else ') 35635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(argtuple_error_label) 35645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 35655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # print the correct number of values (args or 35665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # kwargs) that were passed into positional 35675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # arguments up to this point 35685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('else {') 35695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 35705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c")) 35715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % ( 35725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, has_fixed_positional_count, 35735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) min_positional_args, max_positional_args, i)) 35745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(code.error_goto(self.pos)) 35755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 35765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.kw_only: 35775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('else {') 35785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %( 35795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, pystring_cname)) 35805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(code.error_goto(self.pos)) 35815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 35825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if max_positional_args > 0: 35835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 35845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 35855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if has_kw_only_args: 35865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # unpack optional keyword-only arguments separately because 35875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # checking for interned strings in a dict is faster than iterating 35885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_optional_kwonly_args_unpacking_code(all_args, code) 35895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 35905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (unlikely(kw_args > 0)) {') 35915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # non-positional/-required kw args left in dict: default args, 35925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # kw-only args, **kwargs or error 35935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 35945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This is sort of a catch-all: except for checking required 35955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # arguments, this will always do the right thing for unpacking 35965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # keyword arguments, so that we can concentrate on optimising 35975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # common cases above. 35985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if max_positional_args == 0: 35995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_arg_count = "0" 36005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.star_arg: 36015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("const Py_ssize_t used_pos_args = (pos_args < %d) ? pos_args : %d;" % ( 36025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max_positional_args, max_positional_args)) 36035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_arg_count = "used_pos_args" 36045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 36055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_arg_count = "pos_args" 36065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 36075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("ParseKeywords", "FunctionArguments.c")) 36085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 36095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) %s' % ( 36105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.kwds_cname, 36115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.pykwdlist_cname, 36125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.starstar_arg and self.starstar_arg.entry.cname or '0', 36135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_arg_count, 36145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name, 36155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(self.pos))) 36165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 36175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 36185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_optional_kwonly_args_unpacking_code(self, all_args, code): 36195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) optional_args = [] 36205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first_optional_arg = -1 36215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(all_args): 36225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not arg.kw_only or not arg.default: 36235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 36245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not optional_args: 36255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first_optional_arg = i 36265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) optional_args.append(arg.name) 36275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if optional_args: 36285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(optional_args) > 1: 36295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # if we receive more than the named kwargs, we either have **kwargs 36305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (in which case we must iterate anyway) or it's an error (which we 36315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # also handle during iteration) => skip this part if there are more 36325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (kw_args > 0 && %s(kw_args <= %d)) {' % ( 36335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not self.starstar_arg and 'likely' or '', 36345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) len(optional_args))) 36355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('Py_ssize_t index;') 36365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # not unrolling the loop here reduces the C code overhead 36375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('for (index = %d; index < %d && kw_args > 0; index++) {' % ( 36385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first_optional_arg, first_optional_arg + len(optional_args))) 36395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 36405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (kw_args == 1) {') 36415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('const Py_ssize_t index = %d;' % first_optional_arg) 36425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('PyObject* value = PyDict_GetItem(%s, *%s[index]);' % ( 36435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.kwds_cname, Naming.pykwdlist_cname)) 36445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('if (value) { values[index] = value; kw_args--; }') 36455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(optional_args) > 1: 36465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 36475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 36485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 36495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_conversion_code(self, code): 36505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate code to convert arguments from signature type to 36515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # declared type, if needed. Also copies signature arguments 36525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # into closure fields. 36535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 36545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.needs_conversion: 36555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_conversion(arg, code) 36565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 36575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_arg_conversion(self, arg, code): 36585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate conversion code for one argument. 36595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_type = arg.hdr_type 36605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_type = arg.type 36615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if old_type.is_pyobject: 36625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.default: 36635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (%s) {" % arg.hdr_cname) 36645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 36655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("assert(%s); {" % arg.hdr_cname) 36665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_conversion_from_pyobject(arg, code) 36675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 36685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif new_type.is_pyobject: 36695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_conversion_to_pyobject(arg, code) 36705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 36715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if new_type.assignable_from(old_type): 36725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 36735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "%s = %s;" % (arg.entry.cname, arg.hdr_cname)) 36745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 36755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, 36765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Cannot convert 1 argument from '%s' to '%s'" % 36775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (old_type, new_type)) 36785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 36795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_arg_conversion_from_pyobject(self, arg, code): 36805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_type = arg.type 36815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func = new_type.from_py_function 36825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # copied from CoerceFromPyTypeNode 36835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func: 36845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs = arg.entry.cname 36855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = "%s(%s)" % (func, arg.hdr_cname) 36865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if new_type.is_enum: 36875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs) 36885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s; %s" % ( 36895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs, 36905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs, 36915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos))) 36925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 36935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, 36945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Cannot convert Python object argument to type '%s'" 36955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) % new_type) 36965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 36975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_arg_conversion_to_pyobject(self, arg, code): 36985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_type = arg.hdr_type 36995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func = old_type.to_py_function 37005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func: 37015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s(%s); %s" % ( 37025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.entry.cname, 37035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func, 37045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.hdr_cname, 37055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if_null(arg.entry.cname, arg.pos))) 37065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_var_gotref(arg.entry) 37075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 37085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, 37095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Cannot convert argument of type '%s' to Python object" 37105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) % old_type) 37115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_argument_type_tests(self, code): 37135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate type tests for args whose signature 37145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # type is PyObject * and whose declared type is 37155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # a subtype thereof. 37165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 37175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.needs_type_test: 37185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_type_test(arg, code) 37195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif not arg.accept_none and (arg.type.is_pyobject or 37205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type.is_buffer or 37215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type.is_memoryviewslice): 37225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_arg_none_check(arg, code) 37235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def error_value(self): 37255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.signature.error_value 37265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class GeneratorDefNode(DefNode): 37295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generator function node that creates a new generator instance when called. 37305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 37315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # gbody GeneratorBodyDefNode the function implementing the generator 37325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 37335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_generator = True 37355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) needs_closure = True 37365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = DefNode.child_attrs + ["gbody"] 37385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, **kwargs): 37405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # XXX: don't actually needs a body 37415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kwargs['body'] = StatListNode(kwargs['pos'], stats=[]) 37425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(GeneratorDefNode, self).__init__(**kwargs) 37435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 37455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(GeneratorDefNode, self).analyse_declarations(env) 37465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.gbody.local_scope = self.local_scope 37475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.gbody.analyse_declarations(env) 37485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_body(self, env, code): 37505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body_cname = self.gbody.entry.func_cname 37515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('{') 37535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('__pyx_GeneratorObject *gen = __Pyx_Generator_New(' 37545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '(__pyx_generator_body_t) %s, (PyObject *) %s); %s' % ( 37555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body_cname, Naming.cur_scope_cname, 37565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if_null('gen', self.pos))) 37575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref(Naming.cur_scope_cname, py_object_type) 37585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.requires_classobj: 37595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) classobj_cname = 'gen->classobj' 37605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s = __Pyx_CyFunction_GetClassObj(%s);' % ( 37615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) classobj_cname, Naming.self_cname)) 37625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_incref(classobj_cname, py_object_type) 37635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref(classobj_cname) 37645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_finish_refcount_context() 37655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('return (PyObject *) gen;') 37665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 37675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 37695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(UtilityCode.load_cached("Generator", "Generator.c")) 37705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.gbody.generate_function_header(code, proto=True) 37725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(GeneratorDefNode, self).generate_function_definitions(env, code) 37735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.gbody.generate_function_definitions(env, code) 37745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class GeneratorBodyDefNode(DefNode): 37775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Main code body of a generator implemented as a DefNode. 37785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 37795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_generator_body = True 37815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, pos=None, name=None, body=None): 37835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(GeneratorBodyDefNode, self).__init__( 37845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos=pos, body=body, name=name, doc=None, 37855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args=[], star_arg=None, starstar_arg=None) 37865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_generator_body(self, env): 37885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefix = env.next_id(env.scope_prefix) 37895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = env.next_id('generator') 37905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = Naming.genbody_prefix + prefix + name 37915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.declare_var(None, py_object_type, self.pos, 37925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname=cname, visibility='private') 37935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.func_cname = cname 37945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.qualified_name = EncodedString(self.name) 37955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = entry 37965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 37975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 37985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.analyse_argument_types(env) 37995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_generator_body(env) 38005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_header(self, code, proto=False): 38025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) header = "static PyObject *%s(__pyx_GeneratorObject *%s, PyObject *%s)" % ( 38035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.func_cname, 38045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.generator_cname, 38055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.sent_value_cname) 38065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if proto: 38075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s; /* proto */' % header) 38085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 38095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s /* generator body */\n{' % header) 38105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 38125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv = self.local_scope 38135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate closure function definitions 38155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(lenv, code) 38165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generate C code for header and body of function 38185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.enter_cfunc_scope() 38195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.return_from_error_cleanup_label = code.new_label() 38205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Top-level constants used by this function 38225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 38235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_cached_builtins_decls(lenv, code) 38245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Function header 38255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 38265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_function_header(code) 38275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) closure_init_code = code.insertion_point() 38285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Local variables 38295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("PyObject *%s = NULL;" % Naming.retval_cname) 38305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tempvardecl_code = code.insertion_point() 38315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_declare_refcount_context() 38325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_setup_refcount_context(self.entry.name) 38335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Resume switch point. 38355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.init_closure_temps(lenv.scope_class.type.scope) 38365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resume_code = code.insertion_point() 38375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first_run_label = code.new_label('first_run') 38385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.use_label(first_run_label) 38395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(first_run_label) 38405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s' % 38415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (code.error_goto_if_null(Naming.sent_value_cname, self.pos))) 38425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Function body 38445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_function_body(env, code) 38455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Closure initialization 38465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if lenv.scope_class.type.scope.entries: 38475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) closure_init_code.putln('%s = %s;' % ( 38485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.scope_class.type.declaration_code(Naming.cur_scope_cname), 38495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lenv.scope_class.type.cast_code('%s->closure' % 38505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.generator_cname))) 38515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 38535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 38545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* function exit code */") 38555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # on normal generator termination, we do not take the exception propagation 38575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # path: no traceback info is required and not creating it is much faster 38585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.body.is_terminator: 38595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('PyErr_SetNone(PyExc_StopIteration);') 38605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Error cleanup 38615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.error_label in code.labels_used: 38625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.body.is_terminator: 38635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.return_label) 38645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.error_label) 38655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cname, type in code.funcstate.all_managed_temps(): 38665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref(cname, type) 38675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_add_traceback(self.entry.qualified_name) 38685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Non-error return cleanup 38705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.return_label) 38715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref(Naming.retval_cname, py_object_type) 38725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('%s->resume_label = -1;' % Naming.generator_cname) 38735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # clean up as early as possible to help breaking any reference cycles 38745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('__Pyx_Generator_clear((PyObject*)%s);' % Naming.generator_cname) 38755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_finish_refcount_context() 38765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('return NULL;') 38775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 38785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Go back and insert temp variable declarations 38805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tempvardecl_code.put_temp_declarations(code.funcstate) 38815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ----- Generator resume code 38825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resume_code.putln("switch (%s->resume_label) {" % ( 38835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.generator_cname)) 38845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resume_code.putln("case 0: goto %s;" % first_run_label) 38855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, label in code.yield_labels: 38875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resume_code.putln("case %d: goto %s;" % (i, label)) 38885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resume_code.putln("default: /* CPython raises the right error here */") 38895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resume_code.put_finish_refcount_context() 38905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resume_code.putln("return NULL;") 38915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resume_code.putln("}") 38925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.exit_cfunc_scope() 38945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 38965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class OverrideCheckNode(StatNode): 38975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # A Node for dispatching to the def method if it 38985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is overriden. 38995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 39005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # py_func 39015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 39025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # args 39035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # func_temp 39045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body 39055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['body'] 39075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body = None 39095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 39115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.args = env.arg_entries 39125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_func.is_module_scope: 39135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first_arg = 0 39145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 39155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first_arg = 1 39165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 39175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type) 39185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) call_node = ExprNodes.SimpleCallNode( 39195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.pos, function=self.func_node, 39205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args=[ ExprNodes.NameNode(self.pos, name=arg.name) 39215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args[first_arg:] ]) 39225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = ReturnStatNode(self.pos, value=call_node) 39235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 39245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 39255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 39275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) interned_attr_cname = code.intern_identifier(self.py_func.entry.name) 39285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Check to see if we are an extension type 39295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_func.is_module_scope: 39305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self_arg = "((PyObject *)%s)" % Naming.module_cname 39315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 39325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self_arg = "((PyObject *)%s)" % self.args[0].cname 39335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* Check if called by wrapper */") 39345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname) 39355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* Check if overridden in Python */") 39365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_func.is_module_scope: 39375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("else {") 39385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 39395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg) 39405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) 39415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.func_node.set_cname(func_node_temp) 39425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # need to get attribute manually--scope would return cdef method 39435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 39445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c")) 39455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) err = code.error_goto_if_null(func_node_temp, self.pos) 39465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = __Pyx_PyObject_GetAttrStr(%s, %s); %s" % ( 39475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_node_temp, self_arg, interned_attr_cname, err)) 39485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(func_node_temp) 39495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp 39505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (PyCFunction)%s)" % ( 39515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_node_temp, self.py_func.entry.func_cname) 39525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden)) 39535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 39545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 39555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type) 39565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(func_node_temp) 39575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 39585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ClassDefNode(StatNode, BlockNode): 39605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 39615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class PyClassDefNode(ClassDefNode): 39635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # A Python class definition. 39645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 39655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name EncodedString Name of the class 39665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # doc string or None 39675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode Attribute definition code 39685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # entry Symtab.Entry 39695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # scope PyClassScope 39705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # decorators [DecoratorNode] list of decorators or None 39715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 39725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The following subnodes are constructed internally: 39735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 39745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # dict DictNode Class dictionary or Py3 namespace 39755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # classobj ClassNode Class object 39765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # target NameNode Variable to assign class object to 39775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "class_result", 39795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "target", "class_cell", "decorators"] 39805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decorators = None 39815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) class_result = None 39825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_py3_style_class = False # Python3 style class (kwargs) 39835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) metaclass = None 39845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) mkw = None 39855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 39865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, pos, name, bases, doc, body, decorators=None, 39875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) keyword_args=None, starstar_arg=None, force_py3_semantics=False): 39885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) StatNode.__init__(self, pos) 39895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.name = name 39905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.doc = doc 39915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = body 39925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.decorators = decorators 39935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bases = bases 39945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 39955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.doc and Options.docstrings: 39965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc = embed_position(self.pos, self.doc) 39975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc_node = ExprNodes.StringNode(pos, value=doc) 39985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 39995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc_node = None 40005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 40015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) allow_py2_metaclass = not force_py3_semantics 40025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if keyword_args or starstar_arg: 40035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) allow_py2_metaclass = False 40045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_py3_style_class = True 40055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if keyword_args and not starstar_arg: 40065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]: 40075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if item.key.value == 'metaclass': 40085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.metaclass is not None: 40095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(item.pos, "keyword argument 'metaclass' passed multiple times") 40105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # special case: we already know the metaclass, 40115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # so we don't need to do the "build kwargs, 40125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # find metaclass" dance at runtime 40135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.metaclass = item.value 40145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) del keyword_args.key_value_pairs[i] 40155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if starstar_arg: 40165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.mkw = ExprNodes.KeywordArgsNode( 40175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos, keyword_args=keyword_args and keyword_args.key_value_pairs or [], 40185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) starstar_arg=starstar_arg) 40195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif keyword_args.key_value_pairs: 40205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.mkw = keyword_args 40215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 40225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assert self.metaclass is not None 40235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 40245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if force_py3_semantics or self.bases or self.mkw or self.metaclass: 40255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.metaclass is None: 40265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if starstar_arg: 40275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # **kwargs may contain 'metaclass' arg 40285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) mkdict = self.mkw 40295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 40305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) mkdict = None 40315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (not mkdict and 40325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bases.is_sequence_constructor and 40335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not self.bases.args): 40345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass # no base classes => no inherited metaclass 40355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 40365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.metaclass = ExprNodes.PyClassMetaclassNode( 40375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos, mkw=mkdict, bases=self.bases) 40385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) needs_metaclass_calculation = False 40395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 40405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) needs_metaclass_calculation = True 40415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 40425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict = ExprNodes.PyClassNamespaceNode( 40435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos, name=name, doc=doc_node, 40445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) metaclass=self.metaclass, bases=self.bases, mkw=self.mkw) 40455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.classobj = ExprNodes.Py3ClassNode( 40465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos, name=name, 40475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bases=self.bases, dict=self.dict, doc=doc_node, 40485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) metaclass=self.metaclass, mkw=self.mkw, 40495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) calculate_metaclass=needs_metaclass_calculation, 40505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) allow_py2_metaclass=allow_py2_metaclass) 40515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 40525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # no bases, no metaclass => old style class creation 40535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict = ExprNodes.DictNode(pos, key_value_pairs=[]) 40545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.classobj = ExprNodes.ClassNode( 40555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos, name=name, 40565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bases=bases, dict=self.dict, doc=doc_node) 40575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 40585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target = ExprNodes.NameNode(pos, name=name) 40595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_cell = ExprNodes.ClassCellInjectorNode(self.pos) 40605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 40615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def as_cclass(self): 40625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 40635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Return this node as if it were declared as an extension class 40645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 40655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_py3_style_class: 40665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.classobj.pos, "Python3 style class could not be represented as C class") 40675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 40685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bases = self.classobj.bases.args 40695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(bases) == 0: 40705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_name = None 40715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_module = None 40725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif len(bases) == 1: 40735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base = bases[0] 40745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) path = [] 40755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from ExprNodes import AttributeNode, NameNode 40765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while isinstance(base, AttributeNode): 40775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) path.insert(0, base.attribute) 40785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base = base.obj 40795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(base, NameNode): 40805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) path.insert(0, base.name) 40815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_name = path[-1] 40825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(path) > 1: 40835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_module = u'.'.join(path[:-1]) 40845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 40855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_module = None 40865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 40875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.classobj.bases.args.pos, "Invalid base class") 40885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 40895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.classobj.bases.args.pos, "C class may only have one base class") 40905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 40915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 40925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return CClassDefNode(self.pos, 40935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) visibility = 'private', 40945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_name = None, 40955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) class_name = self.name, 40965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_module = base_class_module, 40975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_name = base_class_name, 40985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decorators = self.decorators, 40995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body = self.body, 41005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) in_pxd = False, 41015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) doc = self.doc) 41025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 41035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def create_scope(self, env): 41045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) genv = env 41055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while genv.is_py_class_scope or genv.is_c_class_scope: 41065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) genv = genv.outer_scope 41075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv) 41085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return cenv 41095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 41105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 41115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) class_result = self.classobj 41125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.decorators: 41135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from ExprNodes import SimpleCallNode 41145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for decorator in self.decorators[::-1]: 41155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) class_result = SimpleCallNode( 41165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decorator.pos, 41175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function = decorator.decorator, 41185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = [class_result]) 41195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.decorators = None 41205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_result = class_result 41215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_result.analyse_declarations(env) 41225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.analyse_target_declaration(env) 41235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv = self.create_scope(env) 41245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv.directives = env.directives 41255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv.class_obj_cname = self.target.entry.cname 41265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(cenv) 41275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 41285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 41295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.bases: 41305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bases = self.bases.analyse_expressions(env) 41315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.metaclass: 41325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.metaclass = self.metaclass.analyse_expressions(env) 41335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.mkw: 41345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.mkw = self.mkw.analyse_expressions(env) 41355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict = self.dict.analyse_expressions(env) 41365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_result = self.class_result.analyse_expressions(env) 41375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) genv = env.global_scope() 41385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv = self.scope 41395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(cenv) 41405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.analyse_target_expression(env, self.classobj) 41415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_cell = self.class_cell.analyse_expressions(cenv) 41425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 41435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 41445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 41455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_lambda_definitions(self.scope, code) 41465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(self.scope, code) 41475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 41485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 41495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.pyclass_stack.append(self) 41505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv = self.scope 41515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.bases: 41525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bases.generate_evaluation_code(code) 41535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.mkw: 41545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.mkw.generate_evaluation_code(code) 41555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.metaclass: 41565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.metaclass.generate_evaluation_code(code) 41575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict.generate_evaluation_code(code) 41585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv.namespace_cname = cenv.class_obj_cname = self.dict.result() 41595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_cell.generate_evaluation_code(code) 41605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 41615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_result.generate_evaluation_code(code) 41625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_cell.generate_injection_code( 41635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code, self.class_result.result()) 41645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_cell.generate_disposal_code(code) 41655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result() 41665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.generate_assignment_code(self.class_result, code) 41675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict.generate_disposal_code(code) 41685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict.free_temps(code) 41695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.metaclass: 41705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.metaclass.generate_disposal_code(code) 41715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.metaclass.free_temps(code) 41725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.mkw: 41735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.mkw.generate_disposal_code(code) 41745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.mkw.free_temps(code) 41755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.bases: 41765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bases.generate_disposal_code(code) 41775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bases.free_temps(code) 41785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.pyclass_stack.pop() 41795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 41805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CClassDefNode(ClassDefNode): 41815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # An extension type definition. 41825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 41835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # visibility 'private' or 'public' or 'extern' 41845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # typedef_flag boolean 41855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # api boolean 41865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # module_name string or None For import of extern type objects 41875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # class_name string Unqualified name of class 41885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # as_name string or None Name to declare as in this scope 41895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_class_module string or None Module containing the base class 41905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_class_name string or None Name of the base class 41915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # objstruct_name string or None Specified C name of object struct 41925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # typeobj_name string or None Specified C name of type object 41935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in_pxd boolean Is in a .pxd file 41945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # decorators [DecoratorNode] list of decorators or None 41955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # doc string or None 41965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode or None 41975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # entry Symtab.Entry 41985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # base_type PyExtensionType or None 41995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # buffer_defaults_node DictNode or None Declares defaults for a buffer 42005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # buffer_defaults_pos 42015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 42025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["body"] 42035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buffer_defaults_node = None 42045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buffer_defaults_pos = None 42055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef_flag = False 42065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api = False 42075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) objstruct_name = None 42085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typeobj_name = None 42095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) decorators = None 42105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) shadow = False 42115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 42125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def buffer_defaults(self, env): 42135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not hasattr(self, '_buffer_defaults'): 42145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import Buffer 42155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.buffer_defaults_node: 42165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._buffer_defaults = Buffer.analyse_buffer_options( 42175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.buffer_defaults_pos, 42185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env, [], self.buffer_defaults_node, 42195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) need_complete=False) 42205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 42215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._buffer_defaults = None 42225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self._buffer_defaults 42235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 42245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare(self, env): 42255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.module_name and self.visibility != 'extern': 42265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_path = self.module_name.split(".") 42275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) home_scope = env.find_imported_module(module_path, self.pos) 42285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not home_scope: 42295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return None 42305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 42315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) home_scope = env 42325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 42335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = home_scope.declare_c_class( 42345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.class_name, 42355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos = self.pos, 42365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defining = 0, 42375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) implementing = 0, 42385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_name = self.module_name, 42395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = None, 42405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) objstruct_cname = self.objstruct_name, 42415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typeobj_cname = self.typeobj_name, 42425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) visibility = self.visibility, 42435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef_flag = self.typedef_flag, 42445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api = self.api, 42455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buffer_defaults = self.buffer_defaults(env), 42465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) shadow = self.shadow) 42475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 42485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 42495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "CClassDefNode.analyse_declarations:", self.class_name 42505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "...visibility =", self.visibility 42515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #print "...module_name =", self.module_name 42525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 42535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if env.in_cinclude and not self.objstruct_name: 42545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Object struct name specification required for " 42555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "C class defined in 'extern from' block") 42565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.decorators: 42575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 42585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Decorators not allowed on cdef classes (used on type '%s')" % self.class_name) 42595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_type = None 42605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Now that module imports are cached, we need to 42615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # import the modules for extern classes. 42625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.module_name: 42635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module = None 42645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for module in env.cimported_modules: 42655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if module.name == self.module_name: 42665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module = module 42675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.module is None: 42685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module = ModuleScope(self.module_name, None, env.context) 42695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module.has_extern_class = 1 42705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_imported_module(self.module) 42715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 42725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.base_class_name: 42735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.base_class_module: 42745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_scope = env.find_module(self.base_class_module, self.pos) 42755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 42765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_scope = env 42775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.base_class_name == 'object': 42785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # extension classes are special and don't need to inherit from object 42795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_class_scope is None or base_class_scope.lookup('object') is None: 42805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_class_name = None 42815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_class_module = None 42825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_scope = None 42835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_class_scope: 42845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_entry = base_class_scope.find(self.base_class_name, self.pos) 42855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if base_class_entry: 42865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not base_class_entry.is_type: 42875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "'%s' is not a type name" % self.base_class_name) 42885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif not base_class_entry.type.is_extension_type and \ 42895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not (base_class_entry.type.is_builtin_type and 42905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_entry.type.objstruct_cname): 42915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "'%s' is not an extension type" % self.base_class_name) 42925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif not base_class_entry.type.is_complete(): 42935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Base class '%s' of type '%s' is incomplete" % ( 42945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_class_name, self.class_name)) 42955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \ 42965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_entry.type.is_final_type: 42975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Base class '%s' of type '%s' is final" % ( 42985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_class_name, self.class_name)) 42995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif base_class_entry.type.is_builtin_type and \ 43005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_class_entry.type.name in ('tuple', 'str', 'bytes'): 43015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported" 43025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) % base_class_entry.type.name) 43035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 43045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_type = base_class_entry.type 43055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if env.directives.get('freelist', 0) > 0: 43065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(self.pos, "freelists cannot be used on subtypes, only the base class can manage them", 1) 43075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) has_body = self.body is not None 43095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if has_body and self.base_type and not self.base_type.scope: 43105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # To properly initialize inherited attributes, the base type must 43115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # be analysed before this type. 43125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.base_type.defered_declarations.append(lambda : self.analyse_declarations(env)) 43135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 43145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.module_name and self.visibility != 'extern': 43165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_path = self.module_name.split(".") 43175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) home_scope = env.find_imported_module(module_path, self.pos) 43185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not home_scope: 43195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 43205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 43215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) home_scope = env 43225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.visibility == 'extern': 43245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (self.module_name == '__builtin__' and 43255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.class_name in Builtin.builtin_types and 43265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython 43275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1) 43285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = home_scope.declare_c_class( 43305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.class_name, 43315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos = self.pos, 43325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defining = has_body and self.in_pxd, 43335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) implementing = has_body and not self.in_pxd, 43345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_name = self.module_name, 43355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base_type = self.base_type, 43365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) objstruct_cname = self.objstruct_name, 43375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typeobj_cname = self.typeobj_name, 43385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) visibility = self.visibility, 43395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) typedef_flag = self.typedef_flag, 43405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api = self.api, 43415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buffer_defaults = self.buffer_defaults(env), 43425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) shadow = self.shadow) 43435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.shadow: 43455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) home_scope.lookup(self.class_name).as_variable = self.entry 43465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if home_scope is not env and self.visibility == 'extern': 43475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_imported_entry(self.class_name, self.entry, self.pos) 43485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.scope = scope = self.entry.type.scope 43495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if scope is not None: 43505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.directives = env.directives 43515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.doc and Options.docstrings: 43535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.doc = embed_position(self.pos, self.doc) 43545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if has_body: 43565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(scope) 43575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.in_pxd: 43585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.defined = 1 43595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 43605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.implemented = 1 43615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.allocate_vtable_names(self.entry) 43625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for thunk in self.entry.type.defered_declarations: 43645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) thunk() 43655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 43675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.body: 43685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = self.entry.type.scope 43695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(scope) 43705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 43715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 43735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.body: 43745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_lambda_definitions(self.scope, code) 43755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(self.scope, code) 43765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 43785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This is needed to generate evaluation code for 43795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # default values of method arguments. 43805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.body: 43815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 43825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 43845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.body: 43855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 43865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class PropertyNode(StatNode): 43895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Definition of a property in an extension type. 43905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 43915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # name string 43925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # doc EncodedString or None Doc string 43935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # entry Symtab.Entry 43945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatListNode 43955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["body"] 43975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 43985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 43995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry = env.declare_property(self.name, self.doc, self.pos) 44005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.entry.scope.directives = env.directives 44015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(self.entry.scope) 44025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 44045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 44055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 44065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 44085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 44095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 44115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 44125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 44145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 44155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class GlobalNode(StatNode): 44185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Global variable declaration. 44195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 44205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # names [string] 44215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 44235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 44255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name in self.names: 44265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_global(name, self.pos) 44275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 44295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 44305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 44325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 44335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class NonlocalNode(StatNode): 44365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Nonlocal variable declaration via the 'nonlocal' keyword. 44375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 44385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # names [string] 44395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 44415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 44435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name in self.names: 44445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_nonlocal(name, self.pos) 44455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 44475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 44485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 44505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 44515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ExprStatNode(StatNode): 44545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Expression used as a statement. 44555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 44565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # expr ExprNode 44575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["expr"] 44595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 44615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 44625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.expr, ExprNodes.GeneralCallNode): 44635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func = self.expr.function.as_cython_attribute() 44645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func == u'declare': 44655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args, kwds = self.expr.explicit_args_kwds() 44665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(args): 44675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.expr.pos, "Variable names must be specified.") 44685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var, type_node in kwds.key_value_pairs: 44695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = type_node.analyse_as_type(env) 44705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type is None: 44715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Unknown type") 44725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 44735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_var(var.value, type, var.pos, is_cdef = True) 44745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.__class__ = PassStatNode 44755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 44775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expr.result_is_used = False # hint that .result() may safely be left empty 44785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expr = self.expr.analyse_expressions(env) 44795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 44805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def nogil_check(self, env): 44825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.expr.type.is_pyobject and self.expr.is_temp: 44835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.gil_error() 44845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Discarding owned Python object" 44865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 44885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expr.generate_evaluation_code(code) 44895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.expr.is_temp and self.expr.result(): 44905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s;" % self.expr.result()) 44915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expr.generate_disposal_code(code) 44925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expr.free_temps(code) 44935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 44955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expr.generate_function_definitions(env, code) 44965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 44975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 44985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expr.annotate(code) 44995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class AssignmentNode(StatNode): 45025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Abstract base class for assignment nodes. 45035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 45045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The analyse_expressions and generate_execution_code 45055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # phases of assignments are split into two sub-phases 45065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # each, to enable all the right hand sides of a 45075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # parallel assignment to be evaluated before assigning 45085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # to any of the left hand sides. 45095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 45115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.analyse_types(env) 45125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# def analyse_expressions(self, env): 45145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# self.analyse_expressions_1(env) 45155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# self.analyse_expressions_2(env) 45165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 45185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_rhs_evaluation_code(code) 45195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_assignment_code(code) 45205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class SingleAssignmentNode(AssignmentNode): 45235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The simplest case: 45245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 45255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # a = b 45265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 45275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # lhs ExprNode Left hand side 45285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # rhs ExprNode Right hand side 45295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # first bool Is this guaranteed the first assignment to lhs? 45305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["lhs", "rhs"] 45325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first = False 45335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) declaration_only = False 45345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 45365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 45375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # handle declarations of the form x = cython.foo() 45395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.rhs, ExprNodes.CallNode): 45405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_name = self.rhs.function.as_cython_attribute() 45415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func_name: 45425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args, kwds = self.rhs.explicit_args_kwds() 45435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func_name in ['declare', 'typedef']: 45455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(args) > 2 or kwds is not None: 45465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.rhs.pos, "Can only declare one type at a time.") 45475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 45485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = args[0].analyse_as_type(env) 45505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type is None: 45515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(args[0].pos, "Unknown type") 45525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 45535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs = self.lhs 45545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if func_name == 'declare': 45555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(lhs, ExprNodes.NameNode): 45565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) vars = [(lhs.name, lhs.pos)] 45575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif isinstance(lhs, ExprNodes.TupleNode): 45585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) vars = [(var.name, var.pos) for var in lhs.args] 45595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 45605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(lhs.pos, "Invalid declaration") 45615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 45625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var, pos in vars: 45635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_var(var, type, pos, is_cdef = True) 45645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(args) == 2: 45655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # we have a value 45665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = args[1] 45675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 45685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declaration_only = True 45695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 45705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declaration_only = True 45715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not isinstance(lhs, ExprNodes.NameNode): 45725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(lhs.pos, "Invalid declaration.") 45735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_typedef(lhs.name, type, self.pos, visibility='private') 45745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif func_name in ['struct', 'union']: 45765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declaration_only = True 45775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(args) > 0 or kwds is None: 45785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.rhs.pos, "Struct or union members must be given by name.") 45795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 45805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) members = [] 45815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for member, type_node in kwds.key_value_pairs: 45825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = type_node.analyse_as_type(env) 45835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type is None: 45845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(type_node.pos, "Unknown type") 45855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 45865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) members.append((member.value, type, member.pos)) 45875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(members) < len(kwds.key_value_pairs): 45885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 45895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not isinstance(self.lhs, ExprNodes.NameNode): 45905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.lhs.pos, "Invalid declaration.") 45915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.lhs.name 45925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = StructOrUnionScope(name) 45935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos) 45945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for member, type, pos in members: 45955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.declare_var(member, type, pos) 45965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 45975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif func_name == 'fused_type': 45985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # dtype = cython.fused_type(...) 45995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declaration_only = True 46005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if kwds: 46015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.rhs.function.pos, 46025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "fused_type does not take keyword arguments") 46035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fusednode = FusedTypeNode(self.rhs.pos, 46055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.lhs.name, types=args) 46065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fusednode.analyse_declarations(env) 46075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.declaration_only: 46095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 46105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 46115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.analyse_target_declaration(env) 46125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_types(self, env, use_temp = 0): 46145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 46155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = self.rhs.analyse_types(env) 46175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs = self.lhs.analyse_target_types(env) 46185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.gil_assignment_check(env) 46195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.lhs.memslice_broadcast or self.rhs.memslice_broadcast: 46215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.memslice_broadcast = True 46225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.memslice_broadcast = True 46235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_index_node = isinstance(self.lhs, ExprNodes.IndexNode) 46255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (is_index_node and not self.rhs.type.is_memoryviewslice and 46265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self.lhs.memslice_slice or self.lhs.is_memslice_copy) and 46275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self.lhs.type.dtype.assignable_from(self.rhs.type) or 46285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.type.is_pyobject)): 46295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # scalar slice assignment 46305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.is_memslice_scalar_assignment = True 46315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dtype = self.lhs.type.dtype 46325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 46335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dtype = self.lhs.type 46345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = self.rhs.coerce_to(dtype, env) 46365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if use_temp or rhs.is_attribute or ( 46375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not rhs.is_name and not rhs.is_literal and 46385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs.type.is_pyobject): 46395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # things like (cdef) attribute access are not safe (traverses pointers) 46405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = rhs.coerce_to_temp(env) 46415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif rhs.type.is_pyobject: 46425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = rhs.coerce_to_simple(env) 46435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = rhs 46445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 46455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_rhs_evaluation_code(self, code): 46475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.generate_evaluation_code(code) 46485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_assignment_code(self, code): 46505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.generate_assignment_code(self.rhs, code) 46515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 46535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.generate_function_definitions(env, code) 46545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 46565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.annotate(code) 46575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.annotate(code) 46585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CascadedAssignmentNode(AssignmentNode): 46615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # An assignment with multiple left hand sides: 46625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 46635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # a = b = c 46645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 46655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # lhs_list [ExprNode] Left hand sides 46665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # rhs ExprNode Right hand sides 46675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 46685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Used internally: 46695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 46705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS 46715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"] 46735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coerced_rhs_list = None 46745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 46765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for lhs in self.lhs_list: 46775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs.analyse_target_declaration(env) 46785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_types(self, env, use_temp = 0): 46805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from ExprNodes import CloneNode, ProxyNode 46815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = self.rhs.analyse_types(env) 46835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if use_temp or rhs.is_attribute or ( 46845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not rhs.is_name and not rhs.is_literal and 46855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs.type.is_pyobject): 46865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = rhs.coerce_to_temp(env) 46875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 46885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = rhs.coerce_to_simple(env) 46895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = ProxyNode(rhs) 46905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.coerced_rhs_list = [] 46925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for lhs in self.lhs_list: 46935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs.analyse_target_types(env) 46945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs.gil_assignment_check(env) 46955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = CloneNode(self.rhs) 46965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = rhs.coerce_to(lhs.type, env) 46975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.coerced_rhs_list.append(rhs) 46985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 46995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_rhs_evaluation_code(self, code): 47015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.generate_evaluation_code(code) 47025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_assignment_code(self, code): 47045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in range(len(self.lhs_list)): 47055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs = self.lhs_list[i] 47065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs = self.coerced_rhs_list[i] 47075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs.generate_evaluation_code(code) 47085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs.generate_assignment_code(rhs, code) 47095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Assignment has disposed of the cloned RHS 47105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.generate_disposal_code(code) 47115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.free_temps(code) 47125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 47145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.generate_function_definitions(env, code) 47155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 47175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in range(len(self.lhs_list)): 47185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs_list[i].annotate(code) 47195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.coerced_rhs_list[i].annotate(code) 47205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.annotate(code) 47215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ParallelAssignmentNode(AssignmentNode): 47245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # A combined packing/unpacking assignment: 47255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 47265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # a, b, c = d, e, f 47275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 47285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This has been rearranged by the parser into 47295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 47305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # a = d ; b = e ; c = f 47315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 47325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # but we must evaluate all the right hand sides 47335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # before assigning to any of the left hand sides. 47345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 47355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # stats [AssignmentNode] The constituent assignments 47365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["stats"] 47385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 47405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 47415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.analyse_declarations(env) 47425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 47445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stats = [ stat.analyse_types(env, use_temp = 1) 47455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats ] 47465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 47475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# def analyse_expressions(self, env): 47495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# for stat in self.stats: 47505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# stat.analyse_expressions_1(env, use_temp = 1) 47515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# for stat in self.stats: 47525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# stat.analyse_expressions_2(env) 47535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 47555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 47565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.generate_rhs_evaluation_code(code) 47575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 47585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.generate_assignment_code(code) 47595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 47615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 47625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.generate_function_definitions(env, code) 47635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 47655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for stat in self.stats: 47665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stat.annotate(code) 47675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class InPlaceAssignmentNode(AssignmentNode): 47705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # An in place arithmetic operand: 47715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 47725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # a += b 47735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # a -= b 47745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ... 47755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 47765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # lhs ExprNode Left hand side 47775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # rhs ExprNode Right hand side 47785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # operator char one of "+-*/%^&|" 47795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 47805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This code is a bit tricky because in order to obey Python 47815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # semantics the sub-expressions (e.g. indices) of the lhs must 47825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # not be evaluated twice. So we must re-use the values calculated 47835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in evaluation phase for the assignment phase as well. 47845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Fortunately, the type of the lhs node is fairly constrained 47855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # (it must be a NameNode, AttributeNode, or IndexNode). 47865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["lhs", "rhs"] 47885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 47905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.analyse_target_declaration(env) 47915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_types(self, env): 47935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = self.rhs.analyse_types(env) 47945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs = self.lhs.analyse_target_types(env) 47955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 47965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # When assigning to a fully indexed buffer or memoryview, coerce the rhs 47975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (self.lhs.is_subscript and 47985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self.lhs.memslice_index or self.lhs.is_buffer_access)): 47995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = self.rhs.coerce_to(self.lhs.type, env) 48005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.lhs.type.is_string and self.operator in '+-': 48015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # use pointer arithmetic for char* LHS instead of string concat 48025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = self.rhs.coerce_to(PyrexTypes.c_py_ssize_t_type, env) 48035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 48045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 48065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.generate_evaluation_code(code) 48075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.generate_subexpr_evaluation_code(code) 48085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c_op = self.operator 48095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if c_op == "//": 48105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c_op = "/" 48115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif c_op == "**": 48125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "No C inplace power operator") 48135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.lhs.is_subscript and self.lhs.is_buffer_access: 48145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.lhs.type.is_pyobject: 48155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "In-place operators not allowed on object buffers in this release.") 48165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (c_op in ('/', '%') and self.lhs.type.is_int 48175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not code.globalstate.directives['cdivision']): 48185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "In-place non-c divide operators not allowed on int buffers.") 48195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op) 48205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 48215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # C++ 48225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # TODO: make sure overload is declared 48235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result())) 48245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.generate_subexpr_disposal_code(code) 48255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.free_subexpr_temps(code) 48265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.generate_disposal_code(code) 48275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.free_temps(code) 48285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 48305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.annotate(code) 48315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.annotate(code) 48325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def create_binop_node(self): 48345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 48355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs) 48365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class PrintStatNode(StatNode): 48395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # print statement 48405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 48415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # arg_tuple TupleNode 48425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # stream ExprNode or None (stdout) 48435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # append_newline boolean 48445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["arg_tuple", "stream"] 48465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 48485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.stream: 48495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stream = self.stream.analyse_expressions(env) 48505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stream = stream.coerce_to_pyobject(env) 48515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg_tuple = self.arg_tuple.analyse_expressions(env) 48525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.arg_tuple = arg_tuple.coerce_to_pyobject(env) 48535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(printing_utility_code) 48545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.arg_tuple.args) == 1 and self.append_newline: 48555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(printing_one_utility_code) 48565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 48575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = Node.gil_error 48595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Python print statement" 48605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 48625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.stream: 48635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stream.generate_evaluation_code(code) 48645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stream_result = self.stream.py_result() 48655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 48665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stream_result = '0' 48675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.arg_tuple.args) == 1 and self.append_newline: 48685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg = self.arg_tuple.args[0] 48695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.generate_evaluation_code(code) 48705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 48725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (__Pyx_PrintOne(%s, %s) < 0) %s" % ( 48735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stream_result, 48745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.py_result(), 48755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(self.pos))) 48765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.generate_disposal_code(code) 48775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.free_temps(code) 48785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 48795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.arg_tuple.generate_evaluation_code(code) 48805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 48815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (__Pyx_Print(%s, %s, %d) < 0) %s" % ( 48825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) stream_result, 48835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.arg_tuple.py_result(), 48845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.append_newline, 48855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(self.pos))) 48865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.arg_tuple.generate_disposal_code(code) 48875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.arg_tuple.free_temps(code) 48885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.stream: 48905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stream.generate_disposal_code(code) 48915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stream.free_temps(code) 48925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 48945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.stream: 48955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stream.generate_function_definitions(env, code) 48965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.arg_tuple.generate_function_definitions(env, code) 48975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 48985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 48995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.stream: 49005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stream.annotate(code) 49015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.arg_tuple.annotate(code) 49025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ExecStatNode(StatNode): 49055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exec statement 49065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 49075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # args [ExprNode] 49085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["args"] 49105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 49125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(self.args): 49135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg = arg.analyse_expressions(env) 49145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg = arg.coerce_to_pyobject(env) 49155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.args[i] = arg 49165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(Builtin.pyexec_utility_code) 49175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 49185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = Node.gil_error 49205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Python exec statement" 49215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 49235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = [] 49245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 49255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.generate_evaluation_code(code) 49265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args.append( arg.py_result() ) 49275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args = tuple(args + ['0', '0'][:3-len(args)]) 49285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True) 49295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = __Pyx_PyExec3(%s, %s, %s);" % ( 49305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (temp_result,) + args)) 49315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 49325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.generate_disposal_code(code) 49335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.free_temps(code) 49345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 49355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if_null(temp_result, self.pos)) 49365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(temp_result) 49375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(temp_result, py_object_type) 49385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(temp_result) 49395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 49415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 49425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.annotate(code) 49435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class DelStatNode(StatNode): 49465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # del statement 49475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 49485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # args [ExprNode] 49495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["args"] 49515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ignore_nonexisting = False 49525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 49545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 49555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.analyse_target_declaration(env) 49565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 49585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, arg in enumerate(self.args): 49595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg = self.args[i] = arg.analyse_target_expression(env, None) 49605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_pyobject or (arg.is_name and 49615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type.is_memoryviewslice): 49625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.is_name and arg.entry.is_cglobal: 49635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Deletion of global C variable") 49645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.type.is_ptr and arg.type.base_type.is_cpp_class: 49655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cpp_check(env) 49665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.type.is_cpp_class: 49675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Deletion of non-heap C++ object") 49685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.is_subscript and arg.base.type is Builtin.bytearray_type: 49695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass # del ba[i] 49705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 49715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(arg.pos, "Deletion of non-Python, non-C++ object") 49725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #arg.release_target_temp(env) 49735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 49745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def nogil_check(self, env): 49765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 49775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if arg.type.is_pyobject: 49785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.gil_error() 49795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Deleting Python object" 49815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 49835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 49845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (arg.type.is_pyobject or 49855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.type.is_memoryviewslice or 49865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.is_subscript and arg.base.type is Builtin.bytearray_type): 49875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.generate_deletion_code( 49885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code, ignore_nonexisting=self.ignore_nonexisting) 49895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif arg.type.is_ptr and arg.type.base_type.is_cpp_class: 49905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.generate_result_code(code) 49915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("delete %s;" % arg.result()) 49925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # else error reported earlier 49935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 49955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for arg in self.args: 49965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg.annotate(code) 49975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 49995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class PassStatNode(StatNode): 50005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # pass statement 50015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 50035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 50055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 50065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 50085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 50095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class IndirectionNode(StatListNode): 50125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 50135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) This adds an indirection so that the node can be shared and a subtree can 50145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) be removed at any time by clearing self.stats. 50155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 50165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, stats): 50185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(IndirectionNode, self).__init__(stats[0].pos, stats=stats) 50195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class BreakStatNode(StatNode): 50215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 50235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_terminator = True 50245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 50265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 50275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 50295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not code.break_label: 50305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "break statement not inside loop") 50315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 50325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.break_label) 50335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ContinueStatNode(StatNode): 50365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 50385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_terminator = True 50395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 50415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 50425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 50445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.funcstate.in_try_finally: 50455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "continue statement inside try of try...finally") 50465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif not code.continue_label: 50475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "continue statement not inside loop") 50485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 50495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.continue_label) 50505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ReturnStatNode(StatNode): 50535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # return statement 50545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 50555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # value ExprNode or None 50565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # return_type PyrexType 50575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in_generator return inside of generator => raise StopIteration 50585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["value"] 50605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_terminator = True 50615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) in_generator = False 50625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Whether we are in a parallel section 50645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) in_parallel = False 50655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 50675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return_type = env.return_type 50685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.return_type = return_type 50695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not return_type: 50705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Return not inside a function body") 50715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 50725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value: 50735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value = self.value.analyse_types(env) 50745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if return_type.is_void or return_type.is_returncode: 50755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.value.pos, 50765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Return with value in void function") 50775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 50785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value = self.value.coerce_to(env.return_type, env) 50795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 50805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (not return_type.is_void 50815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not return_type.is_pyobject 50825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and not return_type.is_returncode): 50835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Return value required") 50845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 50855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def nogil_check(self, env): 50875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 50885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.gil_error() 50895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Returning Python object" 50915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 50925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 50935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 50945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.return_type: 50955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # error reported earlier 50965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 50975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 50985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref(Naming.retval_cname, 50995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.return_type) 51005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value: 51025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.generate_evaluation_code(code) 51035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_memoryviewslice: 51045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import MemoryView 51055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MemoryView.put_acquire_memoryviewslice( 51065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs_cname=Naming.retval_cname, 51075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs_type=self.return_type, 51085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lhs_pos=self.value.pos, 51095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) rhs=self.value, 51105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code=code, 51115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) have_gil=self.in_nogil_context) 51125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.in_generator: 51135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # return value == raise StopIteration(value), but uncatchable 51145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 51155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "%s = NULL; PyErr_SetObject(PyExc_StopIteration, %s);" % ( 51165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.retval_cname, 51175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.result_as(self.return_type))) 51185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.generate_disposal_code(code) 51195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 51205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.make_owned_reference(code) 51215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 51225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "%s = %s;" % ( 51235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.retval_cname, 51245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.result_as(self.return_type))) 51255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.generate_post_assignment_code(code) 51265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.free_temps(code) 51275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 51285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.return_type.is_pyobject: 51295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_init_to_py_none(Naming.retval_cname, self.return_type) 51305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.return_type.is_returncode: 51315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.put_return(code, self.return_type.default_value) 51325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cname, type in code.funcstate.temps_holding_reference(): 51345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(cname, type) 51355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.return_label) 51375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def put_return(self, code, value): 51395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.in_parallel: 51405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln_openmp("#pragma omp critical(__pyx_returning)") 51415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (Naming.retval_cname, value)) 51425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 51445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value is not None: 51455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.generate_function_definitions(env, code) 51465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 51485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value: 51495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.annotate(code) 51505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class RaiseStatNode(StatNode): 51535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # raise statement 51545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 51555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exc_type ExprNode or None 51565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exc_value ExprNode or None 51575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exc_tb ExprNode or None 51585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cause ExprNode or None 51595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["exc_type", "exc_value", "exc_tb", "cause"] 51615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_terminator = True 51625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 51645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_type: 51655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_type = self.exc_type.analyse_types(env) 51665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_type = exc_type.coerce_to_pyobject(env) 51675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_value: 51685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_value = self.exc_value.analyse_types(env) 51695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_value = exc_value.coerce_to_pyobject(env) 51705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_tb: 51715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_tb = self.exc_tb.analyse_types(env) 51725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_tb = exc_tb.coerce_to_pyobject(env) 51735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.cause: 51745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cause = self.cause.analyse_types(env) 51755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cause = cause.coerce_to_pyobject(env) 51765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # special cases for builtin exceptions 51775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.builtin_exc_name = None 51785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_type and not self.exc_value and not self.exc_tb: 51795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc = self.exc_type 51805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 51815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (isinstance(exc, ExprNodes.SimpleCallNode) and 51825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not (exc.args or (exc.arg_tuple is not None and 51835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc.arg_tuple.args))): 51845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc = exc.function # extract the exception type 51855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if exc.is_name and exc.entry.is_builtin: 51865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.builtin_exc_name = exc.name 51875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.builtin_exc_name == 'MemoryError': 51885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_type = None # has a separate implementation 51895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 51905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = Node.gil_error 51925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Raising exception" 51935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 51955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.builtin_exc_name == 'MemoryError': 51965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos)) 51975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 51985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 51995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_type: 52005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_type.generate_evaluation_code(code) 52015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_code = self.exc_type.py_result() 52025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 52035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_code = "0" 52045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_value: 52055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_value.generate_evaluation_code(code) 52065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) value_code = self.exc_value.py_result() 52075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 52085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) value_code = "0" 52095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_tb: 52105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_tb.generate_evaluation_code(code) 52115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tb_code = self.exc_tb.py_result() 52125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 52135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tb_code = "0" 52145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.cause: 52155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cause.generate_evaluation_code(code) 52165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cause_code = self.cause.py_result() 52175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 52185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cause_code = "0" 52195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(raise_utility_code) 52205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 52215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "__Pyx_Raise(%s, %s, %s, %s);" % ( 52225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_code, 52235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) value_code, 52245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tb_code, 52255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cause_code)) 52265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for obj in (self.exc_type, self.exc_value, self.exc_tb, self.cause): 52275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if obj: 52285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) obj.generate_disposal_code(code) 52295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) obj.free_temps(code) 52305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 52315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(self.pos)) 52325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 52345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_type is not None: 52355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_type.generate_function_definitions(env, code) 52365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_value is not None: 52375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_value.generate_function_definitions(env, code) 52385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_tb is not None: 52395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_tb.generate_function_definitions(env, code) 52405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.cause is not None: 52415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cause.generate_function_definitions(env, code) 52425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 52445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_type: 52455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_type.annotate(code) 52465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_value: 52475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_value.annotate(code) 52485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.exc_tb: 52495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_tb.annotate(code) 52505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.cause: 52515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cause.annotate(code) 52525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ReraiseStatNode(StatNode): 52555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 52575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_terminator = True 52585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 52605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 52615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = Node.gil_error 52635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Raising exception" 52645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 52665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) vars = code.funcstate.exc_vars 52675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if vars: 52685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(restore_exception_utility_code) 52695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref(vars[0]) 52705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref(vars[1]) 52715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # fresh exceptions may not have a traceback yet (-> finally!) 52725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xgiveref(vars[2]) 52735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars)) 52745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for varname in vars: 52755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("%s = 0; " % varname) 52765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln() 52775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(code.error_goto(self.pos)) 52785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 52795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 52805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("ReRaiseException", "Exceptions.c")) 52815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ReraiseException(); %s" % code.error_goto(self.pos)) 52825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class AssertStatNode(StatNode): 52845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # assert statement 52855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 52865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cond ExprNode 52875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # value ExprNode or None 52885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["cond", "value"] 52905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 52915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 52925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cond = self.cond.analyse_boolean_expression(env) 52935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value: 52945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) value = self.value.analyse_types(env) 52955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if value.type is Builtin.tuple_type or not value.type.is_builtin_type: 52965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # prevent tuple values from being interpreted as argument value tuples 52975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from ExprNodes import TupleNode 52985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) value = TupleNode(value.pos, args=[value], slow=True) 52995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value = value.analyse_types(env, skip_children=True) 53005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 53015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value = value.coerce_to_pyobject(env) 53025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 53035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = Node.gil_error 53055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Raising exception" 53065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 53085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS") 53095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (unlikely(!Py_OptimizeFlag)) {") 53105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cond.generate_evaluation_code(code) 53115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 53125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (unlikely(!%s)) {" % 53135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cond.result()) 53145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value: 53155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.generate_evaluation_code(code) 53165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 53175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "PyErr_SetObject(PyExc_AssertionError, %s);" % 53185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.py_result()) 53195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.generate_disposal_code(code) 53205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.free_temps(code) 53215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 53225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 53235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "PyErr_SetNone(PyExc_AssertionError);") 53245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 53255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(self.pos)) 53265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 53275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") 53285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cond.generate_disposal_code(code) 53295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cond.free_temps(code) 53305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 53315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") 53325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#endif") 53335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 53355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cond.generate_function_definitions(env, code) 53365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value is not None: 53375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.generate_function_definitions(env, code) 53385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 53405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cond.annotate(code) 53415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value: 53425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value.annotate(code) 53435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class IfStatNode(StatNode): 53465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # if statement 53475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 53485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # if_clauses [IfClauseNode] 53495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # else_clause StatNode or None 53505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["if_clauses", "else_clause"] 53525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 53545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for if_clause in self.if_clauses: 53555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if_clause.analyse_declarations(env) 53565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 53575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.analyse_declarations(env) 53585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 53605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.if_clauses = [ if_clause.analyse_expressions(env) 53615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for if_clause in self.if_clauses ] 53625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 53635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause = self.else_clause.analyse_expressions(env) 53645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 53655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 53675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 53685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_label = code.new_label() 53695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for if_clause in self.if_clauses: 53705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if_clause.generate_execution_code(code, end_label) 53715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 53725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/*else*/ {") 53735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_execution_code(code) 53745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 53755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(end_label) 53765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 53785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for clause in self.if_clauses: 53795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) clause.generate_function_definitions(env, code) 53805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 53815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_function_definitions(env, code) 53825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 53845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for if_clause in self.if_clauses: 53855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if_clause.annotate(code) 53865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 53875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.annotate(code) 53885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class IfClauseNode(Node): 53915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # if or elif clause in an if statement 53925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 53935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # condition ExprNode 53945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 53955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["condition", "body"] 53975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 53985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 53995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 54005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 54025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition = \ 54035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.analyse_temp_boolean_expression(env) 54045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 54055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 54065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code, end_label): 54085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.generate_evaluation_code(code) 54095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 54105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (%s) {" % 54115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.result()) 54125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.generate_disposal_code(code) 54135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.free_temps(code) 54145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 54155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.body.is_terminator: 54165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(end_label) 54175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 54185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 54205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.generate_function_definitions(env, code) 54215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 54225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 54245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.annotate(code) 54255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 54265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class SwitchCaseNode(StatNode): 54295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generated in the optimization of an if-elif-else node 54305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 54315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # conditions [ExprNode] 54325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 54335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['conditions', 'body'] 54355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 54375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cond in self.conditions: 54385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(cond.pos) 54395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cond.generate_evaluation_code(code) 54405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("case %s:" % cond.result()) 54415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 54425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("break;") 54435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 54455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cond in self.conditions: 54465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cond.generate_function_definitions(env, code) 54475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 54485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 54505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cond in self.conditions: 54515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cond.annotate(code) 54525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 54535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class SwitchStatNode(StatNode): 54555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Generated in the optimization of an if-elif-else node 54565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 54575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # test ExprNode 54585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cases [SwitchCaseNode] 54595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # else_clause StatNode or None 54605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['test', 'cases', 'else_clause'] 54625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 54645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.test.generate_evaluation_code(code) 54655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("switch (%s) {" % self.test.result()) 54665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for case in self.cases: 54675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case.generate_execution_code(code) 54685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 54695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("default:") 54705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_execution_code(code) 54715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("break;") 54725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 54735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Always generate a default clause to prevent C compiler warnings 54745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # about unmatched enum values (it was not the user who decided to 54755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # generate the switch statement, so shouldn't be bothered). 54765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("default: break;") 54775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 54785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 54805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.test.generate_function_definitions(env, code) 54815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for case in self.cases: 54825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case.generate_function_definitions(env, code) 54835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 54845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_function_definitions(env, code) 54855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 54875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.test.annotate(code) 54885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for case in self.cases: 54895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case.annotate(code) 54905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 54915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.annotate(code) 54925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class LoopNode(object): 54945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 54955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 54975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class WhileStatNode(LoopNode, StatNode): 54985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # while statement 54995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 55005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # condition ExprNode 55015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 55025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # else_clause StatNode 55035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["condition", "body", "else_clause"] 55055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 55075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 55085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 55095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.analyse_declarations(env) 55105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 55125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.condition: 55135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition = self.condition.analyse_temp_boolean_expression(env) 55145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 55155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 55165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause = self.else_clause.analyse_expressions(env) 55175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 55185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 55205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_loop_labels = code.new_loop_labels() 55215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 55225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "while (1) {") 55235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.condition: 55245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.generate_evaluation_code(code) 55255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.generate_disposal_code(code) 55265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 55275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (!%s) break;" % 55285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.result()) 55295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.free_temps(code) 55305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 55315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.continue_label) 55325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 55335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break_label = code.break_label 55345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.set_loop_labels(old_loop_labels) 55355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 55365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.else_clause.pos) 55375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/*else*/ {") 55385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_execution_code(code) 55395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 55405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(break_label) 55415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 55435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.condition: 55445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.generate_function_definitions(env, code) 55455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 55465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 55475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_function_definitions(env, code) 55485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 55505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.condition: 55515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.condition.annotate(code) 55525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 55535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 55545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.annotate(code) 55555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class DictIterationNextNode(Node): 55585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Helper node for calling PyDict_Next() inside of a WhileStatNode 55595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # and checking the dictionary size for changes. Created in 55605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Optimize.py. 55615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['dict_obj', 'expected_size', 'pos_index_var', 55625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'coerced_key_var', 'coerced_value_var', 'coerced_tuple_var', 55635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'key_target', 'value_target', 'tuple_target', 'is_dict_flag'] 55645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coerced_key_var = key_ref = None 55665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coerced_value_var = value_ref = None 55675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coerced_tuple_var = tuple_ref = None 55685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, dict_obj, expected_size, pos_index_var, 55705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) key_target, value_target, tuple_target, is_dict_flag): 55715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Node.__init__( 55725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self, dict_obj.pos, 55735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dict_obj = dict_obj, 55745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) expected_size = expected_size, 55755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_index_var = pos_index_var, 55765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) key_target = key_target, 55775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) value_target = value_target, 55785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tuple_target = tuple_target, 55795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_dict_flag = is_dict_flag, 55805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_temp = True, 55815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = PyrexTypes.c_bint_type) 55825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 55845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 55855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict_obj = self.dict_obj.analyse_types(env) 55865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expected_size = self.expected_size.analyse_types(env) 55875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.pos_index_var: 55885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.pos_index_var = self.pos_index_var.analyse_types(env) 55895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.key_target: 55905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.key_target = self.key_target.analyse_target_types(env) 55915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.key_ref = ExprNodes.TempNode(self.key_target.pos, PyrexTypes.py_object_type) 55925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.coerced_key_var = self.key_ref.coerce_to(self.key_target.type, env) 55935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.value_target: 55945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value_target = self.value_target.analyse_target_types(env) 55955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.value_ref = ExprNodes.TempNode(self.value_target.pos, type=PyrexTypes.py_object_type) 55965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.coerced_value_var = self.value_ref.coerce_to(self.value_target.type, env) 55975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.tuple_target: 55985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.tuple_target = self.tuple_target.analyse_target_types(env) 55995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.tuple_ref = ExprNodes.TempNode(self.tuple_target.pos, PyrexTypes.py_object_type) 56005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.coerced_tuple_var = self.tuple_ref.coerce_to(self.tuple_target.type, env) 56015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_dict_flag = self.is_dict_flag.analyse_types(env) 56025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 56035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 56055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict_obj.generate_function_definitions(env, code) 56065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 56085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(UtilityCode.load_cached("dict_iter", "Optimize.c")) 56095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict_obj.generate_evaluation_code(code) 56105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assignments = [] 56125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_addresses = [] 56135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var, result, target in [(self.key_ref, self.coerced_key_var, self.key_target), 56145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self.value_ref, self.coerced_value_var, self.value_target), 56155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self.tuple_ref, self.coerced_tuple_var, self.tuple_target)]: 56165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if target is None: 56175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) addr = 'NULL' 56185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 56195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assignments.append((var, result, target)) 56205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var.allocate(code) 56215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) addr = '&%s' % var.result() 56225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_addresses.append(addr) 56235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result_temp = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False) 56255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = __Pyx_dict_iter_next(%s, %s, &%s, %s, %s, %s, %s);" % ( 56265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result_temp, 56275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.dict_obj.py_result(), 56285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.expected_size.result(), 56295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.pos_index_var.result(), 56305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_addresses[0], 56315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_addresses[1], 56325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_addresses[2], 56335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_dict_flag.result() 56345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) )) 56355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (unlikely(%s == 0)) break;" % result_temp) 56365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(code.error_goto_if("%s == -1" % result_temp, self.pos)) 56375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(result_temp) 56385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # evaluate all coercions before the assignments 56405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var, result, target in assignments: 56415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(var.result()) 56425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var, result, target in assignments: 56435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result.generate_evaluation_code(code) 56445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var, result, target in assignments: 56455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.generate_assignment_code(result, code) 56465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) var.release(code) 56475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def ForStatNode(pos, **kw): 56495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if 'iterator' in kw: 56505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ForInStatNode(pos, **kw) 56515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 56525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ForFromStatNode(pos, **kw) 56535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ForInStatNode(LoopNode, StatNode): 56555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # for statement 56565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 56575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # target ExprNode 56585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # iterator IteratorNode 56595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 56605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # else_clause StatNode 56615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # item NextNode used internally 56625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["target", "iterator", "body", "else_clause"] 56645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) item = None 56655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 56675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 56685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.analyse_target_declaration(env) 56695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 56705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 56715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.analyse_declarations(env) 56725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.item = ExprNodes.NextNode(self.iterator) 56735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 56755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target = self.target.analyse_target_types(env) 56765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.iterator = self.iterator.analyse_expressions(env) 56775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 56785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.item = ExprNodes.NextNode(self.iterator) # must rewrap after analysis 56795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.item = self.item.analyse_expressions(env) 56805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (self.iterator.type.is_ptr or self.iterator.type.is_array) and \ 56815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.type.assignable_from(self.iterator.type): 56825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # C array slice optimization. 56835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 56845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 56855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.item = self.item.coerce_to(self.target.type, env) 56865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 56875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 56885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause = self.else_clause.analyse_expressions(env) 56895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 56905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 56915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 56925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_loop_labels = code.new_loop_labels() 56935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.iterator.generate_evaluation_code(code) 56945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("for (;;) {") 56955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.item.generate_evaluation_code(code) 56965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.generate_assignment_code(self.item, code) 56975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 56985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.continue_label) 56995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 57005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break_label = code.break_label 57015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.set_loop_labels(old_loop_labels) 57025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 57045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in nested loops, the 'else' block can contain a 57055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 'continue' statement for the outer loop, but we may need 57065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # to generate cleanup code before taking that path, so we 57075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # intercept it here 57085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) orig_continue_label = code.continue_label 57095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.continue_label = code.new_label('outer_continue') 57105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/*else*/ {") 57125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_execution_code(code) 57135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 57145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(code.continue_label): 57165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(break_label) 57175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.continue_label) 57185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.iterator.generate_disposal_code(code) 57195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(orig_continue_label) 57205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.set_loop_labels(old_loop_labels) 57215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(break_label): 57235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(break_label) 57245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.iterator.generate_disposal_code(code) 57255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.iterator.free_temps(code) 57265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 57285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.generate_function_definitions(env, code) 57295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.iterator.generate_function_definitions(env, code) 57305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 57315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 57325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_function_definitions(env, code) 57335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 57355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.annotate(code) 57365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.iterator.annotate(code) 57375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 57385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 57395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.annotate(code) 57405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.item.annotate(code) 57415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ForFromStatNode(LoopNode, StatNode): 57445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # for name from expr rel name rel expr 57455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 57465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # target NameNode 57475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # bound1 ExprNode 57485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # relation1 string 57495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # relation2 string 57505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # bound2 ExprNode 57515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # step ExprNode or None 57525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 57535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # else_clause StatNode or None 57545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 57555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Used internally: 57565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 57575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # from_range bool 57585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_py_target bool 57595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # loopvar_node ExprNode (usually a NameNode or temp node) 57605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # py_loopvar_node PyTempNode or None 57615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"] 57625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_py_target = False 57645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loopvar_node = None 57655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) py_loopvar_node = None 57665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from_range = False 57675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "For-loop using object bounds or target" 57695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def nogil_check(self, env): 57715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for x in (self.target, self.bound1, self.bound2): 57725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if x.type.is_pyobject: 57735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.gil_error() 57745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 57765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.analyse_target_declaration(env) 57775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 57785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 57795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.analyse_declarations(env) 57805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 57825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 57835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target = self.target.analyse_target_types(env) 57845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound1 = self.bound1.analyse_types(env) 57855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound2 = self.bound2.analyse_types(env) 57865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.step is not None: 57875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.step, ExprNodes.UnaryMinusNode): 57885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(self.step.pos, "Probable infinite loop in for-from-by statement. Consider switching the directions of the relations.", 2) 57895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.step = self.step.analyse_types(env) 57905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 57915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target.type.is_numeric: 57925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loop_type = self.target.type 57935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 57945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loop_type = PyrexTypes.c_int_type 57955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.bound1.type.is_pyobject: 57965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type) 57975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.bound2.type.is_pyobject: 57985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type) 57995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.step is not None and not self.step.type.is_pyobject: 58005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type) 58015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound1 = self.bound1.coerce_to(loop_type, env) 58025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound2 = self.bound2.coerce_to(loop_type, env) 58035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.bound2.is_literal: 58045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound2 = self.bound2.coerce_to_temp(env) 58055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.step is not None: 58065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.step = self.step.coerce_to(loop_type, env) 58075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.step.is_literal: 58085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.step = self.step.coerce_to_temp(env) 58095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 58105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_type = self.target.type 58115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not (target_type.is_pyobject or target_type.is_numeric): 58125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.target.pos, 58135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "for-from loop variable must be c numeric type or Python object") 58145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if target_type.is_numeric: 58155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_py_target = False 58165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access: 58175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) raise error(self.pos, "Buffer indexing not allowed as for loop target.") 58185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.loopvar_node = self.target 58195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_loopvar_node = None 58205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 58215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_py_target = True 58225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env) 58235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.loopvar_node = c_loopvar_node 58245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_loopvar_node = \ 58255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env) 58265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 58275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 58285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause = self.else_clause.analyse_expressions(env) 58295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 58305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 58315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 58325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_loop_labels = code.new_loop_labels() 58335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from_range = self.from_range 58345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound1.generate_evaluation_code(code) 58355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound2.generate_evaluation_code(code) 58365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) offset, incop = self.relation_table[self.relation1] 58375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.step is not None: 58385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.step.generate_evaluation_code(code) 58395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) step = self.step.result() 58405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) incop = "%s=%s" % (incop[0], step) 58415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 58425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.loopvar_node, ExprNodes.TempNode): 58435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.loopvar_node.allocate(code) 58445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.py_loopvar_node, ExprNodes.TempNode): 58455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_loopvar_node.allocate(code) 58465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if from_range: 58475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loopvar_name = code.funcstate.allocate_temp(self.target.type, False) 58485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 58495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loopvar_name = self.loopvar_node.result() 58505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 58515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "for (%s = %s%s; %s %s %s; %s%s) {" % ( 58525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loopvar_name, 58535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound1.result(), offset, 58545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loopvar_name, self.relation2, self.bound2.result(), 58555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loopvar_name, incop)) 58565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_loopvar_node: 58575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_loopvar_node.generate_evaluation_code(code) 58585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.generate_assignment_code(self.py_loopvar_node, code) 58595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif from_range: 58605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % ( 58615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.result(), loopvar_name)) 58625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 58635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(code.continue_label) 58645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_loopvar_node: 58655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This mess is to make for..from loops with python targets behave 58665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exactly like those with C targets with regards to re-assignment 58675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # of the loop variable. 58685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 58695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target.entry.is_pyglobal: 58705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # We know target is a NameNode, this is the only ugly case. 58715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_node = ExprNodes.PyTempNode(self.target.pos, None) 58725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_node.allocate(code) 58735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) interned_cname = code.intern_identifier(self.target.entry.name) 58745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target.entry.scope.is_module_scope: 58755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 58765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c")) 58775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lookup_func = '__Pyx_GetModuleGlobalName(%s)' 58785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 58795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 58805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("GetNameInClass", "ObjectHandling.c")) 58815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lookup_func = '__Pyx_GetNameInClass(%s, %%s)' % ( 58825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.entry.scope.namespace_cname) 58835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s; %s" % ( 58845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_node.result(), 58855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lookup_func % interned_cname, 58865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if_null(target_node.result(), self.target.pos))) 58875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(target_node.result()) 58885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 58895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_node = self.target 58905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from_py_node = ExprNodes.CoerceFromPyTypeNode( 58915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.loopvar_node.type, target_node, self.target.entry.scope) 58925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from_py_node.temp_code = loopvar_name 58935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from_py_node.generate_result_code(code) 58945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target.entry.is_pyglobal: 58955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref(target_node.result(), target_node.type) 58965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_node.release(code) 58975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 58985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.py_loopvar_node: 58995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This is potentially wasteful, but we don't want the semantics to 59005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # depend on whether or not the loop is a python type. 59015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_loopvar_node.generate_evaluation_code(code) 59025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.generate_assignment_code(self.py_loopvar_node, code) 59035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if from_range: 59045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(loopvar_name) 59055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break_label = code.break_label 59065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.set_loop_labels(old_loop_labels) 59075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 59085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/*else*/ {") 59095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_execution_code(code) 59105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 59115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(break_label) 59125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound1.generate_disposal_code(code) 59135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound1.free_temps(code) 59145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound2.generate_disposal_code(code) 59155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound2.free_temps(code) 59165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.loopvar_node, ExprNodes.TempNode): 59175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.loopvar_node.release(code) 59185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.py_loopvar_node, ExprNodes.TempNode): 59195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.py_loopvar_node.release(code) 59205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.step is not None: 59215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.step.generate_disposal_code(code) 59225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.step.free_temps(code) 59235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) relation_table = { 59255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # {relop : (initial offset, increment op)} 59265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '<=': ("", "++"), 59275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '<' : ("+1", "++"), 59285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '>=': ("", "--"), 59295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '>' : ("-1", "--") 59305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 59315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 59335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.generate_function_definitions(env, code) 59345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound1.generate_function_definitions(env, code) 59355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound2.generate_function_definitions(env, code) 59365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.step is not None: 59375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.step.generate_function_definitions(env, code) 59385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 59395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 59405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_function_definitions(env, code) 59415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 59435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.annotate(code) 59445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound1.annotate(code) 59455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.bound2.annotate(code) 59465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.step: 59475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.step.annotate(code) 59485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 59495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 59505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.annotate(code) 59515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class WithStatNode(StatNode): 59545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 59555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Represents a Python with statement. 59565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Implemented by the WithTransform as follows: 59585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MGR = EXPR 59605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXIT = MGR.__exit__ 59615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) VALUE = MGR.__enter__() 59625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXC = True 59635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try: 59645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try: 59655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TARGET = VALUE # optional 59665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BODY 59675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except: 59685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXC = False 59695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not EXIT(*EXCINFO): 59705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) raise 59715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) finally: 59725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if EXC: 59735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXIT(None, None, None) 59745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MGR = EXIT = VALUE = None 59755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 59765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # manager The with statement manager object 59775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # target ExprNode the target lhs of the __enter__() call 59785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 59795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # enter_call ExprNode the call to the __enter__() method 59805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exit_var String the cname of the __exit__() method reference 59815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["manager", "enter_call", "target", "body"] 59835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) enter_call = None 59855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 59875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.manager.analyse_declarations(env) 59885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.enter_call.analyse_declarations(env) 59895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 59905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 59925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.manager = self.manager.analyse_types(env) 59935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.enter_call = self.enter_call.analyse_types(env) 59945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 59955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 59965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 59975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 59985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.manager.generate_function_definitions(env, code) 59995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.enter_call.generate_function_definitions(env, code) 60005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 60015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 60035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/*with:*/ {") 60045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.manager.generate_evaluation_code(code) 60055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exit_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False) 60065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 60075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("PyObjectLookupSpecial", "ObjectHandling.c")) 60085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = __Pyx_PyObject_LookupSpecial(%s, %s); %s" % ( 60095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exit_var, 60105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.manager.py_result(), 60115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.intern_identifier(EncodedString('__exit__')), 60125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if_null(self.exit_var, self.pos), 60135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) )) 60145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(self.exit_var) 60155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # need to free exit_var in the face of exceptions during setup 60175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_error_label = code.new_error_label() 60185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) intermediate_error_label = code.error_label 60195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.enter_call.generate_evaluation_code(code) 60215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.target: 60225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.enter_call.generate_disposal_code(code) 60235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.enter_call.free_temps(code) 60245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 60255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Otherwise, the node will be cleaned up by the 60265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # WithTargetAssignmentStatNode after assigning its result 60275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # to the target of the 'with' statement. 60285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 60295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.manager.generate_disposal_code(code) 60305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.manager.free_temps(code) 60315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_label = old_error_label 60335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 60345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(intermediate_error_label): 60365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) step_over_label = code.new_label() 60375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(step_over_label) 60385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(intermediate_error_label) 60395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(self.exit_var, py_object_type) 60405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(old_error_label) 60415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(step_over_label) 60425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(self.exit_var) 60445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 60455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class WithTargetAssignmentStatNode(AssignmentNode): 60475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The target assignment of the 'with' statement value (return 60485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # value of the __enter__() call). 60495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 60505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This is a special cased assignment that steals the RHS reference 60515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # and frees its temp. 60525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 60535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # lhs ExprNode the assignment target 60545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # rhs CloneNode a (coerced) CloneNode for the orig_rhs (not owned by this node) 60555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # orig_rhs ExprNode the original ExprNode of the rhs. this node will clean up the 60565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # temps of the orig_rhs. basically, it takes ownership of the node 60575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # when the WithStatNode is done with it. 60585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["lhs"] 60605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 60625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.analyse_target_declaration(env) 60635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 60655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = self.rhs.analyse_types(env) 60665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs = self.lhs.analyse_target_types(env) 60675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.gil_assignment_check(env) 60685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs = self.rhs.coerce_to(self.lhs.type, env) 60695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 60705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 60725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.orig_rhs.type.is_pyobject: 60735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # make sure rhs gets freed on errors, see below 60745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_error_label = code.new_error_label() 60755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) intermediate_error_label = code.error_label 60765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.generate_evaluation_code(code) 60785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.generate_assignment_code(self.rhs, code) 60795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.orig_rhs.type.is_pyobject: 60815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.orig_rhs.generate_disposal_code(code) 60825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_label = old_error_label 60835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(intermediate_error_label): 60845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) step_over_label = code.new_label() 60855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(step_over_label) 60865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(intermediate_error_label) 60875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.orig_rhs.generate_disposal_code(code) 60885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(old_error_label) 60895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(step_over_label) 60905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.orig_rhs.free_temps(code) 60925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 60945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.lhs.annotate(code) 60955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.rhs.annotate(code) 60965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 60985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TryExceptStatNode(StatNode): 60995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # try .. except statement 61005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 61015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 61025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # except_clauses [ExceptClauseNode] 61035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # else_clause StatNode or None 61045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["body", "except_clauses", "else_clause"] 61065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 61085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 61095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for except_clause in self.except_clauses: 61105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except_clause.analyse_declarations(env) 61115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 61125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.analyse_declarations(env) 61135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 61155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 61165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_clause_seen = 0 61175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, except_clause in enumerate(self.except_clauses): 61185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except_clause = self.except_clauses[i] = except_clause.analyse_expressions(env) 61195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if default_clause_seen: 61205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(except_clause.pos, "default 'except:' must be last") 61215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not except_clause.pattern: 61225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default_clause_seen = 1 61235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.has_default_clause = default_clause_seen 61245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 61255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause = self.else_clause.analyse_expressions(env) 61265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 61275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = Node.gil_error 61295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Try-except statement" 61305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 61325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_return_label = code.return_label 61335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_break_label = code.break_label 61345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_continue_label = code.continue_label 61355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_error_label = code.new_error_label() 61365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) our_error_label = code.error_label 61375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except_end_label = code.new_label('exception_handled') 61385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except_error_label = code.new_label('except_error') 61395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except_return_label = code.new_label('except_return') 61405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try_return_label = code.new_label('try_return') 61415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try_break_label = code.new_label('try_break') 61425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try_continue_label = code.new_label('try_continue') 61435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try_end_label = code.new_label('try_end') 61445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False) 61465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for _ in xrange(3)] 61475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("{") 61485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) save_exc = code.insertion_point() 61495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 61505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "/*try:*/ {") 61515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.return_label = try_return_label 61525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.break_label = try_break_label 61535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.continue_label = try_continue_label 61545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 61555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 61565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") 61575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temps_to_clean_up = code.funcstate.all_free_managed_temps() 61585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) can_raise = code.label_used(our_error_label) 61595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if can_raise: 61615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # inject code before the try block to save away the exception state 61625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(reset_exception_utility_code) 61635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) save_exc.putln("__Pyx_ExceptionSave(%s);" % 61645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ', '.join(['&%s' % var for var in exc_save_vars])) 61655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_save_vars: 61665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) save_exc.put_xgotref(var) 61675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def restore_saved_exception(): 61695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name in exc_save_vars: 61705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xgiveref(name) 61715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ExceptionReset(%s);" % 61725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ', '.join(exc_save_vars)) 61735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 61745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # try block cannot raise exceptions, but we had to allocate the temps above, 61755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # so just keep the C compiler from complaining about them being unused 61765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) save_exc.putln("if (%s); else {/*mark used*/};" % '||'.join(exc_save_vars)) 61775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def restore_saved_exception(): 61795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 61805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_label = except_error_label 61825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.return_label = except_return_label 61835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 61845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 61855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "/*else:*/ {") 61865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_execution_code(code) 61875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 61885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") 61895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 61905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if can_raise: 61915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_save_vars: 61925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref_clear(var, py_object_type) 61935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(try_end_label) 61945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(our_error_label) 61955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for temp_name, temp_type in temps_to_clean_up: 61965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref_clear(temp_name, temp_type) 61975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for except_clause in self.except_clauses: 61985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except_clause.generate_handling_code(code, except_end_label) 61995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.has_default_clause: 62005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(except_error_label) 62015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for exit_label, old_label in [(except_error_label, old_error_label), 62035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (try_break_label, old_break_label), 62045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (try_continue_label, old_continue_label), 62055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (try_return_label, old_return_label), 62065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (except_return_label, old_return_label)]: 62075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(exit_label): 62085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not code.label_used(try_end_label): 62095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(try_end_label) 62105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(exit_label) 62115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) restore_saved_exception() 62125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(old_label) 62135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(except_end_label): 62155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not code.label_used(try_end_label): 62165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(try_end_label) 62175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(except_end_label) 62185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) restore_saved_exception() 62195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(try_end_label): 62205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(try_end_label) 62215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 62225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cname in exc_save_vars: 62245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(cname) 62255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.return_label = old_return_label 62275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.break_label = old_break_label 62285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.continue_label = old_continue_label 62295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_label = old_error_label 62305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 62325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 62335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for except_clause in self.except_clauses: 62345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except_clause.generate_function_definitions(env, code) 62355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 62365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_function_definitions(env, code) 62375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 62395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 62405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for except_node in self.except_clauses: 62415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except_node.annotate(code) 62425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 62435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.annotate(code) 62445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ExceptClauseNode(Node): 62475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Part of try ... except statement. 62485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 62495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # pattern [ExprNode] 62505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # target ExprNode or None 62515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 62525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # excinfo_target TupleNode(3*ResultRefNode) or None optional target for exception info (not owned here!) 62535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # match_flag string result of exception match 62545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exc_value ExcValueNode used internally 62555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # function_name string qualified name of enclosing function 62565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exc_vars (string * 3) local exception variables 62575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # is_except_as bool Py3-style "except ... as xyz" 62585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # excinfo_target is never set by the parser, but can be set by a transform 62605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # in order to extract more extensive information about the exception as a 62615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # sys.exc_info()-style tuple into a target variable 62625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["pattern", "target", "body", "exc_value"] 62645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_value = None 62665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) excinfo_target = None 62675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_except_as = False 62685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 62705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target: 62715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.analyse_target_declaration(env) 62725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 62735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 62755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.function_name = env.qualified_name 62765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.pattern: 62775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # normalise/unpack self.pattern into a list 62785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, pattern in enumerate(self.pattern): 62795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pattern = pattern.analyse_expressions(env) 62805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.pattern[i] = pattern.coerce_to_pyobject(env) 62815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target: 62835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 62845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_value = ExprNodes.ExcValueNode(self.pos) 62855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target = self.target.analyse_target_expression(env, self.exc_value) 62865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 62885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 62895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_handling_code(self, code, end_label): 62915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 62925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.pattern: 62935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_tests = [] 62945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for pattern in self.pattern: 62955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pattern.generate_evaluation_code(code) 62965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result()) 62975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 62985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False) 62995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 63005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "%s = %s;" % (match_flag, ' || '.join(exc_tests))) 63015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for pattern in self.pattern: 63025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pattern.generate_disposal_code(code) 63035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pattern.free_temps(code) 63045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 63055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (%s) {" % 63065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) match_flag) 63075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(match_flag) 63085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 63095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/*except:*/ {") 63105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (not getattr(self.body, 'stats', True) 63125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and self.excinfo_target is None 63135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and self.target is None): 63145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # most simple case: no exception variable, empty body (pass) 63155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # => reset the exception state, done 63165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("PyErr_Restore(0,0,0);") 63175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(end_label) 63185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 63195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 63205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_vars = [code.funcstate.allocate_temp(py_object_type, 63225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) manage_ref=True) 63235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for _ in xrange(3)] 63245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_add_traceback(self.function_name) 63255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # We always have to fetch the exception value even if 63265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # there is no target, because this also normalises the 63275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exception and stores it in the thread state. 63285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(get_exception_utility_code) 63295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_args = "&%s, &%s, &%s" % tuple(exc_vars) 63305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args, 63315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(self.pos))) 63325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for x in exc_vars: 63335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(x) 63345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target: 63355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_value.set_var(exc_vars[1]) 63365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.exc_value.generate_evaluation_code(code) 63375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.generate_assignment_code(self.exc_value, code) 63385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.excinfo_target is not None: 63395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for tempvar, node in zip(exc_vars, self.excinfo_target.args): 63405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.set_var(tempvar) 63415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_break_label, old_continue_label = code.break_label, code.continue_label 63435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.break_label = code.new_label('except_break') 63445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.continue_label = code.new_label('except_continue') 63455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_exc_vars = code.funcstate.exc_vars 63475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.exc_vars = exc_vars 63485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 63495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.exc_vars = old_exc_vars 63505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_vars: 63515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(var, py_object_type) 63525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(end_label) 63535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for new_label, old_label in [(code.break_label, old_break_label), 63555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (code.continue_label, old_continue_label)]: 63565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(new_label): 63575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(new_label) 63585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_vars: 63595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(var, py_object_type) 63605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(old_label) 63615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.break_label = old_break_label 63625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.continue_label = old_continue_label 63635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for temp in exc_vars: 63655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(temp) 63665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 63685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") 63695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 63715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target is not None: 63725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.generate_function_definitions(env, code) 63735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 63745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 63765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.pattern: 63775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for pattern in self.pattern: 63785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pattern.annotate(code) 63795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target: 63805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.annotate(code) 63815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 63825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TryFinallyStatNode(StatNode): 63855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # try ... finally statement 63865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 63875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # body StatNode 63885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # finally_clause StatNode 63895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 63905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The plan is that we funnel all continue, break 63915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # return and error gotos into the beginning of the 63925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # finally block, setting a variable to remember which 63935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # one we're doing. At the end of the finally block, we 63945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # switch on the variable to figure out where to go. 63955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # In addition, if we're doing an error, we save the 63965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exception on entry to the finally block and restore 63975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # it on exit. 63985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 63995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["body", "finally_clause"] 64005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) preserve_exception = 1 64025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # handle exception case, in addition to return/break/continue 64045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) handle_error_case = True 64055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) func_return_type = None 64065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) disallow_continue_in_try_finally = 0 64085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # There doesn't seem to be any point in disallowing 64095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # continue in the try block, since we have no problem 64105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # handling it. 64115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_try_finally_in_nogil = False 64135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def create_analysed(pos, env, body, finally_clause): 64155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause) 64165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return node 64175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) create_analysed = staticmethod(create_analysed) 64185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 64205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 64215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.finally_clause.analyse_declarations(env) 64225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 64245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 64255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.finally_clause = self.finally_clause.analyse_expressions(env) 64265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if env.return_type and not env.return_type.is_void: 64275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.func_return_type = env.return_type 64285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 64295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = Node.gil_error 64315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gil_message = "Try-finally statement" 64325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 64345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_error_label = code.error_label 64355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_labels = code.all_new_labels() 64365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_labels = code.get_all_labels() 64375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_error_label = code.error_label 64385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.handle_error_case: 64395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_label = old_error_label 64405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) catch_label = code.new_label() 64415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/*try:*/ {") 64435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.disallow_continue_in_try_finally: 64455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) was_in_try_finally = code.funcstate.in_try_finally 64465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.in_try_finally = 1 64475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 64495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.disallow_continue_in_try_finally: 64515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.in_try_finally = was_in_try_finally 64525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 64545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.set_all_labels(old_labels) 64555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temps_to_clean_up = code.funcstate.all_free_managed_temps() 64575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.finally_clause.pos) 64585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/*finally:*/ {") 64595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def fresh_finally_clause(_next=[self.finally_clause]): 64615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # generate the original subtree once and always keep a fresh copy 64625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = _next[0] 64635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node_copy = copy.deepcopy(node) 64645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if node is self.finally_clause: 64655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _next[0] = node_copy 64665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 64675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = node_copy 64685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return node 64695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) preserve_error = self.preserve_exception and code.label_used(new_error_label) 64715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) needs_success_cleanup = not self.finally_clause.is_terminator 64725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.body.is_terminator: 64745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('/*normal exit:*/{') 64755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fresh_finally_clause().generate_execution_code(code) 64765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.finally_clause.is_terminator: 64775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(catch_label) 64785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 64795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 64805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if preserve_error: 64815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('/*exception exit:*/{') 64825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_try_finally_in_nogil: 64835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.declare_gilstate() 64845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if needs_success_cleanup: 64855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_lineno_cnames = tuple([ 64865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False) 64875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for _ in range(2)]) 64885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_filename_cname = code.funcstate.allocate_temp( 64895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyrexTypes.CPtrType(PyrexTypes.c_const_type(PyrexTypes.c_char_type)), 64905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) manage_ref=False) 64915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 64925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_lineno_cnames = exc_filename_cname = None 64935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_vars = tuple([ 64945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.allocate_temp(py_object_type, manage_ref=False) 64955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for _ in range(6)]) 64965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(new_error_label) 64975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.put_error_catcher( 64985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code, temps_to_clean_up, exc_vars, exc_lineno_cnames, exc_filename_cname) 64995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) finally_old_labels = code.all_new_labels() 65005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('{') 65025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_exc_vars = code.funcstate.exc_vars 65035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.exc_vars = exc_vars[:3] 65045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fresh_finally_clause().generate_execution_code(code) 65055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.exc_vars = old_exc_vars 65065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 65075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if needs_success_cleanup: 65095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.put_error_uncatcher(code, exc_vars, exc_lineno_cnames, exc_filename_cname) 65105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if exc_lineno_cnames: 65115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cname in exc_lineno_cnames: 65125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(cname) 65135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if exc_filename_cname: 65145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(exc_filename_cname) 65155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(old_error_label) 65165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for new_label, old_label in zip(code.get_all_labels(), finally_old_labels): 65185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not code.label_used(new_label): 65195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 65205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(new_label) 65215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.put_error_cleaner(code, exc_vars) 65225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(old_label) 65235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for cname in exc_vars: 65255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(cname) 65265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 65275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.set_all_labels(old_labels) 65295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return_label = code.return_label 65305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, (new_label, old_label) in enumerate(zip(new_labels, old_labels)): 65315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not code.label_used(new_label): 65325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 65335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if new_label == new_error_label and preserve_error: 65345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue # handled above 65355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('%s: ' % new_label) 65375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('{') 65385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret_temp = None 65395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if old_label == return_label and not self.finally_clause.is_terminator: 65405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # store away return value for later reuse 65415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (self.func_return_type and 65425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not self.is_try_finally_in_nogil and 65435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) not isinstance(self.finally_clause, GILExitNode)): 65445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret_temp = code.funcstate.allocate_temp( 65455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.func_return_type, manage_ref=False) 65465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (ret_temp, Naming.retval_cname)) 65475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.func_return_type.is_pyobject: 65485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = 0;" % Naming.retval_cname) 65495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fresh_finally_clause().generate_execution_code(code) 65505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ret_temp: 65515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (Naming.retval_cname, ret_temp)) 65525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.func_return_type.is_pyobject: 65535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = 0;" % ret_temp) 65545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(ret_temp) 65555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret_temp = None 65565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.finally_clause.is_terminator: 65575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(old_label) 65585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln('}') 65595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # End finally 65615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(catch_label) 65625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 65635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") 65645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 65665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_function_definitions(env, code) 65675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.finally_clause.generate_function_definitions(env, code) 65685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def put_error_catcher(self, code, temps_to_clean_up, exc_vars, 65705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_lineno_cnames, exc_filename_cname): 65715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(restore_exception_utility_code) 65725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(get_exception_utility_code) 65735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(swap_exception_utility_code) 65745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(' '.join(["%s = 0;"]*len(exc_vars)) % exc_vars) 65765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_try_finally_in_nogil: 65775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil(declare_gilstate=False) 65785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for temp_name, type in temps_to_clean_up: 65805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref_clear(temp_name, type) 65815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # not using preprocessor here to avoid warnings about 65835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # unused utility functions and/or temps 65845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (PY_MAJOR_VERSION >= 3)" 65855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) " __Pyx_ExceptionSwap(&%s, &%s, &%s);" % exc_vars[3:]) 65865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if ((PY_MAJOR_VERSION < 3) ||" 65875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # if __Pyx_GetException() fails in Py3, 65885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # store the newly raised exception instead 65895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) " unlikely(__Pyx_GetException(&%s, &%s, &%s) < 0)) " 65905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "__Pyx_ErrFetch(&%s, &%s, &%s);" % (exc_vars[:3] * 2)) 65915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_vars: 65925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xgotref(var) 65935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if exc_lineno_cnames: 65945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s; %s = %s; %s = %s;" % ( 65955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_lineno_cnames[0], Naming.lineno_cname, 65965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_lineno_cnames[1], Naming.clineno_cname, 65975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exc_filename_cname, Naming.filename_cname)) 65985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 65995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_try_finally_in_nogil: 66005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 66015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def put_error_uncatcher(self, code, exc_vars, exc_lineno_cnames, exc_filename_cname): 66035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(restore_exception_utility_code) 66045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(reset_exception_utility_code) 66055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_try_finally_in_nogil: 66075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil(declare_gilstate=False) 66085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # not using preprocessor here to avoid warnings about 66105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # unused utility functions and/or temps 66115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (PY_MAJOR_VERSION >= 3) {") 66125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_vars[3:]: 66135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xgiveref(var) 66145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ExceptionReset(%s, %s, %s);" % exc_vars[3:]) 66155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 66165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_vars[:3]: 66175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xgiveref(var) 66185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % exc_vars[:3]) 66195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_try_finally_in_nogil: 66215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 66225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(' '.join(["%s = 0;"]*len(exc_vars)) % exc_vars) 66245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if exc_lineno_cnames: 66255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s; %s = %s; %s = %s;" % ( 66265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.lineno_cname, exc_lineno_cnames[0], 66275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.clineno_cname, exc_lineno_cnames[1], 66285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.filename_cname, exc_filename_cname)) 66295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def put_error_cleaner(self, code, exc_vars): 66315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(reset_exception_utility_code) 66325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_try_finally_in_nogil: 66335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil(declare_gilstate=False) 66345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # not using preprocessor here to avoid warnings about 66355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # unused utility functions and/or temps 66365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (PY_MAJOR_VERSION >= 3) {") 66375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_vars[3:]: 66385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xgiveref(var) 66395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ExceptionReset(%s, %s, %s);" % exc_vars[3:]) 66405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") 66415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for var in exc_vars[:3]: 66425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref_clear(var, py_object_type) 66435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_try_finally_in_nogil: 66445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 66455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(' '.join(["%s = 0;"]*3) % exc_vars[3:]) 66465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def annotate(self, code): 66485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.annotate(code) 66495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.finally_clause.annotate(code) 66505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class NogilTryFinallyStatNode(TryFinallyStatNode): 66535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 66545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) A try/finally statement that may be used in nogil code sections. 66555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 66565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) preserve_exception = False 66585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = None 66595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class GILStatNode(NogilTryFinallyStatNode): 66625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 'with gil' or 'with nogil' statement 66635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 66645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # state string 'gil' or 'nogil' 66655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state_temp = None 66675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, pos, state, body): 66695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.state = state 66705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.create_state_temp_if_needed(pos, state, body) 66715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TryFinallyStatNode.__init__(self, pos, 66725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body=body, 66735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) finally_clause=GILExitNode( 66745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos, state=state, state_temp=self.state_temp)) 66755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def create_state_temp_if_needed(self, pos, state, body): 66775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from ParseTreeTransforms import YieldNodeCollector 66785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) collector = YieldNodeCollector() 66795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) collector.visitchildren(body) 66805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not collector.yields: 66815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 66825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if state == 'gil': 66845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_type = PyrexTypes.c_gilstate_type 66855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 66865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_type = PyrexTypes.c_threadstate_ptr_type 66875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 66885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.state_temp = ExprNodes.TempNode(pos, temp_type) 66895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 66915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env._in_with_gil_block = (self.state == 'gil') 66925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.state == 'gil': 66935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.has_with_gil_block = True 66945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return super(GILStatNode, self).analyse_declarations(env) 66965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 66975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 66985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code( 66995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("ForceInitThreads", "ModuleSetupCode.c")) 67005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) was_nogil = env.nogil 67015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.nogil = self.state == 'nogil' 67025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = TryFinallyStatNode.analyse_expressions(self, env) 67035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.nogil = was_nogil 67045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return node 67055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 67075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.mark_pos(self.pos) 67085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() 67095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.state_temp: 67105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.state_temp.allocate(code) 67115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) variable = self.state_temp.result() 67125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 67135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) variable = None 67145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) old_trace_config = code.funcstate.can_trace 67165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.state == 'gil': 67175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil(variable=variable) 67185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # FIXME: not that easy, tracing may not be possible at all here 67195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #code.funcstate.can_trace = True 67205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 67215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_gil(variable=variable) 67225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.can_trace = False 67235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TryFinallyStatNode.generate_execution_code(self, code) 67255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.state_temp: 67275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.state_temp.release(code) 67285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.can_trace = old_trace_config 67305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() 67315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class GILExitNode(StatNode): 67345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 67355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Used as the 'finally' block in a GILStatNode 67365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state string 'gil' or 'nogil' 67385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 67395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 67415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state_temp = None 67425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 67445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 67455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 67475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.state_temp: 67485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) variable = self.state_temp.result() 67495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 67505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) variable = None 67515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.state == 'gil': 67535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil(variable) 67545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 67555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_acquire_gil(variable) 67565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class EnsureGILNode(GILExitNode): 67595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 67605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Ensure the GIL in nogil functions for cleanup before returning. 67615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 67625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 67645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil(declare_gilstate=False) 67655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)utility_code_for_cimports = { 67675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # utility code (or inlining c) in a pxd (or pyx) file. 67685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # TODO: Consider a generic user-level mechanism for importing 67695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'cpython.array' : ("ArrayAPI", "arrayarray.h"), 67705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'cpython.array.array' : ("ArrayAPI", "arrayarray.h"), 67715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 67725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CImportStatNode(StatNode): 67745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cimport statement 67755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 67765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # module_name string Qualified name of module being imported 67775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # as_name string or None Name specified in "as" clause, if any 67785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 67805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 67815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 67825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not env.is_module_scope: 67835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "cimport only allowed at module level") 67845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 67855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_scope = env.find_module(self.module_name, self.pos) 67865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if "." in self.module_name: 67875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) names = [EncodedString(name) for name in self.module_name.split(".")] 67885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) top_name = names[0] 67895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) top_module_scope = env.context.find_submodule(top_name) 67905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_scope = top_module_scope 67915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name in names[1:]: 67925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) submodule_scope = module_scope.find_submodule(name) 67935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_scope.declare_module(name, submodule_scope, self.pos) 67945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_scope = submodule_scope 67955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.as_name: 67965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_module(self.as_name, module_scope, self.pos) 67975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 67985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_imported_module(module_scope) 67995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_module(top_name, top_module_scope, self.pos) 68005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 68015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) name = self.as_name or self.module_name 68025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_module(name, module_scope, self.pos) 68035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.module_name in utility_code_for_cimports: 68045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(UtilityCode.load_cached( 68055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *utility_code_for_cimports[self.module_name])) 68065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 68085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 68095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 68115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 68125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FromCImportStatNode(StatNode): 68155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # from ... cimport statement 68165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 68175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # module_name string Qualified name of module 68185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # imported_names [(pos, name, as_name, kind)] Names to be imported 68195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = [] 68215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 68235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not env.is_module_scope: 68245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "cimport only allowed at module level") 68255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 68265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_scope = env.find_module(self.module_name, self.pos) 68275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_imported_module(module_scope) 68285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for pos, name, as_name, kind in self.imported_names: 68295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name == "*": 68305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for local_name, entry in module_scope.entries.items(): 68315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_imported_entry(local_name, entry, pos) 68325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 68335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = module_scope.lookup(name) 68345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry: 68355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if kind and not self.declaration_matches(entry, kind): 68365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.redeclared(pos) 68375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.used = 1 68385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 68395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if kind == 'struct' or kind == 'union': 68405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = module_scope.declare_struct_or_union(name, 68415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kind = kind, scope = None, typedef_flag = 0, pos = pos) 68425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif kind == 'class': 68435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = module_scope.declare_c_class(name, pos = pos, 68445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module_name = self.module_name) 68455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 68465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos) 68475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if submodule_scope.parent_module is module_scope: 68485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.declare_module(as_name or name, submodule_scope, self.pos) 68495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 68505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(pos, "Name '%s' not declared in module '%s'" 68515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) % (name, self.module_name)) 68525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry: 68545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) local_name = as_name or name 68555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.add_imported_entry(local_name, entry, pos) 68565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.module_name.startswith('cpython'): # enough for now 68585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.module_name in utility_code_for_cimports: 68595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(UtilityCode.load_cached( 68605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *utility_code_for_cimports[self.module_name])) 68615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for _, name, _, _ in self.imported_names: 68625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fqname = '%s.%s' % (self.module_name, name) 68635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if fqname in utility_code_for_cimports: 68645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(UtilityCode.load_cached( 68655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *utility_code_for_cimports[fqname])) 68665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declaration_matches(self, entry, kind): 68685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not entry.is_type: 68695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0 68705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type = entry.type 68715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if kind == 'class': 68725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not type.is_extension_type: 68735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0 68745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 68755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not type.is_struct_or_union: 68765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0 68775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if kind != type.kind: 68785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0 68795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 1 68805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 68825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 68835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 68855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 68865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FromImportStatNode(StatNode): 68895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # from ... import statement 68905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 68915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # module ImportNode 68925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # items [(string, NameNode)] 68935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # interned_items [(string, NameNode, ExprNode)] 68945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # item PyTempNode used internally 68955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # import_star boolean used internally 68965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ["module"] 68985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import_star = 0 68995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 69015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name, target in self.items: 69025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name == "*": 69035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not env.is_module_scope: 69045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "import * only allowed at module level") 69055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 69065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.has_import_star = 1 69075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.import_star = 1 69085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 69095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.analyse_target_declaration(env) 69105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 69125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ExprNodes 69135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module = self.module.analyse_expressions(env) 69145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type) 69155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.interned_items = [] 69165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name, target in self.items: 69175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if name == '*': 69185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for _, entry in env.entries.items(): 69195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not entry.is_type and entry.type.is_extension_type: 69205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.use_utility_code(UtilityCode.load_cached("ExtTypeTest", "ObjectHandling.c")) 69215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break 69225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 69235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = env.lookup(target.name) 69245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # check whether or not entry is already cimported 69255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (entry.is_type and entry.type.name == name 69265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and hasattr(entry.type, 'module_name')): 69275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.module_name == self.module.module_name.value: 69285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cimported with absolute name 69295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 69305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try: 69315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # cimported with relative name 69325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) module = env.find_module(self.module.module_name.value, 69335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos=None) 69345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.module_name == module.qualified_name: 69355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 69365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except AttributeError: 69375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass 69385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target = target.analyse_target_expression(env, None) # FIXME? 69395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if target.type is py_object_type: 69405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coerced_item = None 69415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 69425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coerced_item = self.item.coerce_to(target.type, env) 69435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.interned_items.append((name, target, coerced_item)) 69445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 69455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 69475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module.generate_evaluation_code(code) 69485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.import_star: 69495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 69505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'if (%s(%s) < 0) %s;' % ( 69515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.import_star, 69525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module.py_result(), 69535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto(self.pos))) 69545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) 69555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.item.set_cname(item_temp) 69565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.interned_items: 69575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code( 69585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UtilityCode.load_cached("ImportFrom", "ImportExport.c")) 69595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name, target, coerced_item in self.interned_items: 69605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 69615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) '%s = __Pyx_ImportFrom(%s, %s); %s' % ( 69625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) item_temp, 69635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module.py_result(), 69645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.intern_identifier(name), 69655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.error_goto_if_null(item_temp, self.pos))) 69665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(item_temp) 69675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if coerced_item is None: 69685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.generate_assignment_code(self.item, code) 69695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 69705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coerced_item.allocate_temp_result(code) 69715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) coerced_item.generate_result_code(code) 69725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target.generate_assignment_code(coerced_item, code) 69735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_decref_clear(item_temp, py_object_type) 69745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(item_temp) 69755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module.generate_disposal_code(code) 69765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.module.free_temps(code) 69775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ParallelNode(Node): 69805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 69815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Base class for cython.parallel constructs. 69825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 69835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil_check = None 69855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ParallelStatNode(StatNode, ParallelNode): 69885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 69895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Base class for 'with cython.parallel.parallel():' and 'for i in prange():'. 69905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assignments { Entry(var) : (var.pos, inplace_operator_or_None) } 69925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assignments to variables in this parallel section 69935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent parent ParallelStatNode or None 69955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_parallel indicates whether this node is OpenMP parallel 69965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (true for #pragma omp parallel for and 69975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp parallel) 69985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 69995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_parallel is true for: 70005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp parallel 70025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp parallel for 70035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sections, but NOT for 70055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp for 70075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) We need this to determine the sharing attributes. 70095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) privatization_insertion_point a code insertion point used to make temps 70115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private (esp. the "nsteps" temp) 70125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) args tuple the arguments passed to the parallel construct 70145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kwargs DictNode the keyword arguments passed to the parallel 70155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) construct (replaced by its compile time value) 70165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 70175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['body', 'num_threads'] 70195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body = None 70215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_prange = False 70235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_nested_prange = False 70245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error_label_used = False 70265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) num_threads = None 70285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) chunksize = None 70295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parallel_exc = ( 70315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.parallel_exc_type, 70325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.parallel_exc_value, 70335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.parallel_exc_tb, 70345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ) 70355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parallel_pos_info = ( 70375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.parallel_filename, 70385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.parallel_lineno, 70395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.parallel_clineno, 70405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ) 70415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_info = ( 70435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.filename_cname, 70445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.lineno_cname, 70455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Naming.clineno_cname, 70465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ) 70475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) critical_section_counter = 0 70495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, pos, **kwargs): 70515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(ParallelStatNode, self).__init__(pos, **kwargs) 70525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # All assignments in this scope 70545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.assignments = kwargs.get('assignments') or {} 70555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # All seen closure cnames and their temporary cnames 70575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.seen_closure_vars = set() 70585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Dict of variables that should be declared (first|last|)private or 70605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # reduction { Entry: (op, lastprivate) }. 70615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # If op is not None, it's a reduction. 70625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.privates = {} 70635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # [NameNode] 70655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.assigned_nodes = [] 70665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 70685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.analyse_declarations(env) 70695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_threads = None 70715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.kwargs: 70735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Try to find num_threads and chunksize keyword arguments 70745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pairs = [] 70755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for dictitem in self.kwargs.key_value_pairs: 70765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if dictitem.key.value == 'num_threads': 70775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_threads = dictitem.value 70785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.is_prange and dictitem.key.value == 'chunksize': 70795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.chunksize = dictitem.value 70805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 70815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pairs.append(dictitem) 70825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.kwargs.key_value_pairs = pairs 70845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) try: 70865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.kwargs = self.kwargs.compile_time_value(env) 70875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) except Exception, e: 70885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.kwargs.pos, "Only compile-time values may be " 70895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "supplied as keyword arguments") 70905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 70915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.kwargs = {} 70925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for kw, val in self.kwargs.iteritems(): 70945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if kw not in self.valid_keyword_arguments: 70955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Invalid keyword argument: %s" % kw) 70965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 70975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) setattr(self, kw, val) 70985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 70995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 71005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.num_threads: 71015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_threads = self.num_threads.analyse_expressions(env) 71025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.chunksize: 71045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.chunksize = self.chunksize.analyse_expressions(env) 71055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body = self.body.analyse_expressions(env) 71075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.analyse_sharing_attributes(env) 71085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.num_threads is not None: 71105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (self.parent and self.parent.num_threads is not None and not 71115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.parent.is_prange): 71125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 71135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "num_threads already declared in outer section") 71145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif self.parent and not self.parent.is_prange: 71155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 71165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "num_threads must be declared in the parent parallel section") 71175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif (self.num_threads.type.is_int and 71185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_threads.is_literal and 71195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_threads.compile_time_value(env) <= 0): 71205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, 71215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "argument to num_threads must be greater than 0") 71225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.num_threads.is_simple(): 71245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_threads = self.num_threads.coerce_to( 71255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyrexTypes.c_int_type, env).coerce_to_temp(env) 71265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 71275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_sharing_attributes(self, env): 71295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 71305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Analyse the privates for this block and set them in self.privates. 71315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) This should be called in a post-order fashion during the 71325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) analyse_expressions phase 71335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 71345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry, (pos, op) in self.assignments.iteritems(): 71355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_prange and not self.is_parallel: 71375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # closely nested prange in a with parallel block, disallow 71385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # assigning to privates in the with parallel block (we 71395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # consider it too implicit and magicky for users) 71405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry in self.parent.assignments: 71415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(pos, 71425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Cannot assign to private of outer parallel block") 71435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 71445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.is_prange and op: 71465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Again possible, but considered to magicky 71475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(pos, "Reductions not allowed for parallel blocks") 71485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 71495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # By default all variables should have the same values as if 71515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # executed sequentially 71525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lastprivate = True 71535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.propagate_var_privatization(entry, pos, op, lastprivate) 71545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def propagate_var_privatization(self, entry, pos, op, lastprivate): 71565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 71575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Propagate the sharing attributes of a variable. If the privatization is 71585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) determined by a parent scope, done propagate further. 71595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) If we are a prange, we propagate our sharing attributes outwards to 71615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) other pranges. If we are a prange in parallel block and the parallel 71625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) block does not determine the variable private, we propagate to the 71635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent of the parent. Recursion stops at parallel blocks, as they have 71645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) no concept of lastprivate or reduction. 71655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) So the following cases propagate: 71675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sum is a reduction for all loops: 71695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in prange(n): 71715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for j in prange(n): 71725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for k in prange(n): 71735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sum += i * j * k 71745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sum is a reduction for both loops, local_var is private to the 71765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parallel with block: 71775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in prange(n): 71795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with parallel: 71805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) local_var = ... # private to the parallel 71815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for j in prange(n): 71825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sum += i * j 71835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Nested with parallel blocks are disallowed, because they wouldn't 71855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) allow you to propagate lastprivates or reductions: 71865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp parallel for lastprivate(i) 71885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in prange(n): 71895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sum = 0 71915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp parallel private(j, sum) 71935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with parallel: 71945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp parallel 71965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with parallel: 71975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp for lastprivate(j) reduction(+:sum) 71995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for j in prange(n): 72005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sum += i 72015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # sum and j are well-defined here 72035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # sum and j are undefined here 72055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # sum and j are undefined here 72075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 72085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.privates[entry] = (op, lastprivate) 72095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_memoryviewslice: 72115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(pos, "Memoryview slices can only be shared in parallel sections") 72125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 72135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_prange: 72155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.is_parallel and entry not in self.parent.assignments: 72165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Parent is a parallel with block 72175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent = self.parent.parent 72185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 72195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent = self.parent 72205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # We don't need to propagate privates, only reductions and 72225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # lastprivates 72235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if parent and (op or lastprivate): 72245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent.propagate_var_privatization(entry, pos, op, lastprivate) 72255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def _allocate_closure_temp(self, code, entry): 72275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 72285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Helper function that allocate a temporary for a closure variable that 72295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is assigned to. 72305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 72315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.parent: 72325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self.parent._allocate_closure_temp(code, entry) 72335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.cname in self.seen_closure_vars: 72355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return entry.cname 72365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = code.funcstate.allocate_temp(entry.type, True) 72385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Add both the actual cname and the temp cname, as the actual cname 72405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # will be replaced with the temp cname on the entry 72415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.seen_closure_vars.add(entry.cname) 72425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.seen_closure_vars.add(cname) 72435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.modified_entries.append((entry, entry.cname)) 72455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (cname, entry.cname)) 72465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.cname = cname 72475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def initialize_privates_to_nan(self, code, exclude=None): 72495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first = True 72505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry, (op, lastprivate) in self.privates.iteritems(): 72525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not op and (not exclude or entry != exclude): 72535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) invalid_value = entry.type.invalid_value() 72545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if invalid_value: 72565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if first: 72575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* Initialize private variables to " 72585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "invalid values */") 72595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) first = False 72605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (entry.cname, 72615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.type.cast_code(invalid_value))) 72625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def evaluate_before_block(self, code, expr): 72645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c = self.begin_of_parallel_control_block_point_after_decls 72655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # we need to set the owner to ourselves temporarily, as 72665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # allocate_temp may generate a comment in the middle of our pragma 72675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # otherwise when DebugFlags.debug_temp_code_comments is in effect 72685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) owner = c.funcstate.owner 72695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.funcstate.owner = c 72705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) expr.generate_evaluation_code(c) 72715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.funcstate.owner = owner 72725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return expr.result() 72745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def put_num_threads(self, code): 72765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 72775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Write self.num_threads if set as the num_threads OpenMP directive 72785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 72795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.num_threads is not None: 72805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(" num_threads(%s)" % self.evaluate_before_block(code, 72815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.num_threads)) 72825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def declare_closure_privates(self, code): 72855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 72865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) If a variable is in a scope object, we need to allocate a temp and 72875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) assign the value from the temp to the variable in the scope object 72885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) after the parallel section. This kind of copying should be done only 72895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) in the outermost parallel section. 72905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 72915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.modified_entries = [] 72925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry in self.assignments: 72945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.from_closure or entry.in_closure: 72955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self._allocate_closure_temp(code, entry) 72965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 72975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def release_closure_privates(self, code): 72985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 72995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Release any temps used for variables in scope objects. As this is the 73005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outermost parallel block, we don't need to delete the cnames from 73015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.seen_closure_vars. 73025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 73035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry, original_cname in self.modified_entries: 73045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (original_cname, entry.cname)) 73055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(entry.cname) 73065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.cname = original_cname 73075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def privatize_temps(self, code, exclude_temps=()): 73095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 73105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Make any used temporaries private. Before the relevant code block 73115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.start_collecting_temps() should have been called. 73125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 73135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_parallel: 73145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c = self.privatization_insertion_point 73155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.temps = temps = code.funcstate.stop_collecting_temps() 73175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) privates, firstprivates = [], [] 73185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for temp, type in temps: 73195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.is_pyobject or type.is_memoryviewslice: 73205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) firstprivates.append(temp) 73215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 73225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) privates.append(temp) 73235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if privates: 73255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.put(" private(%s)" % ", ".join(privates)) 73265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if firstprivates: 73275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.put(" firstprivate(%s)" % ", ".join(firstprivates)) 73285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.breaking_label_used: 73305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) shared_vars = [Naming.parallel_why] 73315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.error_label_used: 73325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) shared_vars.extend(self.parallel_exc) 73335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.put(" private(%s, %s, %s)" % self.pos_info) 73345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.put(" shared(%s)" % ', '.join(shared_vars)) 73365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def cleanup_temps(self, code): 73385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Now clean up any memoryview slice and object temporaries 73395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_parallel and not self.is_nested_prange: 73405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* Clean up any temporaries */") 73415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for temp, type in self.temps: 73425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if type.is_memoryviewslice: 73435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref_memoryviewslice(temp, have_gil=False) 73445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif type.is_pyobject: 73455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_xdecref(temp, type) 73465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = NULL;" % temp) 73475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def setup_parallel_control_flow_block(self, code): 73495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 73505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Sets up a block that surrounds the parallel block to determine 73515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) how the parallel section was exited. Any kind of return is 73525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) trapped (break, continue, return, exceptions). This is the idea: 73535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 73555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int why = 0; 73565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp parallel 73585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 73595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return # -> goto new_return_label; 73605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto end_parallel; 73615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_return_label: 73635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) why = 3; 73645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto end_parallel; 73655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_parallel:; 73675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp flush(why) # we need to flush for every iteration 73685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 73695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (why == 3) 73715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto old_return_label; 73725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 73735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 73745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.old_loop_labels = code.new_loop_labels() 73755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.old_error_label = code.new_error_label() 73765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.old_return_label = code.return_label 73775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.return_label = code.new_label(name="return") 73785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() # parallel control flow block 73805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.begin_of_parallel_control_block_point = code.insertion_point() 73815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.begin_of_parallel_control_block_point_after_decls = code.insertion_point() 73825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.undef_builtin_expect_apple_gcc_bug(code) 73845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def begin_parallel_block(self, code): 73865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 73875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Each OpenMP thread in a parallel section that contains a with gil block 73885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) must have the thread-state initialized. The call to 73895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyGILState_Release() then deallocates our threadstate. If we wouldn't 73905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) do this, each with gil block would allocate and deallocate one, thereby 73915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) losing exception information before it can be saved before leaving the 73925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parallel section. 73935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 73945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.begin_of_parallel_block = code.insertion_point() 73955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 73965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def end_parallel_block(self, code): 73975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 73985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) To ensure all OpenMP threads have thread states, we ensure the GIL 73995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) in each thread (which creates a thread state if it doesn't exist), 74005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) after which we release the GIL. 74015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) On exit, reacquire the GIL and release the thread state. 74025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) If compiled without OpenMP support (at the C level), then we still have 74045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) to acquire the GIL to decref any object temporaries. 74055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 74065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.error_label_used: 74075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) begin_code = self.begin_of_parallel_block 74085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code = code 74095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) begin_code.putln("#ifdef _OPENMP") 74115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) begin_code.put_ensure_gil(declare_gilstate=True) 74125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) begin_code.putln("Py_BEGIN_ALLOW_THREADS") 74135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) begin_code.putln("#endif /* _OPENMP */") 74145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.putln("#ifdef _OPENMP") 74165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.putln("Py_END_ALLOW_THREADS") 74175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.putln("#else") 74185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.put_safe("{\n") 74195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.put_ensure_gil() 74205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.putln("#endif /* _OPENMP */") 74215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.cleanup_temps(end_code) 74225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.put_release_ensured_gil() 74235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.putln("#ifndef _OPENMP") 74245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.put_safe("}\n") 74255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_code.putln("#endif /* _OPENMP */") 74265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def trap_parallel_exit(self, code, should_flush=False): 74285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 74295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Trap any kind of return inside a parallel construct. 'should_flush' 74305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) indicates whether the variable should be flushed, which is needed by 74315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prange to skip the loop. It also indicates whether we need to register 74325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) a continue (we need this for parallel blocks, but not for prange 74335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loops, as it is a direct jump there). 74345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) It uses the same mechanism as try/finally: 74365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1 continue 74375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2 break 74385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3 return 74395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4 error 74405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 74415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) save_lastprivates_label = code.new_label() 74425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dont_return_label = code.new_label() 74435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.any_label_used = False 74455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.breaking_label_used = False 74465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.error_label_used = False 74475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.parallel_private_temps = [] 74495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) all_labels = code.get_all_labels() 74515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Figure this out before starting to generate any code 74535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for label in all_labels: 74545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if code.label_used(label): 74555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.breaking_label_used = (self.breaking_label_used or 74565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) label != code.continue_label) 74575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.any_label_used = True 74585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.any_label_used: 74605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(dont_return_label) 74615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i, label in enumerate(all_labels): 74635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not code.label_used(label): 74645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 74655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_continue_label = label == code.continue_label 74675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(label) 74695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not (should_flush and is_continue_label): 74715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if label == code.error_label: 74725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.error_label_used = True 74735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.fetch_parallel_exception(code) 74745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %d;" % (Naming.parallel_why, i + 1)) 74765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (self.breaking_label_used and self.is_prange and not 74785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_continue_label): 74795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(save_lastprivates_label) 74805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 74815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(dont_return_label) 74825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.any_label_used: 74845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_prange and self.breaking_label_used: 74855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Don't rely on lastprivate, save our lastprivates 74865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(save_lastprivates_label) 74875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.save_parallel_vars(code) 74885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_label(dont_return_label) 74905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if should_flush and self.breaking_label_used: 74925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln_openmp("#pragma omp flush(%s)" % Naming.parallel_why) 74935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 74945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def save_parallel_vars(self, code): 74955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 74965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) The following shenanigans are instated when we break, return or 74975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) propagate errors from a prange. In this case we cannot rely on 74985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lastprivate() to do its job, as no iterations may have executed yet 74995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) in the last thread, leaving the values undefined. It is most likely 75005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) that the breaking thread has well-defined values of the lastprivate 75015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) variables, so we keep those values. 75025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 75035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) section_name = ("__pyx_parallel_lastprivates%d" % 75045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.critical_section_counter) 75055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln_openmp("#pragma omp critical(%s)" % section_name) 75065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ParallelStatNode.critical_section_counter += 1 75075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() # begin critical section 75095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c = self.begin_of_parallel_control_block_point 75115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_count = 0 75135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry, (op, lastprivate) in self.privates.iteritems(): 75145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not lastprivate or entry.type.is_pyobject: 75155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 75165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type_decl = entry.type.declaration_code("") 75185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_cname = "__pyx_parallel_temp%d" % temp_count 75195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private_cname = entry.cname 75205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp_count += 1 75225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) invalid_value = entry.type.invalid_value() 75245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if invalid_value: 75255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) init = ' = ' + invalid_value 75265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 75275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) init = '' 75285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Declare the parallel private in the outer block 75295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.putln("%s %s%s;" % (type_decl, temp_cname, init)) 75305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Initialize before escaping 75325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (temp_cname, private_cname)) 75335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.parallel_private_temps.append((temp_cname, private_cname)) 75355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() # end critical section 75375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def fetch_parallel_exception(self, code): 75395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 75405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) As each OpenMP thread may raise an exception, we need to fetch that 75415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exception from the threadstate and save it for after the parallel 75425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) section where it can be re-raised in the master thread. 75435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Although it would seem that __pyx_filename, __pyx_lineno and 75455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) __pyx_clineno are only assigned to under exception conditions (i.e., 75465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) when we have the GIL), and thus should be allowed to be shared without 75475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) any race condition, they are in fact subject to the same race 75485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) conditions that they were previously when they were global variables 75495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) and functions were allowed to release the GIL: 75505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) thread A thread B 75525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) acquire 75535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) set lineno 75545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) release 75555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) acquire 75565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) set lineno 75575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) release 75585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) acquire 75595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fetch exception 75605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) release 75615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) skip the fetch 75625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) deallocate threadstate deallocate threadstate 75645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 75655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() 75665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil(declare_gilstate=True) 75675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln_openmp("#pragma omp flush(%s)" % Naming.parallel_exc_type) 75695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 75705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (!%s) {" % Naming.parallel_exc_type) 75715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ErrFetch(&%s, &%s, &%s);" % self.parallel_exc) 75735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_info = chain(*zip(self.parallel_pos_info, self.pos_info)) 75745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.uses_error_indicator = True 75755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s; %s = %s; %s = %s;" % tuple(pos_info)) 75765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_gotref(Naming.parallel_exc_type) 75775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 75795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") 75805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 75825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() 75835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def restore_parallel_exception(self, code): 75855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Re-raise a parallel exception" 75865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() 75875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_ensure_gil(declare_gilstate=True) 75885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_giveref(Naming.parallel_exc_type) 75905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % self.parallel_exc) 75915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pos_info = chain(*zip(self.pos_info, self.parallel_pos_info)) 75925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s; %s = %s; %s = %s;" % tuple(pos_info)) 75935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_release_ensured_gil() 75955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() 75965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def restore_labels(self, code): 75985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 75995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Restore all old labels. Call this before the 'else' clause to for 76005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) loops and always before ending the parallel control flow block. 76015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 76025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.set_all_labels(self.old_loop_labels + (self.old_return_label, 76035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.old_error_label)) 76045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def end_parallel_control_flow_block(self, code, 76065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break_=False, continue_=False): 76075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 76085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) This ends the parallel control flow block and based on how the parallel 76095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) section was exited, takes the corresponding action. The break_ and 76105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue_ parameters indicate whether these should be propagated 76115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outwards: 76125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in prange(...): 76145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) with cython.parallel.parallel(): 76155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 76165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Here break should be trapped in the parallel block, and propagated to 76185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) the for loop. 76195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 76205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c = self.begin_of_parallel_control_block_point 76215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Firstly, always prefer errors over returning, continue or break 76235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.error_label_used: 76245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.putln("const char *%s = NULL; int %s = 0, %s = 0;" % 76255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.parallel_pos_info) 76265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.putln("PyObject *%s = NULL, *%s = NULL, *%s = NULL;" % 76285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.parallel_exc) 76295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 76315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (%s) {" % Naming.parallel_exc_type) 76325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* This may have been overridden by a continue, " 76335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "break or return in another thread. Prefer the error. */") 76345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = 4;" % Naming.parallel_why) 76355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 76365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") 76375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if continue_: 76395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) any_label_used = self.any_label_used 76405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 76415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) any_label_used = self.breaking_label_used 76425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if any_label_used: 76445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # __pyx_parallel_why is used, declare and initialize 76455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.putln("int %s;" % Naming.parallel_why) 76465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) c.putln("%s = 0;" % Naming.parallel_why) 76475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 76495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "if (%s) {" % Naming.parallel_why) 76505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for temp_cname, private_cname in self.parallel_private_temps: 76525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%s = %s;" % (private_cname, temp_cname)) 76535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("switch (%s) {" % Naming.parallel_why) 76555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if continue_: 76565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(" case 1: ") 76575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.continue_label) 76585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if break_: 76605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(" case 2: ") 76615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.break_label) 76625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(" case 3: ") 76645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.return_label) 76655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.error_label_used: 76675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.globalstate.use_utility_code(restore_exception_utility_code) 76685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln(" case 4:") 76695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.restore_parallel_exception(code) 76705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put_goto(code.error_label) 76715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("}") # end switch 76735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln( 76745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "}") # end if 76755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() # end parallel control flow block 76775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.redef_builtin_expect_apple_gcc_bug(code) 76785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # FIXME: improve with version number for OS X Lion 76805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buggy_platform_macro_condition = "(defined(__APPLE__) || defined(__OSX__))" 76815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) have_expect_condition = "(defined(__GNUC__) && " \ 76825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "(__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))" 76835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) redef_condition = "(%s && %s)" % (buggy_platform_macro_condition, have_expect_condition) 76845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def undef_builtin_expect_apple_gcc_bug(self, code): 76865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 76875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) A bug on OS X Lion disallows __builtin_expect macros. This code avoids them 76885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 76895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.parent: 76905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.undef_builtin_expect(self.redef_condition) 76915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def redef_builtin_expect_apple_gcc_bug(self, code): 76935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.parent: 76945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.redef_builtin_expect(self.redef_condition) 76955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 76975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ParallelWithBlockNode(ParallelStatNode): 76985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 76995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) This node represents a 'with cython.parallel.parallel():' block 77005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 77015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) valid_keyword_arguments = ['num_threads'] 77035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) num_threads = None 77055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 77075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(ParallelWithBlockNode, self).analyse_declarations(env) 77085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.args: 77095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "cython.parallel.parallel() does not take " 77105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "positional arguments") 77115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 77135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_closure_privates(code) 77145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.setup_parallel_control_flow_block(code) 77155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#ifdef _OPENMP") 77175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("#pragma omp parallel ") 77185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.privates: 77205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) privates = [e.cname for e in self.privates 77215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not e.type.is_pyobject] 77225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put('private(%s)' % ', '.join(privates)) 77235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.privatization_insertion_point = code.insertion_point() 77255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.put_num_threads(code) 77265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 77275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#endif /* _OPENMP */") 77295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() # parallel block 77315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.begin_parallel_block(code) 77325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.initialize_privates_to_nan(code) 77335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.start_collecting_temps() 77345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 77355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.trap_parallel_exit(code) 77365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.privatize_temps(code) 77375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.end_parallel_block(code) 77385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() # end parallel block 77395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue_ = code.label_used(code.continue_label) 77415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break_ = code.label_used(code.break_label) 77425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.restore_labels(code) 77445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.end_parallel_control_flow_block(code, break_=break_, 77455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue_=continue_) 77465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.release_closure_privates(code) 77475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ParallelRangeNode(ParallelStatNode): 77505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 77515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) This node represents a 'for i in cython.parallel.prange():' construct. 77525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target NameNode the target iteration variable 77545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else_clause Node or None the else clause of this loop 77555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 77565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['body', 'target', 'else_clause', 'args', 'num_threads', 77585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'chunksize'] 77595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) body = target = else_clause = args = None 77615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) start = stop = step = None 77635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_prange = True 77655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nogil = None 77675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) schedule = None 77685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) valid_keyword_arguments = ['schedule', 'nogil', 'num_threads', 'chunksize'] 77705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def __init__(self, pos, **kwds): 77725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(ParallelRangeNode, self).__init__(pos, **kwds) 77735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Pretend to be a ForInStatNode for control flow analysis 77745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.iterator = PassStatNode(pos) 77755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 77775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) super(ParallelRangeNode, self).analyse_declarations(env) 77785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target.analyse_target_declaration(env) 77795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 77805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.analyse_declarations(env) 77815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.args or len(self.args) > 3: 77835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Invalid number of positional arguments to prange") 77845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 77855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if len(self.args) == 1: 77875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.stop, = self.args 77885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif len(self.args) == 2: 77895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.start, self.stop = self.args 77905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 77915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.start, self.stop, self.step = self.args 77925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if hasattr(self.schedule, 'decode'): 77945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.schedule = self.schedule.decode('ascii') 77955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 77965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.schedule not in (None, 'static', 'dynamic', 'guided', 77975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'runtime'): 77985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Invalid schedule argument to prange: %s" % 77995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (self.schedule,)) 78005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 78025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) was_nogil = env.nogil 78035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.nogil: 78045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.nogil = True 78055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.target is None: 78075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "prange() can only be used as part of a for loop") 78085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 78095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.target = self.target.analyse_target_types(env) 78115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.target.type.is_numeric: 78135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Not a valid type, assume one for now anyway 78145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.target.type.is_pyobject: 78165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # nogil_check will catch the is_pyobject case 78175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.target.pos, 78185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Must be of numeric type, not %s" % self.target.type) 78195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.index_type = PyrexTypes.c_py_ssize_t_type 78215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 78225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.index_type = self.target.type 78235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.index_type.signed: 78245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) warning(self.target.pos, 78255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Unsigned index type not allowed before OpenMP 3.0", 78265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) level=2) 78275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Setup start, stop and step, allocating temps if needed 78295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.names = 'start', 'stop', 'step' 78305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) start_stop_step = self.start, self.stop, self.step 78315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for node, name in zip(start_stop_step, self.names): 78335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if node is not None: 78345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.analyse_types(env) 78355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not node.type.is_numeric: 78365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(node.pos, "%s argument must be numeric" % name) 78375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 78385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not node.is_literal: 78405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = node.coerce_to_temp(env) 78415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) setattr(self, name, node) 78425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # As we range from 0 to nsteps, computing the index along the 78445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # way, we need a fitting type for 'i' and 'nsteps' 78455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.index_type = PyrexTypes.widest_numeric_type( 78465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.index_type, node.type) 78475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause is not None: 78495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause = self.else_clause.analyse_expressions(env) 78505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Although not actually an assignment in this scope, it should be 78525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # treated as such to ensure it is unpacked if a closure temp, and to 78535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ensure lastprivate behaviour and propagation. If the target index is 78545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # not a NameNode, it won't have an entry, and an error was issued by 78555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ParallelRangeTransform 78565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if hasattr(self.target, 'entry'): 78575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.assignments[self.target.entry] = self.target.pos, None 78585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = super(ParallelRangeNode, self).analyse_expressions(env) 78605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if node.chunksize: 78625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not node.schedule: 78635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(node.chunksize.pos, 78645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Must provide schedule with chunksize") 78655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif node.schedule == 'runtime': 78665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(node.chunksize.pos, 78675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Chunksize not valid for the schedule runtime") 78685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif (node.chunksize.type.is_int and 78695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.chunksize.is_literal and 78705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.chunksize.compile_time_value(env) <= 0): 78715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(node.chunksize.pos, "Chunksize must not be negative") 78725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.chunksize = node.chunksize.coerce_to( 78745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyrexTypes.c_int_type, env).coerce_to_temp(env) 78755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if node.nogil: 78775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.nogil = was_nogil 78785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.is_nested_prange = node.parent and node.parent.is_prange 78805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if node.is_nested_prange: 78815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent = node 78825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while parent.parent and parent.parent.is_prange: 78835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent = parent.parent 78845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent.assignments.update(node.assignments) 78865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent.privates.update(node.privates) 78875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) parent.assigned_nodes.extend(node.assigned_nodes) 78885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return node 78895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def nogil_check(self, env): 78915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) names = 'start', 'stop', 'step', 'target' 78925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nodes = self.start, self.stop, self.step, self.target 78935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name, node in zip(names, nodes): 78945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if node is not None and node.type.is_pyobject: 78955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(node.pos, "%s may not be a Python object " 78965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "as we don't have the GIL" % name) 78975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 78985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 78995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 79005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Generate code in the following steps 79015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1) copy any closure variables determined thread-private 79035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) into temporaries 79045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2) allocate temps for start, stop and step 79065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3) generate a loop that calculates the total number of steps, 79085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) which then computes the target iteration variable for every step: 79095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for i in prange(start, stop, step): 79115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ... 79125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) becomes 79145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nsteps = (stop - start) / step; 79165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i = start; 79175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #pragma omp parallel for lastprivate(i) 79195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (temp = 0; temp < nsteps; temp++) { 79205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i = start + step * temp; 79215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ... 79225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 79235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Note that accumulation of 'i' would have a data dependency 79255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) between iterations. 79265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Also, you can't do this 79285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (i = start; i < stop; i += step) 79305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ... 79315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) as the '<' operator should become '>' for descending loops. 79335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'for i from x < i < y:' does not suffer from this problem 79345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) as the relational operator is known at compile time! 79355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4) release our temps and write back any private closure variables 79375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 79385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.declare_closure_privates(code) 79395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This can only be a NameNode 79415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) target_index_cname = self.target.entry.cname 79425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This will be used as the dict to format our code strings, holding 79445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # the start, stop , step, temps and target cnames 79455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fmt_dict = { 79465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 'target': target_index_cname, 79475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 79485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Setup start, stop and step, allocating temps if needed 79505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) start_stop_step = self.start, self.stop, self.step 79515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) defaults = '0', '0', '1' 79525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for node, name, default in zip(start_stop_step, self.names, defaults): 79535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if node is None: 79545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = default 79555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif node.is_literal: 79565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = node.get_constant_c_result_code() 79575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 79585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node.generate_evaluation_code(code) 79595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = node.result() 79605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fmt_dict[name] = result 79625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fmt_dict['i'] = code.funcstate.allocate_temp(self.index_type, False) 79645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fmt_dict['nsteps'] = code.funcstate.allocate_temp(self.index_type, False) 79655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # TODO: check if the step is 0 and if so, raise an exception in a 79675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # 'with gil' block. For now, just abort 79685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (%(step)s == 0) abort();" % fmt_dict) 79695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.setup_parallel_control_flow_block(code) # parallel control flow block 79715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.control_flow_var_code_point = code.insertion_point() 79735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Note: nsteps is private in an outer scope if present 79755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%(nsteps)s = (%(stop)s - %(start)s) / %(step)s;" % fmt_dict) 79765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # The target iteration variable might not be initialized, do it only if 79785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # we are executing at least 1 iteration, otherwise we should leave the 79795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # target unaffected. The target iteration variable is firstprivate to 79805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # shut up compiler warnings caused by lastprivate, as the compiler 79815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # erroneously believes that nsteps may be <= 0, leaving the private 79825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # target index uninitialized 79835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("if (%(nsteps)s > 0)" % fmt_dict) 79845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() # if block 79855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.generate_loop(code, fmt_dict) 79865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() # end if block 79875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.restore_labels(code) 79895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.else_clause: 79915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.breaking_label_used: 79925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("if (%s < 2)" % Naming.parallel_why) 79935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() # else block 79955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("/* else */") 79965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.else_clause.generate_execution_code(code) 79975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() # end else block 79985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 79995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # ------ cleanup ------ 80005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.end_parallel_control_flow_block(code) # end parallel control flow block 80015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # And finally, release our privates and write back any closure 80035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # variables 80045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for temp in start_stop_step: 80055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if temp is not None: 80065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp.generate_disposal_code(code) 80075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) temp.free_temps(code) 80085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(fmt_dict['i']) 80105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.release_temp(fmt_dict['nsteps']) 80115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.release_closure_privates(code) 80135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_loop(self, code, fmt_dict): 80155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_nested_prange: 80165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#if 0") 80175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 80185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#ifdef _OPENMP") 80195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not self.is_parallel: 80215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("#pragma omp for") 80225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.privatization_insertion_point = code.insertion_point() 80235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reduction_codepoint = self.parent.privatization_insertion_point 80245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 80255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("#pragma omp parallel") 80265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.privatization_insertion_point = code.insertion_point() 80275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reduction_codepoint = self.privatization_insertion_point 80285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 80295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#endif /* _OPENMP */") 80305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() # pragma omp parallel begin block 80325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Initialize the GIL if needed for this thread 80345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.begin_parallel_block(code) 80355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_nested_prange: 80375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#if 0") 80385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 80395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#ifdef _OPENMP") 80405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("#pragma omp for") 80415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for entry, (op, lastprivate) in self.privates.iteritems(): 80435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Don't declare the index variable as a reduction 80445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if op and op in "+*-&^|" and entry != self.target.entry: 80455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.type.is_pyobject: 80465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error(self.pos, "Python objects cannot be reductions") 80475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 80485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #code.put(" reduction(%s:%s)" % (op, entry.cname)) 80495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # This is the only way reductions + nesting works in gcc4.5 80505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) reduction_codepoint.put( 80515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) " reduction(%s:%s)" % (op, entry.cname)) 80525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 80535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry == self.target.entry: 80545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(" firstprivate(%s)" % entry.cname) 80555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(" lastprivate(%s)" % entry.cname) 80565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue 80575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if not entry.type.is_pyobject: 80595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if lastprivate: 80605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private = 'lastprivate' 80615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 80625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private = 'private' 80635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(" %s(%s)" % (private, entry.cname)) 80655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.schedule: 80675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.chunksize: 80685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) chunksize = ", %s" % self.evaluate_before_block(code, 80695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.chunksize) 80705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 80715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) chunksize = "" 80725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put(" schedule(%s%s)" % (self.schedule, chunksize)) 80745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.put_num_threads(reduction_codepoint) 80765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("") 80785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("#endif /* _OPENMP */") 80795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.put("for (%(i)s = 0; %(i)s < %(nsteps)s; %(i)s++)" % fmt_dict) 80815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() # for loop block 80825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) guard_around_body_codepoint = code.insertion_point() 80845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Start if guard block around the body. This may be unnecessary, but 80865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # at least it doesn't spoil indentation 80875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.begin_block() 80885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.putln("%(target)s = %(start)s + %(step)s * %(i)s;" % fmt_dict) 80905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.initialize_privates_to_nan(code, exclude=self.target.entry) 80915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_parallel: 80935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.funcstate.start_collecting_temps() 80945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.body.generate_execution_code(code) 80965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.trap_parallel_exit(code, should_flush=True) 80975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.privatize_temps(code) 80985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 80995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.breaking_label_used: 81005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Put a guard around the loop body in case return, break or 81015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # exceptions might be used 81025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) guard_around_body_codepoint.putln("if (%s < 2)" % Naming.parallel_why) 81035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() # end guard around loop body 81055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() # end for loop block 81065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_parallel: 81085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # Release the GIL and deallocate the thread state 81095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.end_parallel_block(code) 81105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code.end_block() # pragma omp parallel end block 81115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CnameDecoratorNode(StatNode): 81145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 81155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) This node is for the cname decorator in CythonUtilityCode: 81165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) @cname('the_cname') 81185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cdef func(...): 81195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ... 81205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) In case of a cdef class the cname specifies the objstruct_cname. 81225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node the node to which the cname decorator is applied 81245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname the cname the node should get 81255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) """ 81265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_attrs = ['node'] 81285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_declarations(self, env): 81305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.node.analyse_declarations(env) 81315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = self.node 81335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(node, CompilerDirectivesNode): 81345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) node = node.body.stats[0] 81355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.is_function = isinstance(node, FuncDefNode) 81375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_struct_or_enum = isinstance(node, (CStructOrUnionDefNode, 81385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CEnumDefNode)) 81395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e = node.entry 81405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_function: 81425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.cname = self.cname 81435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.func_cname = self.cname 81445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.used = True 81455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if e.pyfunc_cname and '.' in e.pyfunc_cname: 81465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.pyfunc_cname = self.mangle(e.pyfunc_cname) 81475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) elif is_struct_or_enum: 81485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.cname = e.type.cname = self.cname 81495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 81505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope = node.scope 81515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.cname = self.cname 81535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.type.objstruct_cname = self.cname + '_obj' 81545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.type.typeobj_cname = Naming.typeobj_prefix + self.cname 81555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.type.typeptr_cname = self.cname + '_type' 81565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.type.scope.namespace_cname = e.type.typeptr_cname 81575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e.as_variable.cname = py_object_type.cast_code(e.type.typeptr_cname) 81595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope.scope_prefix = self.cname + "_" 81615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for name, entry in scope.entries.iteritems(): 81635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.func_cname: 81645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.func_cname = self.mangle(entry.cname) 81655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if entry.pyfunc_cname: 81665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.pyfunc_cname = self.mangle(entry.pyfunc_cname) 81675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def mangle(self, cname): 81695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if '.' in cname: 81705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # remove __pyx_base from func_cname 81715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = cname.split('.')[-1] 81725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return '%s_%s' % (self.cname, cname) 81735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def analyse_expressions(self, env): 81755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.node = self.node.analyse_expressions(env) 81765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self 81775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_function_definitions(self, env, code): 81795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Ensure a prototype for every @cname method in the right place" 81805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if self.is_function and env.is_c_class_scope: 81815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) # method in cdef class, generate a prototype in the header 81825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) h_code = code.globalstate['utility_code_proto'] 81835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if isinstance(self.node, DefNode): 81855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.node.generate_function_header( 81865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) h_code, with_pymethdef=False, proto_only=True) 81875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else: 81885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) import ModuleNode 81895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry = self.node.entry 81905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) cname = entry.cname 81915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.cname = entry.func_cname 81925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ModuleNode.generate_cfunction_declaration( 81945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry, 81955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env.global_scope(), 81965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) h_code, 81975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) definition=True) 81985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 81995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry.cname = cname 82005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.node.generate_function_definitions(env, code) 82025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def generate_execution_code(self, code): 82045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) self.node.generate_execution_code(code) 82055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#------------------------------------------------------------------------------------ 82085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# 82095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Runtime support code 82105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# 82115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#------------------------------------------------------------------------------------ 82125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)if Options.gcc_branch_hints: 82145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) branch_prediction_macros = """ 82155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/* Test for GCC > 2.95 */ 82165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(__GNUC__) \ 82175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) 82185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #define likely(x) __builtin_expect(!!(x), 1) 82195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #define unlikely(x) __builtin_expect(!!(x), 0) 82205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else /* !__GNUC__ or GCC < 2.95 */ 82215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #define likely(x) (x) 82225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) #define unlikely(x) (x) 82235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif /* __GNUC__ */ 82245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)""" 82255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)else: 82265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) branch_prediction_macros = """ 82275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define likely(x) (x) 82285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define unlikely(x) (x) 82295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)""" 82305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#------------------------------------------------------------------------------------ 82325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)printing_utility_code = UtilityCode.load_cached("Print", "Printing.c") 82345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)printing_one_utility_code = UtilityCode.load_cached("PrintOne", "Printing.c") 82355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#------------------------------------------------------------------------------------ 82375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Exception raising code 82395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# 82405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Exceptions are raised by __Pyx_Raise() and stored as plain 82415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# type/value/tb in PyThreadState->curexc_*. When being caught by an 82425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# 'except' statement, curexc_* is moved over to exc_* by 82435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# __Pyx_GetException() 82445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)restore_exception_utility_code = UtilityCode.load_cached("PyErrFetchRestore", "Exceptions.c") 82465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)raise_utility_code = UtilityCode.load_cached("RaiseException", "Exceptions.c") 82475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)get_exception_utility_code = UtilityCode.load_cached("GetException", "Exceptions.c") 82485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)swap_exception_utility_code = UtilityCode.load_cached("SwapException", "Exceptions.c") 82495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)reset_exception_utility_code = UtilityCode.load_cached("SaveResetException", "Exceptions.c") 82505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)traceback_utility_code = UtilityCode.load_cached("AddTraceback", "Exceptions.c") 82515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#------------------------------------------------------------------------------------ 82535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 82545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)get_exception_tuple_utility_code = UtilityCode(proto=""" 82555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/ 82565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)""", 82575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# I doubt that calling __Pyx_GetException() here is correct as it moves 82585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# the exception from tstate->curexc_* to tstate->exc_*, which prevents 82595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# exception handlers later on from receiving it. 82605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)impl = """ 82615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static PyObject *__Pyx_GetExceptionTuple(void) { 82625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyObject *type = NULL, *value = NULL, *tb = NULL; 82635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (__Pyx_GetException(&type, &value, &tb) == 0) { 82645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyObject* exc_info = PyTuple_New(3); 82655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (exc_info) { 82665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Py_INCREF(type); 82675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Py_INCREF(value); 82685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Py_INCREF(tb); 82695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyTuple_SET_ITEM(exc_info, 0, type); 82705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyTuple_SET_ITEM(exc_info, 1, value); 82715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PyTuple_SET_ITEM(exc_info, 2, tb); 82725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return exc_info; 82735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 82745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 82755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return NULL; 82765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 82775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)""", 82785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)requires=[get_exception_utility_code]) 8279