ExprNodes.py 302 KB
Newer Older
William Stein's avatar
William Stein committed
1 2 3 4
#
#   Pyrex - Parse tree nodes for expressions
#

5 6 7 8 9 10 11 12 13 14
import cython
from cython import set
cython.declare(error=object, warning=object, warn_once=object, InternalError=object,
               CompileError=object, UtilityCode=object, StringEncoding=object, operator=object,
               Naming=object, Nodes=object, PyrexTypes=object, py_object_type=object,
               list_type=object, tuple_type=object, set_type=object, dict_type=object, \
               unicode_type=object, str_type=object, bytes_type=object, type_type=object,
               Builtin=object, Symtab=object, Utils=object, find_coercion_error=object,
               debug_disposal_code=object, debug_temp_alloc=object, debug_coercion=object)

15
import operator
William Stein's avatar
William Stein committed
16

17
from Errors import error, warning, warn_once, InternalError, CompileError
18
from Errors import hold_errors, release_errors, held_errors, report_error
19
from Code import UtilityCode
20
import StringEncoding
William Stein's avatar
William Stein committed
21
import Naming
Robert Bradshaw's avatar
Robert Bradshaw committed
22
import Nodes
William Stein's avatar
William Stein committed
23 24
from Nodes import Node
import PyrexTypes
25 26
from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
     unspecified_type
27 28
from Builtin import list_type, tuple_type, set_type, dict_type, \
     unicode_type, str_type, bytes_type, type_type
29
import Builtin
William Stein's avatar
William Stein committed
30 31
import Symtab
import Options
32
from Cython import Utils
33
from Annotate import AnnotationItem
William Stein's avatar
William Stein committed
34

William Stein's avatar
William Stein committed
35
from Cython.Debugging import print_call_chain
William Stein's avatar
William Stein committed
36 37 38
from DebugFlags import debug_disposal_code, debug_temp_alloc, \
    debug_coercion

39 40 41 42 43
try:
    from __builtin__ import basestring
except ImportError:
    basestring = str # Python 3

Stefan Behnel's avatar
Stefan Behnel committed
44 45 46 47
class NotConstant(object):
    def __repr__(self):
        return "<NOT CONSTANT>"

48
not_a_constant = NotConstant()
49
constant_value_not_set = object()
50

51 52 53 54 55 56 57 58 59 60
# error messages when coercing from key[0] to key[1]
find_coercion_error = {
    # string related errors
    (Builtin.unicode_type, Builtin.bytes_type) : "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
    (Builtin.unicode_type, Builtin.str_type)   : "Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding.",
    (Builtin.unicode_type, PyrexTypes.c_char_ptr_type) : "Unicode objects do not support coercion to C types.",
    (Builtin.bytes_type, Builtin.unicode_type) : "Cannot convert 'bytes' object to unicode implicitly, decoding required",
    (Builtin.bytes_type, Builtin.str_type) : "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
    (Builtin.str_type, Builtin.unicode_type) : "str objects do not support coercion to unicode, use a unicode string literal instead (u'')",
    (Builtin.str_type, Builtin.bytes_type) : "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
61
    (Builtin.str_type, PyrexTypes.c_char_ptr_type) : "'str' objects do not support coercion to C types (use 'bytes'?).",
62 63 64 65 66
    (PyrexTypes.c_char_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
    (PyrexTypes.c_uchar_ptr_type, Builtin.unicode_type) : "Cannot convert 'char*' to unicode implicitly, decoding required",
    }.get


William Stein's avatar
William Stein committed
67 68 69 70 71 72
class ExprNode(Node):
    #  subexprs     [string]     Class var holding names of subexpr node attrs
    #  type         PyrexType    Type of the result
    #  result_code  string       Code fragment
    #  result_ctype string       C type of result_code if different from type
    #  is_temp      boolean      Result is in a temporary variable
73
    #  is_sequence_constructor
William Stein's avatar
William Stein committed
74
    #               boolean      Is a list or tuple constructor expression
75
    #  is_starred   boolean      Is a starred expression (e.g. '*a')
William Stein's avatar
William Stein committed
76 77 78
    #  saved_subexpr_nodes
    #               [ExprNode or [ExprNode or None] or None]
    #                            Cached result of subexpr_nodes()
79
    #  use_managed_ref boolean   use ref-counted temps/assignments/etc.
80

William Stein's avatar
William Stein committed
81
    result_ctype = None
82
    type = None
83 84
    temp_code = None
    old_temp = None # error checker for multiple frees etc.
85
    use_managed_ref = True # can be set by optimisation transforms
William Stein's avatar
William Stein committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

    #  The Analyse Expressions phase for expressions is split
    #  into two sub-phases:
    #
    #    Analyse Types
    #      Determines the result type of the expression based
    #      on the types of its sub-expressions, and inserts
    #      coercion nodes into the expression tree where needed.
    #      Marks nodes which will need to have temporary variables
    #      allocated.
    #
    #    Allocate Temps
    #      Allocates temporary variables where needed, and fills
    #      in the result_code field of each node.
    #
    #  ExprNode provides some convenience routines which
    #  perform both of the above phases. These should only
    #  be called from statement nodes, and only when no
    #  coercion nodes need to be added around the expression
    #  being analysed. In that case, the above two phases
    #  should be invoked separately.
    #
    #  Framework code in ExprNode provides much of the common
    #  processing for the various phases. It makes use of the
    #  'subexprs' class attribute of ExprNodes, which should
    #  contain a list of the names of attributes which can
    #  hold sub-nodes or sequences of sub-nodes.
113 114
    #
    #  The framework makes use of a number of abstract methods.
William Stein's avatar
William Stein committed
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    #  Their responsibilities are as follows.
    #
    #    Declaration Analysis phase
    #
    #      analyse_target_declaration
    #        Called during the Analyse Declarations phase to analyse
    #        the LHS of an assignment or argument of a del statement.
    #        Nodes which cannot be the LHS of an assignment need not
    #        implement it.
    #
    #    Expression Analysis phase
    #
    #      analyse_types
    #        - Call analyse_types on all sub-expressions.
    #        - Check operand types, and wrap coercion nodes around
    #          sub-expressions where needed.
    #        - Set the type of this node.
    #        - If a temporary variable will be required for the
    #          result, set the is_temp flag of this node.
    #
    #      analyse_target_types
    #        Called during the Analyse Types phase to analyse
137
    #        the LHS of an assignment or argument of a del
William Stein's avatar
William Stein committed
138 139
    #        statement. Similar responsibilities to analyse_types.
    #
140 141 142 143
    #      target_code
    #        Called by the default implementation of allocate_target_temps.
    #        Should return a C lvalue for assigning to the node. The default
    #        implementation calls calculate_result_code.
William Stein's avatar
William Stein committed
144 145 146 147
    #
    #      check_const
    #        - Check that this node and its subnodes form a
    #          legal constant expression. If so, do nothing,
148
    #          otherwise call not_const.
William Stein's avatar
William Stein committed
149
    #
150
    #        The default implementation of check_const
William Stein's avatar
William Stein committed
151 152 153 154 155 156 157 158
    #        assumes that the expression is not constant.
    #
    #      check_const_addr
    #        - Same as check_const, except check that the
    #          expression is a C lvalue whose address is
    #          constant. Otherwise, call addr_not_const.
    #
    #        The default implementation of calc_const_addr
159
    #        assumes that the expression is not a constant
William Stein's avatar
William Stein committed
160 161 162 163 164 165 166 167 168 169 170 171
    #        lvalue.
    #
    #   Code Generation phase
    #
    #      generate_evaluation_code
    #        - Call generate_evaluation_code for sub-expressions.
    #        - Perform the functions of generate_result_code
    #          (see below).
    #        - If result is temporary, call generate_disposal_code
    #          on all sub-expressions.
    #
    #        A default implementation of generate_evaluation_code
172
    #        is provided which uses the following abstract methods:
William Stein's avatar
William Stein committed
173 174 175 176 177 178
    #
    #          generate_result_code
    #            - Generate any C statements necessary to calculate
    #              the result of this node from the results of its
    #              sub-expressions.
    #
179
    #          calculate_result_code
180 181
    #            - Should return a C code fragment evaluating to the
    #              result. This is only called when the result is not
182 183
    #              a temporary.
    #
William Stein's avatar
William Stein committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
    #      generate_assignment_code
    #        Called on the LHS of an assignment.
    #        - Call generate_evaluation_code for sub-expressions.
    #        - Generate code to perform the assignment.
    #        - If the assignment absorbed a reference, call
    #          generate_post_assignment_code on the RHS,
    #          otherwise call generate_disposal_code on it.
    #
    #      generate_deletion_code
    #        Called on an argument of a del statement.
    #        - Call generate_evaluation_code for sub-expressions.
    #        - Generate code to perform the deletion.
    #        - Call generate_disposal_code on all sub-expressions.
    #
    #
199

William Stein's avatar
William Stein committed
200 201
    is_sequence_constructor = 0
    is_attribute = 0
202

William Stein's avatar
William Stein committed
203 204
    saved_subexpr_nodes = None
    is_temp = 0
205
    is_target = 0
206
    is_starred = 0
William Stein's avatar
William Stein committed
207

208 209
    constant_result = constant_value_not_set

210 211 212 213
    try:
        _get_child_attrs = operator.attrgetter('subexprs')
    except AttributeError:
        # Python 2.3
214
        def __get_child_attrs(self):
215
            return self.subexprs
216
        _get_child_attrs = __get_child_attrs
217
    child_attrs = property(fget=_get_child_attrs)
218

William Stein's avatar
William Stein committed
219 220 221 222
    def not_implemented(self, method_name):
        print_call_chain(method_name, "not implemented") ###
        raise InternalError(
            "%s.%s not implemented" %
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
223
                (self.__class__.__name__, method_name))
224

William Stein's avatar
William Stein committed
225 226
    def is_lvalue(self):
        return 0
227

William Stein's avatar
William Stein committed
228 229 230 231 232 233 234 235 236 237 238
    def is_ephemeral(self):
        #  An ephemeral node is one whose result is in
        #  a Python temporary and we suspect there are no
        #  other references to it. Certain operations are
        #  disallowed on such values, since they are
        #  likely to result in a dangling pointer.
        return self.type.is_pyobject and self.is_temp

    def subexpr_nodes(self):
        #  Extract a list of subexpression nodes based
        #  on the contents of the subexprs class attribute.
239 240 241
        nodes = []
        for name in self.subexprs:
            item = getattr(self, name)
Stefan Behnel's avatar
Stefan Behnel committed
242 243
            if item is not None:
                if type(item) is list:
244
                    nodes.extend(item)
Stefan Behnel's avatar
Stefan Behnel committed
245 246
                else:
                    nodes.append(item)
247
        return nodes
248

249
    def result(self):
250 251 252
        if self.is_temp:
            return self.temp_code
        else:
253
            return self.calculate_result_code()
254

William Stein's avatar
William Stein committed
255 256
    def result_as(self, type = None):
        #  Return the result code cast to the specified C type.
257
        return typecast(type, self.ctype(), self.result())
258

William Stein's avatar
William Stein committed
259 260 261
    def py_result(self):
        #  Return the result code cast to PyObject *.
        return self.result_as(py_object_type)
262

William Stein's avatar
William Stein committed
263 264 265 266
    def ctype(self):
        #  Return the native C type of the result (i.e. the
        #  C type of the result_code expression).
        return self.result_ctype or self.type
267

268
    def get_constant_c_result_code(self):
269
        # Return the constant value of this node as a result code
270 271 272 273 274 275 276
        # string, or None if the node is not constant.  This method
        # can be called when the constant result code is required
        # before the code generation phase.
        #
        # The return value is a string that can represent a simple C
        # value, a constant C name or a constant C expression.  If the
        # node type depends on Python code, this must return None.
277 278
        return None

279
    def calculate_constant_result(self):
280 281 282 283 284
        # Calculate the constant compile time result value of this
        # expression and store it in ``self.constant_result``.  Does
        # nothing by default, thus leaving ``self.constant_result``
        # unknown.  If valid, the result can be an arbitrary Python
        # value.
285 286 287 288 289 290
        #
        # This must only be called when it is assured that all
        # sub-expressions have a valid constant_result value.  The
        # ConstantFolding transform will do this.
        pass

291 292 293 294
    def has_constant_result(self):
        return self.constant_result is not constant_value_not_set and \
               self.constant_result is not not_a_constant

295 296 297
    def compile_time_value(self, denv):
        #  Return value of compile-time expression, or report error.
        error(self.pos, "Invalid compile-time expression")
298

299 300 301
    def compile_time_value_error(self, e):
        error(self.pos, "Error in compile-time expression: %s: %s" % (
            e.__class__.__name__, e))
302

William Stein's avatar
William Stein committed
303
    # ------------- Declaration Analysis ----------------
304

William Stein's avatar
William Stein committed
305 306
    def analyse_target_declaration(self, env):
        error(self.pos, "Cannot assign to or delete this")
307

William Stein's avatar
William Stein committed
308
    # ------------- Expression Analysis ----------------
309

William Stein's avatar
William Stein committed
310 311 312 313 314 315
    def analyse_const_expression(self, env):
        #  Called during the analyse_declarations phase of a
        #  constant expression. Analyses the expression's type,
        #  checks whether it is a legal const expression,
        #  and determines its value.
        self.analyse_types(env)
316
        return self.check_const()
317

William Stein's avatar
William Stein committed
318 319
    def analyse_expressions(self, env):
        #  Convenience routine performing both the Type
320
        #  Analysis and Temp Allocation phases for a whole
William Stein's avatar
William Stein committed
321 322
        #  expression.
        self.analyse_types(env)
323

324
    def analyse_target_expression(self, env, rhs):
William Stein's avatar
William Stein committed
325 326 327 328
        #  Convenience routine performing both the Type
        #  Analysis and Temp Allocation phases for the LHS of
        #  an assignment.
        self.analyse_target_types(env)
329

William Stein's avatar
William Stein committed
330 331 332 333 334
    def analyse_boolean_expression(self, env):
        #  Analyse expression and coerce to a boolean.
        self.analyse_types(env)
        bool = self.coerce_to_boolean(env)
        return bool
335

William Stein's avatar
William Stein committed
336 337 338 339 340 341 342 343 344
    def analyse_temp_boolean_expression(self, env):
        #  Analyse boolean expression and coerce result into
        #  a temporary. This is used when a branch is to be
        #  performed on the result and we won't have an
        #  opportunity to ensure disposal code is executed
        #  afterwards. By forcing the result into a temporary,
        #  we ensure that all disposal has been done by the
        #  time we get the result.
        self.analyse_types(env)
Stefan Behnel's avatar
Stefan Behnel committed
345 346
        return self.coerce_to_boolean(env).coerce_to_simple(env)

347
    # --------------- Type Inference -----------------
348

Robert Bradshaw's avatar
Robert Bradshaw committed
349
    def type_dependencies(self, env):
350 351 352 353
        # Returns the list of entries whose types must be determined
        # before the type of self can be infered.
        if hasattr(self, 'type') and self.type is not None:
            return ()
Robert Bradshaw's avatar
Robert Bradshaw committed
354
        return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
355

356
    def infer_type(self, env):
357 358
        # Attempt to deduce the type of self.
        # Differs from analyse_types as it avoids unnecessary
359 360 361 362 363 364 365 366
        # analysis of subexpressions, but can assume everything
        # in self.type_dependencies() has been resolved.
        if hasattr(self, 'type') and self.type is not None:
            return self.type
        elif hasattr(self, 'entry') and self.entry is not None:
            return self.entry.type
        else:
            self.not_implemented("infer_type")
367

368 369 370
    def nonlocally_immutable(self):
        # Returns whether this variable is a safe reference, i.e.
        # can't be modified as part of globals or closures.
371
        return self.is_temp or self.type.is_array or self.type.is_cfunction
372

William Stein's avatar
William Stein committed
373
    # --------------- Type Analysis ------------------
374

William Stein's avatar
William Stein committed
375 376 377 378
    def analyse_as_module(self, env):
        # If this node can be interpreted as a reference to a
        # cimported module, return its scope, else None.
        return None
379

380 381 382 383
    def analyse_as_type(self, env):
        # If this node can be interpreted as a reference to a
        # type, return that type, else None.
        return None
384

William Stein's avatar
William Stein committed
385 386 387 388
    def analyse_as_extension_type(self, env):
        # If this node can be interpreted as a reference to an
        # extension type, return its type, else None.
        return None
389

William Stein's avatar
William Stein committed
390 391
    def analyse_types(self, env):
        self.not_implemented("analyse_types")
392

William Stein's avatar
William Stein committed
393 394
    def analyse_target_types(self, env):
        self.analyse_types(env)
395

396
    def nogil_check(self, env):
397 398 399 400
        # By default, any expression based on Python objects is
        # prevented in nogil environments.  Subtypes must override
        # this if they can work without the GIL.
        if self.type.is_pyobject:
401
            self.gil_error()
402

403 404 405 406
    def gil_assignment_check(self, env):
        if env.nogil and self.type.is_pyobject:
            error(self.pos, "Assignment of Python object not allowed without gil")

William Stein's avatar
William Stein committed
407 408
    def check_const(self):
        self.not_const()
409
        return False
410

William Stein's avatar
William Stein committed
411 412
    def not_const(self):
        error(self.pos, "Not allowed in a constant expression")
413

William Stein's avatar
William Stein committed
414 415
    def check_const_addr(self):
        self.addr_not_const()
416
        return False
417

William Stein's avatar
William Stein committed
418 419
    def addr_not_const(self):
        error(self.pos, "Address is not constant")
420

William Stein's avatar
William Stein committed
421
    # ----------------- Result Allocation -----------------
422

William Stein's avatar
William Stein committed
423 424 425 426 427 428
    def result_in_temp(self):
        #  Return true if result is in a temporary owned by
        #  this node or one of its subexpressions. Overridden
        #  by certain nodes which can share the result of
        #  a subnode.
        return self.is_temp
429

William Stein's avatar
William Stein committed
430 431 432
    def target_code(self):
        #  Return code fragment for use as LHS of a C assignment.
        return self.calculate_result_code()
433

William Stein's avatar
William Stein committed
434 435
    def calculate_result_code(self):
        self.not_implemented("calculate_result_code")
436

Robert Bradshaw's avatar
Robert Bradshaw committed
437 438 439
#    def release_target_temp(self, env):
#        #  Release temporaries used by LHS of an assignment.
#        self.release_subexpr_temps(env)
William Stein's avatar
William Stein committed
440

441 442
    def allocate_temp_result(self, code):
        if self.temp_code:
443
            raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
444 445 446 447 448
        type = self.type
        if not type.is_void:
            if type.is_pyobject:
                type = PyrexTypes.py_object_type
            self.temp_code = code.funcstate.allocate_temp(
449
                type, manage_ref=self.use_managed_ref)
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
        else:
            self.temp_code = None

    def release_temp_result(self, code):
        if not self.temp_code:
            if self.old_temp:
                raise RuntimeError("temp %s released multiple times in %s" % (
                        self.old_temp, self.__class__.__name__))
            else:
                raise RuntimeError("no temp, but release requested in %s" % (
                        self.__class__.__name__))
        code.funcstate.release_temp(self.temp_code)
        self.old_temp = self.temp_code
        self.temp_code = None

William Stein's avatar
William Stein committed
465
    # ---------------- Code Generation -----------------
466

William Stein's avatar
William Stein committed
467 468 469 470
    def make_owned_reference(self, code):
        #  If result is a pyobject, make sure we own
        #  a reference to it.
        if self.type.is_pyobject and not self.result_in_temp():
471
            code.put_incref(self.result(), self.ctype())
472

William Stein's avatar
William Stein committed
473
    def generate_evaluation_code(self, code):
474
        code.mark_pos(self.pos)
475

William Stein's avatar
William Stein committed
476 477 478 479
        #  Generate code to evaluate this node and
        #  its sub-expressions, and dispose of any
        #  temporary results of its sub-expressions.
        self.generate_subexpr_evaluation_code(code)
480 481 482 483

        if self.is_temp:
            self.allocate_temp_result(code)

William Stein's avatar
William Stein committed
484 485
        self.generate_result_code(code)
        if self.is_temp:
486 487
            # If we are temp we do not need to wait until this node is disposed
            # before disposing children.
William Stein's avatar
William Stein committed
488
            self.generate_subexpr_disposal_code(code)
489
            self.free_subexpr_temps(code)
490

William Stein's avatar
William Stein committed
491 492 493
    def generate_subexpr_evaluation_code(self, code):
        for node in self.subexpr_nodes():
            node.generate_evaluation_code(code)
494

William Stein's avatar
William Stein committed
495 496
    def generate_result_code(self, code):
        self.not_implemented("generate_result_code")
497

498 499 500 501
    def generate_disposal_code(self, code):
        if self.is_temp:
            if self.type.is_pyobject:
                code.put_decref_clear(self.result(), self.ctype())
William Stein's avatar
William Stein committed
502
        else:
503
            # Already done if self.is_temp
504
            self.generate_subexpr_disposal_code(code)
505

William Stein's avatar
William Stein committed
506 507 508 509 510
    def generate_subexpr_disposal_code(self, code):
        #  Generate code to dispose of temporary results
        #  of all sub-expressions.
        for node in self.subexpr_nodes():
            node.generate_disposal_code(code)
511

William Stein's avatar
William Stein committed
512 513 514
    def generate_post_assignment_code(self, code):
        if self.is_temp:
            if self.type.is_pyobject:
515
                code.putln("%s = 0;" % self.result())
William Stein's avatar
William Stein committed
516 517
        else:
            self.generate_subexpr_disposal_code(code)
518

William Stein's avatar
William Stein committed
519 520
    def generate_assignment_code(self, rhs, code):
        #  Stub method for nodes which are not legal as
521
        #  the LHS of an assignment. An error will have
William Stein's avatar
William Stein committed
522 523
        #  been reported earlier.
        pass
524

William Stein's avatar
William Stein committed
525 526 527 528 529
    def generate_deletion_code(self, code):
        #  Stub method for nodes that are not legal as
        #  the argument of a del statement. An error
        #  will have been reported earlier.
        pass
530 531

    def free_temps(self, code):
532 533 534 535
        if self.is_temp:
            if not self.type.is_void:
                self.release_temp_result(code)
        else:
536
            self.free_subexpr_temps(code)
537

538 539 540 541
    def free_subexpr_temps(self, code):
        for sub in self.subexpr_nodes():
            sub.free_temps(code)

542 543 544
    def generate_function_definitions(self, env, code):
        pass

545
    # ---------------- Annotation ---------------------
546

547 548 549
    def annotate(self, code):
        for node in self.subexpr_nodes():
            node.annotate(code)
550

William Stein's avatar
William Stein committed
551
    # ----------------- Coercion ----------------------
552

William Stein's avatar
William Stein committed
553 554 555 556 557 558 559 560
    def coerce_to(self, dst_type, env):
        #   Coerce the result so that it can be assigned to
        #   something of type dst_type. If processing is necessary,
        #   wraps this node in a coercion node and returns that.
        #   Otherwise, returns this node unchanged.
        #
        #   This method is called during the analyse_expressions
        #   phase of the src_node's processing.
561 562 563 564 565 566 567 568
        #
        #   Note that subclasses that override this (especially
        #   ConstNodes) must not (re-)set their own .type attribute
        #   here.  Since expression nodes may turn up in different
        #   places in the tree (e.g. inside of CloneNodes in cascaded
        #   assignments), this method must return a new node instance
        #   if it changes the type.
        #
William Stein's avatar
William Stein committed
569 570 571 572
        src = self
        src_type = self.type
        src_is_py_type = src_type.is_pyobject
        dst_is_py_type = dst_type.is_pyobject
573

574 575 576
        if self.check_for_coercion_error(dst_type):
            return self

577 578
        if dst_type.is_reference:
            dst_type = dst_type.ref_base_type
579

William Stein's avatar
William Stein committed
580 581
        if dst_type.is_pyobject:
            if not src.type.is_pyobject:
582 583 584 585
                if dst_type is bytes_type and src.type.is_int:
                    src = CoerceIntToBytesNode(src, env)
                else:
                    src = CoerceToPyTypeNode(src, env)
William Stein's avatar
William Stein committed
586
            if not src.type.subtype_of(dst_type):
587 588
                if not isinstance(src, NoneNode):
                    src = PyTypeTestNode(src, dst_type, env)
William Stein's avatar
William Stein committed
589 590
        elif src.type.is_pyobject:
            src = CoerceFromPyTypeNode(dst_type, src, env)
591
        elif (dst_type.is_complex
592 593
              and src_type != dst_type
              and dst_type.assignable_from(src_type)):
594
            src = CoerceToComplexNode(src, dst_type, env)
William Stein's avatar
William Stein committed
595
        else: # neither src nor dst are py types
596
            # Added the string comparison, since for c types that
597
            # is enough, but Cython gets confused when the types are
598
            # in different pxi files.
599
            if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
600
                self.fail_assignment(dst_type)
William Stein's avatar
William Stein committed
601 602
        return src

603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
    def fail_assignment(self, dst_type):
        error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))

    def check_for_coercion_error(self, dst_type, fail=False, default=None):
        if fail and not default:
            default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
        message = find_coercion_error((self.type, dst_type), default)
        if message is not None:
            error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
            return True
        if fail:
            self.fail_assignment(dst_type)
            return True
        return False

William Stein's avatar
William Stein committed
618 619 620 621 622 623
    def coerce_to_pyobject(self, env):
        return self.coerce_to(PyrexTypes.py_object_type, env)

    def coerce_to_boolean(self, env):
        #  Coerce result to something acceptable as
        #  a boolean value.
624 625 626 627 628 629 630

        # if it's constant, calculate the result now
        if self.has_constant_result():
            bool_value = bool(self.constant_result)
            return BoolNode(self.pos, value=bool_value,
                            constant_result=bool_value)

William Stein's avatar
William Stein committed
631 632 633 634
        type = self.type
        if type.is_pyobject or type.is_ptr or type.is_float:
            return CoerceToBooleanNode(self, env)
        else:
635
            if not (type.is_int or type.is_enum or type.is_error):
636
                error(self.pos,
William Stein's avatar
William Stein committed
637 638
                    "Type '%s' not acceptable as a boolean" % type)
            return self
639

William Stein's avatar
William Stein committed
640 641 642 643 644 645
    def coerce_to_integer(self, env):
        # If not already some C integer type, coerce to longint.
        if self.type.is_int:
            return self
        else:
            return self.coerce_to(PyrexTypes.c_long_type, env)
646

William Stein's avatar
William Stein committed
647 648 649 650 651 652
    def coerce_to_temp(self, env):
        #  Ensure that the result is in a temporary.
        if self.result_in_temp():
            return self
        else:
            return CoerceToTempNode(self, env)
653

William Stein's avatar
William Stein committed
654 655 656 657 658 659
    def coerce_to_simple(self, env):
        #  Ensure that the result is simple (see is_simple).
        if self.is_simple():
            return self
        else:
            return self.coerce_to_temp(env)
660

William Stein's avatar
William Stein committed
661 662 663 664 665 666
    def is_simple(self):
        #  A node is simple if its result is something that can
        #  be referred to without performing any operations, e.g.
        #  a constant, local var, C global var, struct member
        #  reference, or temporary.
        return self.result_in_temp()
667 668

    def may_be_none(self):
669 670 671 672 673
        if not self.type.is_pyobject:
            return False
        if self.constant_result not in (not_a_constant, constant_value_not_set):
            return self.constant_result is not None
        return True
674

675
    def as_cython_attribute(self):
676
        return None
William Stein's avatar
William Stein committed
677

678
    def as_none_safe_node(self, message, error="PyExc_TypeError"):
679 680 681 682 683 684 685 686
        # Wraps the node in a NoneCheckNode if it is not known to be
        # not-None (e.g. because it is a Python literal).
        if self.may_be_none():
            return NoneCheckNode(self, error, message)
        else:
            return self


William Stein's avatar
William Stein committed
687
class AtomicExprNode(ExprNode):
688 689
    #  Abstract base class for expression nodes which have
    #  no sub-expressions.
690

691 692 693
    subexprs = []

    # Override to optimize -- we know we have no children
694 695 696 697
    def generate_subexpr_evaluation_code(self, code):
        pass
    def generate_subexpr_disposal_code(self, code):
        pass
698

699
class PyConstNode(AtomicExprNode):
William Stein's avatar
William Stein committed
700
    #  Abstract base class for constant Python values.
701

702
    is_literal = 1
703
    type = py_object_type
704

William Stein's avatar
William Stein committed
705 706
    def is_simple(self):
        return 1
707 708 709 710

    def may_be_none(self):
        return False

William Stein's avatar
William Stein committed
711
    def analyse_types(self, env):
712
        pass
713

William Stein's avatar
William Stein committed
714 715 716 717 718 719 720 721 722
    def calculate_result_code(self):
        return self.value

    def generate_result_code(self, code):
        pass


class NoneNode(PyConstNode):
    #  The constant value None
723

William Stein's avatar
William Stein committed
724
    value = "Py_None"
725 726

    constant_result = None
727

728
    nogil_check = None
729

730 731
    def compile_time_value(self, denv):
        return None
732 733 734 735 736

    def may_be_none(self):
        return True


William Stein's avatar
William Stein committed
737 738
class EllipsisNode(PyConstNode):
    #  '...' in a subscript list.
739

William Stein's avatar
William Stein committed
740 741
    value = "Py_Ellipsis"

742 743
    constant_result = Ellipsis

744 745 746
    def compile_time_value(self, denv):
        return Ellipsis

William Stein's avatar
William Stein committed
747

748
class ConstNode(AtomicExprNode):
William Stein's avatar
William Stein committed
749 750 751
    # Abstract base type for literal constant nodes.
    #
    # value     string      C code fragment
752

William Stein's avatar
William Stein committed
753
    is_literal = 1
754
    nogil_check = None
755

William Stein's avatar
William Stein committed
756 757
    def is_simple(self):
        return 1
758

759 760 761
    def nonlocally_immutable(self):
        return 1

762 763 764
    def may_be_none(self):
        return False

William Stein's avatar
William Stein committed
765 766
    def analyse_types(self, env):
        pass # Types are held in class variables
767

William Stein's avatar
William Stein committed
768
    def check_const(self):
769
        return True
770

771
    def get_constant_c_result_code(self):
772 773
        return self.calculate_result_code()

William Stein's avatar
William Stein committed
774 775 776 777 778 779 780
    def calculate_result_code(self):
        return str(self.value)

    def generate_result_code(self, code):
        pass


781 782 783
class BoolNode(ConstNode):
    type = PyrexTypes.c_bint_type
    #  The constant value True or False
784 785 786 787

    def calculate_constant_result(self):
        self.constant_result = self.value

788 789
    def compile_time_value(self, denv):
        return self.value
790

791
    def calculate_result_code(self):
792
        return str(int(self.value))
793

794

William Stein's avatar
William Stein committed
795 796
class NullNode(ConstNode):
    type = PyrexTypes.c_null_ptr_type
797
    value = "NULL"
798
    constant_result = 0
William Stein's avatar
William Stein committed
799

800
    def get_constant_c_result_code(self):
801 802
        return self.value

William Stein's avatar
William Stein committed
803 804 805

class CharNode(ConstNode):
    type = PyrexTypes.c_char_type
806 807 808

    def calculate_constant_result(self):
        self.constant_result = ord(self.value)
809

810
    def compile_time_value(self, denv):
811
        return ord(self.value)
812

William Stein's avatar
William Stein committed
813
    def calculate_result_code(self):
814
        return "'%s'" % StringEncoding.escape_char(self.value)
William Stein's avatar
William Stein committed
815 816 817


class IntNode(ConstNode):
818 819 820

    # unsigned     "" or "U"
    # longness     "" or "L" or "LL"
821
    # is_c_literal   True/False/None   creator considers this a C integer literal
822 823 824

    unsigned = ""
    longness = ""
825
    is_c_literal = None # unknown
826 827 828

    def __init__(self, pos, **kwds):
        ExprNode.__init__(self, pos, **kwds)
Robert Bradshaw's avatar
Robert Bradshaw committed
829
        if 'type' not in kwds:
830 831 832 833 834 835 836 837
            self.type = self.find_suitable_type_for_value()

    def find_suitable_type_for_value(self):
        if self.constant_result is constant_value_not_set:
            try:
                self.calculate_constant_result()
            except ValueError:
                pass
838 839 840 841
        # we ignore 'is_c_literal = True' and instead map signed 32bit
        # integers as C long values
        if self.is_c_literal or \
               self.constant_result in (constant_value_not_set, not_a_constant) or \
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
               self.unsigned or self.longness == 'LL':
            # clearly a C literal
            rank = (self.longness == 'LL') and 2 or 1
            suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
            if self.type:
                suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
        else:
            # C literal or Python literal - split at 32bit boundary
            if self.constant_result >= -2**31 and self.constant_result < 2**31:
                if self.type and self.type.is_int:
                    suitable_type = self.type
                else:
                    suitable_type = PyrexTypes.c_long_type
            else:
                suitable_type = PyrexTypes.py_object_type
        return suitable_type
William Stein's avatar
William Stein committed
858

859
    def coerce_to(self, dst_type, env):
860
        if self.type is dst_type:
861
            return self
862
        elif dst_type.is_float:
863 864 865 866 867 868 869
            if self.constant_result is not not_a_constant:
                float_value = float(self.constant_result)
                return FloatNode(self.pos, value=repr(float_value), type=dst_type,
                                 constant_result=float_value)
            else:
                return FloatNode(self.pos, value=self.value, type=dst_type,
                                 constant_result=not_a_constant)
870
        if dst_type.is_numeric and not dst_type.is_complex:
871
            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
872 873
                           type = dst_type, is_c_literal = True,
                           unsigned=self.unsigned, longness=self.longness)
874
            return node
875 876
        elif dst_type.is_pyobject:
            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
877 878
                           type = PyrexTypes.py_object_type, is_c_literal = False,
                           unsigned=self.unsigned, longness=self.longness)
879
        else:
880 881
            # FIXME: not setting the type here to keep it working with
            # complex numbers. Should they be special cased?
882 883
            node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
                           unsigned=self.unsigned, longness=self.longness)
884 885 886
        # We still need to perform normal coerce_to processing on the
        # result, because we might be coercing to an extension type,
        # in which case a type test node will be needed.
887 888
        return ConstNode.coerce_to(node, dst_type, env)

889
    def coerce_to_boolean(self, env):
890 891 892 893
        return IntNode(
            self.pos, value=self.value,
            type = PyrexTypes.c_bint_type,
            unsigned=self.unsigned, longness=self.longness)
894

895
    def generate_evaluation_code(self, code):
896
        if self.type.is_pyobject:
897
            # pre-allocate a Python version of the number
898 899
            plain_integer_string = self.value_as_c_integer_string(plain_digits=True)
            self.result_code = code.get_py_num(plain_integer_string, self.longness)
900
        else:
901
            self.result_code = self.get_constant_c_result_code()
902

903
    def get_constant_c_result_code(self):
904 905 906
        return self.value_as_c_integer_string() + self.unsigned + self.longness

    def value_as_c_integer_string(self, plain_digits=False):
907 908 909 910
        value = self.value
        if isinstance(value, basestring) and len(value) > 2:
            # must convert C-incompatible Py3 oct/bin notations
            if value[1] in 'oO':
911 912 913 914
                if plain_digits:
                    value = int(value[2:], 8)
                else:
                    value = value[0] + value[2:] # '0o123' => '0123'
915 916
            elif value[1] in 'bB':
                value = int(value[2:], 2)
917 918 919
            elif plain_digits and value[1] in 'xX':
                value = int(value[2:], 16)
        return str(value)
920 921 922

    def calculate_result_code(self):
        return self.result_code
William Stein's avatar
William Stein committed
923

924
    def calculate_constant_result(self):
925
        self.constant_result = Utils.str_to_number(self.value)
926

927
    def compile_time_value(self, denv):
928
        return Utils.str_to_number(self.value)
929 930


William Stein's avatar
William Stein committed
931 932 933
class FloatNode(ConstNode):
    type = PyrexTypes.c_double_type

934
    def calculate_constant_result(self):
935
        self.constant_result = float(self.value)
936

937 938
    def compile_time_value(self, denv):
        return float(self.value)
939

Stefan Behnel's avatar
Stefan Behnel committed
940
    def calculate_result_code(self):
941 942 943 944
        strval = self.value
        assert isinstance(strval, (str, unicode))
        cmpval = repr(float(strval))
        if cmpval == 'nan':
945
            return "(Py_HUGE_VAL * 0)"
946
        elif cmpval == 'inf':
947
            return "Py_HUGE_VAL"
948
        elif cmpval == '-inf':
949
            return "(-Py_HUGE_VAL)"
Stefan Behnel's avatar
Stefan Behnel committed
950 951
        else:
            return strval
952

William Stein's avatar
William Stein committed
953

954
class BytesNode(ConstNode):
955 956 957 958
    # A char* or bytes literal
    #
    # value      BytesLiteral

959 960
    # start off as Python 'bytes' to support len() in O(1)
    type = bytes_type
961 962

    def compile_time_value(self, denv):
963
        return self.value
964

965
    def analyse_as_type(self, env):
966
        type = PyrexTypes.parse_basic_type(self.value)
967
        if type is not None:
968
            return type
969 970 971 972 973 974 975
        from TreeFragment import TreeFragment
        pos = (self.pos[0], self.pos[1], self.pos[2]-7)
        declaration = TreeFragment(u"sizeof(%s)" % self.value, name=pos[0].filename, initial_pos=pos)
        sizeof_node = declaration.root.stats[0].expr
        sizeof_node.analyse_types(env)
        if isinstance(sizeof_node, SizeofTypeNode):
            return sizeof_node.arg_type
976

977 978 979
    def can_coerce_to_char_literal(self):
        return len(self.value) == 1

980
    def coerce_to_boolean(self, env):
981 982
        # This is special because testing a C char* for truth directly
        # would yield the wrong result.
983 984
        return BoolNode(self.pos, value=bool(self.value))

William Stein's avatar
William Stein committed
985
    def coerce_to(self, dst_type, env):
986 987
        if self.type == dst_type:
            return self
988
        if dst_type.is_int:
989
            if not self.can_coerce_to_char_literal():
990 991
                error(self.pos, "Only single-character string literals can be coerced into ints.")
                return self
Stefan Behnel's avatar
Stefan Behnel committed
992 993
            if dst_type.is_unicode_char:
                error(self.pos, "Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.")
994
                return self
995 996
            return CharNode(self.pos, value=self.value)

997
        node = BytesNode(self.pos, value=self.value)
998 999 1000 1001 1002 1003 1004 1005
        if dst_type.is_pyobject:
            if dst_type in (py_object_type, Builtin.bytes_type):
                node.type = Builtin.bytes_type
            else:
                self.check_for_coercion_error(dst_type, fail=True)
                return node
        elif dst_type == PyrexTypes.c_char_ptr_type:
            node.type = dst_type
1006 1007 1008 1009
            return node
        elif dst_type == PyrexTypes.c_uchar_ptr_type:
            node.type = PyrexTypes.c_char_ptr_type
            return CastNode(node, PyrexTypes.c_uchar_ptr_type)
1010 1011
        elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
            node.type = dst_type
1012
            return node
1013

William Stein's avatar
William Stein committed
1014 1015 1016 1017 1018
        # We still need to perform normal coerce_to processing on the
        # result, because we might be coercing to an extension type,
        # in which case a type test node will be needed.
        return ConstNode.coerce_to(node, dst_type, env)

1019
    def generate_evaluation_code(self, code):
William Stein's avatar
William Stein committed
1020
        if self.type.is_pyobject:
1021
            self.result_code = code.get_py_string_const(self.value)
William Stein's avatar
William Stein committed
1022
        else:
1023
            self.result_code = code.get_string_const(self.value)
1024

1025
    def get_constant_c_result_code(self):
1026
        return None # FIXME
1027

1028 1029
    def calculate_result_code(self):
        return self.result_code
William Stein's avatar
William Stein committed
1030 1031


1032
class UnicodeNode(PyConstNode):
1033 1034
    # A Python unicode object
    #
1035 1036
    # value        EncodedString
    # bytes_value  BytesLiteral    the literal parsed as bytes string ('-3' unicode literals only)
Robert Bradshaw's avatar
Robert Bradshaw committed
1037

1038
    bytes_value = None
1039
    type = unicode_type
1040

1041
    def coerce_to(self, dst_type, env):
1042 1043
        if dst_type is self.type:
            pass
Stefan Behnel's avatar
Stefan Behnel committed
1044
        elif dst_type.is_unicode_char:
1045
            if not self.can_coerce_to_char_literal():
Stefan Behnel's avatar
Stefan Behnel committed
1046
                error(self.pos, "Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.")
1047 1048
                return self
            int_value = ord(self.value)
Stefan Behnel's avatar
Stefan Behnel committed
1049
            return IntNode(self.pos, type=dst_type, value=str(int_value), constant_result=int_value)
1050
        elif not dst_type.is_pyobject:
1051 1052 1053
            if dst_type.is_string and self.bytes_value is not None:
                # special case: '-3' enforced unicode literal used in a C char* context
                return BytesNode(self.pos, value=self.bytes_value).coerce_to(dst_type, env)
Stefan Behnel's avatar
Stefan Behnel committed
1054
            error(self.pos, "Unicode literals do not support coercion to C types other than Py_UNICODE or Py_UCS4.")
1055 1056 1057 1058
        elif dst_type is not py_object_type:
            if not self.check_for_coercion_error(dst_type):
                self.fail_assignment(dst_type)
        return self
1059

1060 1061
    def can_coerce_to_char_literal(self):
        return len(self.value) == 1
Stefan Behnel's avatar
Stefan Behnel committed
1062 1063 1064
            ## or (len(self.value) == 2
            ##     and (0xD800 <= self.value[0] <= 0xDBFF)
            ##     and (0xDC00 <= self.value[1] <= 0xDFFF))
1065

1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
    def contains_surrogates(self):
        # Check if the unicode string contains surrogate code points
        # on a CPython platform with wide (UCS-4) or narrow (UTF-16)
        # Unicode, i.e. characters that would be spelled as two
        # separate code units on a narrow platform.
        for c in map(ord, self.value):
            if c > 65535: # can only happen on wide platforms
                return True
            # We only look for the first code unit (D800-DBFF) of a
            # surrogate pair - if we find one, the other one
            # (DC00-DFFF) is likely there, too.  If we don't find it,
            # any second code unit cannot make for a surrogate pair by
            # itself.
            if c >= 0xD800 and c <= 0xDBFF:
                return True
        return False

1083
    def generate_evaluation_code(self, code):
1084
        self.result_code = code.get_py_string_const(self.value)
1085 1086 1087

    def calculate_result_code(self):
        return self.result_code
1088

1089 1090
    def compile_time_value(self, env):
        return self.value
1091 1092


1093 1094 1095 1096
class StringNode(PyConstNode):
    # A Python str object, i.e. a byte string in Python 2.x and a
    # unicode string in Python 3.x
    #
1097 1098
    # value          BytesLiteral (or EncodedString with ASCII content)
    # unicode_value  EncodedString or None
1099
    # is_identifier  boolean
1100

1101
    type = str_type
1102
    is_identifier = None
1103
    unicode_value = None
1104

1105
    def coerce_to(self, dst_type, env):
1106
        if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
1107 1108 1109 1110 1111
#            if dst_type is Builtin.bytes_type:
#                # special case: bytes = 'str literal'
#                return BytesNode(self.pos, value=self.value)
            if not dst_type.is_pyobject:
                return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
1112
            self.check_for_coercion_error(dst_type, fail=True)
1113 1114

        # this will be a unicode string in Py3, so make sure we can decode it
1115
        if self.value.encoding and isinstance(self.value, StringEncoding.BytesLiteral):
1116
            try:
1117 1118 1119 1120 1121
                self.value.decode(self.value.encoding)
            except UnicodeDecodeError:
                error(self.pos, ("Decoding unprefixed string literal from '%s' failed. Consider using"
                                 "a byte string or unicode string explicitly, "
                                 "or adjust the source code encoding.") % self.value.encoding)
1122

1123
        return self
1124

1125 1126
    def can_coerce_to_char_literal(self):
        return not self.is_identifier and len(self.value) == 1
1127

1128
    def generate_evaluation_code(self, code):
1129 1130
        self.result_code = code.get_py_string_const(
            self.value, identifier=self.is_identifier, is_str=True)
1131

1132
    def get_constant_c_result_code(self):
1133 1134
        return None

1135
    def calculate_result_code(self):
1136
        return self.result_code
1137

1138 1139
    def compile_time_value(self, env):
        return self.value
1140 1141


1142 1143 1144 1145
class IdentifierStringNode(StringNode):
    # A special str value that represents an identifier (bytes in Py2,
    # unicode in Py3).
    is_identifier = True
1146 1147


1148
class LongNode(AtomicExprNode):
William Stein's avatar
William Stein committed
1149 1150 1151
    #  Python long integer literal
    #
    #  value   string
1152

1153 1154
    type = py_object_type

1155
    def calculate_constant_result(self):
1156
        self.constant_result = Utils.str_to_number(self.value)
1157

1158
    def compile_time_value(self, denv):
1159
        return Utils.str_to_number(self.value)
1160

William Stein's avatar
William Stein committed
1161 1162
    def analyse_types(self, env):
        self.is_temp = 1
1163

1164 1165 1166
    def may_be_none(self):
        return False

1167 1168
    gil_message = "Constructing Python long int"

1169
    def generate_result_code(self, code):
William Stein's avatar
William Stein committed
1170
        code.putln(
1171
            '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % (
1172
                self.result(),
William Stein's avatar
William Stein committed
1173
                self.value,
1174
                code.error_goto_if_null(self.result(), self.pos)))
1175
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
1176 1177


1178
class ImagNode(AtomicExprNode):
William Stein's avatar
William Stein committed
1179 1180 1181
    #  Imaginary number literal
    #
    #  value   float    imaginary part
1182

1183
    type = PyrexTypes.c_double_complex_type
1184 1185 1186

    def calculate_constant_result(self):
        self.constant_result = complex(0.0, self.value)
1187

1188 1189
    def compile_time_value(self, denv):
        return complex(0.0, self.value)
1190

William Stein's avatar
William Stein committed
1191
    def analyse_types(self, env):
1192 1193
        self.type.create_declaration_utility_code(env)

1194 1195 1196
    def may_be_none(self):
        return False

1197
    def coerce_to(self, dst_type, env):
1198 1199 1200
        if self.type is dst_type:
            return self
        node = ImagNode(self.pos, value=self.value)
1201
        if dst_type.is_pyobject:
1202 1203
            node.is_temp = 1
            node.type = PyrexTypes.py_object_type
1204 1205 1206
        # We still need to perform normal coerce_to processing on the
        # result, because we might be coercing to an extension type,
        # in which case a type test node will be needed.
1207
        return AtomicExprNode.coerce_to(node, dst_type, env)
1208 1209 1210

    gil_message = "Constructing complex number"

1211 1212 1213 1214 1215 1216
    def calculate_result_code(self):
        if self.type.is_pyobject:
            return self.result()
        else:
            return "%s(0, %r)" % (self.type.from_parts, float(self.value))

1217
    def generate_result_code(self, code):
1218 1219 1220 1221 1222 1223 1224
        if self.type.is_pyobject:
            code.putln(
                "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
                    self.result(),
                    float(self.value),
                    code.error_goto_if_null(self.result(), self.pos)))
            code.put_gotref(self.py_result())
1225

William Stein's avatar
William Stein committed
1226

Danilo Freitas's avatar
Danilo Freitas committed
1227
class NewExprNode(AtomicExprNode):
1228 1229 1230

    # C++ new statement
    #
Robert Bradshaw's avatar
Robert Bradshaw committed
1231
    # cppclass              node                 c++ class to create
1232

Robert Bradshaw's avatar
Robert Bradshaw committed
1233
    type = None
1234

1235
    def infer_type(self, env):
Robert Bradshaw's avatar
Robert Bradshaw committed
1236 1237
        type = self.cppclass.analyse_as_type(env)
        if type is None or not type.is_cpp_class:
Danilo Freitas's avatar
Danilo Freitas committed
1238
            error(self.pos, "new operator can only be applied to a C++ class")
Robert Bradshaw's avatar
Robert Bradshaw committed
1239
            self.type = error_type
Danilo Freitas's avatar
Danilo Freitas committed
1240
            return
Robert Bradshaw's avatar
Robert Bradshaw committed
1241
        self.cpp_check(env)
1242
        constructor = type.scope.lookup(u'<init>')
Danilo Freitas's avatar
Danilo Freitas committed
1243
        if constructor is None:
1244 1245
            return_type = PyrexTypes.CFuncType(type, [])
            return_type = PyrexTypes.CPtrType(return_type)
1246 1247
            type.scope.declare_cfunction(u'<init>', return_type, self.pos)
            constructor = type.scope.lookup(u'<init>')
1248
        self.class_type = type
DaniloFreitas's avatar
DaniloFreitas committed
1249
        self.entry = constructor
Robert Bradshaw's avatar
Robert Bradshaw committed
1250
        self.type = constructor.type
1251
        return self.type
1252

1253
    def analyse_types(self, env):
Robert Bradshaw's avatar
Robert Bradshaw committed
1254 1255
        if self.type is None:
            self.infer_type(env)
1256 1257 1258 1259

    def may_be_none(self):
        return False

Danilo Freitas's avatar
Danilo Freitas committed
1260 1261
    def generate_result_code(self, code):
        pass
1262

Danilo Freitas's avatar
Danilo Freitas committed
1263
    def calculate_result_code(self):
1264
        return "new " + self.class_type.declaration_code("")
Danilo Freitas's avatar
Danilo Freitas committed
1265

William Stein's avatar
William Stein committed
1266

1267
class NameNode(AtomicExprNode):
William Stein's avatar
William Stein committed
1268 1269 1270 1271
    #  Reference to a local or global variable name.
    #
    #  name            string    Python name of the variable
    #  entry           Entry     Symbol table entry
1272
    #  type_entry      Entry     For extension type names, the original type entry
1273

1274 1275
    is_name = True
    is_cython_module = False
Robert Bradshaw's avatar
Robert Bradshaw committed
1276
    cython_attribute = None
1277
    lhs_of_first_assignment = False
1278
    is_used_as_rvalue = 0
1279
    entry = None
1280
    type_entry = None
1281 1282 1283 1284 1285

    def create_analysed_rvalue(pos, env, entry):
        node = NameNode(pos)
        node.analyse_types(env, entry=entry)
        return node
1286

1287
    def as_cython_attribute(self):
Robert Bradshaw's avatar
Robert Bradshaw committed
1288
        return self.cython_attribute
1289

1290
    create_analysed_rvalue = staticmethod(create_analysed_rvalue)
1291

Robert Bradshaw's avatar
Robert Bradshaw committed
1292 1293 1294 1295 1296 1297 1298
    def type_dependencies(self, env):
        if self.entry is None:
            self.entry = env.lookup(self.name)
        if self.entry is not None and self.entry.type.is_unspecified:
            return (self.entry,)
        else:
            return ()
1299

Robert Bradshaw's avatar
Robert Bradshaw committed
1300 1301 1302 1303 1304
    def infer_type(self, env):
        if self.entry is None:
            self.entry = env.lookup(self.name)
        if self.entry is None:
            return py_object_type
Robert Bradshaw's avatar
Robert Bradshaw committed
1305 1306 1307
        elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
                self.name == self.entry.type.name:
            # Unfortunately the type attribute of type objects
1308
            # is used for the pointer to the type they represent.
Robert Bradshaw's avatar
Robert Bradshaw committed
1309
            return type_type
1310
        elif self.entry.type.is_cfunction:
Stefan Behnel's avatar
typo  
Stefan Behnel committed
1311
            # special case: referring to a C function must return its pointer
1312
            return PyrexTypes.CPtrType(self.entry.type)
Robert Bradshaw's avatar
Robert Bradshaw committed
1313 1314
        else:
            return self.entry.type
1315

1316 1317 1318 1319
    def compile_time_value(self, denv):
        try:
            return denv.lookup(self.name)
        except KeyError:
Stefan Behnel's avatar
Stefan Behnel committed
1320
            error(self.pos, "Compile-time name '%s' not defined" % self.name)
1321 1322 1323 1324 1325

    def get_constant_c_result_code(self):
        if not self.entry or self.entry.type.is_pyobject:
            return None
        return self.entry.cname
1326

1327 1328 1329 1330 1331 1332 1333
    def coerce_to(self, dst_type, env):
        #  If coercing to a generic pyobject and this is a builtin
        #  C function with a Python equivalent, manufacture a NameNode
        #  referring to the Python builtin.
        #print "NameNode.coerce_to:", self.name, dst_type ###
        if dst_type is py_object_type:
            entry = self.entry
1334
            if entry and entry.is_cfunction:
1335 1336
                var_entry = entry.as_variable
                if var_entry:
1337 1338
                    if var_entry.is_builtin and Options.cache_builtins:
                        var_entry = env.declare_builtin(var_entry.name, self.pos)
1339 1340 1341 1342
                    node = NameNode(self.pos, name = self.name)
                    node.entry = var_entry
                    node.analyse_rvalue_entry(env)
                    return node
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1343
        return super(NameNode, self).coerce_to(dst_type, env)
1344

William Stein's avatar
William Stein committed
1345 1346 1347
    def analyse_as_module(self, env):
        # Try to interpret this as a reference to a cimported module.
        # Returns the module scope, or None.
1348 1349 1350
        entry = self.entry
        if not entry:
            entry = env.lookup(self.name)
William Stein's avatar
William Stein committed
1351 1352 1353
        if entry and entry.as_module:
            return entry.as_module
        return None
1354

1355
    def analyse_as_type(self, env):
1356 1357 1358 1359
        if self.cython_attribute:
            type = PyrexTypes.parse_basic_type(self.cython_attribute)
        else:
            type = PyrexTypes.parse_basic_type(self.name)
1360 1361
        if type:
            return type
1362 1363 1364 1365 1366 1367 1368
        entry = self.entry
        if not entry:
            entry = env.lookup(self.name)
        if entry and entry.is_type:
            return entry.type
        else:
            return None
1369

William Stein's avatar
William Stein committed
1370 1371 1372
    def analyse_as_extension_type(self, env):
        # Try to interpret this as a reference to an extension type.
        # Returns the extension type, or None.
1373 1374 1375
        entry = self.entry
        if not entry:
            entry = env.lookup(self.name)
William Stein's avatar
William Stein committed
1376
        if entry and entry.is_type and entry.type.is_extension_type:
1377 1378 1379
            return entry.type
        else:
            return None
1380

William Stein's avatar
William Stein committed
1381
    def analyse_target_declaration(self, env):
1382 1383
        if not self.entry:
            self.entry = env.lookup_here(self.name)
William Stein's avatar
William Stein committed
1384
        if not self.entry:
1385 1386
            if env.directives['warn.undeclared']:
                warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
1387
            if env.directives['infer_types'] != False:
1388 1389 1390 1391
                type = unspecified_type
            else:
                type = py_object_type
            self.entry = env.declare_var(self.name, type, self.pos)
Craig Citro's avatar
Craig Citro committed
1392
        env.control_flow.set_state(self.pos, (self.name, 'initialized'), True)
Robert Bradshaw's avatar
Robert Bradshaw committed
1393
        env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
1394 1395
        if self.entry.is_declared_generic:
            self.result_ctype = py_object_type
1396

1397 1398 1399
    def analyse_types(self, env):
        if self.entry is None:
            self.entry = env.lookup(self.name)
William Stein's avatar
William Stein committed
1400 1401
        if not self.entry:
            self.entry = env.declare_builtin(self.name, self.pos)
1402 1403 1404
        if not self.entry:
            self.type = PyrexTypes.error_type
            return
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1405 1406 1407 1408 1409 1410 1411 1412
        entry = self.entry
        if entry:
            entry.used = 1
            if entry.type.is_buffer:
                import Buffer
                Buffer.used_buffer_aux_vars(entry)
            if entry.utility_code:
                env.use_utility_code(entry.utility_code)
1413
        self.analyse_rvalue_entry(env)
1414

1415
    def analyse_target_types(self, env):
William Stein's avatar
William Stein committed
1416
        self.analyse_entry(env)
1417 1418 1419 1420
        if not self.is_lvalue():
            error(self.pos, "Assignment to non-lvalue '%s'"
                % self.name)
            self.type = PyrexTypes.error_type
Stefan Behnel's avatar
Stefan Behnel committed
1421
        self.entry.used = 1
1422
        if self.entry.type.is_buffer:
1423 1424
            import Buffer
            Buffer.used_buffer_aux_vars(self.entry)
1425

1426 1427 1428 1429
    def analyse_rvalue_entry(self, env):
        #print "NameNode.analyse_rvalue_entry:", self.name ###
        #print "Entry:", self.entry.__dict__ ###
        self.analyse_entry(env)
1430 1431
        entry = self.entry
        if entry.is_declared_generic:
William Stein's avatar
William Stein committed
1432
            self.result_ctype = py_object_type
1433
        if entry.is_pyglobal or entry.is_builtin:
1434 1435 1436 1437
            if Options.cache_builtins and entry.is_builtin:
                self.is_temp = 0
            else:
                self.is_temp = 1
1438
                env.use_utility_code(get_name_interned_utility_code)
1439 1440
            self.is_used_as_rvalue = 1

1441
    def nogil_check(self, env):
1442 1443 1444
        if self.is_used_as_rvalue:
            entry = self.entry
            if entry.is_builtin:
1445 1446
                if not Options.cache_builtins: # cached builtins are ok
                    self.gil_error()
1447
            elif entry.is_pyglobal:
1448
                self.gil_error()
1449 1450 1451

    gil_message = "Accessing Python global or builtin"

1452 1453
    def analyse_entry(self, env):
        #print "NameNode.analyse_entry:", self.name ###
William Stein's avatar
William Stein committed
1454
        self.check_identifier_kind()
1455 1456 1457 1458
        entry = self.entry
        type = entry.type
        self.type = type

William Stein's avatar
William Stein committed
1459
    def check_identifier_kind(self):
1460 1461 1462
        # Check that this is an appropriate kind of name for use in an
        # expression.  Also finds the variable entry associated with
        # an extension type.
William Stein's avatar
William Stein committed
1463
        entry = self.entry
1464 1465
        if entry.is_type and entry.type.is_extension_type:
            self.type_entry = entry
1466
        if not (entry.is_const or entry.is_variable
Danilo Freitas's avatar
Danilo Freitas committed
1467 1468
            or entry.is_builtin or entry.is_cfunction
            or entry.is_cpp_class):
William Stein's avatar
William Stein committed
1469 1470 1471
                if self.entry.as_variable:
                    self.entry = self.entry.as_variable
                else:
1472
                    error(self.pos,
1473 1474
                          "'%s' is not a constant, variable or function identifier" % self.name)

William Stein's avatar
William Stein committed
1475 1476 1477
    def is_simple(self):
        #  If it's not a C variable, it'll be in a temp.
        return 1
1478

1479
    def nonlocally_immutable(self):
1480 1481
        if ExprNode.nonlocally_immutable(self):
            return True
1482 1483 1484
        entry = self.entry
        return entry and (entry.is_local or entry.is_arg) and not entry.in_closure

William Stein's avatar
William Stein committed
1485 1486
    def calculate_target_results(self, env):
        pass
1487

William Stein's avatar
William Stein committed
1488 1489
    def check_const(self):
        entry = self.entry
Robert Bradshaw's avatar
Robert Bradshaw committed
1490
        if entry is not None and not (entry.is_const or entry.is_cfunction or entry.is_builtin):
William Stein's avatar
William Stein committed
1491
            self.not_const()
1492 1493
            return False
        return True
1494

William Stein's avatar
William Stein committed
1495 1496
    def check_const_addr(self):
        entry = self.entry
1497
        if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
William Stein's avatar
William Stein committed
1498
            self.addr_not_const()
1499 1500
            return False
        return True
William Stein's avatar
William Stein committed
1501 1502 1503 1504 1505

    def is_lvalue(self):
        return self.entry.is_variable and \
            not self.entry.type.is_array and \
            not self.entry.is_readonly
1506

William Stein's avatar
William Stein committed
1507 1508 1509 1510
    def is_ephemeral(self):
        #  Name nodes are never ephemeral, even if the
        #  result is in a temporary.
        return 0
1511

William Stein's avatar
William Stein committed
1512
    def calculate_result_code(self):
Stefan Behnel's avatar
Stefan Behnel committed
1513 1514
        entry = self.entry
        if not entry:
William Stein's avatar
William Stein committed
1515
            return "<error>" # There was an error earlier
Stefan Behnel's avatar
Stefan Behnel committed
1516
        return entry.cname
1517

William Stein's avatar
William Stein committed
1518
    def generate_result_code(self, code):
1519
        assert hasattr(self, 'entry')
William Stein's avatar
William Stein committed
1520 1521 1522
        entry = self.entry
        if entry is None:
            return # There was an error earlier
1523 1524
        if entry.is_builtin and Options.cache_builtins:
            return # Lookup already cached
Stefan Behnel's avatar
Stefan Behnel committed
1525
        elif entry.is_pyclass_attr:
Vitja Makarov's avatar
Vitja Makarov committed
1526 1527 1528 1529 1530 1531 1532
            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
            interned_cname = code.intern_identifier(self.entry.name)
            if entry.is_builtin:
                namespace = Naming.builtins_cname
            else: # entry.is_pyglobal
                namespace = entry.scope.namespace_cname
            code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
1533
                '%s = PyObject_GetItem(%s, %s); %s' % (
Vitja Makarov's avatar
Vitja Makarov committed
1534 1535 1536 1537 1538
                self.result(),
                namespace,
                interned_cname,
                code.error_goto_if_null(self.result(), self.pos)))
            code.put_gotref(self.py_result())
1539

1540
        elif entry.is_pyglobal or entry.is_builtin:
1541 1542
            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
            interned_cname = code.intern_identifier(self.entry.name)
William Stein's avatar
William Stein committed
1543 1544 1545
            if entry.is_builtin:
                namespace = Naming.builtins_cname
            else: # entry.is_pyglobal
1546
                namespace = entry.scope.namespace_cname
1547
            code.globalstate.use_utility_code(get_name_interned_utility_code)
1548 1549
            code.putln(
                '%s = __Pyx_GetName(%s, %s); %s' % (
1550
                self.result(),
1551
                namespace,
1552
                interned_cname,
1553
                code.error_goto_if_null(self.result(), self.pos)))
1554
            code.put_gotref(self.py_result())
1555

1556 1557
        elif entry.is_local and False:
            # control flow not good enough yet
Craig Citro's avatar
Craig Citro committed
1558
            assigned = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
1559 1560
            if assigned is False:
                error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
Robert Bradshaw's avatar
Robert Bradshaw committed
1561
            elif not Options.init_local_none and assigned is None:
1562 1563
                code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
                           (entry.cname, entry.name, code.error_goto(self.pos)))
Craig Citro's avatar
Craig Citro committed
1564
                entry.scope.control_flow.set_state(self.pos, (entry.name, 'initialized'), True)
William Stein's avatar
William Stein committed
1565 1566

    def generate_assignment_code(self, rhs, code):
1567
        #print "NameNode.generate_assignment_code:", self.name ###
William Stein's avatar
William Stein committed
1568 1569 1570
        entry = self.entry
        if entry is None:
            return # There was an error earlier
1571 1572 1573 1574

        if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
            and not self.lhs_of_first_assignment):
            error(self.pos, "Literal list must be assigned to pointer at time of declaration")
1575

1576 1577
        # is_pyglobal seems to be True for module level-globals only.
        # We use this to access class->tp_dict if necessary.
William Stein's avatar
William Stein committed
1578
        if entry.is_pyglobal:
1579 1580
            assert entry.type.is_pyobject, "Python global or builtin not a Python object"
            interned_cname = code.intern_identifier(self.entry.name)
1581
            namespace = self.entry.scope.namespace_cname
1582
            if entry.is_member:
Stefan Behnel's avatar
Stefan Behnel committed
1583
                # if the entry is a member we have to cheat: SetAttr does not work
1584
                # on types, so we create a descriptor which is then added to tp_dict
1585 1586 1587
                code.put_error_if_neg(self.pos,
                    'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
                        namespace,
1588
                        interned_cname,
1589
                        rhs.py_result()))
1590 1591
                rhs.generate_disposal_code(code)
                rhs.free_temps(code)
1592
                # in Py2.6+, we need to invalidate the method cache
1593
                code.putln("PyType_Modified(%s);" %
Vitja Makarov's avatar
Vitja Makarov committed
1594
                            entry.scope.parent_type.typeptr_cname)
Stefan Behnel's avatar
Stefan Behnel committed
1595
            elif entry.is_pyclass_attr:
Vitja Makarov's avatar
Vitja Makarov committed
1596
                code.put_error_if_neg(self.pos,
Stefan Behnel's avatar
Stefan Behnel committed
1597
                    'PyObject_SetItem(%s, %s, %s)' % (
Vitja Makarov's avatar
Vitja Makarov committed
1598 1599 1600 1601 1602 1603
                        namespace,
                        interned_cname,
                        rhs.py_result()))
                rhs.generate_disposal_code(code)
                rhs.free_temps(code)
            else:
1604 1605 1606
                code.put_error_if_neg(self.pos,
                    'PyObject_SetAttr(%s, %s, %s)' % (
                        namespace,
1607
                        interned_cname,
1608
                        rhs.py_result()))
1609
                if debug_disposal_code:
Stefan Behnel's avatar
Stefan Behnel committed
1610 1611
                    print("NameNode.generate_assignment_code:")
                    print("...generating disposal code for %s" % rhs)
1612
                rhs.generate_disposal_code(code)
1613
                rhs.free_temps(code)
William Stein's avatar
William Stein committed
1614
        else:
1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
            if self.type.is_buffer:
                # Generate code for doing the buffer release/acquisition.
                # This might raise an exception in which case the assignment (done
                # below) will not happen.
                #
                # The reason this is not in a typetest-like node is because the
                # variables that the acquired buffer info is stored to is allocated
                # per entry and coupled with it.
                self.generate_acquire_buffer(rhs, code)

1625
            if self.type.is_pyobject:
William Stein's avatar
William Stein committed
1626 1627 1628 1629
                #print "NameNode.generate_assignment_code: to", self.name ###
                #print "...from", rhs ###
                #print "...LHS type", self.type, "ctype", self.ctype() ###
                #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
1630 1631 1632 1633
                if self.use_managed_ref:
                    rhs.make_owned_reference(code)
                    if entry.is_cglobal:
                        code.put_gotref(self.py_result())
1634 1635 1636 1637 1638 1639 1640 1641
                    if not self.lhs_of_first_assignment:
                        if entry.is_local and not Options.init_local_none:
                            initialized = entry.scope.control_flow.get_state((entry.name, 'initialized'), self.pos)
                            if initialized is True:
                                code.put_decref(self.result(), self.ctype())
                            elif initialized is None:
                                code.put_xdecref(self.result(), self.ctype())
                        else:
1642
                            code.put_decref(self.result(), self.ctype())
1643
                    if entry.is_cglobal:
1644
                        code.put_giveref(rhs.py_result())
1645 1646 1647

            code.putln('%s = %s;' % (self.result(),
                                     rhs.result_as(self.ctype())))
William Stein's avatar
William Stein committed
1648
            if debug_disposal_code:
Stefan Behnel's avatar
Stefan Behnel committed
1649 1650
                print("NameNode.generate_assignment_code:")
                print("...generating post-assignment code for %s" % rhs)
William Stein's avatar
William Stein committed
1651
            rhs.generate_post_assignment_code(code)
1652
            rhs.free_temps(code)
1653 1654

    def generate_acquire_buffer(self, rhs, code):
1655 1656 1657
        # rhstmp is only used in case the rhs is a complicated expression leading to
        # the object, to avoid repeating the same C expression for every reference
        # to the rhs. It does NOT hold a reference.
1658 1659 1660 1661 1662 1663 1664
        pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
        if pretty_rhs:
            rhstmp = rhs.result_as(self.ctype())
        else:
            rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
            code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))

1665 1666 1667
        buffer_aux = self.entry.buffer_aux
        bufstruct = buffer_aux.buffer_info_var.cname
        import Buffer
1668
        Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type,
1669
                                    is_initialized=not self.lhs_of_first_assignment,
1670
                                    pos=self.pos, code=code)
1671

1672 1673 1674
        if not pretty_rhs:
            code.putln("%s = 0;" % rhstmp)
            code.funcstate.release_temp(rhstmp)
1675

William Stein's avatar
William Stein committed
1676 1677 1678
    def generate_deletion_code(self, code):
        if self.entry is None:
            return # There was an error earlier
1679 1680 1681 1682 1683 1684
        elif self.entry.is_pyglobal:
            code.put_error_if_neg(self.pos,
                '__Pyx_DelAttrString(%s, "%s")' % (
                    Naming.module_cname,
                    self.entry.name))
        elif self.entry.is_pyclass_attr:
Vitja Makarov's avatar
Vitja Makarov committed
1685 1686
            namespace = self.entry.scope.namespace_cname
            code.put_error_if_neg(self.pos,
Stefan Behnel's avatar
Stefan Behnel committed
1687
                'PyMapping_DelItemString(%s, "%s")' % (
Vitja Makarov's avatar
Vitja Makarov committed
1688 1689
                    namespace,
                    self.entry.name))
1690 1691 1692
        elif self.entry.type.is_pyobject:
            # Fake it until we can do it for real...
            self.generate_assignment_code(NoneNode(self.pos), code)
Vitja Makarov's avatar
Vitja Makarov committed
1693
        else:
1694
            error(self.pos, "Deletion of C names not supported")
1695

1696 1697 1698 1699 1700 1701 1702
    def annotate(self, code):
        if hasattr(self, 'is_called') and self.is_called:
            pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
            if self.type.is_pyobject:
                code.annotate(pos, AnnotationItem('py_call', 'python function', size=len(self.name)))
            else:
                code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
1703

1704
class BackquoteNode(ExprNode):
William Stein's avatar
William Stein committed
1705 1706 1707
    #  `expr`
    #
    #  arg    ExprNode
1708

1709
    type = py_object_type
1710

William Stein's avatar
William Stein committed
1711
    subexprs = ['arg']
1712

William Stein's avatar
William Stein committed
1713 1714 1715 1716
    def analyse_types(self, env):
        self.arg.analyse_types(env)
        self.arg = self.arg.coerce_to_pyobject(env)
        self.is_temp = 1
1717 1718 1719

    gil_message = "Backquote expression"

1720 1721 1722
    def calculate_constant_result(self):
        self.constant_result = repr(self.arg.constant_result)

William Stein's avatar
William Stein committed
1723 1724
    def generate_result_code(self, code):
        code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
1725
            "%s = PyObject_Repr(%s); %s" % (
1726
                self.result(),
William Stein's avatar
William Stein committed
1727
                self.arg.py_result(),
1728
                code.error_goto_if_null(self.result(), self.pos)))
1729
        code.put_gotref(self.py_result())
1730

William Stein's avatar
William Stein committed
1731 1732


1733
class ImportNode(ExprNode):
William Stein's avatar
William Stein committed
1734
    #  Used as part of import statement implementation.
1735
    #  Implements result =
William Stein's avatar
William Stein committed
1736 1737
    #    __import__(module_name, globals(), None, name_list)
    #
1738 1739
    #  module_name   StringNode            dotted name of module
    #  name_list     ListNode or None      list of names to be imported
1740

1741
    type = py_object_type
1742

William Stein's avatar
William Stein committed
1743
    subexprs = ['module_name', 'name_list']
1744

William Stein's avatar
William Stein committed
1745 1746 1747 1748 1749
    def analyse_types(self, env):
        self.module_name.analyse_types(env)
        self.module_name = self.module_name.coerce_to_pyobject(env)
        if self.name_list:
            self.name_list.analyse_types(env)
1750
            self.name_list.coerce_to_pyobject(env)
William Stein's avatar
William Stein committed
1751 1752
        self.is_temp = 1
        env.use_utility_code(import_utility_code)
1753 1754 1755

    gil_message = "Python import"

William Stein's avatar
William Stein committed
1756 1757 1758 1759 1760 1761
    def generate_result_code(self, code):
        if self.name_list:
            name_list_code = self.name_list.py_result()
        else:
            name_list_code = "0"
        code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
1762
            "%s = __Pyx_Import(%s, %s); %s" % (
1763
                self.result(),
William Stein's avatar
William Stein committed
1764 1765
                self.module_name.py_result(),
                name_list_code,
1766
                code.error_goto_if_null(self.result(), self.pos)))
1767
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
1768 1769


1770
class IteratorNode(ExprNode):
William Stein's avatar
William Stein committed
1771
    #  Used as part of for statement implementation.
1772 1773 1774 1775
    #
    #  allocate_counter_temp/release_counter_temp needs to be called
    #  by parent (ForInStatNode)
    #
William Stein's avatar
William Stein committed
1776 1777 1778
    #  Implements result = iter(sequence)
    #
    #  sequence   ExprNode
1779

1780
    type = py_object_type
1781

William Stein's avatar
William Stein committed
1782
    subexprs = ['sequence']
1783

William Stein's avatar
William Stein committed
1784 1785
    def analyse_types(self, env):
        self.sequence.analyse_types(env)
1786 1787
        if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
                not self.sequence.type.is_string:
1788
            # C array iteration will be transformed later on
1789
            self.type = self.sequence.type
1790 1791
        else:
            self.sequence = self.sequence.coerce_to_pyobject(env)
1792 1793 1794
            if self.sequence.type is list_type or \
                   self.sequence.type is tuple_type:
                self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
William Stein's avatar
William Stein committed
1795
        self.is_temp = 1
1796 1797 1798

    gil_message = "Iterating over Python object"

1799 1800 1801 1802 1803 1804 1805
    def allocate_counter_temp(self, code):
        self.counter_cname = code.funcstate.allocate_temp(
            PyrexTypes.c_py_ssize_t_type, manage_ref=False)

    def release_counter_temp(self, code):
        code.funcstate.release_temp(self.counter_cname)

William Stein's avatar
William Stein committed
1806
    def generate_result_code(self, code):
1807 1808
        if self.sequence.type.is_array or self.sequence.type.is_ptr:
            raise InternalError("for in carray slice not transformed")
1809
        is_builtin_sequence = self.sequence.type is list_type or \
1810
                              self.sequence.type is tuple_type
1811 1812
        may_be_a_sequence = not self.sequence.type.is_builtin_type
        if may_be_a_sequence:
1813 1814 1815 1816
            code.putln(
                "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % (
                    self.sequence.py_result(),
                    self.sequence.py_result()))
1817
        if is_builtin_sequence or may_be_a_sequence:
1818 1819 1820 1821 1822 1823
            code.putln(
                "%s = 0; %s = %s; __Pyx_INCREF(%s);" % (
                    self.counter_cname,
                    self.result(),
                    self.sequence.py_result(),
                    self.result()))
1824 1825 1826
        if not is_builtin_sequence:
            if may_be_a_sequence:
                code.putln("} else {")
1827
            code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % (
1828
                    self.counter_cname,
1829 1830 1831
                    self.result(),
                    self.sequence.py_result(),
                    code.error_goto_if_null(self.result(), self.pos)))
1832
            code.put_gotref(self.py_result())
1833 1834
            if may_be_a_sequence:
                code.putln("}")
William Stein's avatar
William Stein committed
1835 1836


1837
class NextNode(AtomicExprNode):
William Stein's avatar
William Stein committed
1838 1839 1840 1841 1842 1843
    #  Used as part of for statement implementation.
    #  Implements result = iterator.next()
    #  Created during analyse_types phase.
    #  The iterator is not owned by this node.
    #
    #  iterator   ExprNode
1844

1845
    type = py_object_type
1846

William Stein's avatar
William Stein committed
1847 1848 1849
    def __init__(self, iterator, env):
        self.pos = iterator.pos
        self.iterator = iterator
1850 1851
        if iterator.type.is_ptr or iterator.type.is_array:
            self.type = iterator.type.base_type
William Stein's avatar
William Stein committed
1852
        self.is_temp = 1
1853

William Stein's avatar
William Stein committed
1854
    def generate_result_code(self, code):
1855 1856
        sequence_type = self.iterator.sequence.type
        if sequence_type is list_type:
1857
            type_checks = [(list_type, "List")]
1858
        elif sequence_type is tuple_type:
1859
            type_checks = [(tuple_type, "Tuple")]
1860
        elif not sequence_type.is_builtin_type:
1861
            type_checks = [(list_type, "List"), (tuple_type, "Tuple")]
1862 1863
        else:
            type_checks = []
1864 1865 1866 1867 1868 1869

        for py_type, prefix in type_checks:
            if len(type_checks) > 1:
                code.putln(
                    "if (likely(Py%s_CheckExact(%s))) {" % (
                        prefix, self.iterator.py_result()))
1870 1871
            code.putln(
                "if (%s >= Py%s_GET_SIZE(%s)) break;" % (
1872
                    self.iterator.counter_cname,
1873
                    prefix,
1874 1875
                    self.iterator.py_result()))
            code.putln(
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1876
                "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % (
1877
                    self.result(),
1878
                    prefix,
1879
                    self.iterator.py_result(),
1880
                    self.iterator.counter_cname,
1881
                    self.result(),
1882
                    self.iterator.counter_cname))
1883 1884 1885 1886
            if len(type_checks) > 1:
                code.put("} else ")
        if len(type_checks) == 1:
            return
1887
        code.putln("{")
William Stein's avatar
William Stein committed
1888 1889
        code.putln(
            "%s = PyIter_Next(%s);" % (
1890
                self.result(),
William Stein's avatar
William Stein committed
1891 1892 1893
                self.iterator.py_result()))
        code.putln(
            "if (!%s) {" %
1894
                self.result())
1895
        code.putln(code.error_goto_if_PyErr(self.pos))
Robert Bradshaw's avatar
Robert Bradshaw committed
1896 1897
        code.putln("break;")
        code.putln("}")
1898
        code.put_gotref(self.py_result())
Robert Bradshaw's avatar
Robert Bradshaw committed
1899
        code.putln("}")
1900

William Stein's avatar
William Stein committed
1901

1902
class ExcValueNode(AtomicExprNode):
William Stein's avatar
William Stein committed
1903 1904 1905
    #  Node created during analyse_types phase
    #  of an ExceptClauseNode to fetch the current
    #  exception value.
1906

1907
    type = py_object_type
1908

1909
    def __init__(self, pos, env):
William Stein's avatar
William Stein committed
1910
        ExprNode.__init__(self, pos)
1911 1912

    def set_var(self, var):
1913
        self.var = var
1914

1915 1916 1917
    def calculate_result_code(self):
        return self.var

William Stein's avatar
William Stein committed
1918
    def generate_result_code(self, code):
1919
        pass
William Stein's avatar
William Stein committed
1920

1921 1922 1923
    def analyse_types(self, env):
        pass

William Stein's avatar
William Stein committed
1924

1925
class TempNode(ExprNode):
1926 1927 1928 1929 1930 1931 1932
    # Node created during analyse_types phase
    # of some nodes to hold a temporary value.
    #
    # Note: One must call "allocate" and "release" on
    # the node during code generation to get/release the temp.
    # This is because the temp result is often used outside of
    # the regular cycle.
1933 1934

    subexprs = []
1935

William Stein's avatar
William Stein committed
1936 1937 1938 1939 1940 1941
    def __init__(self, pos, type, env):
        ExprNode.__init__(self, pos)
        self.type = type
        if type.is_pyobject:
            self.result_ctype = py_object_type
        self.is_temp = 1
1942

1943 1944
    def analyse_types(self, env):
        return self.type
1945

William Stein's avatar
William Stein committed
1946 1947 1948
    def generate_result_code(self, code):
        pass

1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965
    def allocate(self, code):
        self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)

    def release(self, code):
        code.funcstate.release_temp(self.temp_cname)
        self.temp_cname = None

    def result(self):
        try:
            return self.temp_cname
        except:
            assert False, "Remember to call allocate/release on TempNode"
            raise

    # Do not participate in normal temp alloc/dealloc:
    def allocate_temp_result(self, code):
        pass
1966

1967 1968
    def release_temp_result(self, code):
        pass
William Stein's avatar
William Stein committed
1969 1970 1971

class PyTempNode(TempNode):
    #  TempNode holding a Python value.
1972

William Stein's avatar
William Stein committed
1973 1974 1975
    def __init__(self, pos, env):
        TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)

1976 1977
class RawCNameExprNode(ExprNode):
    subexprs = []
1978

1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994
    def __init__(self, pos, type=None):
        self.pos = pos
        self.type = type

    def analyse_types(self, env):
        return self.type

    def set_cname(self, cname):
        self.cname = cname

    def result(self):
        return self.cname

    def generate_result_code(self, code):
        pass

William Stein's avatar
William Stein committed
1995 1996 1997 1998 1999 2000 2001

#-------------------------------------------------------------------
#
#  Trailer nodes
#
#-------------------------------------------------------------------

2002
class IndexNode(ExprNode):
William Stein's avatar
William Stein committed
2003 2004 2005 2006
    #  Sequence indexing.
    #
    #  base     ExprNode
    #  index    ExprNode
2007 2008 2009 2010 2011 2012
    #  indices  [ExprNode]
    #  is_buffer_access boolean Whether this is a buffer access.
    #
    #  indices is used on buffer access, index on non-buffer access.
    #  The former contains a clean list of index parameters, the
    #  latter whatever Python object is needed for index access.
2013

2014 2015 2016 2017 2018 2019
    subexprs = ['base', 'index', 'indices']
    indices = None

    def __init__(self, pos, index, *args, **kw):
        ExprNode.__init__(self, pos, index=index, *args, **kw)
        self._index = index
2020 2021 2022 2023 2024

    def calculate_constant_result(self):
        self.constant_result = \
            self.base.constant_result[self.index.constant_result]

2025 2026 2027 2028 2029 2030 2031
    def compile_time_value(self, denv):
        base = self.base.compile_time_value(denv)
        index = self.index.compile_time_value(denv)
        try:
            return base[index]
        except Exception, e:
            self.compile_time_value_error(e)
2032

William Stein's avatar
William Stein committed
2033 2034
    def is_ephemeral(self):
        return self.base.is_ephemeral()
2035

2036
    def is_simple(self):
2037 2038
        if self.is_buffer_access:
            return False
2039 2040 2041 2042
        base = self.base
        return (base.is_simple() and self.index.is_simple()
                and base.type and (base.type.is_ptr or base.type.is_array))

William Stein's avatar
William Stein committed
2043 2044
    def analyse_target_declaration(self, env):
        pass
2045

2046 2047 2048
    def analyse_as_type(self, env):
        base_type = self.base.analyse_as_type(env)
        if base_type and not base_type.is_pyobject:
2049
            if base_type.is_cpp_class:
2050
                if isinstance(self.index, TupleNode):
2051 2052 2053 2054 2055
                    template_values = self.index.args
                else:
                    template_values = [self.index]
                import Nodes
                type_node = Nodes.TemplatedTypeNode(
2056 2057
                    pos = self.pos,
                    positional_args = template_values,
2058 2059 2060 2061
                    keyword_args = None)
                return type_node.analyse(env, base_type = base_type)
            else:
                return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
2062
        return None
2063

Robert Bradshaw's avatar
Robert Bradshaw committed
2064
    def type_dependencies(self, env):
2065
        return self.base.type_dependencies(env) + self.index.type_dependencies(env)
2066

2067
    def infer_type(self, env):
2068 2069 2070 2071
        base_type = self.base.infer_type(env)
        if isinstance(self.index, SliceNode):
            # slicing!
            if base_type.is_string:
2072
                # sliced C strings must coerce to Python
2073
                return bytes_type
2074 2075 2076
            elif base_type in (unicode_type, bytes_type, str_type, list_type, tuple_type):
                # slicing these returns the same type
                return base_type
2077
            else:
2078 2079 2080
                # TODO: Handle buffers (hopefully without too much redundancy).
                return py_object_type

2081 2082
        index_type = self.index.infer_type(env)
        if index_type and index_type.is_int or isinstance(self.index, (IntNode, LongNode)):
2083 2084
            # indexing!
            if base_type is unicode_type:
2085 2086 2087
                # Py_UCS4 will automatically coerce to a unicode string
                # if required, so this is safe.  We only infer Py_UCS4
                # when the index is a C integer type.  Otherwise, we may
2088 2089 2090 2091
                # need to use normal Python item access, in which case
                # it's faster to return the one-char unicode string than
                # to receive it, throw it away, and potentially rebuild it
                # on a subsequent PyObject coercion.
2092
                return PyrexTypes.c_py_ucs4_type
2093 2094 2095
            elif base_type is str_type:
                # always returns str - Py2: bytes, Py3: unicode
                return base_type
2096 2097 2098 2099 2100 2101
            elif isinstance(self.base, BytesNode):
                #if env.global_scope().context.language_level >= 3:
                #    # infering 'char' can be made to work in Python 3 mode
                #    return PyrexTypes.c_char_type
                # Py2/3 return different types on indexing bytes objects
                return py_object_type
2102 2103
            elif base_type.is_ptr or base_type.is_array:
                return base_type.base_type
2104

2105
        # may be slicing or indexing, we don't know
2106 2107
        if base_type in (unicode_type, str_type):
            # these types always returns their own type on Python indexing/slicing
2108
            return base_type
2109 2110 2111
        else:
            # TODO: Handle buffers (hopefully without too much redundancy).
            return py_object_type
2112

William Stein's avatar
William Stein committed
2113
    def analyse_types(self, env):
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2114
        self.analyse_base_and_index_types(env, getting = 1)
2115

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2116 2117
    def analyse_target_types(self, env):
        self.analyse_base_and_index_types(env, setting = 1)
2118

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2119
    def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
2120 2121 2122
        # Note: This might be cleaned up by having IndexNode
        # parsed in a saner way and only construct the tuple if
        # needed.
2123 2124 2125 2126

        # Note that this function must leave IndexNode in a cloneable state.
        # For buffers, self.index is packed out on the initial analysis, and
        # when cloning self.indices is copied.
2127 2128
        self.is_buffer_access = False

William Stein's avatar
William Stein committed
2129
        self.base.analyse_types(env)
2130 2131 2132 2133 2134
        if self.base.type.is_error:
            # Do not visit child tree if base is undeclared to avoid confusing
            # error messages
            self.type = PyrexTypes.error_type
            return
2135

2136
        is_slice = isinstance(self.index, SliceNode)
2137
        # Potentially overflowing index value.
2138
        if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
2139
            self.index = self.index.coerce_to_pyobject(env)
2140

2141
        # Handle the case where base is a literal char* (and we expect a string, not an int)
2142
        if isinstance(self.base, BytesNode) or is_slice:
Robert Bradshaw's avatar
Robert Bradshaw committed
2143
            if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
2144
                self.base = self.base.coerce_to_pyobject(env)
2145 2146 2147

        skip_child_analysis = False
        buffer_access = False
2148
        if self.base.type.is_buffer:
2149 2150
            if self.indices:
                indices = self.indices
2151
            else:
2152 2153 2154 2155
                if isinstance(self.index, TupleNode):
                    indices = self.index.args
                else:
                    indices = [self.index]
2156
            if len(indices) == self.base.type.ndim:
2157 2158 2159 2160 2161 2162
                buffer_access = True
                skip_child_analysis = True
                for x in indices:
                    x.analyse_types(env)
                    if not x.type.is_int:
                        buffer_access = False
Robert Bradshaw's avatar
Robert Bradshaw committed
2163 2164
            if buffer_access:
                assert hasattr(self.base, "entry") # Must be a NameNode-like node
2165

Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2166 2167 2168
        # On cloning, indices is cloned. Otherwise, unpack index into indices
        assert not (buffer_access and isinstance(self.index, CloneNode))

2169 2170
        if buffer_access:
            self.indices = indices
2171
            self.index = None
2172 2173
            self.type = self.base.type.dtype
            self.is_buffer_access = True
2174
            self.buffer_type = self.base.entry.type
2175 2176

            if getting and self.type.is_pyobject:
2177
                self.is_temp = True
2178 2179 2180 2181 2182
            if setting:
                if not self.base.entry.type.writable:
                    error(self.pos, "Writing to readonly buffer")
                else:
                    self.base.entry.buffer_aux.writable_needed = True
2183
        else:
2184
            base_type = self.base.type
2185 2186 2187 2188
            if isinstance(self.index, TupleNode):
                self.index.analyse_types(env, skip_children=skip_child_analysis)
            elif not skip_child_analysis:
                self.index.analyse_types(env)
2189
            self.original_index_type = self.index.type
Stefan Behnel's avatar
Stefan Behnel committed
2190 2191
            if base_type.is_unicode_char:
                # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
2192 2193 2194 2195 2196 2197 2198
                # cases, but indexing must still work for them
                if self.index.constant_result in (0, -1):
                    # FIXME: we know that this node is redundant -
                    # currently, this needs to get handled in Optimize.py
                    pass
                self.base = self.base.coerce_to_pyobject(env)
                base_type = self.base.type
2199
            if base_type.is_pyobject:
2200
                if self.index.type.is_int:
2201
                    if (not setting
2202
                        and (base_type in (list_type, tuple_type, unicode_type))
2203 2204 2205 2206 2207
                        and (not self.index.type.signed or isinstance(self.index, IntNode) and int(self.index.value) >= 0)
                        and not env.directives['boundscheck']):
                        self.is_temp = 0
                    else:
                        self.is_temp = 1
2208 2209 2210
                    self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
                else:
                    self.index = self.index.coerce_to_pyobject(env)
2211
                    self.is_temp = 1
2212
                if self.index.type.is_int and base_type is unicode_type:
Stefan Behnel's avatar
Stefan Behnel committed
2213
                    # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
2214
                    # if required, so this is fast and safe
2215
                    self.type = PyrexTypes.c_py_ucs4_type
2216 2217
                elif is_slice and base_type in (bytes_type, str_type, unicode_type, list_type, tuple_type):
                    self.type = base_type
2218 2219
                else:
                    self.type = py_object_type
William Stein's avatar
William Stein committed
2220
            else:
2221 2222
                if base_type.is_ptr or base_type.is_array:
                    self.type = base_type.base_type
2223 2224 2225
                    if is_slice:
                        self.type = base_type
                    elif self.index.type.is_pyobject:
Robert Bradshaw's avatar
Robert Bradshaw committed
2226 2227
                        self.index = self.index.coerce_to(
                            PyrexTypes.c_py_ssize_t_type, env)
2228
                    elif not self.index.type.is_int:
Robert Bradshaw's avatar
Robert Bradshaw committed
2229 2230 2231
                        error(self.pos,
                            "Invalid index type '%s'" %
                                self.index.type)
2232
                elif base_type.is_cpp_class:
2233
                    function = env.lookup_operator("[]", [self.base, self.index])
Robert Bradshaw's avatar
Robert Bradshaw committed
2234
                    if function is None:
2235
                        error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
Robert Bradshaw's avatar
Robert Bradshaw committed
2236 2237 2238 2239 2240 2241 2242 2243 2244
                        self.type = PyrexTypes.error_type
                        self.result_code = "<error>"
                        return
                    func_type = function.type
                    if func_type.is_ptr:
                        func_type = func_type.base_type
                    self.index = self.index.coerce_to(func_type.args[0].type, env)
                    self.type = func_type.return_type
                    if setting and not func_type.return_type.is_reference:
Robert Bradshaw's avatar
Robert Bradshaw committed
2245
                        error(self.pos, "Can't set non-reference result '%s'" % self.type)
2246 2247 2248
                else:
                    error(self.pos,
                        "Attempting to index non-array type '%s'" %
2249
                            base_type)
2250
                    self.type = PyrexTypes.error_type
Stefan Behnel's avatar
Stefan Behnel committed
2251

2252 2253
    gil_message = "Indexing Python object"

2254 2255
    def nogil_check(self, env):
        if self.is_buffer_access:
2256 2257 2258 2259 2260 2261
            if env.directives['boundscheck']:
                error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
                return
            elif self.type.is_pyobject:
                error(self.pos, "Cannot access buffer with object dtype without gil")
                return
2262
        super(IndexNode, self).nogil_check(env)
2263 2264


William Stein's avatar
William Stein committed
2265
    def check_const_addr(self):
2266
        return self.base.check_const_addr() and self.index.check_const()
2267

William Stein's avatar
William Stein committed
2268 2269
    def is_lvalue(self):
        return 1
Dag Sverre Seljebotn's avatar
merge  
Dag Sverre Seljebotn committed
2270

William Stein's avatar
William Stein committed
2271
    def calculate_result_code(self):
2272
        if self.is_buffer_access:
2273
            return "(*%s)" % self.buffer_ptr_code
2274 2275 2276 2277
        elif self.base.type is list_type:
            return "PyList_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
        elif self.base.type is tuple_type:
            return "PyTuple_GET_ITEM(%s, %s)" % (self.base.result(), self.index.result())
Stefan Behnel's avatar
Stefan Behnel committed
2278
        elif self.base.type is unicode_type and self.type.is_unicode_char:
2279
            return "PyUnicode_AS_UNICODE(%s)[%s]" % (self.base.result(), self.index.result())
2280 2281
        elif (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
            error(self.pos, "Invalid use of pointer slice")
2282 2283
        else:
            return "(%s[%s])" % (
2284
                self.base.result(), self.index.result())
2285

2286
    def extra_index_params(self):
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2287 2288
        if self.index.type.is_int:
            if self.original_index_type.signed:
2289
                size_adjustment = ""
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2290
            else:
2291 2292
                size_adjustment = "+1"
            return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2293 2294
        else:
            return ""
2295 2296 2297

    def generate_subexpr_evaluation_code(self, code):
        self.base.generate_evaluation_code(code)
2298
        if not self.indices:
2299 2300
            self.index.generate_evaluation_code(code)
        else:
2301 2302
            for i in self.indices:
                i.generate_evaluation_code(code)
2303

2304 2305
    def generate_subexpr_disposal_code(self, code):
        self.base.generate_disposal_code(code)
2306
        if not self.indices:
2307 2308
            self.index.generate_disposal_code(code)
        else:
2309 2310
            for i in self.indices:
                i.generate_disposal_code(code)
2311

2312 2313 2314 2315 2316 2317 2318 2319
    def free_subexpr_temps(self, code):
        self.base.free_temps(code)
        if not self.indices:
            self.index.free_temps(code)
        else:
            for i in self.indices:
                i.free_temps(code)

William Stein's avatar
William Stein committed
2320
    def generate_result_code(self, code):
2321
        if self.is_buffer_access:
2322 2323
            if code.globalstate.directives['nonecheck']:
                self.put_nonecheck(code)
2324 2325 2326 2327
            self.buffer_ptr_code = self.buffer_lookup_code(code)
            if self.type.is_pyobject:
                # is_temp is True, so must pull out value and incref it.
                code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code))
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2328
                code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339
        elif self.is_temp:
            if self.type.is_pyobject:
                if self.index.type.is_int:
                    index_code = self.index.result()
                    if self.base.type is list_type:
                        function = "__Pyx_GetItemInt_List"
                    elif self.base.type is tuple_type:
                        function = "__Pyx_GetItemInt_Tuple"
                    else:
                        function = "__Pyx_GetItemInt"
                    code.globalstate.use_utility_code(getitem_int_utility_code)
2340
                else:
2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356
                    index_code = self.index.py_result()
                    if self.base.type is dict_type:
                        function = "__Pyx_PyDict_GetItem"
                        code.globalstate.use_utility_code(getitem_dict_utility_code)
                    else:
                        function = "PyObject_GetItem"
                code.putln(
                    "%s = %s(%s, %s%s); if (!%s) %s" % (
                        self.result(),
                        function,
                        self.base.py_result(),
                        index_code,
                        self.extra_index_params(),
                        self.result(),
                        code.error_goto(self.pos)))
                code.put_gotref(self.py_result())
Stefan Behnel's avatar
Stefan Behnel committed
2357
            elif self.type.is_unicode_char and self.base.type is unicode_type:
2358 2359 2360
                assert self.index.type.is_int
                index_code = self.index.result()
                function = "__Pyx_GetItemInt_Unicode"
2361 2362 2363 2364 2365 2366 2367 2368 2369 2370
                code.globalstate.use_utility_code(getitem_int_pyunicode_utility_code)
                code.putln(
                    "%s = %s(%s, %s%s); if (unlikely(%s == (Py_UNICODE)-1)) %s;" % (
                        self.result(),
                        function,
                        self.base.py_result(),
                        index_code,
                        self.extra_index_params(),
                        self.result(),
                        code.error_goto(self.pos)))
2371

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2372 2373 2374
    def generate_setitem_code(self, value_code, code):
        if self.index.type.is_int:
            function = "__Pyx_SetItemInt"
2375
            index_code = self.index.result()
2376
            code.globalstate.use_utility_code(setitem_int_utility_code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2377 2378
        else:
            index_code = self.index.py_result()
2379 2380
            if self.base.type is dict_type:
                function = "PyDict_SetItem"
Craig Citro's avatar
Craig Citro committed
2381
            # It would seem that we could specialized lists/tuples, but that
2382 2383 2384 2385 2386 2387
            # shouldn't happen here.
            # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input,
            # not a PyObject*, and bad conversion here would give the wrong
            # exception. Also, tuples are supposed to be immutable, and raise
            # TypeErrors when trying to set their entries (PyTuple_SetItem
            # is for creating new tuples from).
2388 2389
            else:
                function = "PyObject_SetItem"
2390
        code.putln(
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2391 2392
            "if (%s(%s, %s, %s%s) < 0) %s" % (
                function,
2393
                self.base.py_result(),
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2394 2395
                index_code,
                value_code,
2396
                self.extra_index_params(),
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2397
                code.error_goto(self.pos)))
2398 2399 2400

    def generate_buffer_setitem_code(self, rhs, code, op=""):
        # Used from generate_assignment_code and InPlaceAssignmentNode
2401 2402
        if code.globalstate.directives['nonecheck']:
            self.put_nonecheck(code)
2403 2404 2405 2406
        ptrexpr = self.buffer_lookup_code(code)
        if self.buffer_type.dtype.is_pyobject:
            # Must manage refcounts. Decref what is already there
            # and incref what we put in.
2407
            ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
2408
            rhs_code = rhs.result()
2409
            code.putln("%s = %s;" % (ptr, ptrexpr))
2410
            code.put_gotref("*%s" % ptr)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2411
            code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % (
2412 2413 2414
                ptr, rhs_code
                ))
            code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
2415
            code.put_giveref("*%s" % ptr)
2416
            code.funcstate.release_temp(ptr)
2417
        else:
2418
            # Simple case
2419
            code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
2420

William Stein's avatar
William Stein committed
2421 2422
    def generate_assignment_code(self, rhs, code):
        self.generate_subexpr_evaluation_code(code)
2423
        if self.is_buffer_access:
2424
            self.generate_buffer_setitem_code(rhs, code)
2425
        elif self.type.is_pyobject:
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2426
            self.generate_setitem_code(rhs.py_result(), code)
William Stein's avatar
William Stein committed
2427 2428 2429
        else:
            code.putln(
                "%s = %s;" % (
2430
                    self.result(), rhs.result()))
2431
        self.generate_subexpr_disposal_code(code)
2432
        self.free_subexpr_temps(code)
William Stein's avatar
William Stein committed
2433
        rhs.generate_disposal_code(code)
2434
        rhs.free_temps(code)
2435

William Stein's avatar
William Stein committed
2436 2437
    def generate_deletion_code(self, code):
        self.generate_subexpr_evaluation_code(code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2438 2439
        #if self.type.is_pyobject:
        if self.index.type.is_int:
2440
            function = "__Pyx_DelItemInt"
2441
            index_code = self.index.result()
2442
            code.globalstate.use_utility_code(delitem_int_utility_code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2443 2444
        else:
            index_code = self.index.py_result()
2445 2446 2447 2448
            if self.base.type is dict_type:
                function = "PyDict_DelItem"
            else:
                function = "PyObject_DelItem"
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2449
        code.putln(
2450
            "if (%s(%s, %s%s) < 0) %s" % (
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2451
                function,
William Stein's avatar
William Stein committed
2452
                self.base.py_result(),
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2453
                index_code,
2454
                self.extra_index_params(),
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2455
                code.error_goto(self.pos)))
William Stein's avatar
William Stein committed
2456
        self.generate_subexpr_disposal_code(code)
2457
        self.free_subexpr_temps(code)
2458

2459
    def buffer_lookup_code(self, code):
2460
        # Assign indices to temps
2461
        index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices]
2462
        for temp, index in zip(index_temps, self.indices):
2463
            code.putln("%s = %s;" % (temp, index.result()))
2464 2465
        # Generate buffer access code using these temps
        import Buffer
2466 2467
        # The above could happen because child_attrs is wrong somewhere so that
        # options are not propagated.
2468 2469 2470
        return Buffer.put_buffer_lookup_code(entry=self.base.entry,
                                             index_signeds=[i.type.signed for i in self.indices],
                                             index_cnames=index_temps,
2471
                                             directives=code.globalstate.directives,
2472
                                             pos=self.pos, code=code)
William Stein's avatar
William Stein committed
2473

2474 2475 2476 2477 2478 2479 2480
    def put_nonecheck(self, code):
        code.globalstate.use_utility_code(raise_noneindex_error_utility_code)
        code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type))
        code.putln("__Pyx_RaiseNoneIndexingError();")
        code.putln(code.error_goto(self.pos))
        code.putln("}")

2481
class SliceIndexNode(ExprNode):
William Stein's avatar
William Stein committed
2482 2483 2484 2485 2486
    #  2-element slice indexing
    #
    #  base      ExprNode
    #  start     ExprNode or None
    #  stop      ExprNode or None
2487

William Stein's avatar
William Stein committed
2488
    subexprs = ['base', 'start', 'stop']
2489

2490 2491 2492 2493 2494 2495 2496
    def infer_type(self, env):
        base_type = self.base.infer_type(env)
        if base_type.is_string:
            return bytes_type
        elif base_type in (bytes_type, str_type, unicode_type,
                           list_type, tuple_type):
            return base_type
2497 2498
        elif base_type.is_ptr or base_type.is_array:
            return PyrexTypes.c_array_type(base_type.base_type, None)
2499 2500
        return py_object_type

2501 2502 2503 2504
    def calculate_constant_result(self):
        self.constant_result = self.base.constant_result[
            self.start.constant_result : self.stop.constant_result]

2505 2506
    def compile_time_value(self, denv):
        base = self.base.compile_time_value(denv)
2507 2508 2509 2510 2511 2512 2513 2514
        if self.start is None:
            start = 0
        else:
            start = self.start.compile_time_value(denv)
        if self.stop is None:
            stop = None
        else:
            stop = self.stop.compile_time_value(denv)
2515 2516 2517 2518
        try:
            return base[start:stop]
        except Exception, e:
            self.compile_time_value_error(e)
2519

William Stein's avatar
William Stein committed
2520 2521
    def analyse_target_declaration(self, env):
        pass
2522

2523 2524 2525
    def analyse_target_types(self, env):
        self.analyse_types(env)
        # when assigning, we must accept any Python type
2526 2527
        if self.type.is_pyobject:
            self.type = py_object_type
William Stein's avatar
William Stein committed
2528 2529 2530 2531 2532 2533 2534

    def analyse_types(self, env):
        self.base.analyse_types(env)
        if self.start:
            self.start.analyse_types(env)
        if self.stop:
            self.stop.analyse_types(env)
2535 2536 2537
        base_type = self.base.type
        if base_type.is_string:
            self.type = bytes_type
2538 2539 2540
        elif base_type.is_ptr:
            self.type = base_type
        elif base_type.is_array:
2541 2542 2543
            # we need a ptr type here instead of an array type, as
            # array types can result in invalid type casts in the C
            # code
2544
            self.type = PyrexTypes.CPtrType(base_type.base_type)
2545 2546 2547
        else:
            self.base = self.base.coerce_to_pyobject(env)
            self.type = py_object_type
2548 2549 2550
        if base_type.is_builtin_type:
            # slicing builtin types returns something of the same type
            self.type = base_type
2551
        c_int = PyrexTypes.c_py_ssize_t_type
William Stein's avatar
William Stein committed
2552 2553 2554 2555 2556
        if self.start:
            self.start = self.start.coerce_to(c_int, env)
        if self.stop:
            self.stop = self.stop.coerce_to(c_int, env)
        self.is_temp = 1
2557

2558
    nogil_check = Node.gil_error
2559 2560
    gil_message = "Slicing Python object"

William Stein's avatar
William Stein committed
2561
    def generate_result_code(self, code):
2562 2563 2564 2565
        if not self.type.is_pyobject:
            error(self.pos,
                  "Slicing is not currently supported for '%s'." % self.type)
            return
Robert Bradshaw's avatar
Robert Bradshaw committed
2566 2567 2568
        if self.base.type.is_string:
            if self.stop is None:
                code.putln(
2569
                    "%s = PyBytes_FromString(%s + %s); %s" % (
Robert Bradshaw's avatar
Robert Bradshaw committed
2570 2571 2572 2573 2574 2575
                        self.result(),
                        self.base.result(),
                        self.start_code(),
                        code.error_goto_if_null(self.result(), self.pos)))
            else:
                code.putln(
2576
                    "%s = PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
Robert Bradshaw's avatar
Robert Bradshaw committed
2577 2578 2579 2580 2581 2582 2583 2584
                        self.result(),
                        self.base.result(),
                        self.start_code(),
                        self.stop_code(),
                        self.start_code(),
                        code.error_goto_if_null(self.result(), self.pos)))
        else:
            code.putln(
2585
                "%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % (
Robert Bradshaw's avatar
Robert Bradshaw committed
2586 2587 2588 2589 2590
                    self.result(),
                    self.base.py_result(),
                    self.start_code(),
                    self.stop_code(),
                    code.error_goto_if_null(self.result(), self.pos)))
2591
        code.put_gotref(self.py_result())
2592

William Stein's avatar
William Stein committed
2593 2594
    def generate_assignment_code(self, rhs, code):
        self.generate_subexpr_evaluation_code(code)
2595
        if self.type.is_pyobject:
2596
            code.put_error_if_neg(self.pos,
2597
                "__Pyx_PySequence_SetSlice(%s, %s, %s, %s)" % (
2598 2599 2600
                    self.base.py_result(),
                    self.start_code(),
                    self.stop_code(),
Lisandro Dalcin's avatar
Lisandro Dalcin committed
2601
                    rhs.py_result()))
2602 2603 2604 2605 2606 2607 2608 2609
        else:
            start_offset = ''
            if self.start:
                start_offset = self.start_code()
                if start_offset == '0':
                    start_offset = ''
                else:
                    start_offset += '+'
Stefan Behnel's avatar
Stefan Behnel committed
2610 2611
            if rhs.type.is_array:
                array_length = rhs.type.size
2612
                self.generate_slice_guard_code(code, array_length)
Stefan Behnel's avatar
Stefan Behnel committed
2613
            else:
Stefan Behnel's avatar
Stefan Behnel committed
2614 2615
                error(self.pos,
                      "Slice assignments from pointers are not yet supported.")
Stefan Behnel's avatar
Stefan Behnel committed
2616 2617
                # FIXME: fix the array size according to start/stop
                array_length = self.base.type.size
2618 2619 2620 2621
            for i in range(array_length):
                code.putln("%s[%s%s] = %s[%d];" % (
                        self.base.result(), start_offset, i,
                        rhs.result(), i))
William Stein's avatar
William Stein committed
2622
        self.generate_subexpr_disposal_code(code)
2623
        self.free_subexpr_temps(code)
William Stein's avatar
William Stein committed
2624
        rhs.generate_disposal_code(code)
2625
        rhs.free_temps(code)
William Stein's avatar
William Stein committed
2626 2627

    def generate_deletion_code(self, code):
Robert Bradshaw's avatar
Robert Bradshaw committed
2628
        if not self.base.type.is_pyobject:
2629 2630 2631
            error(self.pos,
                  "Deleting slices is only supported for Python types, not '%s'." % self.type)
            return
William Stein's avatar
William Stein committed
2632
        self.generate_subexpr_evaluation_code(code)
Robert Bradshaw's avatar
Robert Bradshaw committed
2633
        code.put_error_if_neg(self.pos,
2634
            "__Pyx_PySequence_DelSlice(%s, %s, %s)" % (
William Stein's avatar
William Stein committed
2635 2636
                self.base.py_result(),
                self.start_code(),
Robert Bradshaw's avatar
Robert Bradshaw committed
2637
                self.stop_code()))
William Stein's avatar
William Stein committed
2638
        self.generate_subexpr_disposal_code(code)
2639
        self.free_subexpr_temps(code)
2640 2641 2642 2643 2644 2645 2646 2647 2648 2649

    def generate_slice_guard_code(self, code, target_size):
        if not self.base.type.is_array:
            return
        slice_size = self.base.type.size
        start = stop = None
        if self.stop:
            stop = self.stop.result()
            try:
                stop = int(stop)
Stefan Behnel's avatar
Stefan Behnel committed
2650
                if stop < 0:
2651
                    slice_size = self.base.type.size + stop
Stefan Behnel's avatar
Stefan Behnel committed
2652 2653
                else:
                    slice_size = stop
2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683
                stop = None
            except ValueError:
                pass
        if self.start:
            start = self.start.result()
            try:
                start = int(start)
                if start < 0:
                    start = self.base.type.size + start
                slice_size -= start
                start = None
            except ValueError:
                pass
        check = None
        if slice_size < 0:
            if target_size > 0:
                error(self.pos, "Assignment to empty slice.")
        elif start is None and stop is None:
            # we know the exact slice length
            if target_size != slice_size:
                error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % (
                        slice_size, target_size))
        elif start is not None:
            if stop is None:
                stop = slice_size
            check = "(%s)-(%s)" % (stop, start)
        else: # stop is not None:
            check = stop
        if check:
            code.putln("if (unlikely((%s) != %d)) {" % (check, target_size))
2684
            code.putln('PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length, expected %%"PY_FORMAT_SIZE_T"d, got %%"PY_FORMAT_SIZE_T"d", (Py_ssize_t)%d, (Py_ssize_t)(%s));' % (
2685 2686 2687
                        target_size, check))
            code.putln(code.error_goto(self.pos))
            code.putln("}")
2688

William Stein's avatar
William Stein committed
2689 2690
    def start_code(self):
        if self.start:
2691
            return self.start.result()
William Stein's avatar
William Stein committed
2692 2693
        else:
            return "0"
2694

William Stein's avatar
William Stein committed
2695 2696
    def stop_code(self):
        if self.stop:
2697
            return self.stop.result()
2698 2699
        elif self.base.type.is_array:
            return self.base.type.size
William Stein's avatar
William Stein committed
2700
        else:
2701
            return "PY_SSIZE_T_MAX"
2702

William Stein's avatar
William Stein committed
2703
    def calculate_result_code(self):
2704
        # self.result() is not used, but this method must exist
William Stein's avatar
William Stein committed
2705
        return "<unused>"
2706

William Stein's avatar
William Stein committed
2707

2708
class SliceNode(ExprNode):
William Stein's avatar
William Stein committed
2709 2710 2711 2712 2713
    #  start:stop:step in subscript list
    #
    #  start     ExprNode
    #  stop      ExprNode
    #  step      ExprNode
2714

2715 2716
    subexprs = ['start', 'stop', 'step']

2717 2718
    type = py_object_type
    is_temp = 1
2719 2720

    def calculate_constant_result(self):
2721 2722 2723 2724
        self.constant_result = slice(
            self.start.constant_result,
            self.stop.constant_result,
            self.step.constant_result)
2725

2726 2727
    def compile_time_value(self, denv):
        start = self.start.compile_time_value(denv)
Stefan Behnel's avatar
Stefan Behnel committed
2728 2729
        stop = self.stop.compile_time_value(denv)
        step = self.step.compile_time_value(denv)
2730 2731 2732 2733
        try:
            return slice(start, stop, step)
        except Exception, e:
            self.compile_time_value_error(e)
2734

William Stein's avatar
William Stein committed
2735 2736 2737 2738 2739 2740 2741
    def analyse_types(self, env):
        self.start.analyse_types(env)
        self.stop.analyse_types(env)
        self.step.analyse_types(env)
        self.start = self.start.coerce_to_pyobject(env)
        self.stop = self.stop.coerce_to_pyobject(env)
        self.step = self.step.coerce_to_pyobject(env)
2742 2743 2744
        if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
            self.is_literal = True
            self.is_temp = False
2745 2746 2747

    gil_message = "Constructing Python slice object"

2748 2749 2750
    def calculate_result_code(self):
        return self.result_code

William Stein's avatar
William Stein committed
2751
    def generate_result_code(self, code):
2752 2753 2754 2755 2756
        if self.is_literal:
            self.result_code = code.get_py_const(py_object_type, 'slice_', cleanup_level=2)
            code = code.get_cached_constants_writer()
            code.mark_pos(self.pos)

William Stein's avatar
William Stein committed
2757
        code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
2758
            "%s = PySlice_New(%s, %s, %s); %s" % (
2759
                self.result(),
2760 2761
                self.start.py_result(),
                self.stop.py_result(),
William Stein's avatar
William Stein committed
2762
                self.step.py_result(),
2763
                code.error_goto_if_null(self.result(), self.pos)))
2764
        code.put_gotref(self.py_result())
2765 2766
        if self.is_literal:
            code.put_giveref(self.py_result())
William Stein's avatar
William Stein committed
2767

2768

2769
class CallNode(ExprNode):
2770

Stefan Behnel's avatar
Stefan Behnel committed
2771 2772 2773 2774 2775 2776 2777 2778
    # allow overriding the default 'may_be_none' behaviour
    may_return_none = None

    def may_be_none(self):
        if self.may_return_none is not None:
            return self.may_return_none
        return ExprNode.may_be_none(self)

Robert Bradshaw's avatar
Robert Bradshaw committed
2779 2780 2781 2782 2783 2784
    def analyse_as_type_constructor(self, env):
        type = self.function.analyse_as_type(env)
        if type and type.is_struct_or_union:
            args, kwds = self.explicit_args_kwds()
            items = []
            for arg, member in zip(args, type.scope.var_entries):
2785
                items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
Robert Bradshaw's avatar
Robert Bradshaw committed
2786 2787 2788 2789 2790 2791 2792
            if kwds:
                items += kwds.key_value_pairs
            self.key_value_pairs = items
            self.__class__ = DictNode
            self.analyse_types(env)
            self.coerce_to(type, env)
            return True
2793 2794 2795 2796 2797 2798 2799 2800 2801
        elif type and type.is_cpp_class:
            for arg in self.args:
                arg.analyse_types(env)
            constructor = type.scope.lookup("<init>")
            self.function = RawCNameExprNode(self.function.pos, constructor.type)
            self.function.entry = constructor
            self.function.set_cname(type.declaration_code(""))
            self.analyse_c_function_call(env)
            return True
2802

2803 2804
    def is_lvalue(self):
        return self.type.is_reference
2805

2806
    def nogil_check(self, env):
2807 2808
        func_type = self.function_type()
        if func_type.is_pyobject:
2809
            self.gil_error()
2810
        elif not getattr(func_type, 'nogil', False):
2811
            self.gil_error()
2812 2813 2814

    gil_message = "Calling gil-requiring function"

2815 2816

class SimpleCallNode(CallNode):
William Stein's avatar
William Stein committed
2817 2818 2819 2820 2821 2822 2823
    #  Function call without keyword, * or ** args.
    #
    #  function       ExprNode
    #  args           [ExprNode]
    #  arg_tuple      ExprNode or None     used internally
    #  self           ExprNode or None     used internally
    #  coerced_self   ExprNode or None     used internally
2824
    #  wrapper_call   bool                 used internally
2825
    #  has_optional_args   bool            used internally
2826
    #  nogil          bool                 used internally
2827

William Stein's avatar
William Stein committed
2828
    subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
2829

William Stein's avatar
William Stein committed
2830 2831 2832
    self = None
    coerced_self = None
    arg_tuple = None
2833
    wrapper_call = False
2834
    has_optional_args = False
2835
    nogil = False
2836
    analysed = False
2837

2838 2839 2840 2841 2842 2843 2844
    def compile_time_value(self, denv):
        function = self.function.compile_time_value(denv)
        args = [arg.compile_time_value(denv) for arg in self.args]
        try:
            return function(*args)
        except Exception, e:
            self.compile_time_value_error(e)
2845

Robert Bradshaw's avatar
Robert Bradshaw committed
2846
    def type_dependencies(self, env):
2847 2848
        # TODO: Update when Danilo's C++ code merged in to handle the
        # the case of function overloading.
Robert Bradshaw's avatar
Robert Bradshaw committed
2849
        return self.function.type_dependencies(env)
2850

2851
    def infer_type(self, env):
2852 2853
        function = self.function
        func_type = function.infer_type(env)
Robert Bradshaw's avatar
Robert Bradshaw committed
2854 2855
        if isinstance(self.function, NewExprNode):
            return PyrexTypes.CPtrType(self.function.class_type)
2856 2857 2858 2859
        if func_type.is_ptr:
            func_type = func_type.base_type
        if func_type.is_cfunction:
            return func_type.return_type
2860 2861 2862 2863 2864 2865
        elif func_type is type_type:
            if function.is_name and function.entry and function.entry.type:
                result_type = function.entry.type
                if result_type.is_extension_type:
                    return result_type
                elif result_type.is_builtin_type:
2866 2867 2868
                    if function.entry.name == 'float':
                        return PyrexTypes.c_double_type
                    elif function.entry.name in Builtin.types_that_construct_their_instance:
2869 2870 2871
                        return result_type
        return py_object_type

2872
    def analyse_as_type(self, env):
2873
        attr = self.function.as_cython_attribute()
2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885
        if attr == 'pointer':
            if len(self.args) != 1:
                error(self.args.pos, "only one type allowed.")
            else:
                type = self.args[0].analyse_as_type(env)
                if not type:
                    error(self.args[0].pos, "Unknown type")
                else:
                    return PyrexTypes.CPtrType(type)

    def explicit_args_kwds(self):
        return self.args, None
2886

William Stein's avatar
William Stein committed
2887
    def analyse_types(self, env):
Robert Bradshaw's avatar
Robert Bradshaw committed
2888 2889
        if self.analyse_as_type_constructor(env):
            return
2890 2891 2892
        if self.analysed:
            return
        self.analysed = True
William Stein's avatar
William Stein committed
2893 2894 2895 2896 2897 2898 2899 2900 2901 2902
        function = self.function
        function.is_called = 1
        self.function.analyse_types(env)
        if function.is_attribute and function.entry and function.entry.is_cmethod:
            # Take ownership of the object from which the attribute
            # was obtained, because we need to pass it as 'self'.
            self.self = function.obj
            function.obj = CloneNode(self.self)
        func_type = self.function_type()
        if func_type.is_pyobject:
2903 2904
            self.arg_tuple = TupleNode(self.pos, args = self.args)
            self.arg_tuple.analyse_types(env)
William Stein's avatar
William Stein committed
2905
            self.args = None
2906 2907 2908
            if func_type is Builtin.type_type and function.is_name and \
                   function.entry and \
                   function.entry.is_builtin and \
2909 2910 2911 2912 2913 2914 2915 2916 2917
                   function.entry.name in Builtin.types_that_construct_their_instance:
                # calling a builtin type that returns a specific object type
                if function.entry.name == 'float':
                    # the following will come true later on in a transform
                    self.type = PyrexTypes.c_double_type
                    self.result_ctype = PyrexTypes.c_double_type
                else:
                    self.type = Builtin.builtin_types[function.entry.name]
                    self.result_ctype = py_object_type
Stefan Behnel's avatar
Stefan Behnel committed
2918
                self.may_return_none = False
2919
            elif function.is_name and function.type_entry:
2920 2921 2922 2923 2924
                # We are calling an extension type constructor.  As
                # long as we do not support __new__(), the result type
                # is clear
                self.type = function.type_entry.type
                self.result_ctype = py_object_type
Stefan Behnel's avatar
Stefan Behnel committed
2925
                self.may_return_none = False
2926 2927
            else:
                self.type = py_object_type
William Stein's avatar
William Stein committed
2928 2929 2930 2931 2932 2933
            self.is_temp = 1
        else:
            for arg in self.args:
                arg.analyse_types(env)
            if self.self and func_type.args:
                # Coerce 'self' to the type expected by the method.
2934 2935 2936
                self_arg = func_type.args[0]
                if self_arg.not_none: # C methods must do the None test for self at *call* time
                    self.self = self.self.as_none_safe_node(
2937 2938
                        "'NoneType' object has no attribute '%s'" % self.function.entry.name,
                        'PyExc_AttributeError')
2939
                expected_type = self_arg.type
William Stein's avatar
William Stein committed
2940 2941 2942 2943 2944
                self.coerced_self = CloneNode(self.self).coerce_to(
                    expected_type, env)
                # Insert coerced 'self' argument into argument list.
                self.args.insert(0, self.coerced_self)
            self.analyse_c_function_call(env)
2945

William Stein's avatar
William Stein committed
2946 2947 2948 2949 2950 2951 2952
    def function_type(self):
        # Return the type of the function being called, coercing a function
        # pointer to a function if necessary.
        func_type = self.function.type
        if func_type.is_ptr:
            func_type = func_type.base_type
        return func_type
2953

2954 2955 2956 2957 2958 2959 2960
    def is_simple(self):
        # C function calls could be considered simple, but they may
        # have side-effects that may hit when multiple operations must
        # be effected in order, e.g. when constructing the argument
        # sequence for a function call or comparing values.
        return False

William Stein's avatar
William Stein committed
2961
    def analyse_c_function_call(self, env):
Robert Bradshaw's avatar
Robert Bradshaw committed
2962
        if self.function.type is error_type:
2963
            self.type = error_type
Robert Bradshaw's avatar
Robert Bradshaw committed
2964
            return
Robert Bradshaw's avatar
Robert Bradshaw committed
2965
        if self.function.type.is_cpp_class:
2966 2967
            overloaded_entry = self.function.type.scope.lookup("operator()")
            if overloaded_entry is None:
Robert Bradshaw's avatar
Robert Bradshaw committed
2968 2969 2970
                self.type = PyrexTypes.error_type
                self.result_code = "<error>"
                return
2971 2972
        elif hasattr(self.function, 'entry'):
            overloaded_entry = self.function.entry
Robert Bradshaw's avatar
Robert Bradshaw committed
2973
        else:
2974 2975 2976 2977 2978 2979 2980 2981 2982
            overloaded_entry = None
        if overloaded_entry:
            entry = PyrexTypes.best_match(self.args, overloaded_entry.all_alternatives(), self.pos)
            if not entry:
                self.type = PyrexTypes.error_type
                self.result_code = "<error>"
                return
            self.function.entry = entry
            self.function.type = entry.type
2983 2984 2985 2986 2987 2988 2989 2990
            func_type = self.function_type()
        else:
            func_type = self.function_type()
            if not func_type.is_cfunction:
                error(self.pos, "Calling non-function type '%s'" % func_type)
                self.type = PyrexTypes.error_type
                self.result_code = "<error>"
                return
William Stein's avatar
William Stein committed
2991
        # Check no. of args
2992 2993
        max_nargs = len(func_type.args)
        expected_nargs = max_nargs - func_type.optional_arg_count
William Stein's avatar
William Stein committed
2994
        actual_nargs = len(self.args)
2995 2996 2997
        if func_type.optional_arg_count and expected_nargs != actual_nargs:
            self.has_optional_args = 1
            self.is_temp = 1
William Stein's avatar
William Stein committed
2998
        # Coerce arguments
2999
        some_args_in_temps = False
3000
        for i in xrange(min(max_nargs, actual_nargs)):
William Stein's avatar
William Stein committed
3001
            formal_type = func_type.args[i].type
3002
            arg = self.args[i].coerce_to(formal_type, env)
3003
            if arg.is_temp:
3004 3005
                if i > 0:
                    # first argument in temp doesn't impact subsequent arguments
3006
                    some_args_in_temps = True
3007
            elif arg.type.is_pyobject and not env.nogil:
3008 3009
                if i == 0 and self.self is not None:
                    # a method's cloned "self" argument is ok
3010
                    pass
3011
                elif arg.nonlocally_immutable():
3012 3013 3014
                    # plain local variables are ok
                    pass
                else:
3015 3016 3017 3018
                    # we do not safely own the argument's reference,
                    # but we must make sure it cannot be collected
                    # before we return from the function, so we create
                    # an owned temp reference to it
3019 3020
                    if i > 0: # first argument doesn't matter
                        some_args_in_temps = True
3021
                    arg = arg.coerce_to_temp(env)
3022
            self.args[i] = arg
3023
        # handle additional varargs parameters
3024
        for i in xrange(max_nargs, actual_nargs):
3025 3026 3027 3028 3029 3030 3031 3032
            arg = self.args[i]
            if arg.type.is_pyobject:
                arg_ctype = arg.type.default_coerced_ctype()
                if arg_ctype is None:
                    error(self.args[i].pos,
                          "Python object cannot be passed as a varargs parameter")
                else:
                    self.args[i] = arg = arg.coerce_to(arg_ctype, env)
3033 3034
            if arg.is_temp and i > 0:
                some_args_in_temps = True
3035 3036 3037
        if some_args_in_temps:
            # if some args are temps and others are not, they may get
            # constructed in the wrong order (temps first) => make
3038 3039 3040 3041
            # sure they are either all temps or all not temps (except
            # for the last argument, which is evaluated last in any
            # case)
            for i in xrange(actual_nargs-1):
3042 3043
                if i == 0 and self.self is not None:
                    continue # self is ok
3044
                arg = self.args[i]
3045 3046
                if arg.nonlocally_immutable():
                    # locals, C functions, unassignable types are safe.
3047
                    pass
3048 3049 3050
                elif arg.type.is_cpp_class:
                    # Assignment has side effects, avoid.
                    pass
3051
                elif env.nogil and arg.type.is_pyobject:
3052 3053 3054
                    # can't copy a Python reference into a temp in nogil
                    # env (this is safe: a construction would fail in
                    # nogil anyway)
3055 3056 3057
                    pass
                else:
                    self.args[i] = arg.coerce_to_temp(env)
William Stein's avatar
William Stein committed
3058
        # Calc result type and code fragment
Robert Bradshaw's avatar
Robert Bradshaw committed
3059
        if isinstance(self.function, NewExprNode):
3060
            self.type = PyrexTypes.CPtrType(self.function.class_type)
Robert Bradshaw's avatar
Robert Bradshaw committed
3061 3062
        else:
            self.type = func_type.return_type
Stefan Behnel's avatar
Stefan Behnel committed
3063 3064 3065 3066 3067 3068
        if self.type.is_pyobject:
            self.result_ctype = py_object_type
            self.is_temp = 1
        elif func_type.exception_value is not None \
                 or func_type.exception_check:
            self.is_temp = 1
3069
        # Called in 'nogil' context?
3070
        self.nogil = env.nogil
3071 3072 3073 3074 3075
        if (self.nogil and
            func_type.exception_check and
            func_type.exception_check != '+'):
            env.use_utility_code(pyerr_occurred_withgil_utility_code)
        # C++ exception handler
Robert Bradshaw's avatar
Robert Bradshaw committed
3076 3077 3078 3079
        if func_type.exception_check == '+':
            if func_type.exception_value is None:
                env.use_utility_code(cpp_exception_utility_code)

William Stein's avatar
William Stein committed
3080 3081
    def calculate_result_code(self):
        return self.c_call_code()
3082

William Stein's avatar
William Stein committed
3083 3084
    def c_call_code(self):
        func_type = self.function_type()
3085
        if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
William Stein's avatar
William Stein committed
3086 3087 3088
            return "<error>"
        formal_args = func_type.args
        arg_list_code = []
3089
        args = list(zip(formal_args, self.args))
3090 3091 3092 3093
        max_nargs = len(func_type.args)
        expected_nargs = max_nargs - func_type.optional_arg_count
        actual_nargs = len(self.args)
        for formal_arg, actual_arg in args[:expected_nargs]:
William Stein's avatar
William Stein committed
3094 3095
                arg_code = actual_arg.result_as(formal_arg.type)
                arg_list_code.append(arg_code)
3096

3097 3098
        if func_type.is_overridable:
            arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
3099

3100
        if func_type.optional_arg_count:
3101
            if expected_nargs == actual_nargs:
3102
                optional_args = 'NULL'
3103
            else:
3104
                optional_args = "&%s" % self.opt_arg_struct
3105
            arg_list_code.append(optional_args)
3106

William Stein's avatar
William Stein committed
3107
        for actual_arg in self.args[len(formal_args):]:
3108 3109
            arg_list_code.append(actual_arg.result())
        result = "%s(%s)" % (self.function.result(),
Stefan Behnel's avatar
Stefan Behnel committed
3110
            ', '.join(arg_list_code))
William Stein's avatar
William Stein committed
3111
        return result
3112

William Stein's avatar
William Stein committed
3113 3114 3115
    def generate_result_code(self, code):
        func_type = self.function_type()
        if func_type.is_pyobject:
3116
            arg_code = self.arg_tuple.py_result()
William Stein's avatar
William Stein committed
3117
            code.putln(
3118
                "%s = PyObject_Call(%s, %s, NULL); %s" % (
3119
                    self.result(),
William Stein's avatar
William Stein committed
3120
                    self.function.py_result(),
3121
                    arg_code,
3122
                    code.error_goto_if_null(self.result(), self.pos)))
3123
            code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
3124
        elif func_type.is_cfunction:
3125 3126 3127
            if self.has_optional_args:
                actual_nargs = len(self.args)
                expected_nargs = len(func_type.args) - func_type.optional_arg_count
3128 3129
                self.opt_arg_struct = code.funcstate.allocate_temp(
                    func_type.op_arg_struct.base_type, manage_ref=True)
3130 3131 3132 3133
                code.putln("%s.%s = %s;" % (
                        self.opt_arg_struct,
                        Naming.pyrex_prefix + "n",
                        len(self.args) - expected_nargs))
3134
                args = list(zip(func_type.args, self.args))
3135 3136 3137
                for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
                    code.putln("%s.%s = %s;" % (
                            self.opt_arg_struct,
3138
                            func_type.opt_arg_cname(formal_arg.name),
3139
                            actual_arg.result_as(formal_arg.type)))
William Stein's avatar
William Stein committed
3140
            exc_checks = []
3141
            if self.type.is_pyobject and self.is_temp:
3142
                exc_checks.append("!%s" % self.result())
William Stein's avatar
William Stein committed
3143
            else:
3144 3145
                exc_val = func_type.exception_value
                exc_check = func_type.exception_check
William Stein's avatar
William Stein committed
3146
                if exc_val is not None:
3147
                    exc_checks.append("%s == %s" % (self.result(), exc_val))
William Stein's avatar
William Stein committed
3148
                if exc_check:
3149 3150
                    if self.nogil:
                        exc_checks.append("__Pyx_ErrOccurredWithGIL()")
3151
                    else:
3152
                        exc_checks.append("PyErr_Occurred()")
William Stein's avatar
William Stein committed
3153 3154
            if self.is_temp or exc_checks:
                rhs = self.c_call_code()
3155 3156
                if self.result():
                    lhs = "%s = " % self.result()
William Stein's avatar
William Stein committed
3157 3158 3159
                    if self.is_temp and self.type.is_pyobject:
                        #return_type = self.type # func_type.return_type
                        #print "SimpleCallNode.generate_result_code: casting", rhs, \
Robert Bradshaw's avatar
Robert Bradshaw committed
3160
                        #    "from", return_type, "to pyobject" ###
William Stein's avatar
William Stein committed
3161 3162 3163
                        rhs = typecast(py_object_type, self.type, rhs)
                else:
                    lhs = ""
Felix Wu's avatar
Felix Wu committed
3164
                if func_type.exception_check == '+':
Robert Bradshaw's avatar
Robert Bradshaw committed
3165 3166 3167
                    if func_type.exception_value is None:
                        raise_py_exception = "__Pyx_CppExn2PyErr()"
                    elif func_type.exception_value.type.is_pyobject:
3168 3169 3170
                        raise_py_exception = ' try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
                            func_type.exception_value.entry.cname,
                            func_type.exception_value.entry.cname)
Robert Bradshaw's avatar
Robert Bradshaw committed
3171 3172
                    else:
                        raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
3173 3174
                    if self.nogil:
                        raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
Felix Wu's avatar
Felix Wu committed
3175
                    code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
3176
                    "try {%s%s;} catch(...) {%s; %s}" % (
Felix Wu's avatar
Felix Wu committed
3177 3178
                        lhs,
                        rhs,
Robert Bradshaw's avatar
Robert Bradshaw committed
3179
                        raise_py_exception,
Felix Wu's avatar
Felix Wu committed
3180
                        code.error_goto(self.pos)))
3181 3182 3183 3184 3185 3186
                else:
                    if exc_checks:
                        goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
                    else:
                        goto_error = ""
                    code.putln("%s%s; %s" % (lhs, rhs, goto_error))
3187
                if self.type.is_pyobject and self.result():
3188
                    code.put_gotref(self.py_result())
3189 3190
            if self.has_optional_args:
                code.funcstate.release_temp(self.opt_arg_struct)
3191 3192 3193 3194


class PythonCapiFunctionNode(ExprNode):
    subexprs = []
3195
    def __init__(self, pos, py_name, cname, func_type, utility_code = None):
3196
        self.pos = pos
3197 3198
        self.name = py_name
        self.cname = cname
3199 3200 3201
        self.type = func_type
        self.utility_code = utility_code

3202 3203 3204
    def analyse_types(self, env):
        pass

3205 3206 3207 3208 3209
    def generate_result_code(self, code):
        if self.utility_code:
            code.globalstate.use_utility_code(self.utility_code)

    def calculate_result_code(self):
3210
        return self.cname
3211 3212 3213 3214

class PythonCapiCallNode(SimpleCallNode):
    # Python C-API Function call (only created in transforms)

Stefan Behnel's avatar
Stefan Behnel committed
3215 3216 3217 3218 3219 3220
    # By default, we assume that the call never returns None, as this
    # is true for most C-API functions in CPython.  If this does not
    # apply to a call, set the following to True (or None to inherit
    # the default behaviour).
    may_return_none = False

3221
    def __init__(self, pos, function_name, func_type,
3222
                 utility_code = None, py_name=None, **kwargs):
3223 3224 3225
        self.type = func_type.return_type
        self.result_ctype = self.type
        self.function = PythonCapiFunctionNode(
3226
            pos, py_name, function_name, func_type,
3227 3228 3229 3230 3231
            utility_code = utility_code)
        # call this last so that we can override the constructed
        # attributes above with explicit keyword arguments if required
        SimpleCallNode.__init__(self, pos, **kwargs)

William Stein's avatar
William Stein committed
3232

3233
class GeneralCallNode(CallNode):
William Stein's avatar
William Stein committed
3234 3235 3236 3237 3238 3239 3240
    #  General Python function call, including keyword,
    #  * and ** arguments.
    #
    #  function         ExprNode
    #  positional_args  ExprNode          Tuple of positional arguments
    #  keyword_args     ExprNode or None  Dict of keyword arguments
    #  starstar_arg     ExprNode or None  Dict of extra keyword args
3241

3242
    type = py_object_type
3243

William Stein's avatar
William Stein committed
3244 3245
    subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']

3246
    nogil_check = Node.gil_error
3247

3248 3249 3250 3251 3252 3253 3254 3255 3256 3257
    def compile_time_value(self, denv):
        function = self.function.compile_time_value(denv)
        positional_args = self.positional_args.compile_time_value(denv)
        keyword_args = self.keyword_args.compile_time_value(denv)
        starstar_arg = self.starstar_arg.compile_time_value(denv)
        try:
            keyword_args.update(starstar_arg)
            return function(*positional_args, **keyword_args)
        except Exception, e:
            self.compile_time_value_error(e)
3258

3259 3260
    def explicit_args_kwds(self):
        if self.starstar_arg or not isinstance(self.positional_args, TupleNode):
3261
            raise CompileError(self.pos,
3262 3263
                'Compile-time keyword arguments must be explicit.')
        return self.positional_args.args, self.keyword_args
3264

William Stein's avatar
William Stein committed
3265
    def analyse_types(self, env):
Robert Bradshaw's avatar
Robert Bradshaw committed
3266 3267
        if self.analyse_as_type_constructor(env):
            return
William Stein's avatar
William Stein committed
3268 3269 3270 3271 3272 3273
        self.function.analyse_types(env)
        self.positional_args.analyse_types(env)
        if self.keyword_args:
            self.keyword_args.analyse_types(env)
        if self.starstar_arg:
            self.starstar_arg.analyse_types(env)
3274
        if not self.function.type.is_pyobject:
3275 3276
            if self.function.type.is_error:
                self.type = error_type
Stefan Behnel's avatar
Stefan Behnel committed
3277
                return
3278
            if hasattr(self.function, 'entry') and not self.function.entry.as_variable:
3279
                error(self.pos, "Keyword and starred arguments not allowed in cdef functions.")
3280 3281
            else:
                self.function = self.function.coerce_to_pyobject(env)
William Stein's avatar
William Stein committed
3282 3283 3284 3285 3286
        self.positional_args = \
            self.positional_args.coerce_to_pyobject(env)
        if self.starstar_arg:
            self.starstar_arg = \
                self.starstar_arg.coerce_to_pyobject(env)
Stefan Behnel's avatar
Stefan Behnel committed
3287
        function = self.function
3288 3289 3290 3291 3292
        if function.is_name and function.type_entry:
            # We are calling an extension type constructor.  As long
            # as we do not support __new__(), the result type is clear
            self.type = function.type_entry.type
            self.result_ctype = py_object_type
Stefan Behnel's avatar
Stefan Behnel committed
3293
            self.may_return_none = False
3294 3295
        else:
            self.type = py_object_type
William Stein's avatar
William Stein committed
3296
        self.is_temp = 1
3297

William Stein's avatar
William Stein committed
3298
    def generate_result_code(self, code):
3299
        if self.type.is_error: return
3300
        kwargs_call_function = "PyEval_CallObjectWithKeywords"
William Stein's avatar
William Stein committed
3301
        if self.keyword_args and self.starstar_arg:
3302
            code.put_error_if_neg(self.pos,
Robert Bradshaw's avatar
Robert Bradshaw committed
3303
                "PyDict_Update(%s, %s)" % (
3304
                    self.keyword_args.py_result(),
Robert Bradshaw's avatar
Robert Bradshaw committed
3305
                    self.starstar_arg.py_result()))
William Stein's avatar
William Stein committed
3306 3307 3308 3309 3310
            keyword_code = self.keyword_args.py_result()
        elif self.keyword_args:
            keyword_code = self.keyword_args.py_result()
        elif self.starstar_arg:
            keyword_code = self.starstar_arg.py_result()
3311 3312
            if self.starstar_arg.type is not Builtin.dict_type:
                # CPython supports calling functions with non-dicts, so do we
3313 3314
                code.globalstate.use_utility_code(kwargs_call_utility_code)
                kwargs_call_function = "__Pyx_PyEval_CallObjectWithKeywords"
William Stein's avatar
William Stein committed
3315 3316 3317
        else:
            keyword_code = None
        if not keyword_code:
3318
            call_code = "PyObject_Call(%s, %s, NULL)" % (
William Stein's avatar
William Stein committed
3319 3320 3321
                self.function.py_result(),
                self.positional_args.py_result())
        else:
3322 3323
            call_code = "%s(%s, %s, %s)" % (
                kwargs_call_function,
William Stein's avatar
William Stein committed
3324 3325 3326 3327
                self.function.py_result(),
                self.positional_args.py_result(),
                keyword_code)
        code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
3328
            "%s = %s; %s" % (
3329
                self.result(),
William Stein's avatar
William Stein committed
3330
                call_code,
3331
                code.error_goto_if_null(self.result(), self.pos)))
3332
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
3333 3334


3335
class AsTupleNode(ExprNode):
William Stein's avatar
William Stein committed
3336 3337 3338 3339
    #  Convert argument to tuple. Used for normalising
    #  the * argument of a function call.
    #
    #  arg    ExprNode
3340

William Stein's avatar
William Stein committed
3341
    subexprs = ['arg']
3342 3343 3344

    def calculate_constant_result(self):
        self.constant_result = tuple(self.base.constant_result)
3345

3346 3347 3348 3349 3350 3351 3352
    def compile_time_value(self, denv):
        arg = self.arg.compile_time_value(denv)
        try:
            return tuple(arg)
        except Exception, e:
            self.compile_time_value_error(e)

William Stein's avatar
William Stein committed
3353 3354 3355
    def analyse_types(self, env):
        self.arg.analyse_types(env)
        self.arg = self.arg.coerce_to_pyobject(env)
3356
        self.type = tuple_type
William Stein's avatar
William Stein committed
3357
        self.is_temp = 1
3358

3359 3360 3361
    def may_be_none(self):
        return False

3362
    nogil_check = Node.gil_error
3363 3364
    gil_message = "Constructing Python tuple"

William Stein's avatar
William Stein committed
3365 3366
    def generate_result_code(self, code):
        code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
3367
            "%s = PySequence_Tuple(%s); %s" % (
3368
                self.result(),
William Stein's avatar
William Stein committed
3369
                self.arg.py_result(),
3370
                code.error_goto_if_null(self.result(), self.pos)))
3371
        code.put_gotref(self.py_result())
3372

William Stein's avatar
William Stein committed
3373

3374
class AttributeNode(ExprNode):
William Stein's avatar
William Stein committed
3375 3376 3377 3378
    #  obj.attribute
    #
    #  obj          ExprNode
    #  attribute    string
3379
    #  needs_none_check boolean        Used if obj is an extension type.
3380
    #                                  If set to True, it is known that the type is not None.
William Stein's avatar
William Stein committed
3381 3382 3383 3384 3385 3386 3387
    #
    #  Used internally:
    #
    #  is_py_attr           boolean   Is a Python getattr operation
    #  member               string    C name of struct member
    #  is_called            boolean   Function call is being done on result
    #  entry                Entry     Symbol table entry of attribute
3388

William Stein's avatar
William Stein committed
3389 3390
    is_attribute = 1
    subexprs = ['obj']
3391

William Stein's avatar
William Stein committed
3392 3393 3394
    type = PyrexTypes.error_type
    entry = None
    is_called = 0
3395
    needs_none_check = True
William Stein's avatar
William Stein committed
3396

3397
    def as_cython_attribute(self):
3398 3399
        if isinstance(self.obj, NameNode) and self.obj.is_cython_module:
            return self.attribute
3400 3401 3402
        cy = self.obj.as_cython_attribute()
        if cy:
            return "%s.%s" % (cy, self.attribute)
3403

3404 3405 3406 3407 3408 3409 3410 3411 3412
    def coerce_to(self, dst_type, env):
        #  If coercing to a generic pyobject and this is a cpdef function
        #  we can create the corresponding attribute
        if dst_type is py_object_type:
            entry = self.entry
            if entry and entry.is_cfunction and entry.as_variable:
                # must be a cpdef function
                self.is_temp = 1
                self.entry = entry.as_variable
3413
                self.analyse_as_python_attribute(env)
3414
                return self
3415
        return ExprNode.coerce_to(self, dst_type, env)
3416 3417 3418

    def calculate_constant_result(self):
        attr = self.attribute
3419
        if attr.startswith("__") and attr.endswith("__"):
3420 3421 3422
            return
        self.constant_result = getattr(self.obj.constant_result, attr)

3423 3424
    def compile_time_value(self, denv):
        attr = self.attribute
3425
        if attr.startswith("__") and attr.endswith("__"):
Stefan Behnel's avatar
Stefan Behnel committed
3426 3427
            error(self.pos,
                  "Invalid attribute name '%s' in compile-time expression" % attr)
3428
            return None
3429
        obj = self.obj.compile_time_value(denv)
3430 3431 3432 3433
        try:
            return getattr(obj, attr)
        except Exception, e:
            self.compile_time_value_error(e)
3434

Robert Bradshaw's avatar
Robert Bradshaw committed
3435 3436
    def type_dependencies(self, env):
        return self.obj.type_dependencies(env)
3437

3438 3439 3440 3441 3442 3443
    def infer_type(self, env):
        if self.analyse_as_cimported_attribute(env, 0):
            return self.entry.type
        elif self.analyse_as_unbound_cmethod(env):
            return self.entry.type
        else:
3444 3445 3446 3447 3448 3449 3450 3451
            obj_type = self.obj.infer_type(env)
            self.analyse_attribute(env, obj_type = obj_type)
            if obj_type.is_builtin_type and self.type.is_cfunction:
                # special case: C-API replacements for C methods of
                # builtin types cannot be inferred as C functions as
                # that would prevent their use as bound methods
                self.type = py_object_type
                return py_object_type
3452
            return self.type
3453

William Stein's avatar
William Stein committed
3454 3455
    def analyse_target_declaration(self, env):
        pass
3456

William Stein's avatar
William Stein committed
3457 3458
    def analyse_target_types(self, env):
        self.analyse_types(env, target = 1)
3459

William Stein's avatar
William Stein committed
3460 3461 3462 3463 3464 3465
    def analyse_types(self, env, target = 0):
        if self.analyse_as_cimported_attribute(env, target):
            return
        if not target and self.analyse_as_unbound_cmethod(env):
            return
        self.analyse_as_ordinary_attribute(env, target)
3466

William Stein's avatar
William Stein committed
3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480
    def analyse_as_cimported_attribute(self, env, target):
        # Try to interpret this as a reference to an imported
        # C const, type, var or function. If successful, mutates
        # this node into a NameNode and returns 1, otherwise
        # returns 0.
        module_scope = self.obj.analyse_as_module(env)
        if module_scope:
            entry = module_scope.lookup_here(self.attribute)
            if entry and (
                entry.is_cglobal or entry.is_cfunction
                or entry.is_type or entry.is_const):
                    self.mutate_into_name_node(env, entry, target)
                    return 1
        return 0
3481

William Stein's avatar
William Stein committed
3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497
    def analyse_as_unbound_cmethod(self, env):
        # Try to interpret this as a reference to an unbound
        # C method of an extension type. If successful, mutates
        # this node into a NameNode and returns 1, otherwise
        # returns 0.
        type = self.obj.analyse_as_extension_type(env)
        if type:
            entry = type.scope.lookup_here(self.attribute)
            if entry and entry.is_cmethod:
                # Create a temporary entry describing the C method
                # as an ordinary function.
                ubcm_entry = Symtab.Entry(entry.name,
                    "%s->%s" % (type.vtabptr_cname, entry.cname),
                    entry.type)
                ubcm_entry.is_cfunction = 1
                ubcm_entry.func_cname = entry.func_cname
3498
                ubcm_entry.is_unbound_cmethod = 1
William Stein's avatar
William Stein committed
3499 3500 3501
                self.mutate_into_name_node(env, ubcm_entry, None)
                return 1
        return 0
3502

3503 3504 3505
    def analyse_as_type(self, env):
        module_scope = self.obj.analyse_as_module(env)
        if module_scope:
3506
            return module_scope.lookup_type(self.attribute)
Robert Bradshaw's avatar
Robert Bradshaw committed
3507 3508
        if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
            base_type = self.obj.analyse_as_type(env)
Robert Bradshaw's avatar
Robert Bradshaw committed
3509
            if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
Robert Bradshaw's avatar
Robert Bradshaw committed
3510
                return base_type.scope.lookup_type(self.attribute)
3511
        return None
3512

William Stein's avatar
William Stein committed
3513 3514 3515 3516 3517 3518 3519 3520 3521
    def analyse_as_extension_type(self, env):
        # Try to interpret this as a reference to an extension type
        # in a cimported module. Returns the extension type, or None.
        module_scope = self.obj.analyse_as_module(env)
        if module_scope:
            entry = module_scope.lookup_here(self.attribute)
            if entry and entry.is_type and entry.type.is_extension_type:
                return entry.type
        return None
3522

William Stein's avatar
William Stein committed
3523 3524 3525 3526 3527 3528 3529 3530 3531
    def analyse_as_module(self, env):
        # Try to interpret this as a reference to a cimported module
        # in another cimported module. Returns the module scope, or None.
        module_scope = self.obj.analyse_as_module(env)
        if module_scope:
            entry = module_scope.lookup_here(self.attribute)
            if entry and entry.as_module:
                return entry.as_module
        return None
3532

William Stein's avatar
William Stein committed
3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543
    def mutate_into_name_node(self, env, entry, target):
        # Mutate this node into a NameNode and complete the
        # analyse_types phase.
        self.__class__ = NameNode
        self.name = self.attribute
        self.entry = entry
        del self.obj
        del self.attribute
        if target:
            NameNode.analyse_target_types(self, env)
        else:
3544
            NameNode.analyse_rvalue_entry(self, env)
3545

William Stein's avatar
William Stein committed
3546 3547 3548 3549
    def analyse_as_ordinary_attribute(self, env, target):
        self.obj.analyse_types(env)
        self.analyse_attribute(env)
        if self.entry and self.entry.is_cmethod and not self.is_called:
3550 3551
#            error(self.pos, "C method can only be called")
            pass
3552 3553
        ## Reference to C array turns into pointer to first element.
        #while self.type.is_array:
Robert Bradshaw's avatar
Robert Bradshaw committed
3554
        #    self.type = self.type.element_ptr_type()
William Stein's avatar
William Stein committed
3555 3556 3557 3558
        if self.is_py_attr:
            if not target:
                self.is_temp = 1
                self.result_ctype = py_object_type
3559 3560 3561
        elif target and self.obj.type.is_builtin_type:
            error(self.pos, "Assignment to an immutable object field")

Robert Bradshaw's avatar
Robert Bradshaw committed
3562
    def analyse_attribute(self, env, obj_type = None):
William Stein's avatar
William Stein committed
3563 3564 3565
        # Look up attribute and set self.type and self.member.
        self.is_py_attr = 0
        self.member = self.attribute
Robert Bradshaw's avatar
Robert Bradshaw committed
3566 3567 3568 3569 3570 3571 3572
        if obj_type is None:
            if self.obj.type.is_string:
                self.obj = self.obj.coerce_to_pyobject(env)
            obj_type = self.obj.type
        else:
            if obj_type.is_string:
                obj_type = py_object_type
3573
        if obj_type.is_ptr or obj_type.is_array:
William Stein's avatar
William Stein committed
3574 3575
            obj_type = obj_type.base_type
            self.op = "->"
3576
        elif obj_type.is_extension_type or obj_type.is_builtin_type:
William Stein's avatar
William Stein committed
3577 3578 3579 3580 3581 3582 3583
            self.op = "->"
        else:
            self.op = "."
        if obj_type.has_attributes:
            entry = None
            if obj_type.attributes_known():
                entry = obj_type.scope.lookup_here(self.attribute)
Robert Bradshaw's avatar
Robert Bradshaw committed
3584 3585
                if entry and entry.is_member:
                    entry = None
William Stein's avatar
William Stein committed
3586
            else:
3587 3588
                error(self.pos,
                    "Cannot select attribute of incomplete type '%s'"
William Stein's avatar
William Stein committed
3589
                    % obj_type)
Robert Bradshaw's avatar
Robert Bradshaw committed
3590 3591
                self.type = PyrexTypes.error_type
                return
William Stein's avatar
William Stein committed
3592 3593
            self.entry = entry
            if entry:
3594 3595
                if obj_type.is_extension_type and entry.name == "__weakref__":
                    error(self.pos, "Illegal use of special attribute __weakref__")
3596 3597
                # methods need the normal attribute lookup
                # because they do not have struct entries
3598 3599 3600 3601
                if entry.is_variable or entry.is_cmethod:
                    self.type = entry.type
                    self.member = entry.cname
                    return
William Stein's avatar
William Stein committed
3602 3603 3604 3605 3606
                else:
                    # If it's not a variable or C method, it must be a Python
                    # method of an extension type, so we treat it like a Python
                    # attribute.
                    pass
3607
        # If we get here, the base object is not a struct/union/extension
William Stein's avatar
William Stein committed
3608 3609 3610
        # type, or it is an extension type and the attribute is either not
        # declared or is declared as a Python method. Treat it as a Python
        # attribute reference.
Robert Bradshaw's avatar
Robert Bradshaw committed
3611
        self.analyse_as_python_attribute(env, obj_type)
Stefan Behnel's avatar
Stefan Behnel committed
3612

Robert Bradshaw's avatar
Robert Bradshaw committed
3613 3614 3615
    def analyse_as_python_attribute(self, env, obj_type = None):
        if obj_type is None:
            obj_type = self.obj.type
3616
        self.member = self.attribute
3617 3618
        self.type = py_object_type
        self.is_py_attr = 1
3619
        if not obj_type.is_pyobject and not obj_type.is_error:
3620
            if obj_type.can_coerce_to_pyobject(env):
3621 3622 3623 3624 3625
                self.obj = self.obj.coerce_to_pyobject(env)
            else:
                error(self.pos,
                      "Object of type '%s' has no attribute '%s'" %
                      (obj_type, self.attribute))
3626

3627
    def nogil_check(self, env):
3628
        if self.is_py_attr:
3629
            self.gil_error()
3630

3631 3632
    gil_message = "Accessing Python attribute"

William Stein's avatar
William Stein committed
3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643
    def is_simple(self):
        if self.obj:
            return self.result_in_temp() or self.obj.is_simple()
        else:
            return NameNode.is_simple(self)

    def is_lvalue(self):
        if self.obj:
            return 1
        else:
            return NameNode.is_lvalue(self)
3644

William Stein's avatar
William Stein committed
3645 3646 3647 3648 3649
    def is_ephemeral(self):
        if self.obj:
            return self.obj.is_ephemeral()
        else:
            return NameNode.is_ephemeral(self)
3650

William Stein's avatar
William Stein committed
3651 3652
    def calculate_result_code(self):
        #print "AttributeNode.calculate_result_code:", self.member ###
3653
        #print "...obj node =", self.obj, "code", self.obj.result() ###
William Stein's avatar
William Stein committed
3654 3655 3656 3657 3658
        #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
        obj = self.obj
        obj_code = obj.result_as(obj.type)
        #print "...obj_code =", obj_code ###
        if self.entry and self.entry.is_cmethod:
Robert Bradshaw's avatar
Robert Bradshaw committed
3659 3660
            if obj.type.is_extension_type:
                return "((struct %s *)%s%s%s)->%s" % (
3661
                    obj.type.vtabstruct_cname, obj_code, self.op,
Robert Bradshaw's avatar
Robert Bradshaw committed
3662 3663 3664
                    obj.type.vtabslot_cname, self.member)
            else:
                return self.member
3665
        elif obj.type.is_complex:
3666
            return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
William Stein's avatar
William Stein committed
3667
        else:
3668 3669 3670
            if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
                # accessing a field of a builtin type, need to cast better than result_as() does
                obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
William Stein's avatar
William Stein committed
3671
            return "%s%s%s" % (obj_code, self.op, self.member)
3672

William Stein's avatar
William Stein committed
3673
    def generate_result_code(self, code):
3674
        interned_attr_cname = code.intern_identifier(self.attribute)
William Stein's avatar
William Stein committed
3675
        if self.is_py_attr:
3676 3677
            code.putln(
                '%s = PyObject_GetAttr(%s, %s); %s' % (
3678
                    self.result(),
3679
                    self.obj.py_result(),
3680
                    interned_attr_cname,
3681
                    code.error_goto_if_null(self.result(), self.pos)))
3682
            code.put_gotref(self.py_result())
3683 3684 3685
        else:
            # result_code contains what is needed, but we may need to insert
            # a check and raise an exception
3686 3687 3688 3689
            if (self.obj.type.is_extension_type
                  and self.needs_none_check
                  and code.globalstate.directives['nonecheck']):
                self.put_nonecheck(code)
3690

William Stein's avatar
William Stein committed
3691
    def generate_assignment_code(self, rhs, code):
3692
        interned_attr_cname = code.intern_identifier(self.attribute)
William Stein's avatar
William Stein committed
3693 3694
        self.obj.generate_evaluation_code(code)
        if self.is_py_attr:
3695
            code.put_error_if_neg(self.pos,
3696 3697
                'PyObject_SetAttr(%s, %s, %s)' % (
                    self.obj.py_result(),
3698
                    interned_attr_cname,
3699
                    rhs.py_result()))
William Stein's avatar
William Stein committed
3700
            rhs.generate_disposal_code(code)
3701
            rhs.free_temps(code)
3702 3703 3704 3705 3706
        elif self.obj.type.is_complex:
            code.putln("__Pyx_SET_C%s(%s, %s);" % (
                self.member.upper(),
                self.obj.result_as(self.obj.type),
                rhs.result_as(self.ctype())))
William Stein's avatar
William Stein committed
3707
        else:
3708 3709 3710 3711 3712
            if (self.obj.type.is_extension_type
                  and self.needs_none_check
                  and code.globalstate.directives['nonecheck']):
                self.put_nonecheck(code)

3713
            select_code = self.result()
3714
            if self.type.is_pyobject and self.use_managed_ref:
William Stein's avatar
William Stein committed
3715
                rhs.make_owned_reference(code)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
3716
                code.put_giveref(rhs.py_result())
3717
                code.put_gotref(select_code)
William Stein's avatar
William Stein committed
3718 3719 3720 3721
                code.put_decref(select_code, self.ctype())
            code.putln(
                "%s = %s;" % (
                    select_code,
3722
                    rhs.result_as(self.ctype())))
3723
                    #rhs.result()))
William Stein's avatar
William Stein committed
3724
            rhs.generate_post_assignment_code(code)
3725
            rhs.free_temps(code)
William Stein's avatar
William Stein committed
3726
        self.obj.generate_disposal_code(code)
3727
        self.obj.free_temps(code)
3728

William Stein's avatar
William Stein committed
3729
    def generate_deletion_code(self, code):
3730
        interned_attr_cname = code.intern_identifier(self.attribute)
William Stein's avatar
William Stein committed
3731
        self.obj.generate_evaluation_code(code)
3732
        if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
3733
                               and u'__del__' in self.entry.scope.entries):
3734 3735 3736
            code.put_error_if_neg(self.pos,
                'PyObject_DelAttr(%s, %s)' % (
                    self.obj.py_result(),
3737
                    interned_attr_cname))
William Stein's avatar
William Stein committed
3738 3739 3740
        else:
            error(self.pos, "Cannot delete C attribute of extension type")
        self.obj.generate_disposal_code(code)
3741
        self.obj.free_temps(code)
3742

3743 3744 3745 3746 3747
    def annotate(self, code):
        if self.is_py_attr:
            code.annotate(self.pos, AnnotationItem('py_attr', 'python attribute', size=len(self.attribute)))
        else:
            code.annotate(self.pos, AnnotationItem('c_attr', 'c attribute', size=len(self.attribute)))
William Stein's avatar
William Stein committed
3748

3749 3750 3751
    def put_nonecheck(self, code):
        code.globalstate.use_utility_code(raise_noneattr_error_utility_code)
        code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.obj.result_as(PyrexTypes.py_object_type))
Stefan Behnel's avatar
Stefan Behnel committed
3752
        code.putln("__Pyx_RaiseNoneAttributeError(\"%s\");" % self.attribute)
3753 3754 3755 3756
        code.putln(code.error_goto(self.pos))
        code.putln("}")


William Stein's avatar
William Stein committed
3757 3758 3759 3760 3761 3762
#-------------------------------------------------------------------
#
#  Constructor nodes
#
#-------------------------------------------------------------------

3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777
class StarredTargetNode(ExprNode):
    #  A starred expression like "*a"
    #
    #  This is only allowed in sequence assignment targets such as
    #
    #      a, *b = (1,2,3,4)    =>     a = 1 ; b = [2,3,4]
    #
    #  and will be removed during type analysis (or generate an error
    #  if it's found at unexpected places).
    #
    #  target          ExprNode

    subexprs = ['target']
    is_starred = 1
    type = py_object_type
Robert Bradshaw's avatar
Robert Bradshaw committed
3778
    is_temp = 1
3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806

    def __init__(self, pos, target):
        self.pos = pos
        self.target = target

    def analyse_declarations(self, env):
        error(self.pos, "can use starred expression only as assignment target")
        self.target.analyse_declarations(env)

    def analyse_types(self, env):
        error(self.pos, "can use starred expression only as assignment target")
        self.target.analyse_types(env)
        self.type = self.target.type

    def analyse_target_declaration(self, env):
        self.target.analyse_target_declaration(env)

    def analyse_target_types(self, env):
        self.target.analyse_target_types(env)
        self.type = self.target.type

    def calculate_result_code(self):
        return ""

    def generate_result_code(self, code):
        pass


3807
class SequenceNode(ExprNode):
William Stein's avatar
William Stein committed
3808 3809 3810 3811
    #  Base class for list and tuple constructor nodes.
    #  Contains common code for performing sequence unpacking.
    #
    #  args                    [ExprNode]
3812
    #  iterator                ExprNode
William Stein's avatar
William Stein committed
3813 3814
    #  unpacked_items          [ExprNode] or None
    #  coerced_unpacked_items  [ExprNode] or None
3815

William Stein's avatar
William Stein committed
3816
    subexprs = ['args']
3817

William Stein's avatar
William Stein committed
3818 3819
    is_sequence_constructor = 1
    unpacked_items = None
3820

3821 3822 3823
    def compile_time_value_list(self, denv):
        return [arg.compile_time_value(denv) for arg in self.args]

3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837
    def replace_starred_target_node(self):
        # replace a starred node in the targets by the contained expression
        self.starred_assignment = False
        args = []
        for arg in self.args:
            if arg.is_starred:
                if self.starred_assignment:
                    error(arg.pos, "more than 1 starred expression in assignment")
                self.starred_assignment = True
                arg = arg.target
                arg.is_starred = True
            args.append(arg)
        self.args = args

William Stein's avatar
William Stein committed
3838
    def analyse_target_declaration(self, env):
3839
        self.replace_starred_target_node()
William Stein's avatar
William Stein committed
3840 3841 3842
        for arg in self.args:
            arg.analyse_target_declaration(env)

3843
    def analyse_types(self, env, skip_children=False):
William Stein's avatar
William Stein committed
3844 3845
        for i in range(len(self.args)):
            arg = self.args[i]
3846
            if not skip_children: arg.analyse_types(env)
William Stein's avatar
William Stein committed
3847 3848
            self.args[i] = arg.coerce_to_pyobject(env)
        self.is_temp = 1
Stefan Behnel's avatar
Stefan Behnel committed
3849
        # not setting self.type here, subtypes do this
3850

3851 3852 3853
    def may_be_none(self):
        return False

William Stein's avatar
William Stein committed
3854
    def analyse_target_types(self, env):
3855 3856
        self.iterator = PyTempNode(self.pos, env)
        self.unpacked_items = []
William Stein's avatar
William Stein committed
3857 3858 3859
        self.coerced_unpacked_items = []
        for arg in self.args:
            arg.analyse_target_types(env)
3860 3861 3862 3863 3864 3865
            if arg.is_starred:
                if not arg.type.assignable_from(Builtin.list_type):
                    error(arg.pos,
                          "starred target must have Python object (list) type")
                if arg.type is py_object_type:
                    arg.type = Builtin.list_type
William Stein's avatar
William Stein committed
3866 3867 3868 3869 3870
            unpacked_item = PyTempNode(self.pos, env)
            coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
            self.unpacked_items.append(unpacked_item)
            self.coerced_unpacked_items.append(coerced_unpacked_item)
        self.type = py_object_type
3871

William Stein's avatar
William Stein committed
3872 3873
    def generate_result_code(self, code):
        self.generate_operation_code(code)
3874

William Stein's avatar
William Stein committed
3875
    def generate_assignment_code(self, rhs, code):
3876 3877 3878
        if self.starred_assignment:
            self.generate_starred_assignment_code(rhs, code)
        else:
3879
            self.generate_parallel_assignment_code(rhs, code)
3880 3881 3882 3883 3884

        for item in self.unpacked_items:
            item.release(code)
        rhs.free_temps(code)

3885
    def generate_parallel_assignment_code(self, rhs, code):
3886 3887 3888 3889
        # Need to work around the fact that generate_evaluation_code
        # allocates the temps in a rather hacky way -- the assignment
        # is evaluated twice, within each if-block.

3890 3891 3892 3893
        if rhs.type is tuple_type:
            tuple_check = "likely(%s != Py_None)"
        else:
            tuple_check = "PyTuple_CheckExact(%s)"
Robert Bradshaw's avatar
Robert Bradshaw committed
3894
        code.putln(
3895
            "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % (
3896 3897
                tuple_check % rhs.py_result(),
                rhs.py_result(),
Robert Bradshaw's avatar
Robert Bradshaw committed
3898
                len(self.args)))
Stefan Behnel's avatar
Stefan Behnel committed
3899
        code.putln("PyObject* tuple = %s;" % rhs.py_result())
3900 3901
        for item in self.unpacked_items:
            item.allocate(code)
Robert Bradshaw's avatar
Robert Bradshaw committed
3902 3903
        for i in range(len(self.args)):
            item = self.unpacked_items[i]
3904 3905
            code.put(
                "%s = PyTuple_GET_ITEM(tuple, %s); " % (
3906
                    item.result(),
Robert Bradshaw's avatar
Robert Bradshaw committed
3907
                    i))
3908
            code.put_incref(item.result(), item.ctype())
3909 3910
            value_node = self.coerced_unpacked_items[i]
            value_node.generate_evaluation_code(code)
3911
        rhs.generate_disposal_code(code)
3912

3913 3914 3915
        for i in range(len(self.args)):
            self.args[i].generate_assignment_code(
                self.coerced_unpacked_items[i], code)
3916

3917
        code.putln("} else {")
Robert Bradshaw's avatar
Robert Bradshaw committed
3918

3919
        if rhs.type is tuple_type:
3920 3921 3922 3923
            code.globalstate.use_utility_code(tuple_unpacking_error_code)
            code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
                        rhs.py_result(), len(self.args)))
            code.putln(code.error_goto(self.pos))
3924
        else:
3925 3926
            code.globalstate.use_utility_code(unpacking_utility_code)

3927
            self.iterator.allocate(code)
3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946
            code.putln(
                "%s = PyObject_GetIter(%s); %s" % (
                    self.iterator.result(),
                    rhs.py_result(),
                    code.error_goto_if_null(self.iterator.result(), self.pos)))
            code.put_gotref(self.iterator.py_result())
            rhs.generate_disposal_code(code)
            for i in range(len(self.args)):
                item = self.unpacked_items[i]
                unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
                    self.iterator.py_result(), i)
                code.putln(
                    "%s = %s; %s" % (
                        item.result(),
                        typecast(item.ctype(), py_object_type, unpack_code),
                        code.error_goto_if_null(item.result(), self.pos)))
                code.put_gotref(item.py_result())
                value_node = self.coerced_unpacked_items[i]
                value_node.generate_evaluation_code(code)
3947 3948 3949
            code.put_error_if_neg(self.pos, "__Pyx_EndUnpack(%s, %d)" % (
                self.iterator.py_result(),
                len(self.args)))
3950 3951 3952 3953 3954
            if debug_disposal_code:
                print("UnpackNode.generate_assignment_code:")
                print("...generating disposal code for %s" % self.iterator)
            self.iterator.generate_disposal_code(code)
            self.iterator.free_temps(code)
3955
            self.iterator.release(code)
3956 3957 3958 3959

            for i in range(len(self.args)):
                self.args[i].generate_assignment_code(
                    self.coerced_unpacked_items[i], code)
William Stein's avatar
William Stein committed
3960

3961
        code.putln("}")
3962 3963

    def generate_starred_assignment_code(self, rhs, code):
3964 3965
        code.globalstate.use_utility_code(unpacking_utility_code)

3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981
        for i, arg in enumerate(self.args):
            if arg.is_starred:
                starred_target = self.unpacked_items[i]
                fixed_args_left  = self.args[:i]
                fixed_args_right = self.args[i+1:]
                break

        self.iterator.allocate(code)
        code.putln(
            "%s = PyObject_GetIter(%s); %s" % (
                self.iterator.result(),
                rhs.py_result(),
                code.error_goto_if_null(self.iterator.result(), self.pos)))
        code.put_gotref(self.iterator.py_result())
        rhs.generate_disposal_code(code)

3982
        for item in self.unpacked_items:
3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017
            item.allocate(code)
        for i in range(len(fixed_args_left)):
            item = self.unpacked_items[i]
            unpack_code = "__Pyx_UnpackItem(%s, %d)" % (
                self.iterator.py_result(), i)
            code.putln(
                "%s = %s; %s" % (
                    item.result(),
                    typecast(item.ctype(), py_object_type, unpack_code),
                    code.error_goto_if_null(item.result(), self.pos)))
            code.put_gotref(item.py_result())
            value_node = self.coerced_unpacked_items[i]
            value_node.generate_evaluation_code(code)

        target_list = starred_target.result()
        code.putln("%s = PySequence_List(%s); %s" % (
            target_list, self.iterator.py_result(),
            code.error_goto_if_null(target_list, self.pos)))
        code.put_gotref(target_list)
        if fixed_args_right:
            code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
            unpacked_right_args = self.unpacked_items[-len(fixed_args_right):]
            code.putln("if (unlikely(PyList_GET_SIZE(%s) < %d)) {" % (
                (target_list, len(unpacked_right_args))))
            code.put("__Pyx_RaiseNeedMoreValuesError(%d+PyList_GET_SIZE(%s)); %s" % (
                     len(fixed_args_left), target_list,
                     code.error_goto(self.pos)))
            code.putln('}')
            for i, (arg, coerced_arg) in enumerate(zip(unpacked_right_args[::-1],
                                                       self.coerced_unpacked_items[::-1])):
                code.putln(
                    "%s = PyList_GET_ITEM(%s, PyList_GET_SIZE(%s)-1); " % (
                        arg.py_result(),
                        target_list, target_list))
                # resize the list the hard way
4018
                code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029
                code.put_gotref(arg.py_result())
                coerced_arg.generate_evaluation_code(code)

        self.iterator.generate_disposal_code(code)
        self.iterator.free_temps(code)
        self.iterator.release(code)

        for i in range(len(self.args)):
            self.args[i].generate_assignment_code(
                self.coerced_unpacked_items[i], code)

4030 4031 4032 4033 4034 4035 4036 4037
    def annotate(self, code):
        for arg in self.args:
            arg.annotate(code)
        if self.unpacked_items:
            for arg in self.unpacked_items:
                arg.annotate(code)
            for arg in self.coerced_unpacked_items:
                arg.annotate(code)
William Stein's avatar
William Stein committed
4038 4039 4040 4041


class TupleNode(SequenceNode):
    #  Tuple constructor.
4042

4043
    type = tuple_type
4044 4045 4046

    gil_message = "Constructing Python tuple"

4047
    def analyse_types(self, env, skip_children=False):
Robert Bradshaw's avatar
Robert Bradshaw committed
4048 4049
        if len(self.args) == 0:
            self.is_temp = 0
4050
            self.is_literal = 1
Robert Bradshaw's avatar
Robert Bradshaw committed
4051
        else:
4052
            SequenceNode.analyse_types(self, env, skip_children)
4053 4054 4055 4056 4057 4058
            for child in self.args:
                if not child.is_literal:
                    break
            else:
                self.is_temp = 0
                self.is_literal = 1
4059

Stefan Behnel's avatar
Stefan Behnel committed
4060 4061 4062 4063
    def is_simple(self):
        # either temp or constant => always simple
        return True

4064 4065 4066 4067
    def nonlocally_immutable(self):
        # either temp or constant => always safe
        return True

Robert Bradshaw's avatar
Robert Bradshaw committed
4068 4069
    def calculate_result_code(self):
        if len(self.args) > 0:
4070
            return self.result_code
Robert Bradshaw's avatar
Robert Bradshaw committed
4071 4072
        else:
            return Naming.empty_tuple
William Stein's avatar
William Stein committed
4073

4074 4075 4076 4077
    def calculate_constant_result(self):
        self.constant_result = tuple([
                arg.constant_result for arg in self.args])

4078 4079 4080 4081 4082 4083
    def compile_time_value(self, denv):
        values = self.compile_time_value_list(denv)
        try:
            return tuple(values)
        except Exception, e:
            self.compile_time_value_error(e)
4084

William Stein's avatar
William Stein committed
4085
    def generate_operation_code(self, code):
Robert Bradshaw's avatar
Robert Bradshaw committed
4086 4087 4088
        if len(self.args) == 0:
            # result_code is Naming.empty_tuple
            return
4089 4090 4091
        if self.is_literal:
            # non-empty cached tuple => result is global constant,
            # creation code goes into separate code writer
4092
            self.result_code = code.get_py_const(py_object_type, 'tuple_', cleanup_level=2)
4093 4094 4095
            code = code.get_cached_constants_writer()
            code.mark_pos(self.pos)

William Stein's avatar
William Stein committed
4096
        code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
4097
            "%s = PyTuple_New(%s); %s" % (
4098
                self.result(),
William Stein's avatar
William Stein committed
4099
                len(self.args),
4100
                code.error_goto_if_null(self.result(), self.pos)))
4101
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
4102 4103 4104
        for i in range(len(self.args)):
            arg = self.args[i]
            if not arg.result_in_temp():
4105
                code.put_incref(arg.result(), arg.ctype())
William Stein's avatar
William Stein committed
4106 4107
            code.putln(
                "PyTuple_SET_ITEM(%s, %s, %s);" % (
4108
                    self.result(),
William Stein's avatar
William Stein committed
4109 4110
                    i,
                    arg.py_result()))
4111
            code.put_giveref(arg.py_result())
4112 4113
        if self.is_literal:
            code.put_giveref(self.py_result())
4114

William Stein's avatar
William Stein committed
4115 4116 4117 4118 4119
    def generate_subexpr_disposal_code(self, code):
        # We call generate_post_assignment_code here instead
        # of generate_disposal_code, because values were stored
        # in the tuple using a reference-stealing operation.
        for arg in self.args:
4120 4121 4122
            arg.generate_post_assignment_code(code)
            # Should NOT call free_temps -- this is invoked by the default
            # generate_evaluation_code which will do that.
William Stein's avatar
William Stein committed
4123 4124 4125 4126


class ListNode(SequenceNode):
    #  List constructor.
4127

4128 4129
    # obj_conversion_errors    [PyrexError]   used internally
    # orignial_args            [ExprNode]     used internally
4130

4131
    obj_conversion_errors = []
Stefan Behnel's avatar
Stefan Behnel committed
4132
    type = list_type
4133

4134
    gil_message = "Constructing Python list"
4135

Robert Bradshaw's avatar
Robert Bradshaw committed
4136
    def type_dependencies(self, env):
4137
        return ()
4138

4139 4140 4141
    def infer_type(self, env):
        # TOOD: Infer non-object list arrays.
        return list_type
4142

4143
    def analyse_expressions(self, env):
4144
        SequenceNode.analyse_expressions(self, env)
4145 4146
        self.coerce_to_pyobject(env)

Robert Bradshaw's avatar
Robert Bradshaw committed
4147
    def analyse_types(self, env):
4148 4149 4150 4151 4152
        hold_errors()
        self.original_args = list(self.args)
        SequenceNode.analyse_types(self, env)
        self.obj_conversion_errors = held_errors()
        release_errors(ignore=True)
4153

Robert Bradshaw's avatar
Robert Bradshaw committed
4154 4155
    def coerce_to(self, dst_type, env):
        if dst_type.is_pyobject:
4156 4157 4158
            for err in self.obj_conversion_errors:
                report_error(err)
            self.obj_conversion_errors = []
Robert Bradshaw's avatar
Robert Bradshaw committed
4159 4160
            if not self.type.subtype_of(dst_type):
                error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
4161
        elif dst_type.is_ptr and dst_type.base_type is not PyrexTypes.c_void_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
4162
            base_type = dst_type.base_type
Robert Bradshaw's avatar
Robert Bradshaw committed
4163
            self.type = PyrexTypes.CArrayType(base_type, len(self.args))
4164
            for i in range(len(self.original_args)):
Robert Bradshaw's avatar
Robert Bradshaw committed
4165
                arg = self.args[i]
4166 4167
                if isinstance(arg, CoerceToPyTypeNode):
                    arg = arg.arg
Robert Bradshaw's avatar
Robert Bradshaw committed
4168
                self.args[i] = arg.coerce_to(base_type, env)
Robert Bradshaw's avatar
Robert Bradshaw committed
4169 4170 4171 4172 4173 4174
        elif dst_type.is_struct:
            if len(self.args) > len(dst_type.scope.var_entries):
                error(self.pos, "Too may members for '%s'" % dst_type)
            else:
                if len(self.args) < len(dst_type.scope.var_entries):
                    warning(self.pos, "Too few members for '%s'" % dst_type, 1)
4175 4176 4177
                for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
                    if isinstance(arg, CoerceToPyTypeNode):
                        arg = arg.arg
Robert Bradshaw's avatar
Robert Bradshaw committed
4178 4179
                    self.args[i] = arg.coerce_to(member.type, env)
            self.type = dst_type
Robert Bradshaw's avatar
Robert Bradshaw committed
4180 4181 4182 4183
        else:
            self.type = error_type
            error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
        return self
4184

Robert Bradshaw's avatar
Robert Bradshaw committed
4185 4186
    def release_temp(self, env):
        if self.type.is_array:
4187 4188
            # To be valid C++, we must allocate the memory on the stack
            # manually and be sure not to reuse it for something else.
Robert Bradshaw's avatar
Robert Bradshaw committed
4189 4190 4191
            pass
        else:
            SequenceNode.release_temp(self, env)
Robert Bradshaw's avatar
Robert Bradshaw committed
4192

4193 4194 4195 4196
    def calculate_constant_result(self):
        self.constant_result = [
            arg.constant_result for arg in self.args]

4197 4198 4199
    def compile_time_value(self, denv):
        return self.compile_time_value_list(denv)

William Stein's avatar
William Stein committed
4200
    def generate_operation_code(self, code):
Robert Bradshaw's avatar
Robert Bradshaw committed
4201
        if self.type.is_pyobject:
4202 4203
            for err in self.obj_conversion_errors:
                report_error(err)
Robert Bradshaw's avatar
Robert Bradshaw committed
4204
            code.putln("%s = PyList_New(%s); %s" %
4205
                (self.result(),
Robert Bradshaw's avatar
Robert Bradshaw committed
4206 4207
                len(self.args),
                code.error_goto_if_null(self.result(), self.pos)))
4208
            code.put_gotref(self.py_result())
Robert Bradshaw's avatar
Robert Bradshaw committed
4209 4210 4211 4212 4213 4214 4215 4216 4217
            for i in range(len(self.args)):
                arg = self.args[i]
                #if not arg.is_temp:
                if not arg.result_in_temp():
                    code.put_incref(arg.result(), arg.ctype())
                code.putln("PyList_SET_ITEM(%s, %s, %s);" %
                    (self.result(),
                    i,
                    arg.py_result()))
4218
                code.put_giveref(arg.py_result())
Robert Bradshaw's avatar
Robert Bradshaw committed
4219 4220 4221 4222 4223 4224
        elif self.type.is_array:
            for i, arg in enumerate(self.args):
                code.putln("%s[%s] = %s;" % (
                                self.result(),
                                i,
                                arg.result()))
Robert Bradshaw's avatar
Robert Bradshaw committed
4225
        elif self.type.is_struct:
Robert Bradshaw's avatar
Robert Bradshaw committed
4226 4227 4228 4229 4230
            for arg, member in zip(self.args, self.type.scope.var_entries):
                code.putln("%s.%s = %s;" % (
                        self.result(),
                        member.cname,
                        arg.result()))
4231 4232
        else:
            raise InternalError("List type never specified")
4233

William Stein's avatar
William Stein committed
4234 4235 4236 4237 4238
    def generate_subexpr_disposal_code(self, code):
        # We call generate_post_assignment_code here instead
        # of generate_disposal_code, because values were stored
        # in the list using a reference-stealing operation.
        for arg in self.args:
4239 4240 4241
            arg.generate_post_assignment_code(code)
            # Should NOT call free_temps -- this is invoked by the default
            # generate_evaluation_code which will do that.
William Stein's avatar
William Stein committed
4242

Robert Bradshaw's avatar
Robert Bradshaw committed
4243

4244 4245 4246 4247 4248 4249 4250 4251 4252
class ScopedExprNode(ExprNode):
    # Abstract base class for ExprNodes that have their own local
    # scope, such as generator expressions.
    #
    # expr_scope    Scope  the inner scope of the expression

    subexprs = []
    expr_scope = None

4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271
    # does this node really have a local scope, e.g. does it leak loop
    # variables or not?  non-leaking Py3 behaviour is default, except
    # for list comprehensions where the behaviour differs in Py2 and
    # Py3 (set in Parsing.py based on parser context)
    has_local_scope = True

    def init_scope(self, outer_scope, expr_scope=None):
        if expr_scope is not None:
            self.expr_scope = expr_scope
        elif self.has_local_scope:
            self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
        else:
            self.expr_scope = None

    def analyse_declarations(self, env):
        self.init_scope(env)

    def analyse_scoped_declarations(self, env):
        # this is called with the expr_scope as env
4272 4273
        pass

4274 4275
    def analyse_types(self, env):
        # no recursion here, the children will be analysed separately below
4276 4277 4278 4279 4280 4281
        pass

    def analyse_scoped_expressions(self, env):
        # this is called with the expr_scope as env
        pass

4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301
    def generate_evaluation_code(self, code):
        # set up local variables and free their references on exit
        generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
        if not self.has_local_scope or not self.expr_scope.var_entries:
            # no local variables => delegate, done
            generate_inner_evaluation_code(code)
            return

        code.putln('{ /* enter inner scope */')
        py_entries = []
        for entry in self.expr_scope.var_entries:
            if not entry.in_closure:
                code.put_var_declaration(entry)
                if entry.type.is_pyobject and entry.used:
                    py_entries.append(entry)
        if not py_entries:
            # no local Python references => no cleanup required
            generate_inner_evaluation_code(code)
            code.putln('} /* exit inner scope */')
            return
4302 4303
        for entry in py_entries:
            code.put_init_var_to_py_none(entry)
4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330

        # must free all local Python references at each exit point
        old_loop_labels = tuple(code.new_loop_labels())
        old_error_label = code.new_error_label()

        generate_inner_evaluation_code(code)

        # normal (non-error) exit
        for entry in py_entries:
            code.put_var_decref(entry)

        # error/loop body exit points
        exit_scope = code.new_label('exit_scope')
        code.put_goto(exit_scope)
        for label, old_label in ([(code.error_label, old_error_label)] +
                                 list(zip(code.get_loop_labels(), old_loop_labels))):
            if code.label_used(label):
                code.put_label(label)
                for entry in py_entries:
                    code.put_var_decref(entry)
                code.put_goto(old_label)
        code.put_label(exit_scope)
        code.putln('} /* exit inner scope */')

        code.set_loop_labels(old_loop_labels)
        code.error_label = old_error_label

4331 4332

class ComprehensionNode(ScopedExprNode):
4333
    subexprs = ["target"]
4334 4335
    child_attrs = ["loop", "append"]

4336 4337
    def infer_type(self, env):
        return self.target.infer_type(env)
4338 4339 4340

    def analyse_declarations(self, env):
        self.append.target = self # this is used in the PyList_Append of the inner loop
4341 4342
        self.init_scope(env)

4343 4344
    def analyse_scoped_declarations(self, env):
        self.loop.analyse_declarations(env)
4345

4346 4347 4348
    def analyse_types(self, env):
        self.target.analyse_expressions(env)
        self.type = self.target.type
4349 4350
        if not self.has_local_scope:
            self.loop.analyse_expressions(env)
4351

4352 4353 4354
    def analyse_scoped_expressions(self, env):
        if self.has_local_scope:
            self.loop.analyse_expressions(env)
4355

4356 4357 4358
    def may_be_none(self):
        return False

4359 4360
    def calculate_result_code(self):
        return self.target.result()
4361

4362 4363
    def generate_result_code(self, code):
        self.generate_operation_code(code)
Robert Bradshaw's avatar
Robert Bradshaw committed
4364

4365 4366 4367
    def generate_operation_code(self, code):
        self.loop.generate_execution_code(code)

4368 4369
    def annotate(self, code):
        self.loop.annotate(code)
4370 4371


4372
class ComprehensionAppendNode(Node):
4373 4374
    # Need to be careful to avoid infinite recursion:
    # target must not be in child_attrs/subexprs
4375 4376

    child_attrs = ['expr']
4377 4378

    type = PyrexTypes.c_int_type
4379

4380 4381
    def analyse_expressions(self, env):
        self.expr.analyse_expressions(env)
4382
        if not self.expr.type.is_pyobject:
Robert Bradshaw's avatar
Robert Bradshaw committed
4383
            self.expr = self.expr.coerce_to_pyobject(env)
4384

4385
    def generate_execution_code(self, code):
4386 4387 4388 4389 4390 4391 4392
        if self.target.type is list_type:
            function = "PyList_Append"
        elif self.target.type is set_type:
            function = "PySet_Add"
        else:
            raise InternalError(
                "Invalid type for comprehension node: %s" % self.target.type)
4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407

        self.expr.generate_evaluation_code(code)
        code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
            function,
            self.target.result(),
            self.expr.result()
            ), self.pos))
        self.expr.generate_disposal_code(code)
        self.expr.free_temps(code)

    def generate_function_definitions(self, env, code):
        self.expr.generate_function_definitions(env, code)

    def annotate(self, code):
        self.expr.annotate(code)
4408 4409

class DictComprehensionAppendNode(ComprehensionAppendNode):
4410
    child_attrs = ['key_expr', 'value_expr']
4411

4412 4413
    def analyse_expressions(self, env):
        self.key_expr.analyse_expressions(env)
4414 4415
        if not self.key_expr.type.is_pyobject:
            self.key_expr = self.key_expr.coerce_to_pyobject(env)
4416
        self.value_expr.analyse_expressions(env)
4417 4418 4419
        if not self.value_expr.type.is_pyobject:
            self.value_expr = self.value_expr.coerce_to_pyobject(env)

4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439
    def generate_execution_code(self, code):
        self.key_expr.generate_evaluation_code(code)
        self.value_expr.generate_evaluation_code(code)
        code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
            self.target.result(),
            self.key_expr.result(),
            self.value_expr.result()
            ), self.pos))
        self.key_expr.generate_disposal_code(code)
        self.key_expr.free_temps(code)
        self.value_expr.generate_disposal_code(code)
        self.value_expr.free_temps(code)

    def generate_function_definitions(self, env, code):
        self.key_expr.generate_function_definitions(env, code)
        self.value_expr.generate_function_definitions(env, code)

    def annotate(self, code):
        self.key_expr.annotate(code)
        self.value_expr.annotate(code)
4440 4441


4442
class GeneratorExpressionNode(ScopedExprNode):
4443 4444 4445 4446
    # A generator expression, e.g.  (i for i in range(10))
    #
    # Result is a generator.
    #
4447 4448
    # loop      ForStatNode   the for-loop, containing a YieldExprNode

4449 4450 4451 4452
    child_attrs = ["loop"]

    type = py_object_type

4453 4454
    def analyse_scoped_declarations(self, env):
        self.loop.analyse_declarations(env)
4455

4456
    def analyse_types(self, env):
4457 4458
        if not self.has_local_scope:
            self.loop.analyse_expressions(env)
4459 4460 4461
        self.is_temp = True

    def analyse_scoped_expressions(self, env):
4462 4463
        if self.has_local_scope:
            self.loop.analyse_expressions(env)
4464 4465 4466 4467 4468 4469 4470 4471

    def may_be_none(self):
        return False

    def annotate(self, code):
        self.loop.annotate(code)


4472 4473
class InlinedGeneratorExpressionNode(GeneratorExpressionNode):
    # An inlined generator expression for which the result is
4474 4475 4476
    # calculated inside of the loop.  This will only be created by
    # transforms when replacing builtin calls on generator
    # expressions.
4477 4478 4479
    #
    # loop           ForStatNode      the for-loop, not containing any YieldExprNodes
    # result_node    ResultRefNode    the reference to the result value temp
4480
    # orig_func      String           the name of the builtin function this node replaces
4481 4482

    child_attrs = ["loop"]
4483 4484 4485 4486
    loop_analysed = False

    def infer_type(self, env):
        return self.result_node.infer_type(env)
4487 4488

    def analyse_types(self, env):
4489 4490 4491
        if not self.has_local_scope:
            self.loop_analysed = True
            self.loop.analyse_expressions(env)
4492 4493 4494
        self.type = self.result_node.type
        self.is_temp = True

4495 4496 4497 4498
    def analyse_scoped_expressions(self, env):
        self.loop_analysed = True
        GeneratorExpressionNode.analyse_scoped_expressions(self, env)

4499
    def coerce_to(self, dst_type, env):
4500 4501 4502 4503 4504 4505
        if self.orig_func == 'sum' and dst_type.is_numeric and not self.loop_analysed:
            # We can optimise by dropping the aggregation variable and
            # the add operations into C.  This can only be done safely
            # before analysing the loop body, after that, the result
            # reference type will have infected expressions and
            # assignments.
4506 4507 4508 4509
            self.result_node.type = self.type = dst_type
            return self
        return GeneratorExpressionNode.coerce_to(self, dst_type, env)

4510 4511 4512 4513 4514
    def generate_result_code(self, code):
        self.result_node.result_code = self.result()
        self.loop.generate_execution_code(code)


4515
class SetNode(ExprNode):
4516 4517
    #  Set constructor.

4518 4519
    type = set_type

4520 4521 4522
    subexprs = ['args']

    gil_message = "Constructing Python set"
4523

4524 4525 4526 4527 4528 4529 4530 4531
    def analyse_types(self, env):
        for i in range(len(self.args)):
            arg = self.args[i]
            arg.analyse_types(env)
            self.args[i] = arg.coerce_to_pyobject(env)
        self.type = set_type
        self.is_temp = 1

4532 4533 4534
    def may_be_none(self):
        return False

4535 4536 4537 4538
    def calculate_constant_result(self):
        self.constant_result = set([
                arg.constant_result for arg in self.args])

4539 4540 4541 4542 4543 4544 4545 4546
    def compile_time_value(self, denv):
        values = [arg.compile_time_value(denv) for arg in self.args]
        try:
            return set(values)
        except Exception, e:
            self.compile_time_value_error(e)

    def generate_evaluation_code(self, code):
4547
        code.globalstate.use_utility_code(Builtin.py23_set_utility_code)
4548 4549 4550 4551 4552
        self.allocate_temp_result(code)
        code.putln(
            "%s = PySet_New(0); %s" % (
                self.result(),
                code.error_goto_if_null(self.result(), self.pos)))
4553
        code.put_gotref(self.py_result())
4554 4555 4556 4557 4558 4559 4560 4561
        for arg in self.args:
            arg.generate_evaluation_code(code)
            code.putln(
                code.error_goto_if_neg(
                    "PySet_Add(%s, %s)" % (self.result(), arg.py_result()),
                    self.pos))
            arg.generate_disposal_code(code)
            arg.free_temps(code)
Robert Bradshaw's avatar
Robert Bradshaw committed
4562

William Stein's avatar
William Stein committed
4563

4564
class DictNode(ExprNode):
William Stein's avatar
William Stein committed
4565 4566
    #  Dictionary constructor.
    #
4567
    #  key_value_pairs  [DictItemNode]
4568 4569
    #
    # obj_conversion_errors    [PyrexError]   used internally
4570

4571
    subexprs = ['key_value_pairs']
4572 4573
    is_temp = 1
    type = dict_type
4574

4575
    obj_conversion_errors = []
4576 4577 4578 4579

    def calculate_constant_result(self):
        self.constant_result = dict([
                item.constant_result for item in self.key_value_pairs])
4580

4581
    def compile_time_value(self, denv):
Robert Bradshaw's avatar
Robert Bradshaw committed
4582 4583
        pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
            for item in self.key_value_pairs]
4584 4585 4586 4587
        try:
            return dict(pairs)
        except Exception, e:
            self.compile_time_value_error(e)
4588

Robert Bradshaw's avatar
Robert Bradshaw committed
4589
    def type_dependencies(self, env):
4590
        return ()
4591

4592 4593 4594 4595
    def infer_type(self, env):
        # TOOD: Infer struct constructors.
        return dict_type

William Stein's avatar
William Stein committed
4596
    def analyse_types(self, env):
4597
        hold_errors()
Robert Bradshaw's avatar
Robert Bradshaw committed
4598 4599
        for item in self.key_value_pairs:
            item.analyse_types(env)
4600 4601
        self.obj_conversion_errors = held_errors()
        release_errors(ignore=True)
4602 4603 4604

    def may_be_none(self):
        return False
4605

4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619
    def coerce_to(self, dst_type, env):
        if dst_type.is_pyobject:
            self.release_errors()
            if not self.type.subtype_of(dst_type):
                error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
        elif dst_type.is_struct_or_union:
            self.type = dst_type
            if not dst_type.is_struct and len(self.key_value_pairs) != 1:
                error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
            elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
                warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
            for item in self.key_value_pairs:
                if isinstance(item.key, CoerceToPyTypeNode):
                    item.key = item.key.arg
4620
                if not isinstance(item.key, (UnicodeNode, StringNode, BytesNode)):
4621
                    error(item.key.pos, "Invalid struct field identifier")
4622
                    item.key = StringNode(item.key.pos, value="<error>")
4623
                else:
Stefan Behnel's avatar
Stefan Behnel committed
4624 4625
                    key = str(item.key.value) # converts string literals to unicode in Py3
                    member = dst_type.scope.lookup_here(key)
4626
                    if not member:
Stefan Behnel's avatar
Stefan Behnel committed
4627
                        error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
4628 4629 4630 4631 4632 4633 4634 4635 4636
                    else:
                        value = item.value
                        if isinstance(value, CoerceToPyTypeNode):
                            value = value.arg
                        item.value = value.coerce_to(member.type, env)
        else:
            self.type = error_type
            error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
        return self
4637

4638 4639 4640 4641
    def release_errors(self):
        for err in self.obj_conversion_errors:
            report_error(err)
        self.obj_conversion_errors = []
4642 4643 4644

    gil_message = "Constructing Python dict"

William Stein's avatar
William Stein committed
4645 4646 4647
    def generate_evaluation_code(self, code):
        #  Custom method used here because key-value
        #  pairs are evaluated and used one at a time.
4648 4649
        code.mark_pos(self.pos)
        self.allocate_temp_result(code)
4650 4651 4652 4653 4654 4655
        if self.type.is_pyobject:
            self.release_errors()
            code.putln(
                "%s = PyDict_New(); %s" % (
                    self.result(),
                    code.error_goto_if_null(self.result(), self.pos)))
4656
            code.put_gotref(self.py_result())
Robert Bradshaw's avatar
Robert Bradshaw committed
4657 4658
        for item in self.key_value_pairs:
            item.generate_evaluation_code(code)
4659
            if self.type.is_pyobject:
4660
                code.put_error_if_neg(self.pos,
4661 4662 4663 4664 4665 4666 4667
                    "PyDict_SetItem(%s, %s, %s)" % (
                        self.result(),
                        item.key.py_result(),
                        item.value.py_result()))
            else:
                code.putln("%s.%s = %s;" % (
                        self.result(),
4668
                        item.key.value,
4669
                        item.value.result()))
Robert Bradshaw's avatar
Robert Bradshaw committed
4670
            item.generate_disposal_code(code)
4671
            item.free_temps(code)
4672

4673
    def annotate(self, code):
Robert Bradshaw's avatar
Robert Bradshaw committed
4674 4675
        for item in self.key_value_pairs:
            item.annotate(code)
4676

4677
class DictItemNode(ExprNode):
Robert Bradshaw's avatar
Robert Bradshaw committed
4678 4679 4680 4681 4682
    # Represents a single item in a DictNode
    #
    # key          ExprNode
    # value        ExprNode
    subexprs = ['key', 'value']
4683

4684
    nogil_check = None # Parent DictNode takes care of it
4685

4686 4687 4688
    def calculate_constant_result(self):
        self.constant_result = (
            self.key.constant_result, self.value.constant_result)
4689

Robert Bradshaw's avatar
Robert Bradshaw committed
4690 4691 4692 4693 4694
    def analyse_types(self, env):
        self.key.analyse_types(env)
        self.value.analyse_types(env)
        self.key = self.key.coerce_to_pyobject(env)
        self.value = self.value.coerce_to_pyobject(env)
4695

Robert Bradshaw's avatar
Robert Bradshaw committed
4696 4697 4698
    def generate_evaluation_code(self, code):
        self.key.generate_evaluation_code(code)
        self.value.generate_evaluation_code(code)
Stefan Behnel's avatar
Stefan Behnel committed
4699

4700 4701 4702
    def generate_disposal_code(self, code):
        self.key.generate_disposal_code(code)
        self.value.generate_disposal_code(code)
4703 4704 4705 4706

    def free_temps(self, code):
        self.key.free_temps(code)
        self.value.free_temps(code)
4707

4708 4709
    def __iter__(self):
        return iter([self.key, self.value])
William Stein's avatar
William Stein committed
4710

4711 4712 4713 4714 4715 4716 4717
class ModuleNameMixin(object):
    def set_mod_name(self, env):
        self.module_name = env.global_scope().qualified_name

    def get_py_mod_name(self, code):
        return code.get_py_string_const(
                 self.module_name, identifier=True)
Stefan Behnel's avatar
Stefan Behnel committed
4718

4719
class ClassNode(ExprNode, ModuleNameMixin):
William Stein's avatar
William Stein committed
4720 4721 4722 4723
    #  Helper class used in the implementation of Python
    #  class definitions. Constructs a class object given
    #  a name, tuple of bases and class dictionary.
    #
Stefan Behnel's avatar
Stefan Behnel committed
4724
    #  name         EncodedString      Name of the class
William Stein's avatar
William Stein committed
4725 4726 4727
    #  bases        ExprNode           Base class tuple
    #  dict         ExprNode           Class dict (not owned by this node)
    #  doc          ExprNode or None   Doc string
4728
    #  module_name  EncodedString      Name of defining module
4729

4730
    subexprs = ['bases', 'doc']
4731

William Stein's avatar
William Stein committed
4732 4733 4734 4735 4736 4737 4738 4739
    def analyse_types(self, env):
        self.bases.analyse_types(env)
        if self.doc:
            self.doc.analyse_types(env)
            self.doc = self.doc.coerce_to_pyobject(env)
        self.type = py_object_type
        self.is_temp = 1
        env.use_utility_code(create_class_utility_code);
4740 4741
        #TODO(craig,haoyu) This should be moved to a better place
        self.set_mod_name(env)
4742

4743
    def may_be_none(self):
Stefan Behnel's avatar
Stefan Behnel committed
4744
        return True
4745

4746 4747
    gil_message = "Constructing Python class"

William Stein's avatar
William Stein committed
4748
    def generate_result_code(self, code):
4749
        cname = code.intern_identifier(self.name)
4750

William Stein's avatar
William Stein committed
4751
        if self.doc:
4752
            code.put_error_if_neg(self.pos,
Robert Bradshaw's avatar
Robert Bradshaw committed
4753
                'PyDict_SetItemString(%s, "__doc__", %s)' % (
William Stein's avatar
William Stein committed
4754
                    self.dict.py_result(),
Robert Bradshaw's avatar
Robert Bradshaw committed
4755
                    self.doc.py_result()))
4756
        py_mod_name = self.get_py_mod_name(code)
William Stein's avatar
William Stein committed
4757
        code.putln(
4758
            '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % (
4759
                self.result(),
William Stein's avatar
William Stein committed
4760 4761
                self.bases.py_result(),
                self.dict.py_result(),
4762
                cname,
4763
                py_mod_name,
4764
                code.error_goto_if_null(self.result(), self.pos)))
4765
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
4766

Stefan Behnel's avatar
Stefan Behnel committed
4767

4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785
class Py3ClassNode(ExprNode):
    #  Helper class used in the implementation of Python3+
    #  class definitions. Constructs a class object given
    #  a name, tuple of bases and class dictionary.
    #
    #  name         EncodedString      Name of the class
    #  dict         ExprNode           Class dict (not owned by this node)
    #  module_name  EncodedString      Name of defining module

    subexprs = []

    def analyse_types(self, env):
        self.type = py_object_type
        self.is_temp = 1

    def may_be_none(self):
        return True

4786
    gil_message = "Constructing Python class"
4787 4788

    def generate_result_code(self, code):
4789
        code.globalstate.use_utility_code(create_py3class_utility_code)
4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837
        cname = code.intern_identifier(self.name)
        code.putln(
            '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s); %s' % (
                self.result(),
                self.metaclass.result(),
                cname,
                self.bases.py_result(),
                self.dict.py_result(),
                self.mkw.py_result(),
                code.error_goto_if_null(self.result(), self.pos)))
        code.put_gotref(self.py_result())

class KeywordArgsNode(ExprNode):
    # Helper class for keyword arguments
    #
    # keyword_args ExprNode or None     Keyword arguments
    # starstar_arg ExprNode or None     Extra arguments

    subexprs = ['keyword_args', 'starstar_arg']

    def analyse_types(self, env):
        if self.keyword_args:
            self.keyword_args.analyse_types(env)
        if self.starstar_arg:
            self.starstar_arg.analyse_types(env)
            # make sure we have a Python object as **kwargs mapping
            self.starstar_arg = \
                self.starstar_arg.coerce_to_pyobject(env)
        self.type = py_object_type
        self.is_temp = 1

    gil_message = "Constructing Keyword Args"

    def generate_result_code(self, code):
        if self.keyword_args and self.starstar_arg:
            code.put_error_if_neg(self.pos,
                "PyDict_Update(%s, %s)" % (
                    self.keyword_args.py_result(),
                    self.starstar_arg.py_result()))
        if self.keyword_args:
            code.putln("%s = %s;" % (self.result(), self.keyword_args.result()))
            code.put_incref(self.keyword_args.result(), self.keyword_args.ctype())
        elif self.starstar_arg:
            code.putln(
                "%s = PyDict_Copy(%s); %s" % (
                    self.result(),
                    self.starstar_arg.py_result(),
                    code.error_goto_if_null(self.result(), self.pos)))
4838
            code.put_gotref(self.py_result())
4839 4840 4841 4842 4843
        else:
            code.putln(
                "%s = PyDict_New(); %s" % (
                    self.result(),
                    code.error_goto_if_null(self.result(), self.pos)))
4844
            code.put_gotref(self.py_result())
4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912

class PyClassMetaclassNode(ExprNode):
    # Helper class holds Python3 metaclass object
    #
    #  bases        ExprNode           Base class tuple (not owned by this node)
    #  mkw          ExprNode           Class keyword arguments (not owned by this node)

    subexprs = []

    def analyse_types(self, env):
        self.type = py_object_type
        self.is_temp = True

    def may_be_none(self):
        return True

    def generate_result_code(self, code):
        code.putln(
            "%s = __Pyx_Py3MetaclassGet(%s, %s); %s" % (
                self.result(),
                self.bases.result(),
                self.mkw.result(),
                code.error_goto_if_null(self.result(), self.pos)))
        code.put_gotref(self.py_result())

class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
    # Helper class holds Python3 namespace object
    #
    # All this are not owned by this node
    #  metaclass    ExprNode           Metaclass object
    #  bases        ExprNode           Base class tuple
    #  mkw          ExprNode           Class keyword arguments
    #  doc          ExprNode or None   Doc string (owned)

    subexprs = ['doc']

    def analyse_types(self, env):
        self.bases.analyse_types(env)
        if self.doc:
            self.doc.analyse_types(env)
            self.doc = self.doc.coerce_to_pyobject(env)
        self.type = py_object_type
        self.is_temp = 1
        #TODO(craig,haoyu) This should be moved to a better place
        self.set_mod_name(env)

    def may_be_none(self):
        return True

    def generate_result_code(self, code):
        cname = code.intern_identifier(self.name)
        py_mod_name = self.get_py_mod_name(code)
        if self.doc:
            doc_code = self.doc.result()
        else:
            doc_code = '(PyObject *) NULL'
        code.putln(
            "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s); %s" % (
                self.result(),
                self.metaclass.result(),
                self.bases.result(),
                cname,
                self.mkw.result(),
                py_mod_name,
                doc_code,
                code.error_goto_if_null(self.result(), self.pos)))
        code.put_gotref(self.py_result())

Robert Bradshaw's avatar
Robert Bradshaw committed
4913 4914 4915 4916 4917 4918 4919
class BoundMethodNode(ExprNode):
    #  Helper class used in the implementation of Python
    #  class definitions. Constructs an bound method
    #  object from a class and a function.
    #
    #  function      ExprNode   Function object
    #  self_object   ExprNode   self object
4920

Robert Bradshaw's avatar
Robert Bradshaw committed
4921
    subexprs = ['function']
4922

Robert Bradshaw's avatar
Robert Bradshaw committed
4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938
    def analyse_types(self, env):
        self.function.analyse_types(env)
        self.type = py_object_type
        self.is_temp = 1

    gil_message = "Constructing an bound method"

    def generate_result_code(self, code):
        code.putln(
            "%s = PyMethod_New(%s, %s, (PyObject*)%s->ob_type); %s" % (
                self.result(),
                self.function.py_result(),
                self.self_object.py_result(),
                self.self_object.py_result(),
                code.error_goto_if_null(self.result(), self.pos)))
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
4939

4940
class UnboundMethodNode(ExprNode):
William Stein's avatar
William Stein committed
4941 4942 4943 4944 4945
    #  Helper class used in the implementation of Python
    #  class definitions. Constructs an unbound method
    #  object from a class and a function.
    #
    #  function      ExprNode   Function object
4946

4947 4948
    type = py_object_type
    is_temp = 1
4949

William Stein's avatar
William Stein committed
4950
    subexprs = ['function']
4951

William Stein's avatar
William Stein committed
4952 4953
    def analyse_types(self, env):
        self.function.analyse_types(env)
4954

4955 4956 4957
    def may_be_none(self):
        return False

4958 4959
    gil_message = "Constructing an unbound method"

William Stein's avatar
William Stein committed
4960
    def generate_result_code(self, code):
4961
        class_cname = code.pyclass_stack[-1].classobj.result()
William Stein's avatar
William Stein committed
4962
        code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
4963
            "%s = PyMethod_New(%s, 0, %s); %s" % (
4964
                self.result(),
William Stein's avatar
William Stein committed
4965
                self.function.py_result(),
4966
                class_cname,
4967
                code.error_goto_if_null(self.result(), self.pos)))
4968
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
4969

Robert Bradshaw's avatar
Robert Bradshaw committed
4970

4971
class PyCFunctionNode(ExprNode, ModuleNameMixin):
William Stein's avatar
William Stein committed
4972 4973 4974 4975
    #  Helper class used in the implementation of Python
    #  class definitions. Constructs a PyCFunction object
    #  from a PyMethodDef struct.
    #
4976
    #  pymethdef_cname   string             PyMethodDef structure
Robert Bradshaw's avatar
Robert Bradshaw committed
4977
    #  self_object       ExprNode or None
Robert Bradshaw's avatar
Robert Bradshaw committed
4978
    #  binding           bool
4979
    #  module_name       EncodedString      Name of defining module
Stefan Behnel's avatar
Stefan Behnel committed
4980 4981

    subexprs = []
Robert Bradshaw's avatar
Robert Bradshaw committed
4982
    self_object = None
Robert Bradshaw's avatar
Robert Bradshaw committed
4983
    binding = False
4984

4985 4986
    type = py_object_type
    is_temp = 1
4987

William Stein's avatar
William Stein committed
4988
    def analyse_types(self, env):
Robert Bradshaw's avatar
Robert Bradshaw committed
4989 4990
        if self.binding:
            env.use_utility_code(binding_cfunc_utility_code)
4991

4992 4993 4994
        #TODO(craig,haoyu) This should be moved to a better place
        self.set_mod_name(env)

4995 4996
    def may_be_none(self):
        return False
4997

4998 4999
    gil_message = "Constructing Python function"

Stefan Behnel's avatar
Stefan Behnel committed
5000
    def self_result_code(self):
Robert Bradshaw's avatar
Robert Bradshaw committed
5001 5002 5003 5004
        if self.self_object is None:
            self_result = "NULL"
        else:
            self_result = self.self_object.py_result()
Stefan Behnel's avatar
Stefan Behnel committed
5005 5006 5007
        return self_result

    def generate_result_code(self, code):
Robert Bradshaw's avatar
Robert Bradshaw committed
5008
        if self.binding:
5009
            constructor = "%s_NewEx" % Naming.binding_cfunc
Robert Bradshaw's avatar
Robert Bradshaw committed
5010
        else:
5011 5012
            constructor = "PyCFunction_NewEx"
        py_mod_name = self.get_py_mod_name(code)
William Stein's avatar
William Stein committed
5013
        code.putln(
5014
            '%s = %s(&%s, %s, %s); %s' % (
5015
                self.result(),
Robert Bradshaw's avatar
Robert Bradshaw committed
5016
                constructor,
William Stein's avatar
William Stein committed
5017
                self.pymethdef_cname,
Stefan Behnel's avatar
Stefan Behnel committed
5018
                self.self_result_code(),
5019
                py_mod_name,
5020
                code.error_goto_if_null(self.result(), self.pos)))
5021
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
5022

Stefan Behnel's avatar
Stefan Behnel committed
5023 5024 5025
class InnerFunctionNode(PyCFunctionNode):
    # Special PyCFunctionNode that depends on a closure class
    #
Vitja Makarov's avatar
Vitja Makarov committed
5026

Robert Bradshaw's avatar
Robert Bradshaw committed
5027
    binding = True
Vitja Makarov's avatar
Vitja Makarov committed
5028 5029
    needs_self_code = True

Stefan Behnel's avatar
Stefan Behnel committed
5030
    def self_result_code(self):
Vitja Makarov's avatar
Vitja Makarov committed
5031 5032 5033
        if self.needs_self_code:
            return "((PyObject*)%s)" % (Naming.cur_scope_cname)
        return "NULL"
Stefan Behnel's avatar
Stefan Behnel committed
5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054

class LambdaNode(InnerFunctionNode):
    # Lambda expression node (only used as a function reference)
    #
    # args          [CArgDeclNode]         formal arguments
    # star_arg      PyArgDeclNode or None  * argument
    # starstar_arg  PyArgDeclNode or None  ** argument
    # lambda_name   string                 a module-globally unique lambda name
    # result_expr   ExprNode
    # def_node      DefNode                the underlying function 'def' node

    child_attrs = ['def_node']

    def_node = None
    name = StringEncoding.EncodedString('<lambda>')

    def analyse_declarations(self, env):
        self.def_node.analyse_declarations(env)
        self.pymethdef_cname = self.def_node.entry.pymethdef_cname
        env.add_lambda_def(self.def_node)

5055 5056 5057 5058 5059 5060
class YieldExprNode(ExprNode):
    # Yield expression node
    #
    # arg         ExprNode   the value to return from the generator
    # label_name  string     name of the C label used for this yield

5061
    subexprs = ['arg']
5062 5063 5064 5065 5066 5067 5068 5069
    type = py_object_type

    def analyse_types(self, env):
        self.is_temp = 1
        if self.arg is not None:
            self.arg.analyse_types(env)
            if not self.arg.type.is_pyobject:
                self.arg = self.arg.coerce_to_pyobject(env)
5070
        error(self.pos, "Generators are not supported")
5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081

    def generate_result_code(self, code):
        self.label_name = code.new_label('resume_from_yield')
        code.use_label(self.label_name)
        code.putln("/* FIXME: save temporary variables */")
        code.putln("/* FIXME: return from function, yielding value */")
        code.put_label(self.label_name)
        code.putln("/* FIXME: restore temporary variables and  */")
        code.putln("/* FIXME: extract sent value from closure */")


William Stein's avatar
William Stein committed
5082 5083 5084 5085 5086 5087
#-------------------------------------------------------------------
#
#  Unary operator nodes
#
#-------------------------------------------------------------------

5088 5089 5090 5091 5092 5093 5094
compile_time_unary_operators = {
    'not': operator.not_,
    '~': operator.inv,
    '-': operator.neg,
    '+': operator.pos,
}

5095
class UnopNode(ExprNode):
William Stein's avatar
William Stein committed
5096 5097 5098 5099 5100 5101 5102 5103 5104 5105
    #  operator     string
    #  operand      ExprNode
    #
    #  Processing during analyse_expressions phase:
    #
    #    analyse_c_operation
    #      Called when the operand is not a pyobject.
    #      - Check operand type and coerce if needed.
    #      - Determine result type and result code fragment.
    #      - Allocate temporary for result if needed.
5106

William Stein's avatar
William Stein committed
5107
    subexprs = ['operand']
Robert Bradshaw's avatar
Robert Bradshaw committed
5108
    infix = True
5109 5110 5111 5112

    def calculate_constant_result(self):
        func = compile_time_unary_operators[self.operator]
        self.constant_result = func(self.operand.constant_result)
5113

5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124
    def compile_time_value(self, denv):
        func = compile_time_unary_operators.get(self.operator)
        if not func:
            error(self.pos,
                "Unary '%s' not supported in compile-time expression"
                    % self.operator)
        operand = self.operand.compile_time_value(denv)
        try:
            return func(operand)
        except Exception, e:
            self.compile_time_value_error(e)
5125

5126
    def infer_type(self, env):
5127 5128 5129 5130 5131
        operand_type = self.operand.infer_type(env)
        if operand_type.is_pyobject:
            return py_object_type
        else:
            return operand_type
5132

William Stein's avatar
William Stein committed
5133 5134 5135 5136 5137 5138
    def analyse_types(self, env):
        self.operand.analyse_types(env)
        if self.is_py_operation():
            self.coerce_operand_to_pyobject(env)
            self.type = py_object_type
            self.is_temp = 1
5139 5140
        elif self.is_cpp_operation():
            self.analyse_cpp_operation(env)
William Stein's avatar
William Stein committed
5141 5142
        else:
            self.analyse_c_operation(env)
5143

William Stein's avatar
William Stein committed
5144
    def check_const(self):
5145
        return self.operand.check_const()
5146

William Stein's avatar
William Stein committed
5147 5148
    def is_py_operation(self):
        return self.operand.type.is_pyobject
5149

5150
    def nogil_check(self, env):
5151
        if self.is_py_operation():
5152
            self.gil_error()
5153

Danilo Freitas's avatar
Danilo Freitas committed
5154
    def is_cpp_operation(self):
Robert Bradshaw's avatar
Robert Bradshaw committed
5155
        type = self.operand.type
Robert Bradshaw's avatar
Robert Bradshaw committed
5156
        return type.is_cpp_class
5157

William Stein's avatar
William Stein committed
5158 5159
    def coerce_operand_to_pyobject(self, env):
        self.operand = self.operand.coerce_to_pyobject(env)
5160

William Stein's avatar
William Stein committed
5161 5162 5163
    def generate_result_code(self, code):
        if self.operand.type.is_pyobject:
            self.generate_py_operation_code(code)
5164

William Stein's avatar
William Stein committed
5165 5166 5167
    def generate_py_operation_code(self, code):
        function = self.py_operation_function()
        code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
5168
            "%s = %s(%s); %s" % (
5169 5170
                self.result(),
                function,
William Stein's avatar
William Stein committed
5171
                self.operand.py_result(),
5172
                code.error_goto_if_null(self.result(), self.pos)))
5173
        code.put_gotref(self.py_result())
5174

William Stein's avatar
William Stein committed
5175 5176 5177 5178 5179 5180
    def type_error(self):
        if not self.operand.type.is_error:
            error(self.pos, "Invalid operand type for '%s' (%s)" %
                (self.operator, self.operand.type))
        self.type = PyrexTypes.error_type

Danilo Freitas's avatar
Danilo Freitas committed
5181
    def analyse_cpp_operation(self, env):
5182
        type = self.operand.type
Robert Bradshaw's avatar
Robert Bradshaw committed
5183
        if type.is_ptr:
Danilo Freitas's avatar
Danilo Freitas committed
5184
            type = type.base_type
Robert Bradshaw's avatar
Robert Bradshaw committed
5185
        function = type.scope.lookup("operator%s" % self.operator)
Danilo Freitas's avatar
Danilo Freitas committed
5186 5187
        if not function:
            error(self.pos, "'%s' operator not defined for %s"
5188
                % (self.operator, type))
Danilo Freitas's avatar
Danilo Freitas committed
5189 5190
            self.type_error()
            return
5191 5192 5193 5194
        func_type = function.type
        if func_type.is_ptr:
            func_type = func_type.base_type
        self.type = func_type.return_type
Danilo Freitas's avatar
Danilo Freitas committed
5195

William Stein's avatar
William Stein committed
5196

5197
class NotNode(ExprNode):
William Stein's avatar
William Stein committed
5198 5199 5200
    #  'not' operator
    #
    #  operand   ExprNode
5201

5202
    type = PyrexTypes.c_bint_type
5203

5204
    subexprs = ['operand']
5205

5206 5207 5208
    def calculate_constant_result(self):
        self.constant_result = not self.operand.constant_result

5209 5210 5211 5212 5213 5214 5215
    def compile_time_value(self, denv):
        operand = self.operand.compile_time_value(denv)
        try:
            return not operand
        except Exception, e:
            self.compile_time_value_error(e)

5216 5217
    def infer_type(self, env):
        return PyrexTypes.c_bint_type
5218

William Stein's avatar
William Stein committed
5219 5220 5221
    def analyse_types(self, env):
        self.operand.analyse_types(env)
        self.operand = self.operand.coerce_to_boolean(env)
5222

William Stein's avatar
William Stein committed
5223
    def calculate_result_code(self):
5224
        return "(!%s)" % self.operand.result()
5225

William Stein's avatar
William Stein committed
5226 5227 5228 5229 5230 5231
    def generate_result_code(self, code):
        pass


class UnaryPlusNode(UnopNode):
    #  unary '+' operator
5232

William Stein's avatar
William Stein committed
5233
    operator = '+'
5234

William Stein's avatar
William Stein committed
5235 5236
    def analyse_c_operation(self, env):
        self.type = self.operand.type
5237

William Stein's avatar
William Stein committed
5238 5239
    def py_operation_function(self):
        return "PyNumber_Positive"
5240

William Stein's avatar
William Stein committed
5241
    def calculate_result_code(self):
5242 5243 5244 5245
        if self.is_cpp_operation():
            return "(+%s)" % self.operand.result()
        else:
            return self.operand.result()
William Stein's avatar
William Stein committed
5246 5247 5248 5249


class UnaryMinusNode(UnopNode):
    #  unary '-' operator
5250

William Stein's avatar
William Stein committed
5251
    operator = '-'
5252

William Stein's avatar
William Stein committed
5253 5254 5255 5256 5257
    def analyse_c_operation(self, env):
        if self.operand.type.is_numeric:
            self.type = self.operand.type
        else:
            self.type_error()
Robert Bradshaw's avatar
Robert Bradshaw committed
5258
        if self.type.is_complex:
5259
            self.infix = False
5260

William Stein's avatar
William Stein committed
5261 5262
    def py_operation_function(self):
        return "PyNumber_Negative"
5263

William Stein's avatar
William Stein committed
5264
    def calculate_result_code(self):
Robert Bradshaw's avatar
Robert Bradshaw committed
5265 5266 5267 5268
        if self.infix:
            return "(-%s)" % self.operand.result()
        else:
            return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
William Stein's avatar
William Stein committed
5269

5270 5271 5272 5273 5274
    def get_constant_c_result_code(self):
        value = self.operand.get_constant_c_result_code()
        if value:
            return "(-%s)" % (value)

William Stein's avatar
William Stein committed
5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285
class TildeNode(UnopNode):
    #  unary '~' operator

    def analyse_c_operation(self, env):
        if self.operand.type.is_int:
            self.type = self.operand.type
        else:
            self.type_error()

    def py_operation_function(self):
        return "PyNumber_Invert"
5286

William Stein's avatar
William Stein committed
5287
    def calculate_result_code(self):
5288
        return "(~%s)" % self.operand.result()
William Stein's avatar
William Stein committed
5289 5290


5291 5292
class CUnopNode(UnopNode):

Robert Bradshaw's avatar
Robert Bradshaw committed
5293 5294 5295
    def is_py_operation(self):
        return False

5296 5297
class DereferenceNode(CUnopNode):
    #  unary * operator
5298 5299

    operator = '*'
5300

Robert Bradshaw's avatar
Robert Bradshaw committed
5301 5302 5303 5304 5305 5306 5307 5308
    def analyse_c_operation(self, env):
        if self.operand.type.is_ptr:
            self.type = self.operand.type.base_type
        else:
            self.type_error()

    def calculate_result_code(self):
        return "(*%s)" % self.operand.result()
William Stein's avatar
William Stein committed
5309 5310


5311 5312
class DecrementIncrementNode(CUnopNode):
    #  unary ++/-- operator
5313

5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329
    def analyse_c_operation(self, env):
        if self.operand.type.is_ptr or self.operand.type.is_numeric:
            self.type = self.operand.type
        else:
            self.type_error()

    def calculate_result_code(self):
        if self.is_prefix:
            return "(%s%s)" % (self.operator, self.operand.result())
        else:
            return "(%s%s)" % (self.operand.result(), self.operator)

def inc_dec_constructor(is_prefix, operator):
    return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)


5330
class AmpersandNode(ExprNode):
William Stein's avatar
William Stein committed
5331 5332 5333
    #  The C address-of operator.
    #
    #  operand  ExprNode
5334

William Stein's avatar
William Stein committed
5335
    subexprs = ['operand']
5336

5337 5338
    def infer_type(self, env):
        return PyrexTypes.c_ptr_type(self.operand.infer_type(env))
William Stein's avatar
William Stein committed
5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349

    def analyse_types(self, env):
        self.operand.analyse_types(env)
        argtype = self.operand.type
        if not (argtype.is_cfunction or self.operand.is_lvalue()):
            self.error("Taking address of non-lvalue")
            return
        if argtype.is_pyobject:
            self.error("Cannot take address of Python variable")
            return
        self.type = PyrexTypes.c_ptr_type(argtype)
5350

William Stein's avatar
William Stein committed
5351
    def check_const(self):
5352
        return self.operand.check_const_addr()
5353

William Stein's avatar
William Stein committed
5354 5355 5356 5357
    def error(self, mess):
        error(self.pos, mess)
        self.type = PyrexTypes.error_type
        self.result_code = "<error>"
5358

William Stein's avatar
William Stein committed
5359
    def calculate_result_code(self):
5360
        return "(&%s)" % self.operand.result()
William Stein's avatar
William Stein committed
5361 5362 5363

    def generate_result_code(self, code):
        pass
5364

William Stein's avatar
William Stein committed
5365 5366 5367 5368 5369 5370 5371 5372

unop_node_classes = {
    "+":  UnaryPlusNode,
    "-":  UnaryMinusNode,
    "~":  TildeNode,
}

def unop_node(pos, operator, operand):
5373
    # Construct unnop node of appropriate class for
William Stein's avatar
William Stein committed
5374
    # given operator.
5375
    if isinstance(operand, IntNode) and operator == '-':
5376
        return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)))
Robert Bradshaw's avatar
Robert Bradshaw committed
5377 5378
    elif isinstance(operand, UnopNode) and operand.operator == operator:
        warning(pos, "Python has no increment/decrement operator: %s%sx = %s(%sx) = x" % ((operator,)*4), 5)
5379 5380
    return unop_node_classes[operator](pos,
        operator = operator,
William Stein's avatar
William Stein committed
5381 5382 5383
        operand = operand)


5384
class TypecastNode(ExprNode):
William Stein's avatar
William Stein committed
5385 5386
    #  C type cast
    #
5387
    #  operand      ExprNode
William Stein's avatar
William Stein committed
5388 5389
    #  base_type    CBaseTypeNode
    #  declarator   CDeclaratorNode
5390 5391 5392
    #
    #  If used from a transform, one can if wanted specify the attribute
    #  "type" directly and leave base_type and declarator to None
5393

William Stein's avatar
William Stein committed
5394
    subexprs = ['operand']
5395
    base_type = declarator = type = None
5396

Robert Bradshaw's avatar
Robert Bradshaw committed
5397
    def type_dependencies(self, env):
5398
        return ()
5399

Robert Bradshaw's avatar
Robert Bradshaw committed
5400
    def infer_type(self, env):
5401 5402 5403 5404
        if self.type is None:
            base_type = self.base_type.analyse(env)
            _, self.type = self.declarator.analyse(base_type, env)
        return self.type
5405

William Stein's avatar
William Stein committed
5406
    def analyse_types(self, env):
5407 5408 5409
        if self.type is None:
            base_type = self.base_type.analyse(env)
            _, self.type = self.declarator.analyse(base_type, env)
5410 5411 5412 5413
        if self.type.is_cfunction:
            error(self.pos,
                "Cannot cast to a function type")
            self.type = PyrexTypes.error_type
William Stein's avatar
William Stein committed
5414 5415 5416
        self.operand.analyse_types(env)
        to_py = self.type.is_pyobject
        from_py = self.operand.type.is_pyobject
5417 5418
        if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
            error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
William Stein's avatar
William Stein committed
5419
        if to_py and not from_py:
5420 5421 5422 5423 5424 5425
            if self.type is bytes_type and self.operand.type.is_int:
                # FIXME: the type cast node isn't needed in this case
                # and can be dropped once analyse_types() can return a
                # different node
                self.operand = CoerceIntToBytesNode(self.operand, env)
            elif self.operand.type.can_coerce_to_pyobject(env):
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
5426
                self.result_ctype = py_object_type
5427
                self.operand = self.operand.coerce_to_pyobject(env)
5428
            else:
5429 5430 5431 5432
                if self.operand.type.is_ptr:
                    if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
                        error(self.pos, "Python objects cannot be cast from pointers of primitive types")
                else:
5433
                    # Should this be an error?
5434
                    warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
5435
                self.operand = self.operand.coerce_to_simple(env)
5436
        elif from_py and not to_py:
5437
            if self.type.create_from_py_utility_code(env):
5438
                self.operand = self.operand.coerce_to(self.type, env)
5439 5440 5441
            elif self.type.is_ptr:
                if not (self.type.base_type.is_void or self.type.base_type.is_struct):
                    error(self.pos, "Python objects cannot be cast to pointers of primitive types")
5442 5443
            else:
                warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
5444 5445
        elif from_py and to_py:
            if self.typecheck and self.type.is_extension_type:
5446
                self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
5447 5448
        elif self.type.is_complex and self.operand.type.is_complex:
            self.operand = self.operand.coerce_to_simple(env)
5449

Stefan Behnel's avatar
Stefan Behnel committed
5450 5451 5452 5453
    def is_simple(self):
        # either temp or a C cast => no side effects
        return True

5454 5455 5456
    def nonlocally_immutable(self):
        return self.operand.nonlocally_immutable()

5457 5458 5459
    def nogil_check(self, env):
        if self.type and self.type.is_pyobject and self.is_temp:
            self.gil_error()
5460

William Stein's avatar
William Stein committed
5461
    def check_const(self):
5462
        return self.operand.check_const()
Stefan Behnel's avatar
Stefan Behnel committed
5463 5464

    def calculate_constant_result(self):
5465 5466 5467
        # we usually do not know the result of a type cast at code
        # generation time
        pass
5468

William Stein's avatar
William Stein committed
5469
    def calculate_result_code(self):
5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480
        if self.type.is_complex:
            operand_result = self.operand.result()
            if self.operand.type.is_complex:
                real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
                imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
            else:
                real_part = self.type.real_type.cast_code(operand_result)
                imag_part = "0"
            return "%s(%s, %s)" % (
                    self.type.from_parts,
                    real_part,
5481
                    imag_part)
5482 5483
        else:
            return self.type.cast_code(self.operand.result())
5484

5485 5486 5487 5488
    def get_constant_c_result_code(self):
        operand_result = self.operand.get_constant_c_result_code()
        if operand_result:
            return self.type.cast_code(operand_result)
5489

William Stein's avatar
William Stein committed
5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500
    def result_as(self, type):
        if self.type.is_pyobject and not self.is_temp:
            #  Optimise away some unnecessary casting
            return self.operand.result_as(type)
        else:
            return ExprNode.result_as(self, type)

    def generate_result_code(self, code):
        if self.is_temp:
            code.putln(
                "%s = (PyObject *)%s;" % (
5501 5502 5503
                    self.result(),
                    self.operand.result()))
            code.put_incref(self.result(), self.ctype())
William Stein's avatar
William Stein committed
5504 5505


5506
class SizeofNode(ExprNode):
William Stein's avatar
William Stein committed
5507
    #  Abstract base class for sizeof(x) expression nodes.
5508

5509
    type = PyrexTypes.c_size_t_type
William Stein's avatar
William Stein committed
5510 5511

    def check_const(self):
5512
        return True
William Stein's avatar
William Stein committed
5513 5514 5515 5516 5517 5518 5519 5520 5521 5522

    def generate_result_code(self, code):
        pass


class SizeofTypeNode(SizeofNode):
    #  C sizeof function applied to a type
    #
    #  base_type   CBaseTypeNode
    #  declarator  CDeclaratorNode
5523

William Stein's avatar
William Stein committed
5524
    subexprs = []
5525
    arg_type = None
5526

William Stein's avatar
William Stein committed
5527
    def analyse_types(self, env):
5528 5529
        # we may have incorrectly interpreted a dotted name as a type rather than an attribute
        # this could be better handled by more uniformly treating types as runtime-available objects
5530
        if 0 and self.base_type.module_path:
5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541
            path = self.base_type.module_path
            obj = env.lookup(path[0])
            if obj.as_module is None:
                operand = NameNode(pos=self.pos, name=path[0])
                for attr in path[1:]:
                    operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
                operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
                self.operand = operand
                self.__class__ = SizeofVarNode
                self.analyse_types(env)
                return
5542 5543 5544 5545
        if self.arg_type is None:
            base_type = self.base_type.analyse(env)
            _, arg_type = self.declarator.analyse(base_type, env)
            self.arg_type = arg_type
5546
        self.check_type()
5547

5548 5549
    def check_type(self):
        arg_type = self.arg_type
5550
        if arg_type.is_pyobject and not arg_type.is_extension_type:
William Stein's avatar
William Stein committed
5551 5552 5553 5554 5555
            error(self.pos, "Cannot take sizeof Python object")
        elif arg_type.is_void:
            error(self.pos, "Cannot take sizeof void")
        elif not arg_type.is_complete():
            error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
5556

William Stein's avatar
William Stein committed
5557
    def calculate_result_code(self):
5558 5559 5560 5561 5562 5563
        if self.arg_type.is_extension_type:
            # the size of the pointer is boring
            # we want the size of the actual struct
            arg_code = self.arg_type.declaration_code("", deref=1)
        else:
            arg_code = self.arg_type.declaration_code("")
William Stein's avatar
William Stein committed
5564
        return "(sizeof(%s))" % arg_code
5565

William Stein's avatar
William Stein committed
5566 5567 5568 5569 5570

class SizeofVarNode(SizeofNode):
    #  C sizeof function applied to a variable
    #
    #  operand   ExprNode
5571

William Stein's avatar
William Stein committed
5572
    subexprs = ['operand']
5573

William Stein's avatar
William Stein committed
5574
    def analyse_types(self, env):
5575 5576 5577 5578 5579 5580 5581 5582 5583
        # We may actually be looking at a type rather than a variable...
        # If we are, traditional analysis would fail...
        operand_as_type = self.operand.analyse_as_type(env)
        if operand_as_type:
            self.arg_type = operand_as_type
            self.__class__ = SizeofTypeNode
            self.check_type()
        else:
            self.operand.analyse_types(env)
5584

William Stein's avatar
William Stein committed
5585
    def calculate_result_code(self):
5586
        return "(sizeof(%s))" % self.operand.result()
5587

William Stein's avatar
William Stein committed
5588 5589 5590
    def generate_result_code(self, code):
        pass

Robert Bradshaw's avatar
Robert Bradshaw committed
5591
class TypeofNode(ExprNode):
5592 5593 5594
    #  Compile-time type of an expression, as a string.
    #
    #  operand   ExprNode
Robert Bradshaw's avatar
Robert Bradshaw committed
5595
    #  literal   StringNode # internal
5596

Robert Bradshaw's avatar
Robert Bradshaw committed
5597 5598
    literal = None
    type = py_object_type
5599

Stefan Behnel's avatar
Stefan Behnel committed
5600
    subexprs = ['literal'] # 'operand' will be ignored after type analysis!
5601

5602 5603
    def analyse_types(self, env):
        self.operand.analyse_types(env)
5604 5605
        self.literal = StringNode(
            self.pos, value=StringEncoding.EncodedString(str(self.operand.type)))
Robert Bradshaw's avatar
Robert Bradshaw committed
5606 5607
        self.literal.analyse_types(env)
        self.literal = self.literal.coerce_to_pyobject(env)
5608 5609 5610 5611

    def may_be_none(self):
        return False

5612
    def generate_evaluation_code(self, code):
Robert Bradshaw's avatar
Robert Bradshaw committed
5613
        self.literal.generate_evaluation_code(code)
5614

Robert Bradshaw's avatar
Robert Bradshaw committed
5615 5616
    def calculate_result_code(self):
        return self.literal.calculate_result_code()
William Stein's avatar
William Stein committed
5617 5618 5619 5620 5621 5622 5623

#-------------------------------------------------------------------
#
#  Binary operator nodes
#
#-------------------------------------------------------------------

Stefan Behnel's avatar
Stefan Behnel committed
5624 5625 5626
def _not_in(x, seq):
    return x not in seq

5627 5628 5629
compile_time_binary_operators = {
    '<': operator.lt,
    '<=': operator.le,
5630
    '==': operator.eq,
5631 5632 5633 5634 5635 5636 5637
    '!=': operator.ne,
    '>=': operator.ge,
    '>': operator.gt,
    'is': operator.is_,
    'is_not': operator.is_not,
    '+': operator.add,
    '&': operator.and_,
5638
    '/': operator.truediv,
5639 5640 5641 5642 5643 5644 5645 5646 5647
    '//': operator.floordiv,
    '<<': operator.lshift,
    '%': operator.mod,
    '*': operator.mul,
    '|': operator.or_,
    '**': operator.pow,
    '>>': operator.rshift,
    '-': operator.sub,
    '^': operator.xor,
Stefan Behnel's avatar
Stefan Behnel committed
5648 5649
    'in': operator.contains,
    'not_in': _not_in,
5650 5651 5652 5653 5654 5655 5656
}

def get_compile_time_binop(node):
    func = compile_time_binary_operators.get(node.operator)
    if not func:
        error(node.pos,
            "Binary '%s' not supported in compile-time expression"
5657
                % node.operator)
5658 5659
    return func

5660
class BinopNode(ExprNode):
William Stein's avatar
William Stein committed
5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671
    #  operator     string
    #  operand1     ExprNode
    #  operand2     ExprNode
    #
    #  Processing during analyse_expressions phase:
    #
    #    analyse_c_operation
    #      Called when neither operand is a pyobject.
    #      - Check operand types and coerce if needed.
    #      - Determine result type and result code fragment.
    #      - Allocate temporary for result if needed.
5672

William Stein's avatar
William Stein committed
5673
    subexprs = ['operand1', 'operand2']
5674
    inplace = False
5675 5676 5677 5678 5679 5680 5681

    def calculate_constant_result(self):
        func = compile_time_binary_operators[self.operator]
        self.constant_result = func(
            self.operand1.constant_result,
            self.operand2.constant_result)

5682 5683 5684 5685 5686 5687 5688 5689
    def compile_time_value(self, denv):
        func = get_compile_time_binop(self)
        operand1 = self.operand1.compile_time_value(denv)
        operand2 = self.operand2.compile_time_value(denv)
        try:
            return func(operand1, operand2)
        except Exception, e:
            self.compile_time_value_error(e)
5690

5691 5692
    def infer_type(self, env):
        return self.result_type(self.operand1.infer_type(env),
Robert Bradshaw's avatar
Robert Bradshaw committed
5693
                                self.operand2.infer_type(env))
5694

William Stein's avatar
William Stein committed
5695 5696 5697
    def analyse_types(self, env):
        self.operand1.analyse_types(env)
        self.operand2.analyse_types(env)
Robert Bradshaw's avatar
Robert Bradshaw committed
5698
        self.analyse_operation(env)
5699

Robert Bradshaw's avatar
Robert Bradshaw committed
5700
    def analyse_operation(self, env):
William Stein's avatar
William Stein committed
5701 5702
        if self.is_py_operation():
            self.coerce_operands_to_pyobjects(env)
5703 5704 5705
            self.type = self.result_type(self.operand1.type,
                                         self.operand2.type)
            assert self.type.is_pyobject
William Stein's avatar
William Stein committed
5706
            self.is_temp = 1
DaniloFreitas's avatar
DaniloFreitas committed
5707 5708
        elif self.is_cpp_operation():
            self.analyse_cpp_operation(env)
William Stein's avatar
William Stein committed
5709 5710
        else:
            self.analyse_c_operation(env)
5711

William Stein's avatar
William Stein committed
5712
    def is_py_operation(self):
5713
        return self.is_py_operation_types(self.operand1.type, self.operand2.type)
5714

5715 5716 5717
    def is_py_operation_types(self, type1, type2):
        return type1.is_pyobject or type2.is_pyobject

DaniloFreitas's avatar
DaniloFreitas committed
5718
    def is_cpp_operation(self):
Robert Bradshaw's avatar
Robert Bradshaw committed
5719 5720
        return (self.operand1.type.is_cpp_class
            or self.operand2.type.is_cpp_class)
5721

5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737
    def analyse_cpp_operation(self, env):
        type1 = self.operand1.type
        type2 = self.operand2.type
        entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
        if not entry:
            self.type_error()
            return
        func_type = entry.type
        if func_type.is_ptr:
            func_type = func_type.base_type
        if len(func_type.args) == 1:
            self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
        else:
            self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
            self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
        self.type = func_type.return_type
5738

5739 5740
    def result_type(self, type1, type2):
        if self.is_py_operation_types(type1, type2):
5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758
            if type2.is_string:
                type2 = Builtin.bytes_type
            if type1.is_string:
                type1 = Builtin.bytes_type
            elif self.operator == '%' \
                     and type1 in (Builtin.str_type, Builtin.unicode_type):
                # note that  b'%s' % b'abc'  doesn't work in Py3
                return type1
            if type1.is_builtin_type:
                if type1 is type2:
                    if self.operator in '**%+|&^':
                        # FIXME: at least these operators should be safe - others?
                        return type1
                elif self.operator == '*':
                    if type1 in (Builtin.bytes_type, Builtin.str_type, Builtin.unicode_type):
                        return type1
                    # multiplication of containers/numbers with an
                    # integer value always (?) returns the same type
5759
                    if type2.is_int:
5760
                        return type1
5761 5762 5763 5764
            elif type2.is_builtin_type and type1.is_int and self.operator == '*':
                # multiplication of containers/numbers with an
                # integer value always (?) returns the same type
                return type2
5765 5766 5767
            return py_object_type
        else:
            return self.compute_c_result_type(type1, type2)
5768

5769
    def nogil_check(self, env):
5770
        if self.is_py_operation():
5771
            self.gil_error()
5772

William Stein's avatar
William Stein committed
5773 5774 5775
    def coerce_operands_to_pyobjects(self, env):
        self.operand1 = self.operand1.coerce_to_pyobject(env)
        self.operand2 = self.operand2.coerce_to_pyobject(env)
5776

William Stein's avatar
William Stein committed
5777
    def check_const(self):
5778
        return self.operand1.check_const() and self.operand2.check_const()
5779

William Stein's avatar
William Stein committed
5780 5781 5782 5783
    def generate_result_code(self, code):
        #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
        if self.operand1.type.is_pyobject:
            function = self.py_operation_function()
5784
            if self.operator == '**':
William Stein's avatar
William Stein committed
5785 5786 5787 5788
                extra_args = ", Py_None"
            else:
                extra_args = ""
            code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
5789
                "%s = %s(%s, %s%s); %s" % (
5790 5791
                    self.result(),
                    function,
William Stein's avatar
William Stein committed
5792 5793 5794
                    self.operand1.py_result(),
                    self.operand2.py_result(),
                    extra_args,
5795
                    code.error_goto_if_null(self.result(), self.pos)))
5796
            code.put_gotref(self.py_result())
5797

William Stein's avatar
William Stein committed
5798 5799 5800 5801
    def type_error(self):
        if not (self.operand1.type.is_error
                or self.operand2.type.is_error):
            error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
5802
                (self.operator, self.operand1.type,
William Stein's avatar
William Stein committed
5803 5804 5805 5806
                    self.operand2.type))
        self.type = PyrexTypes.error_type


Robert Bradshaw's avatar
Robert Bradshaw committed
5807
class CBinopNode(BinopNode):
5808

Robert Bradshaw's avatar
Robert Bradshaw committed
5809 5810 5811 5812
    def analyse_types(self, env):
        BinopNode.analyse_types(self, env)
        if self.is_py_operation():
            self.type = PyrexTypes.error_type
5813

Robert Bradshaw's avatar
Robert Bradshaw committed
5814 5815
    def py_operation_function():
        return ""
5816

Robert Bradshaw's avatar
Robert Bradshaw committed
5817 5818
    def calculate_result_code(self):
        return "(%s %s %s)" % (
5819 5820
            self.operand1.result(),
            self.operator,
Robert Bradshaw's avatar
Robert Bradshaw committed
5821 5822 5823 5824 5825 5826 5827 5828
            self.operand2.result())


def c_binop_constructor(operator):
    def make_binop_node(pos, **operands):
        return CBinopNode(pos, operator=operator, **operands)
    return make_binop_node

William Stein's avatar
William Stein committed
5829 5830
class NumBinopNode(BinopNode):
    #  Binary operation taking numeric arguments.
5831

Robert Bradshaw's avatar
Robert Bradshaw committed
5832
    infix = True
5833

William Stein's avatar
William Stein committed
5834 5835 5836 5837 5838 5839
    def analyse_c_operation(self, env):
        type1 = self.operand1.type
        type2 = self.operand2.type
        self.type = self.compute_c_result_type(type1, type2)
        if not self.type:
            self.type_error()
5840
            return
5841
        if self.type.is_complex:
Robert Bradshaw's avatar
Robert Bradshaw committed
5842
            self.infix = False
5843
        if not self.infix or (type1.is_numeric and type2.is_numeric):
5844 5845
            self.operand1 = self.operand1.coerce_to(self.type, env)
            self.operand2 = self.operand2.coerce_to(self.type, env)
5846

William Stein's avatar
William Stein committed
5847 5848
    def compute_c_result_type(self, type1, type2):
        if self.c_types_okay(type1, type2):
5849 5850 5851 5852 5853 5854
            widest_type = PyrexTypes.widest_numeric_type(type1, type2)
            if widest_type is PyrexTypes.c_bint_type:
                if self.operator not in '|^&':
                    # False + False == 0 # not False!
                    widest_type = PyrexTypes.c_int_type
            return widest_type
William Stein's avatar
William Stein committed
5855 5856
        else:
            return None
5857 5858 5859 5860 5861 5862 5863 5864

    def get_constant_c_result_code(self):
        value1 = self.operand1.get_constant_c_result_code()
        value2 = self.operand2.get_constant_c_result_code()
        if value1 and value2:
            return "(%s %s %s)" % (value1, self.operator, value2)
        else:
            return None
5865

William Stein's avatar
William Stein committed
5866
    def c_types_okay(self, type1, type2):
5867 5868 5869
        #print "NumBinopNode.c_types_okay:", type1, type2 ###
        return (type1.is_numeric  or type1.is_enum) \
            and (type2.is_numeric  or type2.is_enum)
William Stein's avatar
William Stein committed
5870 5871

    def calculate_result_code(self):
5872 5873
        if self.infix:
            return "(%s %s %s)" % (
5874 5875
                self.operand1.result(),
                self.operator,
5876 5877
                self.operand2.result())
        else:
5878 5879 5880
            func = self.type.binary_op(self.operator)
            if func is None:
                error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
5881
            return "%s(%s, %s)" % (
5882
                func,
5883 5884
                self.operand1.result(),
                self.operand2.result())
5885

5886
    def is_py_operation_types(self, type1, type2):
Stefan Behnel's avatar
Stefan Behnel committed
5887 5888
        return (type1.is_unicode_char or
                type2.is_unicode_char or
5889
                BinopNode.is_py_operation_types(self, type1, type2))
5890

William Stein's avatar
William Stein committed
5891
    def py_operation_function(self):
5892 5893 5894 5895
        fuction = self.py_functions[self.operator]
        if self.inplace:
            fuction = fuction.replace('PyNumber_', 'PyNumber_InPlace')
        return fuction
William Stein's avatar
William Stein committed
5896 5897

    py_functions = {
Robert Bradshaw's avatar
Robert Bradshaw committed
5898 5899 5900
        "|":        "PyNumber_Or",
        "^":        "PyNumber_Xor",
        "&":        "PyNumber_And",
5901 5902
        "<<":       "PyNumber_Lshift",
        ">>":       "PyNumber_Rshift",
Robert Bradshaw's avatar
Robert Bradshaw committed
5903 5904 5905 5906
        "+":        "PyNumber_Add",
        "-":        "PyNumber_Subtract",
        "*":        "PyNumber_Multiply",
        "/":        "__Pyx_PyNumber_Divide",
5907
        "//":       "PyNumber_FloorDivide",
Robert Bradshaw's avatar
Robert Bradshaw committed
5908
        "%":        "PyNumber_Remainder",
5909
        "**":       "PyNumber_Power"
William Stein's avatar
William Stein committed
5910 5911 5912 5913
    }

class IntBinopNode(NumBinopNode):
    #  Binary operation taking integer arguments.
5914

William Stein's avatar
William Stein committed
5915
    def c_types_okay(self, type1, type2):
5916 5917 5918
        #print "IntBinopNode.c_types_okay:", type1, type2 ###
        return (type1.is_int or type1.is_enum) \
            and (type2.is_int or type2.is_enum)
William Stein's avatar
William Stein committed
5919

5920

William Stein's avatar
William Stein committed
5921 5922
class AddNode(NumBinopNode):
    #  '+' operator.
5923

5924 5925 5926
    def is_py_operation_types(self, type1, type2):
        if type1.is_string and type2.is_string:
            return 1
William Stein's avatar
William Stein committed
5927
        else:
5928
            return NumBinopNode.is_py_operation_types(self, type1, type2)
William Stein's avatar
William Stein committed
5929 5930

    def compute_c_result_type(self, type1, type2):
5931 5932
        #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
        if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
William Stein's avatar
William Stein committed
5933
            return type1
5934
        elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
William Stein's avatar
William Stein committed
5935 5936 5937 5938 5939 5940 5941 5942
            return type2
        else:
            return NumBinopNode.compute_c_result_type(
                self, type1, type2)


class SubNode(NumBinopNode):
    #  '-' operator.
5943

William Stein's avatar
William Stein committed
5944
    def compute_c_result_type(self, type1, type2):
5945
        if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
William Stein's avatar
William Stein committed
5946
            return type1
5947
        elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
William Stein's avatar
William Stein committed
5948 5949 5950 5951 5952 5953 5954 5955
            return PyrexTypes.c_int_type
        else:
            return NumBinopNode.compute_c_result_type(
                self, type1, type2)


class MulNode(NumBinopNode):
    #  '*' operator.
5956

5957
    def is_py_operation_types(self, type1, type2):
William Stein's avatar
William Stein committed
5958 5959 5960 5961
        if (type1.is_string and type2.is_int) \
            or (type2.is_string and type1.is_int):
                return 1
        else:
5962
            return NumBinopNode.is_py_operation_types(self, type1, type2)
William Stein's avatar
William Stein committed
5963 5964


5965 5966
class DivNode(NumBinopNode):
    #  '/' or '//' operator.
5967

5968
    cdivision = None
5969 5970
    truedivision = None   # == "unknown" if operator == '/'
    ctruedivision = False
Robert Bradshaw's avatar
Robert Bradshaw committed
5971
    cdivision_warnings = False
5972
    zerodivision_check = None
5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994

    def find_compile_time_binary_operator(self, op1, op2):
        func = compile_time_binary_operators[self.operator]
        if self.operator == '/' and self.truedivision is None:
            # => true div for floats, floor div for integers
            if isinstance(op1, (int,long)) and isinstance(op2, (int,long)):
                func = compile_time_binary_operators['//']
        return func

    def calculate_constant_result(self):
        op1 = self.operand1.constant_result
        op2 = self.operand2.constant_result
        func = self.find_compile_time_binary_operator(op1, op2)
        self.constant_result = func(
            self.operand1.constant_result,
            self.operand2.constant_result)

    def compile_time_value(self, denv):
        operand1 = self.operand1.compile_time_value(denv)
        operand2 = self.operand2.compile_time_value(denv)
        try:
            func = self.find_compile_time_binary_operator(
Robert Bradshaw's avatar
Robert Bradshaw committed
5995
                operand1, operand2)
5996 5997 5998 5999
            return func(operand1, operand2)
        except Exception, e:
            self.compile_time_value_error(e)

Robert Bradshaw's avatar
Robert Bradshaw committed
6000
    def analyse_operation(self, env):
6001 6002 6003 6004
        if self.cdivision or env.directives['cdivision']:
            self.ctruedivision = False
        else:
            self.ctruedivision = self.truedivision
Robert Bradshaw's avatar
Robert Bradshaw committed
6005
        NumBinopNode.analyse_operation(self, env)
6006 6007
        if self.is_cpp_operation():
            self.cdivision = True
6008
        if not self.type.is_pyobject:
6009 6010
            self.zerodivision_check = (
                self.cdivision is None and not env.directives['cdivision']
6011
                and (not self.operand2.has_constant_result() or
6012
                     self.operand2.constant_result == 0))
6013 6014 6015 6016
            if self.zerodivision_check or env.directives['cdivision_warnings']:
                # Need to check ahead of time to warn or raise zero division error
                self.operand1 = self.operand1.coerce_to_simple(env)
                self.operand2 = self.operand2.coerce_to_simple(env)
6017 6018
                if env.nogil:
                    error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)")
6019 6020 6021 6022 6023 6024 6025 6026 6027

    def compute_c_result_type(self, type1, type2):
        if self.operator == '/' and self.ctruedivision:
            if not type1.is_float and not type2.is_float:
                widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
                widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
                return widest_type
        return NumBinopNode.compute_c_result_type(self, type1, type2)

6028 6029 6030 6031 6032
    def zero_division_message(self):
        if self.type.is_int:
            return "integer division or modulo by zero"
        else:
            return "float division"
Robert Bradshaw's avatar
Robert Bradshaw committed
6033

6034
    def generate_evaluation_code(self, code):
6035
        if not self.type.is_pyobject and not self.type.is_complex:
6036
            if self.cdivision is None:
6037
                self.cdivision = (code.globalstate.directives['cdivision']
6038 6039 6040
                                    or not self.type.signed
                                    or self.type.is_float)
            if not self.cdivision:
6041
                code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
6042
        NumBinopNode.generate_evaluation_code(self, code)
6043
        self.generate_div_warning_code(code)
6044

6045
    def generate_div_warning_code(self, code):
6046 6047
        if not self.type.is_pyobject:
            if self.zerodivision_check:
6048 6049 6050 6051 6052
                if not self.infix:
                    zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
                else:
                    zero_test = "%s == 0" % self.operand2.result()
                code.putln("if (unlikely(%s)) {" % zero_test)
6053 6054 6055
                code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
                code.putln(code.error_goto(self.pos))
                code.putln("}")
6056 6057 6058
                if self.type.is_int and self.type.signed and self.operator != '%':
                    code.globalstate.use_utility_code(division_overflow_test_code)
                    code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
6059
                                    self.type.declaration_code(''),
6060 6061 6062 6063 6064
                                    self.operand2.result(),
                                    self.operand1.result()))
                    code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");')
                    code.putln(code.error_goto(self.pos))
                    code.putln("}")
Robert Bradshaw's avatar
Robert Bradshaw committed
6065
            if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
6066 6067 6068 6069 6070 6071 6072 6073
                code.globalstate.use_utility_code(cdivision_warning_utility_code)
                code.putln("if ((%s < 0) ^ (%s < 0)) {" % (
                                self.operand1.result(),
                                self.operand2.result()))
                code.putln(code.set_error_info(self.pos));
                code.put("if (__Pyx_cdivision_warning()) ")
                code.put_goto(code.error_label)
                code.putln("}")
6074

Robert Bradshaw's avatar
Robert Bradshaw committed
6075
    def calculate_result_code(self):
6076 6077 6078
        if self.type.is_complex:
            return NumBinopNode.calculate_result_code(self)
        elif self.type.is_float and self.operator == '//':
6079
            return "floor(%s / %s)" % (
6080
                self.operand1.result(),
6081
                self.operand2.result())
6082 6083 6084 6085 6086 6087 6088 6089 6090
        elif self.truedivision or self.cdivision:
            op1 = self.operand1.result()
            op2 = self.operand2.result()
            if self.truedivision:
                if self.type != self.operand1.type:
                    op1 = self.type.cast_code(op1)
                if self.type != self.operand2.type:
                    op2 = self.type.cast_code(op2)
            return "(%s / %s)" % (op1, op2)
6091 6092
        else:
            return "__Pyx_div_%s(%s, %s)" % (
Craig Citro's avatar
Craig Citro committed
6093
                    self.type.specialization_name(),
6094
                    self.operand1.result(),
6095
                    self.operand2.result())
Robert Bradshaw's avatar
Robert Bradshaw committed
6096 6097


Robert Bradshaw's avatar
Robert Bradshaw committed
6098
class ModNode(DivNode):
William Stein's avatar
William Stein committed
6099
    #  '%' operator.
6100

6101 6102 6103 6104
    def is_py_operation_types(self, type1, type2):
        return (type1.is_string
            or type2.is_string
            or NumBinopNode.is_py_operation_types(self, type1, type2))
William Stein's avatar
William Stein committed
6105

6106 6107 6108 6109 6110
    def zero_division_message(self):
        if self.type.is_int:
            return "integer division or modulo by zero"
        else:
            return "float divmod()"
6111

6112
    def generate_evaluation_code(self, code):
6113 6114 6115 6116 6117
        if not self.type.is_pyobject:
            if self.cdivision is None:
                self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
            if not self.cdivision:
                if self.type.is_int:
6118
                    code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
6119
                else:
6120 6121
                    code.globalstate.use_utility_code(
                        mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
6122
        NumBinopNode.generate_evaluation_code(self, code)
6123
        self.generate_div_warning_code(code)
6124

Robert Bradshaw's avatar
Robert Bradshaw committed
6125
    def calculate_result_code(self):
6126 6127 6128 6129
        if self.cdivision:
            if self.type.is_float:
                return "fmod%s(%s, %s)" % (
                    self.type.math_h_modifier,
6130
                    self.operand1.result(),
6131 6132 6133
                    self.operand2.result())
            else:
                return "(%s %% %s)" % (
6134
                    self.operand1.result(),
6135
                    self.operand2.result())
Robert Bradshaw's avatar
Robert Bradshaw committed
6136
        else:
6137
            return "__Pyx_mod_%s(%s, %s)" % (
Craig Citro's avatar
Craig Citro committed
6138
                    self.type.specialization_name(),
6139
                    self.operand1.result(),
6140
                    self.operand2.result())
William Stein's avatar
William Stein committed
6141 6142 6143

class PowNode(NumBinopNode):
    #  '**' operator.
6144

Robert Bradshaw's avatar
Robert Bradshaw committed
6145 6146
    def analyse_c_operation(self, env):
        NumBinopNode.analyse_c_operation(self, env)
6147
        if self.type.is_complex:
Robert Bradshaw's avatar
Robert Bradshaw committed
6148 6149 6150 6151 6152 6153 6154
            if self.type.real_type.is_float:
                self.operand1 = self.operand1.coerce_to(self.type, env)
                self.operand2 = self.operand2.coerce_to(self.type, env)
                self.pow_func = "__Pyx_c_pow" + self.type.real_type.math_h_modifier
            else:
                error(self.pos, "complex int powers not supported")
                self.pow_func = "<error>"
6155
        elif self.type.is_float:
6156
            self.pow_func = "pow" + self.type.math_h_modifier
William Stein's avatar
William Stein committed
6157
        else:
Robert Bradshaw's avatar
Robert Bradshaw committed
6158 6159
            self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_')
            env.use_utility_code(
6160
                    int_pow_utility_code.specialize(func_name=self.pow_func,
Robert Bradshaw's avatar
Robert Bradshaw committed
6161
                                                type=self.type.declaration_code('')))
6162

William Stein's avatar
William Stein committed
6163
    def calculate_result_code(self):
6164 6165 6166 6167 6168 6169
        # Work around MSVC overloading ambiguity.
        def typecast(operand):
            if self.type == operand.type:
                return operand.result()
            else:
                return self.type.cast_code(operand.result())
Robert Bradshaw's avatar
Robert Bradshaw committed
6170
        return "%s(%s, %s)" % (
6171 6172
            self.pow_func,
            typecast(self.operand1),
6173
            typecast(self.operand2))
6174

William Stein's avatar
William Stein committed
6175

Craig Citro's avatar
Craig Citro committed
6176
# Note: This class is temporarily "shut down" into an ineffective temp
6177 6178
# allocation mode.
#
Craig Citro's avatar
Craig Citro committed
6179 6180 6181
# More sophisticated temp reuse was going on before, one could have a
# look at adding this again after /all/ classes are converted to the
# new temp scheme. (The temp juggling cannot work otherwise).
6182
class BoolBinopNode(ExprNode):
William Stein's avatar
William Stein committed
6183 6184 6185 6186 6187
    #  Short-circuiting boolean operation.
    #
    #  operator     string
    #  operand1     ExprNode
    #  operand2     ExprNode
6188

6189
    subexprs = ['operand1', 'operand2']
6190

6191
    def infer_type(self, env):
6192 6193
        type1 = self.operand1.infer_type(env)
        type2 = self.operand2.infer_type(env)
6194
        return PyrexTypes.independent_spanning_type(type1, type2)
6195

Stefan Behnel's avatar
Stefan Behnel committed
6196 6197 6198 6199 6200 6201
    def may_be_none(self):
        if self.operator == 'or':
            return self.operand2.may_be_none()
        else:
            return self.operand1.may_be_none() or self.operand2.may_be_none()

6202 6203 6204 6205 6206 6207 6208 6209 6210
    def calculate_constant_result(self):
        if self.operator == 'and':
            self.constant_result = \
                self.operand1.constant_result and \
                self.operand2.constant_result
        else:
            self.constant_result = \
                self.operand1.constant_result or \
                self.operand2.constant_result
6211

6212 6213 6214 6215 6216 6217 6218
    def compile_time_value(self, denv):
        if self.operator == 'and':
            return self.operand1.compile_time_value(denv) \
                and self.operand2.compile_time_value(denv)
        else:
            return self.operand1.compile_time_value(denv) \
                or self.operand2.compile_time_value(denv)
6219

6220
    def coerce_to_boolean(self, env):
6221 6222 6223 6224 6225 6226 6227
        return BoolBinopNode(
            self.pos,
            operator = self.operator,
            operand1 = self.operand1.coerce_to_boolean(env),
            operand2 = self.operand2.coerce_to_boolean(env),
            type = PyrexTypes.c_bint_type,
            is_temp = self.is_temp)
6228

William Stein's avatar
William Stein committed
6229 6230 6231
    def analyse_types(self, env):
        self.operand1.analyse_types(env)
        self.operand2.analyse_types(env)
6232
        self.type = PyrexTypes.independent_spanning_type(self.operand1.type, self.operand2.type)
6233 6234
        self.operand1 = self.operand1.coerce_to(self.type, env)
        self.operand2 = self.operand2.coerce_to(self.type, env)
6235

William Stein's avatar
William Stein committed
6236 6237
        # For what we're about to do, it's vital that
        # both operands be temp nodes.
6238 6239
        self.operand1 = self.operand1.coerce_to_simple(env)
        self.operand2 = self.operand2.coerce_to_simple(env)
William Stein's avatar
William Stein committed
6240
        self.is_temp = 1
6241 6242 6243

    gil_message = "Truth-testing Python object"

William Stein's avatar
William Stein committed
6244
    def check_const(self):
6245
        return self.operand1.check_const() and self.operand2.check_const()
6246

William Stein's avatar
William Stein committed
6247
    def generate_evaluation_code(self, code):
6248
        code.mark_pos(self.pos)
William Stein's avatar
William Stein committed
6249
        self.operand1.generate_evaluation_code(code)
6250
        test_result, uses_temp = self.generate_operand1_test(code)
William Stein's avatar
William Stein committed
6251 6252 6253 6254 6255 6256 6257 6258
        if self.operator == 'and':
            sense = ""
        else:
            sense = "!"
        code.putln(
            "if (%s%s) {" % (
                sense,
                test_result))
6259 6260
        if uses_temp:
            code.funcstate.release_temp(test_result)
6261
        self.operand1.generate_disposal_code(code)
William Stein's avatar
William Stein committed
6262
        self.operand2.generate_evaluation_code(code)
6263
        self.allocate_temp_result(code)
6264
        self.operand2.make_owned_reference(code)
6265
        code.putln("%s = %s;" % (self.result(), self.operand2.result()))
6266 6267
        self.operand2.generate_post_assignment_code(code)
        self.operand2.free_temps(code)
6268
        code.putln("} else {")
6269
        self.operand1.make_owned_reference(code)
6270
        code.putln("%s = %s;" % (self.result(), self.operand1.result()))
6271 6272
        self.operand1.generate_post_assignment_code(code)
        self.operand1.free_temps(code)
6273
        code.putln("}")
6274

William Stein's avatar
William Stein committed
6275 6276 6277
    def generate_operand1_test(self, code):
        #  Generate code to test the truth of the first operand.
        if self.type.is_pyobject:
6278 6279
            test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type,
                                                       manage_ref=False)
William Stein's avatar
William Stein committed
6280
            code.putln(
6281
                "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
William Stein's avatar
William Stein committed
6282 6283
                    test_result,
                    self.operand1.py_result(),
Robert Bradshaw's avatar
Robert Bradshaw committed
6284
                    code.error_goto_if_neg(test_result, self.pos)))
William Stein's avatar
William Stein committed
6285
        else:
6286
            test_result = self.operand1.result()
6287
        return (test_result, self.type.is_pyobject)
William Stein's avatar
William Stein committed
6288 6289


6290
class CondExprNode(ExprNode):
Robert Bradshaw's avatar
Robert Bradshaw committed
6291 6292 6293 6294 6295
    #  Short-circuiting conditional expression.
    #
    #  test        ExprNode
    #  true_val    ExprNode
    #  false_val   ExprNode
6296

6297 6298
    true_val = None
    false_val = None
6299

Robert Bradshaw's avatar
Robert Bradshaw committed
6300
    subexprs = ['test', 'true_val', 'false_val']
6301

Robert Bradshaw's avatar
Robert Bradshaw committed
6302 6303
    def type_dependencies(self, env):
        return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
6304

Robert Bradshaw's avatar
Robert Bradshaw committed
6305
    def infer_type(self, env):
6306 6307
        return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env),
                                                    self.false_val.infer_type(env))
6308 6309 6310 6311 6312 6313 6314

    def calculate_constant_result(self):
        if self.test.constant_result:
            self.constant_result = self.true_val.constant_result
        else:
            self.constant_result = self.false_val.constant_result

Robert Bradshaw's avatar
Robert Bradshaw committed
6315 6316 6317 6318 6319
    def analyse_types(self, env):
        self.test.analyse_types(env)
        self.test = self.test.coerce_to_boolean(env)
        self.true_val.analyse_types(env)
        self.false_val.analyse_types(env)
6320
        self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type)
6321 6322 6323 6324 6325
        if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
            self.true_val = self.true_val.coerce_to(self.type, env)
            self.false_val = self.false_val.coerce_to(self.type, env)
        self.is_temp = 1
        if self.type == PyrexTypes.error_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
6326
            self.type_error()
6327

Robert Bradshaw's avatar
Robert Bradshaw committed
6328 6329 6330 6331 6332
    def type_error(self):
        if not (self.true_val.type.is_error or self.false_val.type.is_error):
            error(self.pos, "Incompatable types in conditional expression (%s; %s)" %
                (self.true_val.type, self.false_val.type))
        self.type = PyrexTypes.error_type
6333

Robert Bradshaw's avatar
Robert Bradshaw committed
6334
    def check_const(self):
6335
        return (self.test.check_const()
6336 6337
            and self.true_val.check_const()
            and self.false_val.check_const())
6338

Robert Bradshaw's avatar
Robert Bradshaw committed
6339
    def generate_evaluation_code(self, code):
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
6340 6341
        # Because subexprs may not be evaluated we can use a more optimal
        # subexpr allocation strategy than the default, so override evaluation_code.
6342

Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
6343
        code.mark_pos(self.pos)
6344
        self.allocate_temp_result(code)
Robert Bradshaw's avatar
Robert Bradshaw committed
6345
        self.test.generate_evaluation_code(code)
6346
        code.putln("if (%s) {" % self.test.result() )
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
6347
        self.eval_and_get(code, self.true_val)
Robert Bradshaw's avatar
Robert Bradshaw committed
6348
        code.putln("} else {")
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
6349
        self.eval_and_get(code, self.false_val)
Robert Bradshaw's avatar
Robert Bradshaw committed
6350 6351
        code.putln("}")
        self.test.generate_disposal_code(code)
6352
        self.test.free_temps(code)
Robert Bradshaw's avatar
Robert Bradshaw committed
6353

Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
6354 6355 6356 6357 6358 6359 6360
    def eval_and_get(self, code, expr):
        expr.generate_evaluation_code(code)
        expr.make_owned_reference(code)
        code.putln("%s = %s;" % (self.result(), expr.result()))
        expr.generate_post_assignment_code(code)
        expr.free_temps(code)

6361 6362 6363 6364 6365 6366 6367 6368 6369 6370
richcmp_constants = {
    "<" : "Py_LT",
    "<=": "Py_LE",
    "==": "Py_EQ",
    "!=": "Py_NE",
    "<>": "Py_NE",
    ">" : "Py_GT",
    ">=": "Py_GE",
}

6371
class CmpNode(object):
William Stein's avatar
William Stein committed
6372 6373
    #  Mixin class containing code common to PrimaryCmpNodes
    #  and CascadedCmpNodes.
6374 6375 6376

    special_bool_cmp_function = None

Stefan Behnel's avatar
typo  
Stefan Behnel committed
6377
    def infer_type(self, env):
6378 6379
        # TODO: Actually implement this (after merging with -unstable).
        return py_object_type
6380 6381 6382 6383 6384

    def calculate_cascaded_constant_result(self, operand1_result):
        func = compile_time_binary_operators[self.operator]
        operand2_result = self.operand2.constant_result
        result = func(operand1_result, operand2_result)
6385 6386 6387 6388 6389 6390 6391
        if self.cascade:
            self.cascade.calculate_cascaded_constant_result(operand2_result)
            if self.cascade.constant_result:
                self.constant_result = result and self.cascade.constant_result
        else:
            self.constant_result = result

6392 6393
    def cascaded_compile_time_value(self, operand1, denv):
        func = get_compile_time_binop(self)
6394
        operand2 = self.operand2.compile_time_value(denv)
6395 6396 6397 6398
        try:
            result = func(operand1, operand2)
        except Exception, e:
            self.compile_time_value_error(e)
6399
            result = None
6400 6401 6402
        if result:
            cascade = self.cascade
            if cascade:
6403
                # FIXME: I bet this must call cascaded_compile_time_value()
6404
                result = result and cascade.cascaded_compile_time_value(operand2, denv)
6405 6406
        return result

6407
    def is_cpp_comparison(self):
Robert Bradshaw's avatar
Robert Bradshaw committed
6408
        return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
6409

6410
    def find_common_int_type(self, env, op, operand1, operand2):
6411 6412 6413 6414 6415 6416
        # type1 != type2 and at least one of the types is not a C int
        type1 = operand1.type
        type2 = operand2.type
        type1_can_be_int = False
        type2_can_be_int = False

6417
        if isinstance(operand1, (StringNode, BytesNode, UnicodeNode)) \
6418 6419
               and operand1.can_coerce_to_char_literal():
            type1_can_be_int = True
6420
        if isinstance(operand2, (StringNode, BytesNode, UnicodeNode)) \
6421 6422 6423 6424 6425
                 and operand2.can_coerce_to_char_literal():
            type2_can_be_int = True

        if type1.is_int:
            if type2_can_be_int:
6426
                return type1
6427 6428
        elif type2.is_int:
            if type1_can_be_int:
6429
                return type2
6430 6431
        elif type1_can_be_int:
            if type2_can_be_int:
6432
                return PyrexTypes.c_uchar_type
William Stein's avatar
William Stein committed
6433

6434
        return None
6435

6436
    def find_common_type(self, env, op, operand1, common_type=None):
6437
        operand2 = self.operand2
William Stein's avatar
William Stein committed
6438 6439
        type1 = operand1.type
        type2 = operand2.type
6440

6441 6442
        new_common_type = None

Stefan Behnel's avatar
Stefan Behnel committed
6443
        # catch general errors
6444 6445 6446
        if type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or \
               type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type)):
            error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
6447
            new_common_type = error_type
Stefan Behnel's avatar
Stefan Behnel committed
6448 6449

        # try to use numeric comparisons where possible
6450
        elif type1.is_complex or type2.is_complex:
6451
            if op not in ('==', '!='):
6452 6453 6454 6455 6456 6457
                error(self.pos, "complex types are unordered")
                new_common_type = error_type
            if type1.is_pyobject:
                new_common_type = type1
            elif type2.is_pyobject:
                new_common_type = type2
6458
            else:
6459
                new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6460 6461
        elif type1.is_numeric and type2.is_numeric:
            new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
6462
        elif common_type is None or not common_type.is_pyobject:
6463
            new_common_type = self.find_common_int_type(env, op, operand1, operand2)
6464 6465

        if new_common_type is None:
Stefan Behnel's avatar
Stefan Behnel committed
6466
            # fall back to generic type compatibility tests
6467
            if type1 == type2:
6468 6469 6470 6471 6472 6473
                new_common_type = type1
            elif type1.is_pyobject or type2.is_pyobject:
                if type2.is_numeric or type2.is_string:
                    if operand2.check_for_coercion_error(type1):
                        new_common_type = error_type
                    else:
Robert Bradshaw's avatar
Robert Bradshaw committed
6474
                        new_common_type = py_object_type
6475 6476 6477 6478
                elif type1.is_numeric or type1.is_string:
                    if operand1.check_for_coercion_error(type2):
                        new_common_type = error_type
                    else:
Robert Bradshaw's avatar
Robert Bradshaw committed
6479 6480 6481
                        new_common_type = py_object_type
                elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
                    new_common_type = py_object_type
6482 6483 6484 6485
                else:
                    # one Python type and one non-Python type, not assignable
                    self.invalid_types_error(operand1, op, operand2)
                    new_common_type = error_type
6486 6487 6488 6489
            elif type1.assignable_from(type2):
                new_common_type = type1
            elif type2.assignable_from(type1):
                new_common_type = type2
6490 6491 6492 6493
            else:
                # C types that we couldn't handle up to here are an error
                self.invalid_types_error(operand1, op, operand2)
                new_common_type = error_type
6494

6495 6496 6497 6498 6499 6500
        if new_common_type.is_string and (isinstance(operand1, BytesNode) or
                                          isinstance(operand2, BytesNode)):
            # special case when comparing char* to bytes literal: must
            # compare string values!
            new_common_type = bytes_type

Stefan Behnel's avatar
Stefan Behnel committed
6501
        # recursively merge types
6502
        if common_type is None or new_common_type.is_error:
6503
            common_type = new_common_type
William Stein's avatar
William Stein committed
6504
        else:
6505 6506 6507
            # we could do a lot better by splitting the comparison
            # into a non-Python part and a Python part, but this is
            # safer for now
6508
            common_type = PyrexTypes.spanning_type(common_type, new_common_type)
6509 6510

        if self.cascade:
6511
            common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
6512

6513 6514
        return common_type

6515 6516 6517 6518
    def invalid_types_error(self, operand1, op, operand2):
        error(self.pos, "Invalid types for '%s' (%s, %s)" %
              (op, operand1.type, operand2.type))

Stefan Behnel's avatar
Stefan Behnel committed
6519
    def is_python_comparison(self):
6520 6521 6522 6523 6524
        return (not self.is_ptr_contains()
            and not self.is_c_string_contains()
            and (self.has_python_operands()
                 or (self.cascade and self.cascade.is_python_comparison())
                 or self.operator in ('in', 'not_in')))
Stefan Behnel's avatar
Stefan Behnel committed
6525

6526 6527 6528 6529 6530 6531
    def coerce_operands_to(self, dst_type, env):
        operand2 = self.operand2
        if operand2.type != dst_type:
            self.operand2 = operand2.coerce_to(dst_type, env)
        if self.cascade:
            self.cascade.coerce_operands_to(dst_type, env)
6532

6533
    def is_python_result(self):
6534
        return ((self.has_python_operands() and
6535
                 self.special_bool_cmp_function is None and
6536
                 self.operator not in ('is', 'is_not', 'in', 'not_in') and
6537 6538
                 not self.is_c_string_contains() and
                 not self.is_ptr_contains())
6539
            or (self.cascade and self.cascade.is_python_result()))
William Stein's avatar
William Stein committed
6540

6541 6542
    def is_c_string_contains(self):
        return self.operator in ('in', 'not_in') and \
6543 6544
               ((self.operand1.type.is_int
                 and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
Stefan Behnel's avatar
Stefan Behnel committed
6545
                (self.operand1.type.is_unicode_char
6546
                 and self.operand2.type is unicode_type))
6547

6548 6549
    def is_ptr_contains(self):
        if self.operator in ('in', 'not_in'):
6550 6551 6552
            container_type = self.operand2.type
            return (container_type.is_ptr or container_type.is_array) \
                and not container_type.is_string
6553

6554 6555 6556 6557 6558 6559 6560 6561 6562 6563
    def find_special_bool_compare_function(self, env):
        if self.operator in ('==', '!='):
            type1, type2 = self.operand1.type, self.operand2.type
            if type1.is_pyobject and type2.is_pyobject:
                if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
                    env.use_utility_code(pyunicode_equals_utility_code)
                    self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
                    return True
        return False

6564
    def generate_operation_code(self, code, result_code,
William Stein's avatar
William Stein committed
6565
            operand1, op , operand2):
6566
        if self.type.is_pyobject:
6567 6568 6569
            coerce_result = "__Pyx_PyBool_FromLong"
        else:
            coerce_result = ""
6570
        if 'not' in op:
6571
            negation = "!"
6572
        else:
6573
            negation = ""
6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590
        if self.special_bool_cmp_function:
            if operand1.type.is_pyobject:
                result1 = operand1.py_result()
            else:
                result1 = operand1.result()
            if operand2.type.is_pyobject:
                result2 = operand2.py_result()
            else:
                result2 = operand2.result()
            code.putln("%s = %s(%s, %s, %s); %s" % (
                result_code,
                self.special_bool_cmp_function,
                result1,
                result2,
                richcmp_constants[op],
                code.error_goto_if_neg(result_code, self.pos)))
        elif op == 'in' or op == 'not_in':
Stefan Behnel's avatar
typo  
Stefan Behnel committed
6591
            code.globalstate.use_utility_code(contains_utility_code)
6592
            if self.type.is_pyobject:
6593
                coerce_result = "__Pyx_PyBoolOrNull_FromLong"
6594
            if op == 'not_in':
6595
                negation = "__Pyx_NegateNonNeg"
6596
            if operand2.type is dict_type:
6597
                method = "PyDict_Contains"
6598
            else:
6599
                method = "PySequence_Contains"
6600
            if self.type.is_pyobject:
6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611
                error_clause = code.error_goto_if_null
                got_ref = "__Pyx_XGOTREF(%s); " % result_code
            else:
                error_clause = code.error_goto_if_neg
                got_ref = ""
            code.putln(
                "%s = %s(%s(%s(%s, %s))); %s%s" % (
                    result_code,
                    coerce_result,
                    negation,
                    method,
6612 6613
                    operand2.py_result(),
                    operand1.py_result(),
6614 6615
                    got_ref,
                    error_clause(result_code, self.pos)))
William Stein's avatar
William Stein committed
6616 6617
        elif (operand1.type.is_pyobject
            and op not in ('is', 'is_not')):
6618
                code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
6619 6620 6621
                        result_code,
                        operand1.py_result(),
                        operand2.py_result(),
6622 6623
                        richcmp_constants[op],
                        code.error_goto_if_null(result_code, self.pos)))
6624
                code.put_gotref(result_code)
6625
        elif operand1.type.is_complex:
6626
            if op == "!=":
6627
                negation = "!"
6628
            else:
6629
                negation = ""
6630
            code.putln("%s = %s(%s%s(%s, %s));" % (
6631
                result_code,
6632 6633
                coerce_result,
                negation,
6634 6635
                operand1.type.unary_op('eq'),
                operand1.result(),
6636
                operand2.result()))
William Stein's avatar
William Stein committed
6637
        else:
6638 6639 6640 6641 6642
            type1 = operand1.type
            type2 = operand2.type
            if (type1.is_extension_type or type2.is_extension_type) \
                    and not type1.same_as(type2):
                common_type = py_object_type
6643 6644
            elif type1.is_numeric:
                common_type = PyrexTypes.widest_numeric_type(type1, type2)
6645
            else:
6646 6647 6648
                common_type = type1
            code1 = operand1.result_as(common_type)
            code2 = operand2.result_as(common_type)
6649
            code.putln("%s = %s(%s %s %s);" % (
6650 6651 6652 6653
                result_code,
                coerce_result,
                code1,
                self.c_operator(op),
6654 6655
                code2))

William Stein's avatar
William Stein committed
6656 6657 6658 6659 6660 6661 6662
    def c_operator(self, op):
        if op == 'is':
            return "=="
        elif op == 'is_not':
            return "!="
        else:
            return op
6663

Stefan Behnel's avatar
typo  
Stefan Behnel committed
6664
contains_utility_code = UtilityCode(
6665
proto="""
6666 6667
static CYTHON_INLINE long __Pyx_NegateNonNeg(long b) { return unlikely(b < 0) ? b : !b; }
static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
6668 6669 6670 6671
    return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
}
""")

6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693
char_in_bytes_utility_code = UtilityCode(
proto="""
static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
""",
impl="""
static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
    const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
    char* char_start = PyBytes_AS_STRING(bytes);
    char* pos;
    for (pos=char_start; pos < char_start+length; pos++) {
        if (character == pos[0]) return 1;
    }
    return 0;
}
""")

pyunicode_in_unicode_utility_code = UtilityCode(
proto="""
static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character); /*proto*/
""",
impl="""
static CYTHON_INLINE int __Pyx_UnicodeContains(PyObject* unicode, Py_UNICODE character) {
6694
    Py_UNICODE* pos;
6695 6696
    const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
    Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);
6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711

    for (pos=char_start; pos < char_start+length; pos++) {
        if (unlikely(character == pos[0])) return 1;
    }
    return 0;
}
""")

py_ucs4_in_unicode_utility_code = UtilityCode(
proto="""
static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character); /*proto*/
""",
# additionally handles surrogate pairs in 16bit Unicode builds
impl="""
static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
6712
    Py_UNICODE* pos;
6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728
    Py_UNICODE uchar;
    const Py_ssize_t length = PyUnicode_GET_SIZE(unicode);
    Py_UNICODE* char_start = PyUnicode_AS_UNICODE(unicode);

    #if Py_UNICODE_SIZE == 2
    if (unlikely(character > 65535)) {
        Py_UNICODE high_val, low_val;
        high_val = (Py_UNICODE) (0xD800 | (((character - 0x10000) >> 10) & ((1<<10)-1)));
        low_val  = (Py_UNICODE) (0xDC00 | ( (character - 0x10000)        & ((1<<10)-1)));
        for (pos=char_start; pos < char_start+length-1; pos++) {
            if (unlikely(high_val == pos[0]) & unlikely(low_val == pos[1])) return 1;
        }
        return 0;
    }
    #endif
    uchar = (Py_UNICODE) character;
6729
    for (pos=char_start; pos < char_start+length; pos++) {
6730
        if (unlikely(uchar == pos[0])) return 1;
6731 6732 6733 6734 6735
    }
    return 0;
}
""")

6736 6737 6738 6739 6740 6741
pyunicode_equals_utility_code = UtilityCode(
proto="""
static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
""",
impl="""
static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
Stefan Behnel's avatar
Stefan Behnel committed
6742
    if (s1 == s2) {   /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775
        return (equals == Py_EQ);
    } else if (PyUnicode_CheckExact(s1) & PyUnicode_CheckExact(s2)) {
        if (PyUnicode_GET_SIZE(s1) != PyUnicode_GET_SIZE(s2)) {
            return (equals == Py_NE);
        } else if (PyUnicode_GET_SIZE(s1) == 1) {
            if (equals == Py_EQ)
                return (PyUnicode_AS_UNICODE(s1)[0] == PyUnicode_AS_UNICODE(s2)[0]);
            else
                return (PyUnicode_AS_UNICODE(s1)[0] != PyUnicode_AS_UNICODE(s2)[0]);
        } else {
            int result = PyUnicode_Compare(s1, s2);
            if ((result == -1) && unlikely(PyErr_Occurred()))
                return -1;
            return (equals == Py_EQ) ? (result == 0) : (result != 0);
        }
    } else if ((s1 == Py_None) & (s2 == Py_None)) {
        return (equals == Py_EQ);
    } else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
        return (equals == Py_NE);
    } else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
        return (equals == Py_NE);
    } else {
        int result;
        PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
        if (!py_result)
            return -1;
        result = __Pyx_PyObject_IsTrue(py_result);
        Py_DECREF(py_result);
        return result;
    }
}
""")

William Stein's avatar
William Stein committed
6776

6777
class PrimaryCmpNode(ExprNode, CmpNode):
William Stein's avatar
William Stein committed
6778 6779 6780 6781 6782 6783 6784
    #  Non-cascaded comparison or first comparison of
    #  a cascaded sequence.
    #
    #  operator      string
    #  operand1      ExprNode
    #  operand2      ExprNode
    #  cascade       CascadedCmpNode
6785

William Stein's avatar
William Stein committed
6786 6787 6788 6789
    #  We don't use the subexprs mechanism, because
    #  things here are too complicated for it to handle.
    #  Instead, we override all the framework methods
    #  which use it.
6790

Robert Bradshaw's avatar
Robert Bradshaw committed
6791
    child_attrs = ['operand1', 'operand2', 'cascade']
6792

William Stein's avatar
William Stein committed
6793
    cascade = None
6794

Robert Bradshaw's avatar
Robert Bradshaw committed
6795 6796 6797 6798 6799 6800 6801
    def infer_type(self, env):
        # TODO: Actually implement this (after merging with -unstable).
        return py_object_type

    def type_dependencies(self, env):
        return ()

6802
    def calculate_constant_result(self):
6803
        self.calculate_cascaded_constant_result(self.operand1.constant_result)
6804

6805
    def compile_time_value(self, denv):
6806
        operand1 = self.operand1.compile_time_value(denv)
6807 6808
        return self.cascaded_compile_time_value(operand1, denv)

William Stein's avatar
William Stein committed
6809 6810 6811
    def analyse_types(self, env):
        self.operand1.analyse_types(env)
        self.operand2.analyse_types(env)
6812 6813
        if self.is_cpp_comparison():
            self.analyse_cpp_comparison(env)
Robert Bradshaw's avatar
Robert Bradshaw committed
6814 6815 6816
            if self.cascade:
                error(self.pos, "Cascading comparison not yet supported for cpp types.")
            return
William Stein's avatar
William Stein committed
6817
        if self.cascade:
6818 6819
            self.cascade.analyse_types(env)

6820
        if self.operator in ('in', 'not_in'):
6821 6822 6823 6824 6825 6826 6827
            if self.is_c_string_contains():
                self.is_pycmp = False
                common_type = None
                if self.cascade:
                    error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
                    return
                if self.operand2.type is unicode_type:
6828 6829 6830 6831 6832 6833
                    self.uchar_test_type = PyrexTypes.widest_numeric_type(
                        self.operand1.type, PyrexTypes.c_py_unicode_type)
                    if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
                        env.use_utility_code(pyunicode_in_unicode_utility_code)
                    else:
                        env.use_utility_code(py_ucs4_in_unicode_utility_code)
6834 6835 6836 6837 6838 6839
                else:
                    if self.operand1.type is PyrexTypes.c_uchar_type:
                        self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
                    if self.operand2.type is not bytes_type:
                        self.operand2 = self.operand2.coerce_to(bytes_type, env)
                    env.use_utility_code(char_in_bytes_utility_code)
Stefan Behnel's avatar
Stefan Behnel committed
6840 6841
                self.operand2 = self.operand2.as_none_safe_node(
                    "argument of type 'NoneType' is not iterable")
6842 6843 6844 6845 6846 6847
            elif self.is_ptr_contains():
                if self.cascade:
                    error(self.pos, "Cascading comparison not yet supported for 'val in sliced pointer'.")
                self.type = PyrexTypes.c_bint_type
                # Will be transformed by IterationTransform
                return
6848
            else:
6849 6850
                if self.operand2.type is dict_type:
                    self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
6851 6852
                common_type = py_object_type
                self.is_pycmp = True
6853 6854 6855 6856
        elif self.find_special_bool_compare_function(env):
            common_type = None # if coercion needed, the method call above has already done it
            self.is_pycmp = False # result is bint
            self.is_temp = True # must check for error return
6857 6858 6859 6860
        else:
            common_type = self.find_common_type(env, self.operator, self.operand1)
            self.is_pycmp = common_type.is_pyobject

6861
        if common_type is not None and not common_type.is_error:
6862 6863 6864
            if self.operand1.type != common_type:
                self.operand1 = self.operand1.coerce_to(common_type, env)
            self.coerce_operands_to(common_type, env)
6865

William Stein's avatar
William Stein committed
6866 6867 6868
        if self.cascade:
            self.operand2 = self.operand2.coerce_to_simple(env)
            self.cascade.coerce_cascaded_operands_to_temp(env)
6869 6870 6871 6872 6873 6874 6875 6876
        if self.is_python_result():
            self.type = PyrexTypes.py_object_type
        else:
            self.type = PyrexTypes.c_bint_type
        cdr = self.cascade
        while cdr:
            cdr.type = self.type
            cdr = cdr.cascade
William Stein's avatar
William Stein committed
6877 6878
        if self.is_pycmp or self.cascade:
            self.is_temp = 1
6879

6880 6881 6882
    def analyse_cpp_comparison(self, env):
        type1 = self.operand1.type
        type2 = self.operand2.type
6883 6884
        entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
        if entry is None:
6885 6886
            error(self.pos, "Invalid types for '%s' (%s, %s)" %
                (self.operator, type1, type2))
6887 6888 6889
            self.type = PyrexTypes.error_type
            self.result_code = "<error>"
            return
6890 6891 6892 6893 6894
        func_type = entry.type
        if func_type.is_ptr:
            func_type = func_type.base_type
        if len(func_type.args) == 1:
            self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
6895
        else:
6896 6897 6898
            self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
            self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
        self.type = func_type.return_type
6899

William Stein's avatar
William Stein committed
6900 6901 6902
    def has_python_operands(self):
        return (self.operand1.type.is_pyobject
            or self.operand2.type.is_pyobject)
6903

William Stein's avatar
William Stein committed
6904 6905 6906
    def check_const(self):
        if self.cascade:
            self.not_const()
6907 6908 6909
            return False
        else:
            return self.operand1.check_const() and self.operand2.check_const()
William Stein's avatar
William Stein committed
6910 6911

    def calculate_result_code(self):
6912 6913 6914 6915 6916 6917 6918
        if self.operand1.type.is_complex:
            if self.operator == "!=":
                negation = "!"
            else:
                negation = ""
            return "(%s%s(%s, %s))" % (
                negation,
6919 6920
                self.operand1.type.binary_op('=='),
                self.operand1.result(),
6921
                self.operand2.result())
6922
        elif self.is_c_string_contains():
6923 6924 6925 6926 6927
            if self.operand2.type is unicode_type:
                if self.uchar_test_type is PyrexTypes.c_py_unicode_type:
                    method = "__Pyx_UnicodeContains"
                else:
                    method = "__Pyx_UnicodeContainsUCS4"
6928
            else:
6929
                method = "__Pyx_BytesContains"
6930 6931 6932 6933 6934 6935 6936
            if self.operator == "not_in":
                negation = "!"
            else:
                negation = ""
            return "(%s%s(%s, %s))" % (
                negation,
                method,
6937
                self.operand2.result(),
6938
                self.operand1.result())
6939 6940 6941 6942 6943
        else:
            return "(%s %s %s)" % (
                self.operand1.result(),
                self.c_operator(self.operator),
                self.operand2.result())
6944

William Stein's avatar
William Stein committed
6945 6946 6947 6948
    def generate_evaluation_code(self, code):
        self.operand1.generate_evaluation_code(code)
        self.operand2.generate_evaluation_code(code)
        if self.is_temp:
6949
            self.allocate_temp_result(code)
6950
            self.generate_operation_code(code, self.result(),
William Stein's avatar
William Stein committed
6951 6952 6953
                self.operand1, self.operator, self.operand2)
            if self.cascade:
                self.cascade.generate_evaluation_code(code,
6954
                    self.result(), self.operand2)
William Stein's avatar
William Stein committed
6955
            self.operand1.generate_disposal_code(code)
6956
            self.operand1.free_temps(code)
William Stein's avatar
William Stein committed
6957
            self.operand2.generate_disposal_code(code)
6958
            self.operand2.free_temps(code)
6959

William Stein's avatar
William Stein committed
6960 6961 6962 6963 6964
    def generate_subexpr_disposal_code(self, code):
        #  If this is called, it is a non-cascaded cmp,
        #  so only need to dispose of the two main operands.
        self.operand1.generate_disposal_code(code)
        self.operand2.generate_disposal_code(code)
6965

6966 6967 6968 6969 6970
    def free_subexpr_temps(self, code):
        #  If this is called, it is a non-cascaded cmp,
        #  so only need to dispose of the two main operands.
        self.operand1.free_temps(code)
        self.operand2.free_temps(code)
6971

6972 6973 6974 6975 6976
    def annotate(self, code):
        self.operand1.annotate(code)
        self.operand2.annotate(code)
        if self.cascade:
            self.cascade.annotate(code)
William Stein's avatar
William Stein committed
6977 6978 6979


class CascadedCmpNode(Node, CmpNode):
6980 6981 6982
    #  A CascadedCmpNode is not a complete expression node. It
    #  hangs off the side of another comparison node, shares
    #  its left operand with that node, and shares its result
William Stein's avatar
William Stein committed
6983 6984 6985 6986 6987 6988
    #  with the PrimaryCmpNode at the head of the chain.
    #
    #  operator      string
    #  operand2      ExprNode
    #  cascade       CascadedCmpNode

Robert Bradshaw's avatar
Robert Bradshaw committed
6989 6990
    child_attrs = ['operand2', 'cascade']

William Stein's avatar
William Stein committed
6991
    cascade = None
6992 6993
    constant_result = constant_value_not_set # FIXME: where to calculate this?

Robert Bradshaw's avatar
Robert Bradshaw committed
6994 6995 6996 6997 6998 6999 7000
    def infer_type(self, env):
        # TODO: Actually implement this (after merging with -unstable).
        return py_object_type

    def type_dependencies(self, env):
        return ()

7001 7002 7003 7004
    def has_constant_result(self):
        return self.constant_result is not constant_value_not_set and \
               self.constant_result is not not_a_constant

7005
    def analyse_types(self, env):
William Stein's avatar
William Stein committed
7006 7007
        self.operand2.analyse_types(env)
        if self.cascade:
7008
            self.cascade.analyse_types(env)
7009

William Stein's avatar
William Stein committed
7010 7011
    def has_python_operands(self):
        return self.operand2.type.is_pyobject
7012

William Stein's avatar
William Stein committed
7013 7014
    def coerce_operands_to_pyobjects(self, env):
        self.operand2 = self.operand2.coerce_to_pyobject(env)
7015 7016
        if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
            self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
William Stein's avatar
William Stein committed
7017 7018 7019 7020 7021 7022 7023 7024
        if self.cascade:
            self.cascade.coerce_operands_to_pyobjects(env)

    def coerce_cascaded_operands_to_temp(self, env):
        if self.cascade:
            #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
            self.operand2 = self.operand2.coerce_to_simple(env)
            self.cascade.coerce_cascaded_operands_to_temp(env)
7025

William Stein's avatar
William Stein committed
7026
    def generate_evaluation_code(self, code, result, operand1):
7027 7028
        if self.type.is_pyobject:
            code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
7029
            code.put_decref(result, self.type)
7030 7031
        else:
            code.putln("if (%s) {" % result)
William Stein's avatar
William Stein committed
7032
        self.operand2.generate_evaluation_code(code)
7033
        self.generate_operation_code(code, result,
William Stein's avatar
William Stein committed
7034 7035 7036 7037 7038 7039
            operand1, self.operator, self.operand2)
        if self.cascade:
            self.cascade.generate_evaluation_code(
                code, result, self.operand2)
        # Cascaded cmp result is always temp
        self.operand2.generate_disposal_code(code)
7040
        self.operand2.free_temps(code)
William Stein's avatar
William Stein committed
7041 7042
        code.putln("}")

7043 7044 7045 7046 7047
    def annotate(self, code):
        self.operand2.annotate(code)
        if self.cascade:
            self.cascade.annotate(code)

William Stein's avatar
William Stein committed
7048 7049

binop_node_classes = {
7050 7051
    "or":       BoolBinopNode,
    "and":      BoolBinopNode,
Robert Bradshaw's avatar
Robert Bradshaw committed
7052 7053 7054
    "|":        IntBinopNode,
    "^":        IntBinopNode,
    "&":        IntBinopNode,
7055 7056
    "<<":       IntBinopNode,
    ">>":       IntBinopNode,
Robert Bradshaw's avatar
Robert Bradshaw committed
7057 7058 7059
    "+":        AddNode,
    "-":        SubNode,
    "*":        MulNode,
7060 7061
    "/":        DivNode,
    "//":       DivNode,
Robert Bradshaw's avatar
Robert Bradshaw committed
7062
    "%":        ModNode,
7063
    "**":       PowNode
William Stein's avatar
William Stein committed
7064 7065
}

7066
def binop_node(pos, operator, operand1, operand2, inplace=False):
7067
    # Construct binop node of appropriate class for
William Stein's avatar
William Stein committed
7068
    # given operator.
7069 7070 7071
    return binop_node_classes[operator](pos,
        operator = operator,
        operand1 = operand1,
7072 7073
        operand2 = operand2,
        inplace = inplace)
William Stein's avatar
William Stein committed
7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085

#-------------------------------------------------------------------
#
#  Coercion nodes
#
#  Coercion nodes are special in that they are created during
#  the analyse_types phase of parse tree processing.
#  Their __init__ methods consequently incorporate some aspects
#  of that phase.
#
#-------------------------------------------------------------------

7086
class CoercionNode(ExprNode):
William Stein's avatar
William Stein committed
7087 7088 7089
    #  Abstract base class for coercion nodes.
    #
    #  arg       ExprNode       node being coerced
7090

William Stein's avatar
William Stein committed
7091
    subexprs = ['arg']
7092
    constant_result = not_a_constant
7093

William Stein's avatar
William Stein committed
7094 7095 7096 7097
    def __init__(self, arg):
        self.pos = arg.pos
        self.arg = arg
        if debug_coercion:
Stefan Behnel's avatar
Stefan Behnel committed
7098
            print("%s Coercing %s" % (self, self.arg))
7099 7100

    def calculate_constant_result(self):
7101 7102
        # constant folding can break type coercion, so this is disabled
        pass
7103

7104 7105 7106 7107 7108
    def annotate(self, code):
        self.arg.annotate(code)
        if self.arg.type != self.type:
            file, line, col = self.pos
            code.annotate((file, line, col-1), AnnotationItem(style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
William Stein's avatar
William Stein committed
7109 7110 7111 7112


class CastNode(CoercionNode):
    #  Wrap a node in a C type cast.
7113

William Stein's avatar
William Stein committed
7114 7115 7116
    def __init__(self, arg, new_type):
        CoercionNode.__init__(self, arg)
        self.type = new_type
Stefan Behnel's avatar
Stefan Behnel committed
7117 7118 7119

    def may_be_none(self):
        return self.arg.may_be_none()
7120

William Stein's avatar
William Stein committed
7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132
    def calculate_result_code(self):
        return self.arg.result_as(self.type)

    def generate_result_code(self, code):
        self.arg.generate_result_code(code)


class PyTypeTestNode(CoercionNode):
    #  This node is used to check that a generic Python
    #  object is an instance of a particular extension type.
    #  This node borrows the result of its argument node.

7133
    def __init__(self, arg, dst_type, env, notnone=False):
William Stein's avatar
William Stein committed
7134 7135
        #  The arg is know to be a Python object, and
        #  the dst_type is known to be an extension type.
Robert Bradshaw's avatar
Robert Bradshaw committed
7136
        assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
William Stein's avatar
William Stein committed
7137 7138 7139
        CoercionNode.__init__(self, arg)
        self.type = dst_type
        self.result_ctype = arg.ctype()
7140
        self.notnone = notnone
7141

7142
    nogil_check = Node.gil_error
7143
    gil_message = "Python type test"
7144

7145 7146
    def analyse_types(self, env):
        pass
Stefan Behnel's avatar
Stefan Behnel committed
7147 7148 7149 7150 7151

    def may_be_none(self):
        if self.notnone:
            return False
        return self.arg.may_be_none()
7152

7153 7154 7155
    def is_simple(self):
        return self.arg.is_simple()

William Stein's avatar
William Stein committed
7156 7157
    def result_in_temp(self):
        return self.arg.result_in_temp()
7158

William Stein's avatar
William Stein committed
7159 7160
    def is_ephemeral(self):
        return self.arg.is_ephemeral()
7161 7162 7163 7164 7165

    def calculate_constant_result(self):
        # FIXME
        pass

William Stein's avatar
William Stein committed
7166
    def calculate_result_code(self):
7167
        return self.arg.result()
7168

William Stein's avatar
William Stein committed
7169 7170
    def generate_result_code(self, code):
        if self.type.typeobj_is_available():
7171
            if not self.type.is_builtin_type:
7172
                code.globalstate.use_utility_code(type_test_utility_code)
William Stein's avatar
William Stein committed
7173
            code.putln(
Robert Bradshaw's avatar
Robert Bradshaw committed
7174
                "if (!(%s)) %s" % (
7175
                    self.type.type_test_code(self.arg.py_result(), self.notnone),
William Stein's avatar
William Stein committed
7176 7177 7178 7179
                    code.error_goto(self.pos)))
        else:
            error(self.pos, "Cannot test type of extern C class "
                "without type object name specification")
7180

William Stein's avatar
William Stein committed
7181 7182
    def generate_post_assignment_code(self, code):
        self.arg.generate_post_assignment_code(code)
7183 7184 7185

    def free_temps(self, code):
        self.arg.free_temps(code)
7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202


class NoneCheckNode(CoercionNode):
    # This node is used to check that a Python object is not None and
    # raises an appropriate exception (as specified by the creating
    # transform).

    def __init__(self, arg, exception_type_cname, exception_message):
        CoercionNode.__init__(self, arg)
        self.type = arg.type
        self.result_ctype = arg.ctype()
        self.exception_type_cname = exception_type_cname
        self.exception_message = exception_message

    def analyse_types(self, env):
        pass

7203 7204 7205
    def may_be_none(self):
        return False

7206 7207 7208
    def is_simple(self):
        return self.arg.is_simple()

7209 7210 7211 7212 7213
    def result_in_temp(self):
        return self.arg.result_in_temp()

    def calculate_result_code(self):
        return self.arg.result()
7214

7215 7216 7217 7218 7219
    def generate_result_code(self, code):
        code.putln(
            "if (unlikely(%s == Py_None)) {" % self.arg.result())
        code.putln('PyErr_SetString(%s, "%s"); %s ' % (
            self.exception_type_cname,
Stefan Behnel's avatar
Stefan Behnel committed
7220 7221
            StringEncoding.escape_byte_string(
                self.exception_message.encode('UTF-8')),
7222 7223 7224 7225 7226 7227 7228 7229 7230
            code.error_goto(self.pos)))
        code.putln("}")

    def generate_post_assignment_code(self, code):
        self.arg.generate_post_assignment_code(code)

    def free_temps(self, code):
        self.arg.free_temps(code)

7231

William Stein's avatar
William Stein committed
7232 7233 7234
class CoerceToPyTypeNode(CoercionNode):
    #  This node is used to convert a C data type
    #  to a Python object.
7235

7236
    type = py_object_type
Robert Bradshaw's avatar
Robert Bradshaw committed
7237
    is_temp = 1
William Stein's avatar
William Stein committed
7238

7239
    def __init__(self, arg, env, type=py_object_type):
William Stein's avatar
William Stein committed
7240
        CoercionNode.__init__(self, arg)
7241
        if not arg.type.create_to_py_utility_code(env):
William Stein's avatar
William Stein committed
7242
            error(arg.pos,
7243
                  "Cannot convert '%s' to Python object" % arg.type)
7244 7245 7246 7247
        if type is py_object_type:
            # be specific about some known types
            if arg.type.is_string:
                self.type = bytes_type
Stefan Behnel's avatar
Stefan Behnel committed
7248
            elif arg.type.is_unicode_char:
7249 7250 7251 7252 7253 7254
                self.type = unicode_type
            elif arg.type.is_complex:
                self.type = Builtin.complex_type
        else:
            # FIXME: check that the target type and the resulting type are compatible
            pass
7255

7256
    gil_message = "Converting to Python object"
7257

7258 7259 7260 7261
    def may_be_none(self):
        # FIXME: is this always safe?
        return False

7262
    def coerce_to_boolean(self, env):
7263 7264 7265 7266 7267 7268
        arg_type = self.arg.type
        if (arg_type == PyrexTypes.c_bint_type or
            (arg_type.is_pyobject and arg_type.name == 'bool')):
            return self.arg.coerce_to_temp(env)
        else:
            return CoerceToBooleanNode(self, env)
7269

7270 7271 7272 7273 7274 7275
    def coerce_to_integer(self, env):
        # If not already some C integer type, coerce to longint.
        if self.arg.type.is_int:
            return self.arg
        else:
            return self.arg.coerce_to(PyrexTypes.c_long_type, env)
7276

7277 7278 7279 7280
    def analyse_types(self, env):
        # The arg is always already analysed
        pass

William Stein's avatar
William Stein committed
7281 7282
    def generate_result_code(self, code):
        function = self.arg.type.to_py_function
Robert Bradshaw's avatar
Robert Bradshaw committed
7283
        code.putln('%s = %s(%s); %s' % (
7284 7285 7286
            self.result(),
            function,
            self.arg.result(),
7287
            code.error_goto_if_null(self.result(), self.pos)))
7288
        code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
7289 7290


7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330
class CoerceIntToBytesNode(CoerceToPyTypeNode):
    #  This node is used to convert a C int type to a Python bytes
    #  object.

    is_temp = 1

    def __init__(self, arg, env):
        arg = arg.coerce_to_simple(env)
        CoercionNode.__init__(self, arg)
        self.type = Builtin.bytes_type

    def generate_result_code(self, code):
        arg = self.arg
        arg_result = arg.result()
        if arg.type not in (PyrexTypes.c_char_type,
                            PyrexTypes.c_uchar_type,
                            PyrexTypes.c_schar_type):
            if arg.type.signed:
                code.putln("if ((%s < 0) || (%s > 255)) {" % (
                    arg_result, arg_result))
            else:
                code.putln("if (%s > 255) {" % arg_result)
            code.putln('PyErr_Format(PyExc_OverflowError, '
                       '"value too large to pack into a byte"); %s' % (
                           code.error_goto(self.pos)))
            code.putln('}')
        temp = None
        if arg.type is not PyrexTypes.c_char_type:
            temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
            code.putln("%s = (char)%s;" % (temp, arg_result))
            arg_result = temp
        code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
            self.result(),
            arg_result,
            code.error_goto_if_null(self.result(), self.pos)))
        if temp is not None:
            code.funcstate.release_temp(temp)
        code.put_gotref(self.py_result())


William Stein's avatar
William Stein committed
7331 7332 7333 7334 7335 7336 7337 7338
class CoerceFromPyTypeNode(CoercionNode):
    #  This node is used to convert a Python object
    #  to a C data type.

    def __init__(self, result_type, arg, env):
        CoercionNode.__init__(self, arg)
        self.type = result_type
        self.is_temp = 1
7339
        if not result_type.create_from_py_utility_code(env):
William Stein's avatar
William Stein committed
7340
            error(arg.pos,
Craig Citro's avatar
Craig Citro committed
7341
                  "Cannot convert Python object to '%s'" % result_type)
William Stein's avatar
William Stein committed
7342 7343
        if self.type.is_string and self.arg.is_ephemeral():
            error(arg.pos,
Craig Citro's avatar
Craig Citro committed
7344
                  "Obtaining char * from temporary Python value")
7345

7346 7347 7348 7349
    def analyse_types(self, env):
        # The arg is always already analysed
        pass

William Stein's avatar
William Stein committed
7350 7351
    def generate_result_code(self, code):
        function = self.type.from_py_function
7352 7353 7354 7355
        operand = self.arg.py_result()
        rhs = "%s(%s)" % (function, operand)
        if self.type.is_enum:
            rhs = typecast(self.type, c_long_type, rhs)
Robert Bradshaw's avatar
Robert Bradshaw committed
7356
        code.putln('%s = %s; %s' % (
7357
            self.result(),
7358
            rhs,
7359
            code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
7360
        if self.type.is_pyobject:
7361
            code.put_gotref(self.py_result())
William Stein's avatar
William Stein committed
7362 7363 7364 7365 7366


class CoerceToBooleanNode(CoercionNode):
    #  This node is used when a result needs to be used
    #  in a boolean context.
7367

7368
    type = PyrexTypes.c_bint_type
7369 7370 7371 7372

    _special_builtins = {
        Builtin.list_type    : 'PyList_GET_SIZE',
        Builtin.tuple_type   : 'PyTuple_GET_SIZE',
7373
        Builtin.bytes_type   : 'PyBytes_GET_SIZE',
7374 7375 7376
        Builtin.unicode_type : 'PyUnicode_GET_SIZE',
        }

William Stein's avatar
William Stein committed
7377 7378 7379 7380
    def __init__(self, arg, env):
        CoercionNode.__init__(self, arg)
        if arg.type.is_pyobject:
            self.is_temp = 1
7381

7382
    def nogil_check(self, env):
7383
        if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
7384
            self.gil_error()
7385

7386
    gil_message = "Truth-testing Python object"
7387

William Stein's avatar
William Stein committed
7388 7389 7390
    def check_const(self):
        if self.is_temp:
            self.not_const()
7391 7392
            return False
        return self.arg.check_const()
7393

William Stein's avatar
William Stein committed
7394
    def calculate_result_code(self):
7395
        return "(%s != 0)" % self.arg.result()
William Stein's avatar
William Stein committed
7396 7397

    def generate_result_code(self, code):
7398 7399 7400 7401
        if not self.is_temp:
            return
        test_func = self._special_builtins.get(self.arg.type)
        if test_func is not None:
Stefan Behnel's avatar
Stefan Behnel committed
7402
            code.putln("%s = (%s != Py_None) && (%s(%s) != 0);" % (
7403 7404 7405 7406 7407
                       self.result(),
                       self.arg.py_result(),
                       test_func,
                       self.arg.py_result()))
        else:
William Stein's avatar
William Stein committed
7408
            code.putln(
7409
                "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
7410 7411
                    self.result(),
                    self.arg.py_result(),
7412
                    code.error_goto_if_neg(self.result(), self.pos)))
William Stein's avatar
William Stein committed
7413

7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424
class CoerceToComplexNode(CoercionNode):

    def __init__(self, arg, dst_type, env):
        if arg.type.is_complex:
            arg = arg.coerce_to_simple(env)
        self.type = dst_type
        CoercionNode.__init__(self, arg)
        dst_type.create_declaration_utility_code(env)

    def calculate_result_code(self):
        if self.arg.type.is_complex:
7425 7426
            real_part = "__Pyx_CREAL(%s)" % self.arg.result()
            imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
7427 7428 7429 7430 7431 7432 7433
        else:
            real_part = self.arg.result()
            imag_part = "0"
        return "%s(%s, %s)" % (
                self.type.from_parts,
                real_part,
                imag_part)
7434

7435 7436
    def generate_result_code(self, code):
        pass
William Stein's avatar
William Stein committed
7437 7438 7439 7440 7441 7442 7443 7444 7445

class CoerceToTempNode(CoercionNode):
    #  This node is used to force the result of another node
    #  to be stored in a temporary. It is only used if the
    #  argument node's result is not already in a temporary.

    def __init__(self, arg, env):
        CoercionNode.__init__(self, arg)
        self.type = self.arg.type
7446
        self.constant_result = self.arg.constant_result
William Stein's avatar
William Stein committed
7447 7448 7449
        self.is_temp = 1
        if self.type.is_pyobject:
            self.result_ctype = py_object_type
7450 7451 7452

    gil_message = "Creating temporary Python reference"

7453 7454 7455
    def analyse_types(self, env):
        # The arg is always already analysed
        pass
7456

7457 7458
    def coerce_to_boolean(self, env):
        self.arg = self.arg.coerce_to_boolean(env)
7459 7460
        if self.arg.is_simple():
            return self.arg
7461 7462 7463
        self.type = self.arg.type
        self.result_ctype = self.type
        return self
7464

William Stein's avatar
William Stein committed
7465 7466 7467 7468
    def generate_result_code(self, code):
        #self.arg.generate_evaluation_code(code) # Already done
        # by generic generate_subexpr_evaluation_code!
        code.putln("%s = %s;" % (
7469
            self.result(), self.arg.result_as(self.ctype())))
7470
        if self.type.is_pyobject and self.use_managed_ref:
7471
            code.put_incref(self.result(), self.ctype())
William Stein's avatar
William Stein committed
7472 7473 7474 7475 7476 7477 7478


class CloneNode(CoercionNode):
    #  This node is employed when the result of another node needs
    #  to be used multiple times. The argument node's result must
    #  be in a temporary. This node "borrows" the result from the
    #  argument node, and does not generate any evaluation or
7479
    #  disposal code for it. The original owner of the argument
William Stein's avatar
William Stein committed
7480
    #  node is responsible for doing those things.
7481

William Stein's avatar
William Stein committed
7482
    subexprs = [] # Arg is not considered a subexpr
7483
    nogil_check = None
7484

William Stein's avatar
William Stein committed
7485 7486
    def __init__(self, arg):
        CoercionNode.__init__(self, arg)
7487 7488 7489 7490 7491
        if hasattr(arg, 'type'):
            self.type = arg.type
            self.result_ctype = arg.result_ctype
        if hasattr(arg, 'entry'):
            self.entry = arg.entry
7492

7493
    def result(self):
7494
        return self.arg.result()
7495

Robert Bradshaw's avatar
Robert Bradshaw committed
7496 7497
    def type_dependencies(self, env):
        return self.arg.type_dependencies(env)
7498

7499 7500
    def infer_type(self, env):
        return self.arg.infer_type(env)
Robert Bradshaw's avatar
Robert Bradshaw committed
7501

Robert Bradshaw's avatar
Robert Bradshaw committed
7502 7503 7504 7505
    def analyse_types(self, env):
        self.type = self.arg.type
        self.result_ctype = self.arg.result_ctype
        self.is_temp = 1
7506 7507
        if hasattr(self.arg, 'entry'):
            self.entry = self.arg.entry
7508

7509 7510 7511
    def is_simple(self):
        return True # result is always in a temp (or a name)

William Stein's avatar
William Stein committed
7512 7513 7514 7515 7516
    def generate_evaluation_code(self, code):
        pass

    def generate_result_code(self, code):
        pass
7517

7518
    def generate_disposal_code(self, code):
7519
        pass
7520

7521 7522
    def free_temps(self, code):
        pass
7523

7524

7525 7526
class ModuleRefNode(ExprNode):
    # Simple returns the module object
7527

7528 7529 7530
    type = py_object_type
    is_temp = False
    subexprs = []
7531

7532 7533 7534
    def analyse_types(self, env):
        pass

7535 7536 7537
    def may_be_none(self):
        return False

7538 7539 7540 7541 7542 7543 7544 7545
    def calculate_result_code(self):
        return Naming.module_cname

    def generate_result_code(self, code):
        pass

class DocstringRefNode(ExprNode):
    # Extracts the docstring of the body element
7546

7547 7548 7549
    subexprs = ['body']
    type = py_object_type
    is_temp = True
7550

7551 7552 7553 7554 7555 7556 7557 7558 7559
    def __init__(self, pos, body):
        ExprNode.__init__(self, pos)
        assert body.type.is_pyobject
        self.body = body

    def analyse_types(self, env):
        pass

    def generate_result_code(self, code):
7560 7561 7562
        code.putln('%s = __Pyx_GetAttrString(%s, "__doc__"); %s' % (
            self.result(), self.body.result(),
            code.error_goto_if_null(self.result(), self.pos)))
7563 7564 7565 7566
        code.put_gotref(self.result())



William Stein's avatar
William Stein committed
7567 7568 7569 7570 7571 7572
#------------------------------------------------------------------------------------
#
#  Runtime support code
#
#------------------------------------------------------------------------------------

7573 7574
get_name_interned_utility_code = UtilityCode(
proto = """
7575
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
7576 7577
""",
impl = """
William Stein's avatar
William Stein committed
7578 7579 7580 7581 7582 7583 7584
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
    PyObject *result;
    result = PyObject_GetAttr(dict, name);
    if (!result)
        PyErr_SetObject(PyExc_NameError, name);
    return result;
}
7585
""")
William Stein's avatar
William Stein committed
7586 7587 7588

#------------------------------------------------------------------------------------

7589 7590
import_utility_code = UtilityCode(
proto = """
7591
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
7592 7593
""",
impl = """
William Stein's avatar
William Stein committed
7594
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
7595
    PyObject *py_import = 0;
William Stein's avatar
William Stein committed
7596 7597 7598 7599 7600
    PyObject *empty_list = 0;
    PyObject *module = 0;
    PyObject *global_dict = 0;
    PyObject *empty_dict = 0;
    PyObject *list;
7601 7602
    py_import = __Pyx_GetAttrString(%(BUILTINS)s, "__import__");
    if (!py_import)
William Stein's avatar
William Stein committed
7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617
        goto bad;
    if (from_list)
        list = from_list;
    else {
        empty_list = PyList_New(0);
        if (!empty_list)
            goto bad;
        list = empty_list;
    }
    global_dict = PyModule_GetDict(%(GLOBALS)s);
    if (!global_dict)
        goto bad;
    empty_dict = PyDict_New();
    if (!empty_dict)
        goto bad;
7618
    module = PyObject_CallFunctionObjArgs(py_import,
7619
        name, global_dict, empty_dict, list, NULL);
William Stein's avatar
William Stein committed
7620 7621
bad:
    Py_XDECREF(empty_list);
7622
    Py_XDECREF(py_import);
William Stein's avatar
William Stein committed
7623 7624 7625 7626 7627 7628
    Py_XDECREF(empty_dict);
    return module;
}
""" % {
    "BUILTINS": Naming.builtins_cname,
    "GLOBALS":  Naming.module_cname,
7629
})
William Stein's avatar
William Stein committed
7630 7631 7632

#------------------------------------------------------------------------------------

7633 7634
get_exception_utility_code = UtilityCode(
proto = """
7635
static PyObject *__Pyx_GetExcValue(void); /*proto*/
7636 7637
""",
impl = """
William Stein's avatar
William Stein committed
7638 7639
static PyObject *__Pyx_GetExcValue(void) {
    PyObject *type = 0, *value = 0, *tb = 0;
7640
    PyObject *tmp_type, *tmp_value, *tmp_tb;
William Stein's avatar
William Stein committed
7641 7642 7643 7644 7645 7646 7647 7648 7649 7650
    PyObject *result = 0;
    PyThreadState *tstate = PyThreadState_Get();
    PyErr_Fetch(&type, &value, &tb);
    PyErr_NormalizeException(&type, &value, &tb);
    if (PyErr_Occurred())
        goto bad;
    if (!value) {
        value = Py_None;
        Py_INCREF(value);
    }
7651 7652 7653
    tmp_type = tstate->exc_type;
    tmp_value = tstate->exc_value;
    tmp_tb = tstate->exc_traceback;
William Stein's avatar
William Stein committed
7654 7655 7656
    tstate->exc_type = type;
    tstate->exc_value = value;
    tstate->exc_traceback = tb;
7657 7658 7659 7660 7661
    /* Make sure tstate is in a consistent state when we XDECREF
    these objects (XDECREF may run arbitrary code). */
    Py_XDECREF(tmp_type);
    Py_XDECREF(tmp_value);
    Py_XDECREF(tmp_tb);
William Stein's avatar
William Stein committed
7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672
    result = value;
    Py_XINCREF(result);
    type = 0;
    value = 0;
    tb = 0;
bad:
    Py_XDECREF(type);
    Py_XDECREF(value);
    Py_XDECREF(tb);
    return result;
}
7673
""")
William Stein's avatar
William Stein committed
7674 7675 7676

#------------------------------------------------------------------------------------

7677 7678
type_test_utility_code = UtilityCode(
proto = """
7679
static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
7680 7681
""",
impl = """
7682
static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
7683
    if (unlikely(!type)) {
William Stein's avatar
William Stein committed
7684 7685 7686
        PyErr_Format(PyExc_SystemError, "Missing type object");
        return 0;
    }
7687
    if (likely(PyObject_TypeCheck(obj, type)))
William Stein's avatar
William Stein committed
7688
        return 1;
7689 7690
    PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
                 Py_TYPE(obj)->tp_name, type->tp_name);
William Stein's avatar
William Stein committed
7691 7692
    return 0;
}
7693
""")
William Stein's avatar
William Stein committed
7694 7695 7696

#------------------------------------------------------------------------------------

7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728
find_py2_metaclass_utility_code = UtilityCode(
proto = '''
static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
''',
impl = '''
static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases) {
    PyObject *metaclass;
    /* Default metaclass */
#if PY_MAJOR_VERSION < 3
    if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
        PyObject *base = PyTuple_GET_ITEM(bases, 0);
        metaclass = PyObject_GetAttrString(base, "__class__");
        if (!metaclass) {
            PyErr_Clear();
            metaclass = (PyObject*) Py_TYPE(base);
        }
    } else {
        metaclass = (PyObject *) &PyClass_Type;
    }
#else
    if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
        PyObject *base = PyTuple_GET_ITEM(bases, 0);
        metaclass = (PyObject*) Py_TYPE(base);
    } else {
        metaclass = (PyObject *) &PyType_Type;
    }
#endif
    Py_INCREF(metaclass);
    return metaclass;
}
''')

7729 7730
create_class_utility_code = UtilityCode(
proto = """
7731
static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
7732 7733 7734 7735 7736
                                   PyObject *modname); /*proto*/
""",
impl = """
static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name,
                                   PyObject *modname) {
7737 7738
    PyObject *result;
    PyObject *metaclass;
7739 7740 7741 7742 7743 7744

    if (PyDict_SetItemString(dict, "__module__", modname) < 0)
        return NULL;

    /* Python2 __metaclass__ */
    metaclass = PyDict_GetItemString(dict, "__metaclass__");
7745 7746 7747 7748
    if (metaclass) {
        Py_INCREF(metaclass);
    } else {
        metaclass = __Pyx_FindPy2Metaclass(bases);
7749 7750 7751 7752 7753
    }
    result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL);
    Py_DECREF(metaclass);
    return result;
}
7754 7755
""",
requires = [find_py2_metaclass_utility_code])
7756 7757 7758 7759 7760

#------------------------------------------------------------------------------------

create_py3class_utility_code = UtilityCode(
proto = """
Stefan Behnel's avatar
Stefan Behnel committed
7761 7762 7763
static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/
static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/
static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw); /*proto*/
7764 7765
""",
impl = """
Stefan Behnel's avatar
Stefan Behnel committed
7766
PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) {
7767
    PyObject *metaclass = PyDict_GetItemString(mkw, "metaclass");
7768 7769 7770 7771 7772 7773 7774 7775
    if (metaclass) {
        Py_INCREF(metaclass);
        if (PyDict_DelItemString(mkw, "metaclass") < 0) {
            Py_DECREF(metaclass);
            return NULL;
        }
        return metaclass;
    }
7776
    return __Pyx_FindPy2Metaclass(bases);
7777 7778
}

Stefan Behnel's avatar
Stefan Behnel committed
7779 7780
PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *mkw,
                                    PyObject *modname, PyObject *doc) {
7781 7782 7783
    PyObject *prep;
    PyObject *pargs;
    PyObject *ns;
7784
    PyObject *str;
7785 7786

    prep = PyObject_GetAttrString(metaclass, "__prepare__");
Stefan Behnel's avatar
Stefan Behnel committed
7787
    if (!prep) {
7788
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7789
            return NULL;
7790
        PyErr_Clear();
7791
        return PyDict_New();
7792
    }
Stefan Behnel's avatar
Stefan Behnel committed
7793 7794
    pargs = PyTuple_New(2);
    if (!pargs) {
7795
        Py_DECREF(prep);
7796
        return NULL;
7797
    }
7798

Stefan Behnel's avatar
Stefan Behnel committed
7799 7800 7801 7802
    Py_INCREF(name);
    Py_INCREF(bases);
    PyTuple_SET_ITEM(pargs, 0, name);
    PyTuple_SET_ITEM(pargs, 1, bases);
7803

Stefan Behnel's avatar
Stefan Behnel committed
7804
    ns = PyObject_Call(prep, pargs, mkw);
7805

7806
    Py_DECREF(prep);
7807 7808
    Py_DECREF(pargs);

7809
    if (ns == NULL)
7810 7811 7812 7813
        return NULL;

    /* Required here to emulate assignment order */
    /* XXX: use consts here */
Stefan Behnel's avatar
Stefan Behnel committed
7814 7815 7816
    #if PY_MAJOR_VERSION >= 3
    str = PyUnicode_FromString("__module__");
    #else
7817
    str = PyString_FromString("__module__");
Stefan Behnel's avatar
Stefan Behnel committed
7818
    #endif
7819
    if (!str) {
7820
        Py_DECREF(ns);
7821
        return NULL;
7822
    }
Vitja Makarov's avatar
Vitja Makarov committed
7823

7824 7825 7826
    if (PyObject_SetItem(ns, str, modname) < 0) {
        Py_DECREF(ns);
        Py_DECREF(str);
7827
        return NULL;
7828 7829 7830
    }
    Py_DECREF(str);
    if (doc) {
Stefan Behnel's avatar
Stefan Behnel committed
7831 7832 7833
        #if PY_MAJOR_VERSION >= 3
        str = PyUnicode_FromString("__doc__");
        #else
7834
        str = PyString_FromString("__doc__");
Stefan Behnel's avatar
Stefan Behnel committed
7835
        #endif
7836 7837
        if (!str) {
            Py_DECREF(ns);
7838
            return NULL;
Vitja Makarov's avatar
Vitja Makarov committed
7839
        }
7840 7841 7842 7843
        if (PyObject_SetItem(ns, str, doc) < 0) {
            Py_DECREF(ns);
            Py_DECREF(str);
            return NULL;
Stefan Behnel's avatar
Stefan Behnel committed
7844
        }
7845
        Py_DECREF(str);
Vitja Makarov's avatar
Vitja Makarov committed
7846
    }
7847 7848 7849
    return ns;
}

Stefan Behnel's avatar
Stefan Behnel committed
7850
PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw) {
7851
    PyObject *result;
7852
    PyObject *margs = PyTuple_New(3);
7853 7854
    if (!margs)
        return NULL;
7855 7856 7857 7858 7859 7860
    Py_INCREF(name);
    Py_INCREF(bases);
    Py_INCREF(dict);
    PyTuple_SET_ITEM(margs, 0, name);
    PyTuple_SET_ITEM(margs, 1, bases);
    PyTuple_SET_ITEM(margs, 2, dict);
Stefan Behnel's avatar
Stefan Behnel committed
7861
    result = PyObject_Call(metaclass, margs, mkw);
7862
    Py_DECREF(margs);
William Stein's avatar
William Stein committed
7863 7864
    return result;
}
7865 7866
""",
requires = [find_py2_metaclass_utility_code])
William Stein's avatar
William Stein committed
7867 7868

#------------------------------------------------------------------------------------
Robert Bradshaw's avatar
Robert Bradshaw committed
7869

7870 7871
cpp_exception_utility_code = UtilityCode(
proto = """
7872 7873
#ifndef __Pyx_CppExn2PyErr
static void __Pyx_CppExn2PyErr() {
Robert Bradshaw's avatar
Robert Bradshaw committed
7874 7875 7876 7877 7878
  try {
    if (PyErr_Occurred())
      ; // let the latest Python exn pass through and ignore the current one
    else
      throw;
7879 7880 7881 7882 7883
  } catch (const std::invalid_argument& exn) {
    // Catch a handful of different errors here and turn them into the
    // equivalent Python errors.
    // Change invalid_argument to ValueError
    PyErr_SetString(PyExc_ValueError, exn.what());
Robert Bradshaw's avatar
Robert Bradshaw committed
7884
  } catch (const std::out_of_range& exn) {
7885
    // Change out_of_range to IndexError
Robert Bradshaw's avatar
Robert Bradshaw committed
7886 7887 7888 7889 7890 7891 7892 7893 7894
    PyErr_SetString(PyExc_IndexError, exn.what());
  } catch (const std::exception& exn) {
    PyErr_SetString(PyExc_RuntimeError, exn.what());
  }
  catch (...)
  {
    PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
  }
}
7895
#endif
7896 7897 7898
""",
impl = ""
)
Robert Bradshaw's avatar
Robert Bradshaw committed
7899

7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918
pyerr_occurred_withgil_utility_code= UtilityCode(
proto = """
static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
""",
impl = """
static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
  int err;
  #ifdef WITH_THREAD
  PyGILState_STATE _save = PyGILState_Ensure();
  #endif
  err = !!PyErr_Occurred();
  #ifdef WITH_THREAD
  PyGILState_Release(_save);
  #endif
  return err;
}
"""
)

Robert Bradshaw's avatar
Robert Bradshaw committed
7919
#------------------------------------------------------------------------------------
Robert Bradshaw's avatar
Robert Bradshaw committed
7920

7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954
raise_noneattr_error_utility_code = UtilityCode(
proto = """
static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname);
""",
impl = '''
static CYTHON_INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) {
    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname);
}
''')

raise_noneindex_error_utility_code = UtilityCode(
proto = """
static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void);
""",
impl = '''
static CYTHON_INLINE void __Pyx_RaiseNoneIndexingError(void) {
    PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable");
}
''')

raise_none_iter_error_utility_code = UtilityCode(
proto = """
static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
""",
impl = '''
static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
}
''')

#------------------------------------------------------------------------------------

getitem_dict_utility_code = UtilityCode(
proto = """
7955
#if PY_MAJOR_VERSION >= 3
7956
static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
7957
    PyObject *value;
7958
    if (unlikely(d == Py_None)) {
7959 7960 7961
        __Pyx_RaiseNoneIndexingError();
        return NULL;
    }
7962 7963 7964
    value = PyDict_GetItemWithError(d, key);
    if (unlikely(!value)) {
        if (!PyErr_Occurred())
7965
            PyErr_SetObject(PyExc_KeyError, key);
7966
        return NULL;
7967
    }
7968 7969
    Py_INCREF(value);
    return value;
7970
}
7971 7972 7973
#else
    #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
#endif
7974
""",
7975 7976 7977
requires = [raise_noneindex_error_utility_code])

#------------------------------------------------------------------------------------
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
7978

7979 7980 7981 7982
getitem_int_pyunicode_utility_code = UtilityCode(
proto = '''
#define __Pyx_GetItemInt_Unicode(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
                                               __Pyx_GetItemInt_Unicode_Fast(o, i) : \\
Stefan Behnel's avatar
Stefan Behnel committed
7983
                                               __Pyx_GetItemInt_Unicode_Generic(o, to_py_func(i)))
7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998

static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i) {
    if (likely((0 <= i) & (i < PyUnicode_GET_SIZE(ustring)))) {
        return PyUnicode_AS_UNICODE(ustring)[i];
    } else if ((-PyUnicode_GET_SIZE(ustring) <= i) & (i < 0)) {
        i += PyUnicode_GET_SIZE(ustring);
        return PyUnicode_AS_UNICODE(ustring)[i];
    } else {
        PyErr_SetString(PyExc_IndexError, "string index out of range");
        return (Py_UNICODE)-1;
    }
}

static CYTHON_INLINE Py_UNICODE __Pyx_GetItemInt_Unicode_Generic(PyObject* ustring, PyObject* j) {
    Py_UNICODE uchar;
7999
    PyObject *uchar_string;
8000
    if (!j) return (Py_UNICODE)-1;
8001
    uchar_string = PyObject_GetItem(ustring, j);
8002
    Py_DECREF(j);
8003 8004 8005
    if (!uchar_string) return (Py_UNICODE)-1;
    uchar = PyUnicode_AS_UNICODE(uchar_string)[0];
    Py_DECREF(uchar_string);
8006 8007
    return uchar;
}
8008
''')
8009

8010 8011
getitem_int_utility_code = UtilityCode(
proto = """
8012

8013
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
8014
    PyObject *r;
8015
    if (!j) return NULL;
8016 8017 8018 8019
    r = PyObject_GetItem(o, j);
    Py_DECREF(j);
    return r;
}
8020

8021 8022
""" + ''.join([
"""
8023 8024
#define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
                                                    __Pyx_GetItemInt_%(type)s_Fast(o, i) : \\
8025 8026
                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))

8027
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i) {
8028 8029 8030 8031 8032 8033
    if (likely(o != Py_None)) {
        if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) {
            PyObject *r = Py%(type)s_GET_ITEM(o, i);
            Py_INCREF(r);
            return r;
        }
8034 8035
        else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) {
            PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i);
8036 8037 8038
            Py_INCREF(r);
            return r;
        }
8039
    }
8040
    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
8041
}
8042 8043
""" % {'type' : type_name} for type_name in ('List', 'Tuple')
]) + """
8044

8045 8046
#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
                                                    __Pyx_GetItemInt_Fast(o, i) : \\
8047 8048
                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))

8049
static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8050
    PyObject *r;
Robert Bradshaw's avatar
Robert Bradshaw committed
8051
    if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8052 8053 8054
        r = PyList_GET_ITEM(o, i);
        Py_INCREF(r);
    }
Robert Bradshaw's avatar
Robert Bradshaw committed
8055
    else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8056 8057 8058
        r = PyTuple_GET_ITEM(o, i);
        Py_INCREF(r);
    }
8059
    else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8060
        r = PySequence_GetItem(o, i);
8061
    }
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8062
    else {
8063
        r = __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8064 8065 8066 8067
    }
    return r;
}
""",
8068 8069
impl = """
""")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8070

8071 8072


Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8073 8074
#------------------------------------------------------------------------------------

8075 8076
setitem_int_utility_code = UtilityCode(
proto = """
8077 8078
#define __Pyx_SetItemInt(o, i, v, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
                                                    __Pyx_SetItemInt_Fast(o, i, v) : \\
8079 8080
                                                    __Pyx_SetItemInt_Generic(o, to_py_func(i), v))

8081
static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8082
    int r;
8083 8084 8085 8086 8087 8088
    if (!j) return -1;
    r = PyObject_SetItem(o, j, v);
    Py_DECREF(j);
    return r;
}

8089
static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v) {
Stefan Behnel's avatar
Stefan Behnel committed
8090
    if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8091
        Py_INCREF(v);
8092
        Py_DECREF(PyList_GET_ITEM(o, i));
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8093 8094 8095
        PyList_SET_ITEM(o, i, v);
        return 1;
    }
8096 8097
    else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0)))
        return PySequence_SetItem(o, i, v);
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8098
    else {
8099
        PyObject *j = PyInt_FromSsize_t(i);
8100
        return __Pyx_SetItemInt_Generic(o, j, v);
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
8101 8102 8103
    }
}
""",
8104 8105 8106
impl = """
""")

8107 8108
#------------------------------------------------------------------------------------

8109 8110
delitem_int_utility_code = UtilityCode(
proto = """
8111 8112
#define __Pyx_DelItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \\
                                                    __Pyx_DelItemInt_Fast(o, i) : \\
8113 8114
                                                    __Pyx_DelItem_Generic(o, to_py_func(i)))

8115
static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) {
8116
    int r;
8117 8118 8119 8120 8121 8122
    if (!j) return -1;
    r = PyObject_DelItem(o, j);
    Py_DECREF(j);
    return r;
}

8123
static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i) {
8124 8125
    if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0))
        return PySequence_DelItem(o, i);
8126
    else {
8127
        PyObject *j = PyInt_FromSsize_t(i);
8128
        return __Pyx_DelItem_Generic(o, j);
8129 8130 8131 8132 8133 8134 8135 8136
    }
}
""",
impl = """
""")

#------------------------------------------------------------------------------------

8137 8138
raise_too_many_values_to_unpack = UtilityCode(
proto = """
8139
static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
8140 8141
""",
impl = '''
8142 8143 8144 8145 8146 8147 8148
static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
    PyErr_Format(PyExc_ValueError,
        #if PY_VERSION_HEX < 0x02050000
            "too many values to unpack (expected %d)", (int)expected);
        #else
            "too many values to unpack (expected %zd)", expected);
        #endif
8149 8150 8151 8152 8153
}
''')

raise_need_more_values_to_unpack = UtilityCode(
proto = """
8154
static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
8155 8156
""",
impl = '''
8157
static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169
    PyErr_Format(PyExc_ValueError,
        #if PY_VERSION_HEX < 0x02050000
                 "need more than %d value%s to unpack", (int)index,
        #else
                 "need more than %zd value%s to unpack", index,
        #endif
                 (index == 1) ? "" : "s");
}
''')

#------------------------------------------------------------------------------------

8170 8171 8172
tuple_unpacking_error_code = UtilityCode(
proto = """
static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/
8173
""",
8174 8175 8176 8177 8178 8179 8180
impl = """
static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
    if (t == Py_None) {
      __Pyx_RaiseNoneNotIterableError();
    } else if (PyTuple_GET_SIZE(t) < index) {
      __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
    } else {
8181
      __Pyx_RaiseTooManyValuesError(index);
8182 8183
    }
}
8184
""",
8185 8186 8187 8188 8189
requires = [raise_none_iter_error_utility_code,
            raise_need_more_values_to_unpack,
            raise_too_many_values_to_unpack]
)

8190 8191 8192
unpacking_utility_code = UtilityCode(
proto = """
static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/
8193
static int __Pyx_EndUnpack(PyObject *, Py_ssize_t expected); /*proto*/
8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205
""",
impl = """
static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) {
    PyObject *item;
    if (!(item = PyIter_Next(iter))) {
        if (!PyErr_Occurred()) {
            __Pyx_RaiseNeedMoreValuesError(index);
        }
    }
    return item;
}

8206
static int __Pyx_EndUnpack(PyObject *iter, Py_ssize_t expected) {
8207 8208 8209
    PyObject *item;
    if ((item = PyIter_Next(iter))) {
        Py_DECREF(item);
8210
        __Pyx_RaiseTooManyValuesError(expected);
8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221
        return -1;
    }
    else if (!PyErr_Occurred())
        return 0;
    else
        return -1;
}
""",
requires = [raise_need_more_values_to_unpack,
            raise_too_many_values_to_unpack]
)
Robert Bradshaw's avatar
Robert Bradshaw committed
8222

8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234
#------------------------------------------------------------------------------------

# CPython supports calling functions with non-dict kwargs by
# converting them to a dict first

kwargs_call_utility_code = UtilityCode(
proto = """
static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject*, PyObject*, PyObject*); /*proto*/
""",
impl = """
static PyObject* __Pyx_PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) {
    PyObject* result;
8235
    if (likely(PyDict_Check(kwargs))) {
8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246
        return PyEval_CallObjectWithKeywords(callable, args, kwargs);
    } else {
        PyObject* real_dict;
        real_dict = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, kwargs, NULL);
        if (unlikely(!real_dict))
            return NULL;
        result = PyEval_CallObjectWithKeywords(callable, args, real_dict);
        Py_DECREF(real_dict);
        return result; /* may be NULL */
    }
}
8247
""",
8248 8249
)

Robert Bradshaw's avatar
Robert Bradshaw committed
8250 8251 8252 8253 8254

#------------------------------------------------------------------------------------

int_pow_utility_code = UtilityCode(
proto="""
8255
static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */
Robert Bradshaw's avatar
Robert Bradshaw committed
8256 8257
""",
impl="""
8258
static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
Robert Bradshaw's avatar
Robert Bradshaw committed
8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279
    %(type)s t = b;
    switch (e) {
        case 3:
            t *= b;
        case 2:
            t *= b;
        case 1:
            return t;
        case 0:
            return 1;
    }
    if (unlikely(e<0)) return 0;
    t = 1;
    while (likely(e)) {
        t *= (b * (e&1)) | ((~e)&1);    /* 1 or b */
        b *= b;
        e >>= 1;
    }
    return t;
}
""")
8280 8281 8282

# ------------------------------ Division ------------------------------------

8283 8284
div_int_utility_code = UtilityCode(
proto="""
8285
static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
8286 8287
""",
impl="""
8288
static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
8289 8290 8291 8292 8293
    %(type)s q = a / b;
    %(type)s r = a - q*b;
    q -= ((r != 0) & ((r ^ b) < 0));
    return q;
}
8294 8295
""")

8296
mod_int_utility_code = UtilityCode(
8297
proto="""
8298
static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8299 8300
""",
impl="""
8301
static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8302 8303 8304
    %(type)s r = a %% b;
    r += ((r != 0) & ((r ^ b) < 0)) * b;
    return r;
8305 8306 8307
}
""")

8308
mod_float_utility_code = UtilityCode(
8309
proto="""
8310
static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
8311 8312
""",
impl="""
8313
static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
8314 8315 8316
    %(type)s r = fmod%(math_h_modifier)s(a, b);
    r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
    return r;
8317 8318
}
""")
Robert Bradshaw's avatar
Robert Bradshaw committed
8319

8320
cdivision_warning_utility_code = UtilityCode(
Robert Bradshaw's avatar
Robert Bradshaw committed
8321
proto="""
8322
static int __Pyx_cdivision_warning(void); /* proto */
Robert Bradshaw's avatar
Robert Bradshaw committed
8323 8324
""",
impl="""
8325
static int __Pyx_cdivision_warning(void) {
8326
    return PyErr_WarnExplicit(PyExc_RuntimeWarning,
8327
                              "division with oppositely signed operands, C and Python semantics differ",
8328
                              %(FILENAME)s,
8329
                              %(LINENO)s,
8330
                              __Pyx_MODULE_NAME,
8331
                              NULL);
Robert Bradshaw's avatar
Robert Bradshaw committed
8332
}
8333 8334 8335 8336
""" % {
    'FILENAME': Naming.filename_cname,
    'LINENO':  Naming.lineno_cname,
})
8337 8338 8339 8340 8341 8342 8343

# from intobject.c
division_overflow_test_code = UtilityCode(
proto="""
#define UNARY_NEG_WOULD_OVERFLOW(x)	\
	(((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
""")
Robert Bradshaw's avatar
Robert Bradshaw committed
8344 8345 8346 8347 8348 8349 8350 8351 8352 8353


binding_cfunc_utility_code = UtilityCode(
proto="""
#define %(binding_cfunc)s_USED 1

typedef struct {
    PyCFunctionObject func;
} %(binding_cfunc)s_object;

8354 8355
static PyTypeObject %(binding_cfunc)s_type;
static PyTypeObject *%(binding_cfunc)s = NULL;
Robert Bradshaw's avatar
Robert Bradshaw committed
8356

8357
static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
Robert Bradshaw's avatar
Robert Bradshaw committed
8358 8359
#define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)

8360
static int %(binding_cfunc)s_init(void); /* proto */
Robert Bradshaw's avatar
Robert Bradshaw committed
8361 8362 8363
""" % Naming.__dict__,
impl="""

8364
static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
Robert Bradshaw's avatar
Robert Bradshaw committed
8365 8366 8367 8368 8369 8370 8371 8372
	%(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
    if (op == NULL)
        return NULL;
	op->func.m_ml = ml;
	Py_XINCREF(self);
	op->func.m_self = self;
	Py_XINCREF(module);
	op->func.m_module = module;
8373
	PyObject_GC_Track(op);
Robert Bradshaw's avatar
Robert Bradshaw committed
8374 8375 8376 8377
	return (PyObject *)op;
}

static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
8378
	PyObject_GC_UnTrack(m);
Robert Bradshaw's avatar
Robert Bradshaw committed
8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389
	Py_XDECREF(m->func.m_self);
	Py_XDECREF(m->func.m_module);
    PyObject_GC_Del(m);
}

static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
	if (obj == Py_None)
		obj = NULL;
	return PyMethod_New(func, obj, type);
}

8390
static int %(binding_cfunc)s_init(void) {
Robert Bradshaw's avatar
Robert Bradshaw committed
8391
    %(binding_cfunc)s_type = PyCFunction_Type;
8392
    %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
Robert Bradshaw's avatar
Robert Bradshaw committed
8393 8394 8395 8396 8397 8398 8399 8400 8401 8402
    %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
    %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get;
    if (PyType_Ready(&%(binding_cfunc)s_type) < 0) {
        return -1;
    }
    %(binding_cfunc)s = &%(binding_cfunc)s_type;
    return 0;

}
""" % Naming.__dict__)