Esempio n. 1
0
 def emit_unsigned_int_cast(self, type: RType) -> str:
     if is_int32_rprimitive(type):
         return '(uint32_t)'
     elif is_int64_rprimitive(type):
         return '(uint64_t)'
     else:
         return ''
Esempio n. 2
0
    def emit_box(self, src: str, dest: str, typ: RType, declare_dest: bool = False,
                 can_borrow: bool = False) -> None:
        """Emit code for boxing a value of given type.

        Generate a simple assignment if no boxing is needed.

        The source reference count is stolen for the result (no need to decref afterwards).
        """
        # TODO: Always generate a new reference (if a reference type)
        if declare_dest:
            declaration = 'PyObject *'
        else:
            declaration = ''
        if is_int_rprimitive(typ) or is_short_int_rprimitive(typ):
            # Steal the existing reference if it exists.
            self.emit_line('{}{} = CPyTagged_StealAsObject({});'.format(declaration, dest, src))
        elif is_bool_rprimitive(typ) or is_bit_rprimitive(typ):
            # N.B: bool is special cased to produce a borrowed value
            # after boxing, so we don't need to increment the refcount
            # when this comes directly from a Box op.
            self.emit_lines('{}{} = {} ? Py_True : Py_False;'.format(declaration, dest, src))
            if not can_borrow:
                self.emit_inc_ref(dest, object_rprimitive)
        elif is_none_rprimitive(typ):
            # N.B: None is special cased to produce a borrowed value
            # after boxing, so we don't need to increment the refcount
            # when this comes directly from a Box op.
            self.emit_lines('{}{} = Py_None;'.format(declaration, dest))
            if not can_borrow:
                self.emit_inc_ref(dest, object_rprimitive)
        elif is_int32_rprimitive(typ):
            self.emit_line('{}{} = PyLong_FromLong({});'.format(declaration, dest, src))
        elif is_int64_rprimitive(typ):
            self.emit_line('{}{} = PyLong_FromLongLong({});'.format(declaration, dest, src))
        elif isinstance(typ, RTuple):
            self.declare_tuple_struct(typ)
            self.emit_line('{}{} = PyTuple_New({});'.format(declaration, dest, len(typ.types)))
            self.emit_line('if (unlikely({} == NULL))'.format(dest))
            self.emit_line('    CPyError_OutOfMemory();')
            # TODO: Fail if dest is None
            for i in range(0, len(typ.types)):
                if not typ.is_unboxed:
                    self.emit_line('PyTuple_SET_ITEM({}, {}, {}.f{}'.format(dest, i, src, i))
                else:
                    inner_name = self.temp_name()
                    self.emit_box('{}.f{}'.format(src, i), inner_name, typ.types[i],
                                  declare_dest=True)
                    self.emit_line('PyTuple_SET_ITEM({}, {}, {});'.format(dest, i, inner_name))
        else:
            assert not typ.is_unboxed
            # Type is boxed -- trivially just assign.
            self.emit_line('{}{} = {};'.format(declaration, dest, src))
Esempio n. 3
0
 def visit_load_int(self, op: LoadInt) -> None:
     dest = self.reg(op)
     if is_int32_rprimitive(op.type) or is_int64_rprimitive(op.type):
         self.emit_line('%s = %d;' % (dest, op.value))
     else:
         self.emit_line('%s = %d;' % (dest, op.value * 2))