class VRawBufferValue(AbstractVArrayValue): is_about_raw = True def __init__(self, cpu, logops, size, keybox, source_op): AbstractVirtualValue.__init__(self, keybox, source_op) # note that size is unused, because we assume that the buffer is big # enough to write/read everything we need. If it's not, it's undefined # behavior anyway, although in theory we could probably detect such # cases here self.size = size self.buffer = RawBuffer(cpu, logops) def getintbound(self): return IntUnbounded() def getlength(self): return len(self.buffer.values) def get_item_value(self, i): return self.buffer.values[i] def set_item_value(self, i, newval): self.buffer.values[i] = newval def getitem_raw(self, offset, length, descr): if not self.is_virtual(): raise InvalidRawOperation # see 'test_virtual_raw_buffer_forced_but_slice_not_forced' # for the test above: it's not enough to check is_virtual() # on the original object, because it might be a VRawSliceValue # instead. If it is a virtual one, then we'll reach here anway. return self.buffer.read_value(offset, length, descr) def setitem_raw(self, offset, length, descr, value): if not self.is_virtual(): raise InvalidRawOperation self.buffer.write_value(offset, length, descr, value) def _really_force(self, optforce): op = self.source_op assert op is not None if not we_are_translated(): op.name = "FORCE " + self.source_op.name optforce.emit_operation(self.source_op) self.box = self.source_op.result for i in range(len(self.buffer.offsets)): # write the value offset = self.buffer.offsets[i] descr = self.buffer.descrs[i] itemvalue = self.buffer.values[i] itembox = itemvalue.force_box(optforce) op = ResOperation(rop.RAW_STORE, [self.box, ConstInt(offset), itembox], None, descr=descr) optforce.emit_operation(op) @specialize.argtype(1) def _visitor_dispatch_virtual_type(self, visitor): # I *think* we need to make a copy of offsets and descrs because we # want a snapshot of the virtual state right now: if we grow more # elements later, we don't want them to go in this virtual state return visitor.visit_vrawbuffer(self.size, self.buffer.offsets[:], self.buffer.descrs[:])
def __init__(self, cpu, logops, size, keybox, source_op): AbstractVirtualValue.__init__(self, keybox, source_op) # note that size is unused, because we assume that the buffer is big # enough to write/read everything we need. If it's not, it's undefined # behavior anyway, although in theory we could probably detect such # cases here self.size = size self.buffer = RawBuffer(cpu, logops)
def test_read_value(): buf = RawBuffer(FakeCPU()) buf.write_value(0, 4, 'descr', 'one') buf.write_value(4, 4, 'descr', 'two') assert buf.read_value(0, 4, 'descr') == 'one' assert buf.read_value(4, 4, 'descr') == 'two' with py.test.raises(InvalidRawRead): buf.read_value(0, 2, 'descr') with py.test.raises(InvalidRawRead): buf.read_value(8, 2, 'descr') with py.test.raises(InvalidRawRead): buf.read_value(0, 4, 'another descr')
def test_write_value_invalid_length(): buf = RawBuffer(FakeCPU()) buf.write_value(0, 4, 'descr1', 'one') with py.test.raises(InvalidRawWrite): buf.write_value(0, 5, 'descr1', 'two') with py.test.raises(InvalidRawWrite): buf.write_value(0, 4, 'descr2', 'two')
def test_write_value(): buf = RawBuffer(FakeCPU()) buf.write_value(8, 4, 'descr3', 'three') buf.write_value(0, 4, 'descr1', 'one') buf.write_value(4, 2, 'descr2', 'two') buf.write_value(12, 2, 'descr4', 'four') assert buf._get_memory() == [ (0, 4, 'descr1', 'one'), (4, 2, 'descr2', 'two'), (8, 4, 'descr3', 'three'), (12, 2, 'descr4', 'four'), ]
def test_write_value(): buf = RawBuffer(FakeCPU()) buf.write_value(8, 4, 'descr3', 'three') buf.write_value(0, 4, 'descr1', 'one') buf.write_value(4, 2, 'descr2', 'two') buf.write_value(12, 2, 'descr4', 'four') assert buf._get_memory() == [ ( 0, 4, 'descr1', 'one'), ( 4, 2, 'descr2', 'two'), ( 8, 4, 'descr3', 'three'), (12, 2, 'descr4', 'four'), ]
def test_write_value_update(): buf = RawBuffer(FakeCPU()) buf.write_value(0, 4, 'descr', 'one') buf.write_value(4, 2, 'descr', 'two') buf.write_value(0, 4, 'descr', 'ONE') assert buf._get_memory() == [ (0, 4, 'descr', 'ONE'), (4, 2, 'descr', 'two'), ]
def test_write_value_update(): buf = RawBuffer(FakeCPU()) buf.write_value(0, 4, 'descr', 'one') buf.write_value(4, 2, 'descr', 'two') buf.write_value(0, 4, 'descr', 'ONE') assert buf._get_memory() == [ ( 0, 4, 'descr', 'ONE'), ( 4, 2, 'descr', 'two'), ]
def __init__(self, cpu, size=-1): self.size = size if self.size != -1: self.buffer = RawBuffer(cpu, None)
def test_unpack_descrs(): ArrayS_8_1 = object() ArrayS_8_2 = object() ArrayU_8 = object() class FakeCPU(object): def unpack_arraydescr_size(self, descr): if descr in (ArrayS_8_1, ArrayS_8_2): return 0, 8, True return 0, 8, False buf = RawBuffer(FakeCPU()) buf.write_value(0, 4, ArrayS_8_1, 'one') assert buf.read_value(0, 4, ArrayS_8_1) == 'one' assert buf.read_value(0, 4, ArrayS_8_2) == 'one' # with a non-identical descr # buf.write_value(0, 4, ArrayS_8_2, 'two') # with a non-identical descr assert buf.read_value(0, 4, ArrayS_8_1) == 'two' # with py.test.raises(InvalidRawRead): buf.read_value(0, 4, ArrayU_8) with py.test.raises(InvalidRawWrite): buf.write_value(0, 4, ArrayU_8, 'three')
def test_write_value_overlapping_next(): buf = RawBuffer(FakeCPU()) buf.write_value(0, 4, 'descr', 'one') buf.write_value(6, 4, 'descr', 'two') with py.test.raises(InvalidRawWrite): buf.write_value(4, 4, 'descr', 'three')
def test_write_value_overlapping_prev(): buf = RawBuffer(FakeCPU()) buf.write_value(0, 4, 'descr', 'one') with py.test.raises(InvalidRawWrite): buf.write_value(2, 1, 'descr', 'two')
class VRawBufferValue(AbstractVArrayValue): is_about_raw = True def __init__(self, cpu, logops, size, keybox, source_op): AbstractVirtualValue.__init__(self, keybox, source_op) # note that size is unused, because we assume that the buffer is big # enough to write/read everything we need. If it's not, it's undefined # behavior anyway, although in theory we could probably detect such # cases here self.size = size self.buffer = RawBuffer(cpu, logops) def getintbound(self): return IntUnbounded() def getlength(self): return len(self.buffer.values) def get_item_value(self, i): return self.buffer.values[i] def set_item_value(self, i, newval): self.buffer.values[i] = newval def getitem_raw(self, offset, length, descr): if not self.is_virtual(): raise InvalidRawOperation # see 'test_virtual_raw_buffer_forced_but_slice_not_forced' # for the test above: it's not enough to check is_virtual() # on the original object, because it might be a VRawSliceValue # instead. If it is a virtual one, then we'll reach here anway. return self.buffer.read_value(offset, length, descr) def setitem_raw(self, offset, length, descr, value): if not self.is_virtual(): raise InvalidRawOperation self.buffer.write_value(offset, length, descr, value) def _really_force(self, optforce): op = self.source_op assert op is not None if not we_are_translated(): op.name = 'FORCE ' + self.source_op.name optforce.emit_operation(self.source_op) self.box = self.source_op.result for i in range(len(self.buffer.offsets)): # write the value offset = self.buffer.offsets[i] descr = self.buffer.descrs[i] itemvalue = self.buffer.values[i] itembox = itemvalue.force_box(optforce) op = ResOperation(rop.RAW_STORE, [self.box, ConstInt(offset), itembox], None, descr=descr) optforce.emit_operation(op) @specialize.argtype(1) def _visitor_dispatch_virtual_type(self, visitor): # I *think* we need to make a copy of offsets and descrs because we # want a snapshot of the virtual state right now: if we grow more # elements later, we don't want them to go in this virtual state return visitor.visit_vrawbuffer(self.size, self.buffer.offsets[:], self.buffer.descrs[:])
class VRawBufferValue(AbstractVArrayValue): is_about_raw = True def __init__(self, cpu, logops, size, keybox, source_op): AbstractVirtualValue.__init__(self, keybox, source_op) # note that size is unused, because we assume that the buffer is big # enough to write/read everything we need. If it's not, it's undefined # behavior anyway, although in theory we could probably detect such # cases here self.size = size self.buffer = RawBuffer(cpu, logops) def getlength(self): return len(self.buffer.values) def get_item_value(self, i): return self.buffer.values[i] def set_item_value(self, i, newval): self.buffer.values[i] = newval def getitem_raw(self, offset, length, descr): return self.buffer.read_value(offset, length, descr) def setitem_raw(self, offset, length, descr, value): self.buffer.write_value(offset, length, descr, value) def _really_force(self, optforce): op = self.source_op assert op is not None if not we_are_translated(): op.name = 'FORCE ' + self.source_op.name optforce.emit_operation(self.source_op) self.box = self.source_op.result for i in range(len(self.buffer.offsets)): # get a pointer to self.box+offset offset = self.buffer.offsets[i] if offset == 0: arraybox = self.box else: arraybox = BoxInt() op = ResOperation(rop.INT_ADD, [self.box, ConstInt(offset)], arraybox) optforce.emit_operation(op) # # write the value descr = self.buffer.descrs[i] itemvalue = self.buffer.values[i] itembox = itemvalue.force_box(optforce) op = ResOperation(rop.SETARRAYITEM_RAW, [arraybox, ConstInt(0), itembox], None, descr=descr) optforce.emit_operation(op) def _make_virtual(self, modifier): # I *think* we need to make a copy of offsets and descrs because we # want a snapshot of the virtual state right now: if we grow more # elements later, we don't want them to go in this virtual state return modifier.make_vrawbuffer(self.size, self.buffer.offsets[:], self.buffer.descrs[:])