|
27 | 27 | from mypyc.ir.rtypes import ( |
28 | 28 | RType, RUnion, RInstance, optional_value_type, int_rprimitive, float_rprimitive, |
29 | 29 | bool_rprimitive, list_rprimitive, str_rprimitive, is_none_rprimitive, object_rprimitive, |
30 | | - c_pyssize_t_rprimitive, is_short_int_rprimitive, is_tagged, PyVarObject, short_int_rprimitive |
| 30 | + c_pyssize_t_rprimitive, is_short_int_rprimitive, is_tagged, PyVarObject, short_int_rprimitive, |
| 31 | + is_list_rprimitive, is_tuple_rprimitive, is_dict_rprimitive, is_set_rprimitive, PySetObject |
31 | 32 | ) |
32 | 33 | from mypyc.ir.func_ir import FuncDecl, FuncSignature |
33 | 34 | from mypyc.ir.class_ir import ClassIR, all_concrete_classes |
|
45 | 46 | ) |
46 | 47 | from mypyc.primitives.tuple_ops import list_tuple_op, new_tuple_op |
47 | 48 | from mypyc.primitives.dict_ops import ( |
48 | | - dict_update_in_display_op, dict_new_op, dict_build_op |
| 49 | + dict_update_in_display_op, dict_new_op, dict_build_op, dict_size_op |
49 | 50 | ) |
50 | 51 | from mypyc.primitives.generic_ops import ( |
51 | | - py_getattr_op, py_call_op, py_call_with_kwargs_op, py_method_call_op |
| 52 | + py_getattr_op, py_call_op, py_call_with_kwargs_op, py_method_call_op, generic_len_op |
52 | 53 | ) |
53 | 54 | from mypyc.primitives.misc_ops import ( |
54 | 55 | none_op, none_object_op, false_op, fast_isinstance_op, bool_op, type_is_op |
@@ -704,7 +705,7 @@ def add_bool_branch(self, value: Value, true: BasicBlock, false: BasicBlock) -> |
704 | 705 | zero = self.add(LoadInt(0)) |
705 | 706 | value = self.binary_op(value, zero, '!=', value.line) |
706 | 707 | elif is_same_type(value.type, list_rprimitive): |
707 | | - length = self.list_len(value, value.line) |
| 708 | + length = self.builtin_len(value, value.line) |
708 | 709 | zero = self.add(LoadInt(0)) |
709 | 710 | value = self.binary_op(length, zero, '!=', value.line) |
710 | 711 | elif (isinstance(value.type, RInstance) and value.type.class_ir.is_ext_class |
@@ -811,12 +812,29 @@ def matching_call_c(self, |
811 | 812 | def binary_int_op(self, type: RType, lhs: Value, rhs: Value, op: int, line: int) -> Value: |
812 | 813 | return self.add(BinaryIntOp(type, lhs, rhs, op, line)) |
813 | 814 |
|
814 | | - def list_len(self, val: Value, line: int) -> Value: |
815 | | - elem_address = self.add(GetElementPtr(val, PyVarObject, 'ob_size')) |
816 | | - size_value = self.add(LoadMem(c_pyssize_t_rprimitive, elem_address)) |
817 | | - offset = self.add(LoadInt(1, -1, rtype=c_pyssize_t_rprimitive)) |
818 | | - return self.binary_int_op(short_int_rprimitive, size_value, offset, |
819 | | - BinaryIntOp.LEFT_SHIFT, -1) |
| 815 | + def builtin_len(self, val: Value, line: int) -> Value: |
| 816 | + typ = val.type |
| 817 | + if is_list_rprimitive(typ) or is_tuple_rprimitive(typ): |
| 818 | + elem_address = self.add(GetElementPtr(val, PyVarObject, 'ob_size')) |
| 819 | + size_value = self.add(LoadMem(c_pyssize_t_rprimitive, elem_address)) |
| 820 | + offset = self.add(LoadInt(1, line, rtype=c_pyssize_t_rprimitive)) |
| 821 | + return self.binary_int_op(short_int_rprimitive, size_value, offset, |
| 822 | + BinaryIntOp.LEFT_SHIFT, line) |
| 823 | + elif is_dict_rprimitive(typ): |
| 824 | + size_value = self.call_c(dict_size_op, [val], line) |
| 825 | + offset = self.add(LoadInt(1, line, rtype=c_pyssize_t_rprimitive)) |
| 826 | + return self.binary_int_op(short_int_rprimitive, size_value, offset, |
| 827 | + BinaryIntOp.LEFT_SHIFT, line) |
| 828 | + elif is_set_rprimitive(typ): |
| 829 | + elem_address = self.add(GetElementPtr(val, PySetObject, 'used')) |
| 830 | + size_value = self.add(LoadMem(c_pyssize_t_rprimitive, elem_address)) |
| 831 | + offset = self.add(LoadInt(1, line, rtype=c_pyssize_t_rprimitive)) |
| 832 | + return self.binary_int_op(short_int_rprimitive, size_value, offset, |
| 833 | + BinaryIntOp.LEFT_SHIFT, line) |
| 834 | + # generic case |
| 835 | + else: |
| 836 | + return self.call_c(generic_len_op, [val], line) |
| 837 | + |
820 | 838 | # Internal helpers |
821 | 839 |
|
822 | 840 | def decompose_union_helper(self, |
|
0 commit comments