Esempio n. 1
0
 def assign(self, target: Union[Register, AssignmentTarget],
            rvalue_reg: Value, line: int) -> None:
     if isinstance(target, Register):
         self.add(Assign(target, rvalue_reg))
     elif isinstance(target, AssignmentTargetRegister):
         rvalue_reg = self.coerce(rvalue_reg, target.type, line)
         self.add(Assign(target.register, rvalue_reg))
     elif isinstance(target, AssignmentTargetAttr):
         if isinstance(target.obj_type, RInstance):
             rvalue_reg = self.coerce(rvalue_reg, target.type, line)
             self.add(SetAttr(target.obj, target.attr, rvalue_reg, line))
         else:
             key = self.load_static_unicode(target.attr)
             boxed_reg = self.builder.box(rvalue_reg)
             self.add(
                 PrimitiveOp([target.obj, key, boxed_reg], py_setattr_op,
                             line))
     elif isinstance(target, AssignmentTargetIndex):
         target_reg2 = self.gen_method_call(target.base, '__setitem__',
                                            [target.index, rvalue_reg],
                                            None, line)
         assert target_reg2 is not None, target.base.type
     elif isinstance(target, AssignmentTargetTuple):
         if isinstance(rvalue_reg.type, RTuple) and target.star_idx is None:
             rtypes = rvalue_reg.type.types
             assert len(rtypes) == len(target.items)
             for i in range(len(rtypes)):
                 item_value = self.add(TupleGet(rvalue_reg, i, line))
                 self.assign(target.items[i], item_value, line)
         else:
             self.process_iterator_tuple_assignment(target, rvalue_reg,
                                                    line)
     else:
         assert False, 'Unsupported assignment target'
Esempio n. 2
0
 def assert_emit_binary_op(self,
                           op: str,
                           dest: Value,
                           left: Value,
                           right: Value,
                           expected: str) -> None:
     # TODO: merge this
     if op in c_binary_ops:
         c_ops = c_binary_ops[op]
         for c_desc in c_ops:
             if (is_subtype(left.type, c_desc.arg_types[0])
                     and is_subtype(right.type, c_desc.arg_types[1])):
                 args = [left, right]
                 if c_desc.ordering is not None:
                     args = [args[i] for i in c_desc.ordering]
                 self.assert_emit(CallC(c_desc.c_function_name, args, c_desc.return_type,
                                        c_desc.steals, c_desc.error_kind, 55), expected)
                 return
     ops = binary_ops[op]
     for desc in ops:
         if (is_subtype(left.type, desc.arg_types[0])
                 and is_subtype(right.type, desc.arg_types[1])):
             self.assert_emit(PrimitiveOp([left, right], desc, 55), expected)
             break
     else:
         assert False, 'Could not find matching op'
Esempio n. 3
0
    def py_get_attr(self, obj: Value, attr: str, line: int) -> Value:
        """Get a Python attribute (slow).

        Prefer get_attr() which generates optimized code for native classes.
        """
        key = self.load_static_unicode(attr)
        return self.add(PrimitiveOp([obj, key], py_getattr_op, line))
Esempio n. 4
0
 def test_new_list(self) -> None:
     self.assert_emit(PrimitiveOp([self.n, self.m], new_list_op, 55),
                      """cpy_r_r0 = PyList_New(2);
                         if (likely(cpy_r_r0 != NULL)) {
                             PyList_SET_ITEM(cpy_r_r0, 0, cpy_r_n);
                             PyList_SET_ITEM(cpy_r_r0, 1, cpy_r_m);
                         }
                      """)
Esempio n. 5
0
 def primitive_op(self, desc: OpDescription, args: List[Value], line: int) -> Value:
     assert desc.result_type is not None
     coerced = []
     for i, arg in enumerate(args):
         formal_type = self.op_arg_type(desc, i)
         arg = self.coerce(arg, formal_type, line)
         coerced.append(arg)
     target = self.add(PrimitiveOp(coerced, desc, line))
     return target
Esempio n. 6
0
def transform_name_expr(builder: IRBuilder, expr: NameExpr) -> Value:
    assert expr.node, "RefExpr not resolved"
    fullname = expr.node.fullname
    if fullname in builtin_names:
        typ, src = builtin_names[fullname]
        return builder.add(LoadAddress(typ, src, expr.line))
    # special cases
    if fullname == 'builtins.None':
        return builder.none()
    if fullname == 'builtins.True':
        return builder.true()
    if fullname == 'builtins.False':
        return builder.false()
    if fullname in name_ref_ops:
        # Use special access op for this particular name.
        desc = name_ref_ops[fullname]
        assert desc.result_type is not None
        return builder.add(PrimitiveOp([], desc, expr.line))

    if isinstance(expr.node, Var) and expr.node.is_final:
        value = builder.emit_load_final(
            expr.node,
            fullname,
            expr.name,
            builder.is_native_ref_expr(expr),
            builder.types[expr],
            expr.line,
        )
        if value is not None:
            return value

    if isinstance(expr.node,
                  MypyFile) and expr.node.fullname in builder.imports:
        return builder.load_module(expr.node.fullname)

    # If the expression is locally defined, then read the result from the corresponding
    # assignment target and return it. Otherwise if the expression is a global, load it from
    # the globals dictionary.
    # Except for imports, that currently always happens in the global namespace.
    if expr.kind == LDEF and not (isinstance(expr.node, Var)
                                  and expr.node.is_suppressed_import):
        # Try to detect and error when we hit the irritating mypy bug
        # where a local variable is cast to None. (#5423)
        if (isinstance(expr.node, Var)
                and is_none_rprimitive(builder.node_type(expr))
                and expr.node.is_inferred):
            builder.error(
                "Local variable '{}' has inferred type None; add an annotation"
                .format(expr.node.name), expr.node.line)

        # TODO: Behavior currently only defined for Var and FuncDef node types.
        return builder.read(builder.get_assignment_target(expr), expr.line)

    return builder.load_global(expr)
Esempio n. 7
0
 def assert_emit_binary_op(self, op: str, dest: Value, left: Value,
                           right: Value, expected: str) -> None:
     ops = binary_ops[op]
     for desc in ops:
         if (is_subtype(left.type, desc.arg_types[0])
                 and is_subtype(right.type, desc.arg_types[1])):
             self.assert_emit(PrimitiveOp([left, right], desc, 55),
                              expected)
             break
     else:
         assert False, 'Could not find matching op'
Esempio n. 8
0
def transform_del_item(builder: IRBuilder, target: AssignmentTarget,
                       line: int) -> None:
    if isinstance(target, AssignmentTargetIndex):
        builder.gen_method_call(target.base,
                                '__delitem__', [target.index],
                                result_type=None,
                                line=line)
    elif isinstance(target, AssignmentTargetAttr):
        key = builder.load_static_unicode(target.attr)
        builder.add(PrimitiveOp([target.obj, key], py_delattr_op, line))
    elif isinstance(target, AssignmentTargetRegister):
        # Delete a local by assigning an error value to it, which will
        # prompt the insertion of uninit checks.
        builder.add(
            Assign(target.register,
                   builder.add(LoadErrorValue(target.type, undefines=True))))
    elif isinstance(target, AssignmentTargetTuple):
        for subtarget in target.items:
            transform_del_item(builder, subtarget, line)
Esempio n. 9
0
 def test_load_True(self) -> None:
     self.assert_emit(PrimitiveOp([], true_op, 0), "cpy_r_r0 = 1;")
Esempio n. 10
0
 def test_load_None(self) -> None:
     self.assert_emit(PrimitiveOp([], none_object_op, 0),
                      "cpy_r_r0 = Py_None;")
Esempio n. 11
0
 def test_new_dict(self) -> None:
     self.assert_emit(PrimitiveOp([], new_dict_op, 1),
                      """cpy_r_r0 = PyDict_New();""")
Esempio n. 12
0
 def test_dict_update(self) -> None:
     self.assert_emit(
         PrimitiveOp([self.d, self.o], dict_update_op, 1),
         """cpy_r_r0 = CPyDict_Update(cpy_r_d, cpy_r_o) >= 0;""")
Esempio n. 13
0
 def py_get_attr(self, obj: Value, attr: str, line: int) -> Value:
     key = self.load_static_unicode(attr)
     return self.add(PrimitiveOp([obj, key], py_getattr_op, line))
Esempio n. 14
0
 def none_object(self) -> Value:
     """Load Python None value (type: object_rprimitive)."""
     return self.add(PrimitiveOp([], none_object_op, line=-1))
Esempio n. 15
0
 def load_len(self) -> Value:
     return self.builder.add(PrimitiveOp([self.builder.read(self.expr_target, self.line)],
                                         list_len_op, self.line))
Esempio n. 16
0
 def test_list_get_item(self) -> None:
     self.assert_emit(PrimitiveOp([self.m, self.k], list_get_item_op, 55),
                      """cpy_r_r0 = CPyList_GetItem(cpy_r_m, cpy_r_k);""")
Esempio n. 17
0
 def test_list_len(self) -> None:
     self.assert_emit(
         PrimitiveOp([self.l], list_len_op, 55), """Py_ssize_t __tmp1;
                         __tmp1 = PyList_GET_SIZE(cpy_r_l);
                         cpy_r_r0 = CPyTagged_ShortFromSsize_t(__tmp1);
                      """)
Esempio n. 18
0
 def test_int_neg(self) -> None:
     self.assert_emit(PrimitiveOp([self.m], int_neg_op, 55),
                      "cpy_r_r0 = CPyTagged_Negate(cpy_r_m);")
Esempio n. 19
0
 def test_load_False(self) -> None:
     self.assert_emit(PrimitiveOp([], false_op, 0), "cpy_r_r0 = 0;")
Esempio n. 20
0
 def test_list_append(self) -> None:
     self.assert_emit(
         PrimitiveOp([self.l, self.o], list_append_op, 1),
         """cpy_r_r0 = PyList_Append(cpy_r_l, cpy_r_o) >= 0;""")
Esempio n. 21
0
 def none(self) -> Value:
     """Load unboxed None value (type: none_rprimitive)."""
     return self.add(PrimitiveOp([], none_op, line=-1))
Esempio n. 22
0
 def test_dict_set_item(self) -> None:
     self.assert_emit(
         PrimitiveOp([self.d, self.o, self.o2], dict_set_item_op, 1),
         """cpy_r_r0 = CPyDict_SetItem(cpy_r_d, cpy_r_o, cpy_r_o2) >= 0;""")
Esempio n. 23
0
 def test_list_set_item(self) -> None:
     self.assert_emit(
         PrimitiveOp([self.l, self.n, self.o], list_set_item_op, 55),
         """cpy_r_r0 = CPyList_SetItem(cpy_r_l, cpy_r_n, cpy_r_o);""")
Esempio n. 24
0
 def none_object(self) -> Value:
     return self.add(PrimitiveOp([], none_object_op, line=-1))