示例#1
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'
示例#2
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'
示例#3
0
 def matching_primitive_op(self,
                           candidates: List[OpDescription],
                           args: List[Value],
                           line: int,
                           result_type: Optional[RType] = None) -> Optional[Value]:
     # Find the highest-priority primitive op that matches.
     matching = None  # type: Optional[OpDescription]
     for desc in candidates:
         if len(desc.arg_types) != len(args):
             continue
         if all(is_subtype(actual.type, formal)
                for actual, formal in zip(args, desc.arg_types)):
             if matching:
                 assert matching.priority != desc.priority, 'Ambiguous:\n1) %s\n2) %s' % (
                     matching, desc)
                 if desc.priority > matching.priority:
                     matching = desc
             else:
                 matching = desc
     if matching:
         target = self.primitive_op(matching, args, line)
         if result_type and not is_runtime_subtype(target.type, result_type):
             if is_none_rprimitive(result_type):
                 # Special case None return. The actual result may actually be a bool
                 # and so we can't just coerce it.
                 target = self.none()
             else:
                 target = self.coerce(target, result_type, line)
         return target
     return None
示例#4
0
    def coerce(self, src: Value, target_type: RType, line: int, force: bool = False) -> Value:
        """Generate a coercion/cast from one type to other (only if needed).

        For example, int -> object boxes the source int; int -> int emits nothing;
        object -> int unboxes the object. All conversions preserve object value.

        If force is true, always generate an op (even if it is just an assignment) so
        that the result will have exactly target_type as the type.

        Returns the register with the converted value (may be same as src).
        """
        if src.type.is_unboxed and not target_type.is_unboxed:
            return self.box(src)
        if ((src.type.is_unboxed and target_type.is_unboxed)
                and not is_runtime_subtype(src.type, target_type)):
            # To go from one unboxed type to another, we go through a boxed
            # in-between value, for simplicity.
            tmp = self.box(src)
            return self.unbox_or_cast(tmp, target_type, line)
        if ((not src.type.is_unboxed and target_type.is_unboxed)
                or not is_subtype(src.type, target_type)):
            return self.unbox_or_cast(src, target_type, line)
        elif force:
            tmp = self.alloc_temp(target_type)
            self.add(Assign(tmp, src))
            return tmp
        return src
示例#5
0
 def matching_call_c(
         self,
         candidates: List[CFunctionDescription],
         args: List[Value],
         line: int,
         result_type: Optional[RType] = None) -> Optional[Value]:
     # TODO: this function is very similar to matching_primitive_op
     # we should remove the old one or refactor both them into only as we move forward
     matching = None  # type: Optional[CFunctionDescription]
     for desc in candidates:
         if len(desc.arg_types) != len(args):
             continue
         if all(
                 is_subtype(actual.type, formal)
                 for actual, formal in zip(args, desc.arg_types)):
             if matching:
                 assert matching.priority != desc.priority, 'Ambiguous:\n1) %s\n2) %s' % (
                     matching, desc)
                 if desc.priority > matching.priority:
                     matching = desc
             else:
                 matching = desc
     if matching:
         target = self.call_c(matching, args, line, result_type)
         return target
     return None
示例#6
0
 def assert_emit_binary_op(self, op: str, dest: Value, left: Value,
                           right: Value, expected: str) -> None:
     if op in binary_ops:
         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])):
                 args = [left, right]
                 if desc.ordering is not None:
                     args = [args[i] for i in desc.ordering]
                 self.assert_emit(
                     CallC(desc.c_function_name, args, desc.return_type,
                           desc.steals, desc.is_borrowed, desc.error_kind,
                           55), expected)
                 return
     else:
         assert False, 'Could not find matching op'
示例#7
0
 def visit_runion(self, left: RUnion) -> bool:
     return is_subtype(left, self.right)
示例#8
0
 def visit_rinstance(self, left: RInstance) -> bool:
     return is_subtype(left, self.right)
示例#9
0
 def test_bool(self) -> None:
     assert not is_subtype(bool_rprimitive, bit_rprimitive)
     assert is_subtype(bool_rprimitive, int_rprimitive)