예제 #1
0
def push_field(self, num, value):
    ptr = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[num])
    TP = lltype.typeOf(value)
    T = lltype.Ptr(rffi.CArray(TP))

    # Handle bitfields
    for c in unroll_letters_for_numbers:
        if LL_TYPEMAP[c] is TP and self.shape.ll_bitsizes:
            # Modify the current value with the bitfield changed
            bitsize = self.shape.ll_bitsizes[num]
            numbits = NUM_BITS(bitsize)
            lowbit = LOW_BIT(bitsize)
            if numbits:
                value = widen(value)
                current = widen(rffi.cast(T, ptr)[0])
                bitmask = BIT_MASK(numbits)
                current &= ~(bitmask << lowbit)
                current |= (value & bitmask) << lowbit
                value = rffi.cast(TP, current)
            break

    rffi.cast(T, ptr)[0] = value
예제 #2
0
def pack_float(fmtiter):
    doubleval = fmtiter.accept_float_arg()
    floatval = r_singlefloat(doubleval)
    value = longlong2float.singlefloat2uint(floatval)
    value = widen(value)
    if fmtiter.bigendian:
        for i in range_4_unroll:
            x = (value >> (8*i)) & 0xff
            fmtiter.result.append(chr(x))
    else:
        for i in range_4_unroll:
            fmtiter.result.append(chr(value & 0xff))
            value >>= 8
예제 #3
0
def pack_float(fmtiter):
    doubleval = fmtiter.accept_float_arg()
    floatval = r_singlefloat(doubleval)
    value = longlong2float.singlefloat2uint(floatval)
    value = widen(value)
    if fmtiter.bigendian:
        for i in range_4_unroll:
            x = (value >> (8 * i)) & 0xff
            fmtiter.result.append(chr(x))
    else:
        for i in range_4_unroll:
            fmtiter.result.append(chr(value & 0xff))
            value >>= 8
예제 #4
0
def push_field(self, num, value):
    ptr = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[num])
    TP = lltype.typeOf(value)
    T = lltype.Ptr(rffi.CArray(TP))

    # Handle bitfields
    for c in unroll_letters_for_numbers:
        if LL_TYPEMAP[c] is TP and self.shape.ll_bitsizes:
            # Modify the current value with the bitfield changed
            bitsize = self.shape.ll_bitsizes[num]
            numbits = NUM_BITS(bitsize)
            lowbit = LOW_BIT(bitsize)
            if numbits:
                value = widen(value)
                current = widen(rffi.cast(T, ptr)[0])
                bitmask = BIT_MASK(numbits)
                current &= ~ (bitmask << lowbit)
                current |= (value & bitmask) << lowbit
                value = rffi.cast(TP, current)
            break

    rffi.cast(T, ptr)[0] = value
예제 #5
0
 def wrap(self, x):
     "Wraps the Python value 'x' into one of the wrapper classes."
     # You might notice that this function is rather conspicuously
     # not RPython.  We can get away with this because the function
     # is specialized (see after the function body).  Also worth
     # noting is that the isinstance's involving integer types
     # behave rather differently to how you might expect during
     # annotation (see pypy/annotation/builtin.py)
     if x is None:
         return self.w_None
     if isinstance(x, model.W_Object):
         raise TypeError, "attempt to wrap already wrapped object: %s" % (
             x, )
     if isinstance(x, OperationError):
         raise TypeError, ("attempt to wrap already wrapped exception: %s" %
                           (x, ))
     if isinstance(x, int):
         if isinstance(x, bool):
             return self.newbool(x)
         else:
             return self.newint(x)
     if isinstance(x, str):
         return wrapstr(self, x)
     if isinstance(x, unicode):
         return wrapunicode(self, x)
     if isinstance(x, float):
         return W_FloatObject(x)
     if isinstance(x, Wrappable):
         w_result = x.__spacebind__(self)
         #print 'wrapping', x, '->', w_result
         return w_result
     if isinstance(x, base_int):
         if self.config.objspace.std.withsmalllong:
             from pypy.objspace.std.smalllongobject import W_SmallLongObject
             from pypy.rlib.rarithmetic import r_longlong, r_ulonglong
             from pypy.rlib.rarithmetic import longlongmax
             if (not isinstance(x, r_ulonglong)
                     or x <= r_ulonglong(longlongmax)):
                 return W_SmallLongObject(r_longlong(x))
         x = widen(x)
         if isinstance(x, int):
             return self.newint(x)
         else:
             return W_LongObject.fromrarith_int(x)
     return self._wrap_not_rpython(x)
예제 #6
0
def ll_alloc_and_set(LIST, count, item):
    if count < 0:
        count = 0
    l = LIST.ll_newlist(count)
    T = typeOf(item)
    if T is Char or T is UniChar:
        check = ord(item)
    elif isinstance(T, Number):
        check = widen(item)
    else:
        check = item
    if (not malloc_zero_filled) or check: # as long as malloc it is known to zero the allocated memory avoid zeroing twice
    
        i = 0
        while i < count:
            l.ll_setitem_fast(i, item)
            i += 1
    return l
예제 #7
0
 def wrap(self, x):
     "Wraps the Python value 'x' into one of the wrapper classes."
     # You might notice that this function is rather conspicuously
     # not RPython.  We can get away with this because the function
     # is specialized (see after the function body).  Also worth
     # noting is that the isinstance's involving integer types
     # behave rather differently to how you might expect during
     # annotation (see pypy/annotation/builtin.py)
     if x is None:
         return self.w_None
     if isinstance(x, model.W_Object):
         raise TypeError, "attempt to wrap already wrapped object: %s"%(x,)
     if isinstance(x, OperationError):
         raise TypeError, ("attempt to wrap already wrapped exception: %s"%
                           (x,))
     if isinstance(x, int):
         if isinstance(x, bool):
             return self.newbool(x)
         else:
             return self.newint(x)
     if isinstance(x, str):
         return wrapstr(self, x)
     if isinstance(x, unicode):
         return wrapunicode(self, x)
     if isinstance(x, float):
         return W_FloatObject(x)
     if isinstance(x, Wrappable):
         w_result = x.__spacebind__(self)
         #print 'wrapping', x, '->', w_result
         return w_result
     if isinstance(x, base_int):
         if self.config.objspace.std.withsmalllong:
             from pypy.objspace.std.smalllongobject import W_SmallLongObject
             from pypy.rlib.rarithmetic import r_longlong, r_ulonglong
             from pypy.rlib.rarithmetic import longlongmax
             if (not isinstance(x, r_ulonglong)
                 or x <= r_ulonglong(longlongmax)):
                 return W_SmallLongObject(r_longlong(x))
         x = widen(x)
         if isinstance(x, int):
             return self.newint(x)
         else:
             return W_LongObject.fromrarith_int(x)
     return self._wrap_not_rpython(x)
예제 #8
0
def ll_alloc_and_set(LIST, count, item):
    if count < 0:
        count = 0
    l = LIST.ll_newlist(count)
    T = typeOf(item)
    if T is Char or T is UniChar:
        check = ord(item)
    elif isinstance(T, Number):
        check = widen(item)
    else:
        check = item
    if (
            not malloc_zero_filled
    ) or check:  # as long as malloc it is known to zero the allocated memory avoid zeroing twice

        i = 0
        while i < count:
            l.ll_setitem_fast(i, item)
            i += 1
    return l
예제 #9
0
def cast_pos(self, i, ll_t):
    pos = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[i])
    TP = lltype.Ptr(rffi.CArray(ll_t))
    value = rffi.cast(TP, pos)[0]

    # Handle bitfields
    for c in unroll_letters_for_numbers:
        if LL_TYPEMAP[c] is ll_t and self.shape.ll_bitsizes:
            bitsize = self.shape.ll_bitsizes[i]
            numbits = NUM_BITS(bitsize)
            lowbit = LOW_BIT(bitsize)
            if numbits:
                value = widen(value)
                value >>= lowbit
                value &= BIT_MASK(numbits)
                if ll_t is lltype.Bool or signedtype(ll_t._type):
                    sign = (value >> (numbits - 1)) & 1
                    if sign:
                        value = value - (1 << numbits)
                value = rffi.cast(ll_t, value)
            break

    return value
예제 #10
0
def cast_pos(self, i, ll_t):
    pos = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[i])
    TP = lltype.Ptr(rffi.CArray(ll_t))
    value = rffi.cast(TP, pos)[0]

    # Handle bitfields
    for c in unroll_letters_for_numbers:
        if LL_TYPEMAP[c] is ll_t and self.shape.ll_bitsizes:
            bitsize = self.shape.ll_bitsizes[i]
            numbits = NUM_BITS(bitsize)
            lowbit = LOW_BIT(bitsize)
            if numbits:
                value = widen(value)
                value >>= lowbit
                value &= BIT_MASK(numbits)
                if ll_t is lltype.Bool or signedtype(ll_t._type):
                    sign = (value >> (numbits - 1)) & 1
                    if sign:
                        value = value - (1 << numbits)
                value = rffi.cast(ll_t, value)
            break

    return value
예제 #11
0
 def f(i):
     l = [r_short(0)] * 10
     l[i + 1] = r_short(3)
     return rarithmetic.widen(l[i])
예제 #12
0
 def str_format(self, item):
     return str(widen(self.unbox(item)))
예제 #13
0
 def for_computation(self, v):
     return widen(v)
예제 #14
0
 def for_computation(self, v):
     return widen(v)
예제 #15
0
 def f(i):
     l = [r_short(0)] * 10
     l[i + 1] = r_short(3)
     return rarithmetic.widen(l[i])
예제 #16
0
def make_array(mytype):
    W_ArrayBase = globals()['W_ArrayBase']

    class W_Array(W_ArrayBase):
        itemsize = mytype.bytes
        typecode = mytype.typecode

        @staticmethod
        def register(typeorder):
            typeorder[W_Array] = [(W_ArrayBase, None)]

        def __init__(self, space):
            self.space = space
            self.len = 0
            self.allocated = 0
            self.buffer = lltype.nullptr(mytype.arraytype)

        def item_w(self, w_item):
            space = self.space
            unwrap = getattr(space, mytype.unwrap)
            item = unwrap(w_item)
            if mytype.unwrap == 'bigint_w':
                try:
                    item = item.touint()
                except (ValueError, OverflowError):
                    msg = 'unsigned %d-byte integer out of range' % \
                          mytype.bytes
                    raise OperationError(space.w_OverflowError,
                                         space.wrap(msg))
                return rffi.cast(mytype.itemtype, item)
            if mytype.unwrap == 'str_w' or mytype.unwrap == 'unicode_w':
                if len(item) != 1:
                    msg = 'array item must be char'
                    raise OperationError(space.w_TypeError, space.wrap(msg))
                item = item[0]
                return rffi.cast(mytype.itemtype, item)
            #
            # "regular" case: it fits in an rpython integer (lltype.Signed)
            result = rffi.cast(mytype.itemtype, item)
            if mytype.canoverflow:
                if rffi.cast(lltype.Signed, result) != item:
                    # overflow.  build the correct message
                    if item < 0:
                        msg = ('signed %d-byte integer is less than minimum' %
                               mytype.bytes)
                    else:
                        msg = ('signed %d-byte integer is greater than maximum'
                               % mytype.bytes)
                    if not mytype.signed:
                        msg = 'un' + msg      # 'signed' => 'unsigned'
                    raise OperationError(space.w_OverflowError,
                                         space.wrap(msg))
            return result

        def __del__(self):
            # note that we don't call clear_all_weakrefs here because
            # an array with freed buffer is ok to see - it's just empty with 0
            # length
            self.setlen(0)

        def setlen(self, size, zero=False, overallocate=True):
            if size > 0:
                if size > self.allocated or size < self.allocated / 2:
                    if overallocate:
                        if size < 9:
                            some = 3
                        else:
                            some = 6
                        some += size >> 3
                    else:
                        some = 0
                    self.allocated = size + some
                    if zero:
                        new_buffer = lltype.malloc(mytype.arraytype,
                                                   self.allocated, flavor='raw',
                                                   add_memory_pressure=True,
                                                   zero=True)
                    else:
                        new_buffer = lltype.malloc(mytype.arraytype,
                                                   self.allocated, flavor='raw',
                                                   add_memory_pressure=True)
                        for i in range(min(size, self.len)):
                            new_buffer[i] = self.buffer[i]
                else:
                    self.len = size
                    return
            else:
                assert size == 0
                self.allocated = 0
                new_buffer = lltype.nullptr(mytype.arraytype)

            if self.buffer:
                lltype.free(self.buffer, flavor='raw')
            self.buffer = new_buffer
            self.len = size

        def fromsequence(self, w_seq):
            space = self.space
            oldlen = self.len
            try:
                new = space.len_w(w_seq)
                self.setlen(self.len + new)
            except OperationError:
                pass

            i = 0
            try:
                if mytype.typecode == 'u':
                    myiter = space.unpackiterable
                else:
                    myiter = space.listview
                for w_i in myiter(w_seq):
                    if oldlen + i >= self.len:
                        self.setlen(oldlen + i + 1)
                    self.buffer[oldlen + i] = self.item_w(w_i)
                    i += 1
            except OperationError:
                self.setlen(oldlen + i)
                raise
            self.setlen(oldlen + i)

        def fromstring(self, s):
            if len(s) % self.itemsize != 0:
                msg = 'string length not a multiple of item size'
                raise OperationError(self.space.w_ValueError, self.space.wrap(msg))
            oldlen = self.len
            new = len(s) / mytype.bytes
            self.setlen(oldlen + new)
            cbuf = self._charbuf_start()
            for i in range(len(s)):
                cbuf[oldlen * mytype.bytes + i] = s[i]
            self._charbuf_stop()

        def fromlist(self, w_lst):
            s = self.len
            try:
                self.fromsequence(w_lst)
            except OperationError:
                self.setlen(s)
                raise

        def extend(self, w_iterable, accept_different_array=False):
            space = self.space
            if isinstance(w_iterable, W_Array):
                oldlen = self.len
                new = w_iterable.len
                self.setlen(self.len + new)
                i = 0
                while i < new:
                    if oldlen + i >= self.len:
                        self.setlen(oldlen + i + 1)
                    self.buffer[oldlen + i] = w_iterable.buffer[i]
                    i += 1
                self.setlen(oldlen + i)
            elif (not accept_different_array
                  and isinstance(w_iterable, W_ArrayBase)):
                msg = "can only extend with array of same kind"
                raise OperationError(space.w_TypeError, space.wrap(msg))
            else:
                self.fromsequence(w_iterable)

        def _charbuf_start(self):
            return rffi.cast(rffi.CCHARP, self.buffer)

        def _charbuf_stop(self):
            keepalive_until_here(self)

        def w_getitem(self, space, idx):
            item = self.buffer[idx]
            if mytype.typecode in 'bBhHil':
                item = rffi.cast(lltype.Signed, item)
            elif mytype.typecode == 'f':
                item = float(item)
            return space.wrap(item)

    # Basic get/set/append/extend methods

    def len__Array(space, self):
        return space.wrap(self.len)

    def getitem__Array_ANY(space, self, w_idx):
        idx, stop, step = space.decode_index(w_idx, self.len)
        assert step == 0
        return self.w_getitem(space, idx)

    def getitem__Array_Slice(space, self, w_slice):
        start, stop, step, size = space.decode_index4(w_slice, self.len)
        w_a = mytype.w_class(self.space)
        w_a.setlen(size, overallocate=False)
        assert step != 0
        j = 0
        for i in range(start, stop, step):
            w_a.buffer[j] = self.buffer[i]
            j += 1
        return w_a

    def getslice__Array_ANY_ANY(space, self, w_i, w_j):
        return space.getitem(self, space.newslice(w_i, w_j, space.w_None))

    def setitem__Array_ANY_ANY(space, self, w_idx, w_item):
        idx, stop, step = space.decode_index(w_idx, self.len)
        if step != 0:
            msg = 'can only assign array to array slice'
            raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
        item = self.item_w(w_item)
        self.buffer[idx] = item

    def setitem__Array_Slice_Array(space, self, w_idx, w_item):
        start, stop, step, size = self.space.decode_index4(w_idx, self.len)
        assert step != 0
        if w_item.len != size or self is w_item:
            # XXX this is a giant slow hack
            w_lst = array_tolist__Array(space, self)
            w_item = space.call_method(w_item, 'tolist')
            space.setitem(w_lst, w_idx, w_item)
            self.setlen(0)
            self.fromsequence(w_lst)
        else:
            j = 0
            for i in range(start, stop, step):
                self.buffer[i] = w_item.buffer[j]
                j += 1

    def setslice__Array_ANY_ANY_ANY(space, self, w_i, w_j, w_x):
        space.setitem(self, space.newslice(w_i, w_j, space.w_None), w_x)

    def array_append__Array_ANY(space, self, w_x):
        x = self.item_w(w_x)
        self.setlen(self.len + 1)
        self.buffer[self.len - 1] = x

    def array_extend__Array_ANY(space, self, w_iterable):
        self.extend(w_iterable)

    # List interface
    def array_count__Array_ANY(space, self, w_val):
        cnt = 0
        for i in range(self.len):
            w_item = self.w_getitem(space, i)
            if space.is_true(space.eq(w_item, w_val)):
                cnt += 1
        return space.wrap(cnt)

    def array_index__Array_ANY(space, self, w_val):
        cnt = 0
        for i in range(self.len):
            w_item = self.w_getitem(space, i)
            if space.is_true(space.eq(w_item, w_val)):
                return space.wrap(i)
        msg = 'array.index(x): x not in list'
        raise OperationError(space.w_ValueError, space.wrap(msg))

    def array_reverse__Array(space, self):
        b = self.buffer
        for i in range(self.len / 2):
            b[i], b[self.len - i - 1] = b[self.len - i - 1], b[i]

    def array_pop__Array_ANY(space, self, w_idx):
        i = space.int_w(w_idx)
        if i < 0:
            i += self.len
        if i < 0 or i >= self.len:
            msg = 'pop index out of range'
            raise OperationError(space.w_IndexError, space.wrap(msg))
        w_val = self.w_getitem(space, i)
        while i < self.len - 1:
            self.buffer[i] = self.buffer[i + 1]
            i += 1
        self.setlen(self.len - 1)
        return w_val

    def array_remove__Array_ANY(space, self, w_val):
        w_idx = array_index__Array_ANY(space, self, w_val)
        array_pop__Array_ANY(space, self, w_idx)

    def array_insert__Array_ANY_ANY(space, self, w_idx, w_val):
        idx = space.int_w(w_idx)
        if idx < 0:
            idx += self.len
        if idx < 0:
            idx = 0
        if idx > self.len:
            idx = self.len

        val = self.item_w(w_val)
        self.setlen(self.len + 1)
        i = self.len - 1
        while i > idx:
            self.buffer[i] = self.buffer[i - 1]
            i -= 1
        self.buffer[i] = val

    def delitem__Array_ANY(space, self, w_idx):
        # XXX this is a giant slow hack
        w_lst = array_tolist__Array(space, self)
        space.delitem(w_lst, w_idx)
        self.setlen(0)
        self.fromsequence(w_lst)

    def delslice__Array_ANY_ANY(space, self, w_i, w_j):
        return space.delitem(self, space.newslice(w_i, w_j, space.w_None))

    # Add and mul methods

    def add__Array_Array(space, self, other):
        a = mytype.w_class(space)
        a.setlen(self.len + other.len, overallocate=False)
        for i in range(self.len):
            a.buffer[i] = self.buffer[i]
        for i in range(other.len):
            a.buffer[i + self.len] = other.buffer[i]
        return a

    def inplace_add__Array_Array(space, self, other):
        oldlen = self.len
        otherlen = other.len
        self.setlen(oldlen + otherlen)
        for i in range(otherlen):
            self.buffer[oldlen + i] = other.buffer[i]
        return self

    def mul__Array_ANY(space, self, w_repeat):
        return _mul_helper(space, self, w_repeat, False)

    def mul__ANY_Array(space, w_repeat, self):
        return _mul_helper(space, self, w_repeat, False)

    def inplace_mul__Array_ANY(space, self, w_repeat):
        return _mul_helper(space, self, w_repeat, True)

    def _mul_helper(space, self, w_repeat, is_inplace):
        try:
            repeat = space.getindex_w(w_repeat, space.w_OverflowError)
        except OperationError, e:
            if e.match(space, space.w_TypeError):
                raise FailedToImplement
            raise
        repeat = max(repeat, 0)
        try:
            newlen = ovfcheck(self.len * repeat)
        except OverflowError:
            raise MemoryError
        oldlen = self.len
        if is_inplace:
            a = self
            start = 1
        else:
            a = mytype.w_class(space)
            start = 0
        # <a performance hack>
        if oldlen == 1:
            if mytype.unwrap == 'str_w' or mytype.unwrap == 'unicode_w':
                zero = not ord(self.buffer[0])
            elif mytype.unwrap == 'int_w' or mytype.unwrap == 'bigint_w':
                zero = not widen(self.buffer[0])
            #elif mytype.unwrap == 'float_w':
            #    value = ...float(self.buffer[0])  xxx handle the case of -0.0
            else:
                zero = False
            if zero:
                a.setlen(newlen, zero=True, overallocate=False)
                return a
            a.setlen(newlen, overallocate=False)
            item = self.buffer[0]
            for r in range(start, repeat):
                a.buffer[r] = item
            return a
        # </a performance hack>
        a.setlen(newlen, overallocate=False)
        for r in range(start, repeat):
            for i in range(oldlen):
                a.buffer[r * oldlen + i] = self.buffer[i]
        return a
예제 #17
0
def tagged_eq(x, y):
    # please rpython :(
    return rarithmetic.widen(x) == rarithmetic.widen(y)
예제 #18
0
def untag(value):
    value = rarithmetic.widen(value)
    tagbits = value&TAGMASK
    return value>>2, tagbits
예제 #19
0
파일: rbigint.py 프로젝트: xx312022850/pypy
def args_from_rarith_int(x):
    return args_from_rarith_int1(widen(x))
예제 #20
0
def tagged_eq(x, y):
    # please rpython :(
    return rarithmetic.widen(x) == rarithmetic.widen(y)
예제 #21
0
def untag(value):
    value = rarithmetic.widen(value)
    tagbits = value&TAGMASK
    return value>>2, tagbits