|
@@ -6,7 +6,6 @@ |
|
|
from pypy.module._cffi_backend import misc |
|
|
|
|
|
import sys |
|
|
import pytest |
|
|
|
|
|
test_types = [ffitype.INT8, ffitype.INT16, ffitype.INT32, ffitype.INT64, |
|
|
ffitype.UINT8, ffitype.UINT16, ffitype.UINT32, ffitype.UINT64, |
|
@@ -23,38 +22,44 @@ |
|
|
minval = {} |
|
|
maxval = {} |
|
|
for bits in [8, 16, 32, 64]: |
|
|
minval['int' + str(bits)] = int(-2**(bits-1)) |
|
|
minval['int' + str(bits)] = int(-2**(bits - 1)) |
|
|
minval['uint' + str(bits)] = 0 |
|
|
maxval['int' + str(bits)] = int(2**(bits-1) - 1) |
|
|
maxval['int' + str(bits)] = int(2**(bits - 1) - 1) |
|
|
# for some reason int(2**64 -1) is not accepted as biggest uint64 |
|
|
maxval['uint' + str(bits)] = int(2**(bits-1) - 1) |
|
|
minval['long'] = int(-2**(8*rffi.sizeof(rffi.LONG))) |
|
|
maxval['uint' + str(bits)] = int(2**(bits - 1) - 1) |
|
|
minval['long'] = int(-2**(8 * rffi.sizeof(rffi.LONG))) |
|
|
minval['ulong'] = 0 |
|
|
maxval['long'] = int(2**(8*rffi.sizeof(rffi.LONG)) - 1) |
|
|
maxval['ulong'] = int(2**(8*rffi.sizeof(rffi.LONG)-1) - 1) |
|
|
maxval['long'] = int(2**(8 * rffi.sizeof(rffi.LONG)) - 1) |
|
|
maxval['ulong'] = int(2**(8 * rffi.sizeof(rffi.LONG) - 1) - 1) |
|
|
minval['float32'] = 1.1754943508222875e-38 |
|
|
maxval['float32'] = 3.4028234663852886e+38 |
|
|
minval['float64'] = sys.float_info.min |
|
|
maxval['float64'] = sys.float_info.max |
|
|
|
|
|
|
|
|
def new_cast_method(typ): |
|
|
ctype = ffitype.lltypes[typ] |
|
|
|
|
|
def cast_method(memory): |
|
|
return rffi.cast(ffitype.lltype.Ptr(rffi.CArray(ctype)), memory.ptr) |
|
|
return cast_method |
|
|
|
|
|
|
|
|
def new_numberof_method(typ): |
|
|
csize = ffitype.lltype_sizes[typ] |
|
|
if csize & (csize - 1) == 0: # csize is a power of 2 |
|
|
shift = 0 |
|
|
while 1 << shift < csize: shift += 1 |
|
|
while 1 << shift < csize: |
|
|
shift += 1 |
|
|
|
|
|
def numberof_method(self): |
|
|
return self.sizeof_memory >> shift |
|
|
else: |
|
|
def numberof_method(self): |
|
|
return self.sizeof_memory / csize |
|
|
return numberof_method |
|
|
|
|
|
|
|
|
def put_method_test_code(typename): |
|
|
# For some reason, str(some_float) cuts off a few digits. |
|
|
# Only repr prints the entire float. |
|
@@ -66,9 +71,10 @@ def put_method_test_code(typename): |
|
|
mem_ptr.put_TYPE(FFI::Type::UPPER.size, MAX) |
|
|
mem_ptr |
|
|
""".replace('TYPE', typename). |
|
|
replace('UPPER', typename.upper()). |
|
|
replace('MIN', strfunc(minval[typename])). |
|
|
replace('MAX', strfunc(maxval[typename]))) |
|
|
replace('UPPER', typename.upper()). |
|
|
replace('MIN', strfunc(minval[typename])). |
|
|
replace('MAX', strfunc(maxval[typename]))) |
|
|
|
|
|
|
|
|
def get_method_test_code(typename): |
|
|
strfunc = ((lambda x: repr(x)) if 'float' in typename else |
|
@@ -81,9 +87,10 @@ def get_method_test_code(typename): |
|
|
mem_ptr.put_TYPE(pos_4, MAX) |
|
|
[mem_ptr.get_TYPE(pos_3), mem_ptr.get_TYPE(pos_4)] |
|
|
""".replace('TYPE', typename). |
|
|
replace('UPPER', typename.upper()). |
|
|
replace('MIN', strfunc(minval[typename])). |
|
|
replace('MAX', strfunc(maxval[typename]))) |
|
|
replace('UPPER', typename.upper()). |
|
|
replace('MIN', strfunc(minval[typename])). |
|
|
replace('MAX', strfunc(maxval[typename]))) |
|
|
|
|
|
|
|
|
class TestAbstractMemory_put_methods(BaseFFITest): |
|
|
def test_they_put_a_single_value_into_the_given_offset(self, space): |
|
@@ -106,7 +113,7 @@ def test_they_refuse_negative_offsets(self, space): |
|
|
sizeof_t = ffitype.lltype_sizes[t] |
|
|
with self.raises(space, 'IndexError', |
|
|
"Memory access offset=-1 size=%s is out of bounds" |
|
|
% sizeof_t): |
|
|
% sizeof_t): |
|
|
space.execute(""" |
|
|
FFI::MemoryPointer.new(:T, 1).put_T(-1, 230) |
|
|
""".replace('T', tn.lower())) |
|
@@ -115,13 +122,15 @@ def test_they_refuse_too_large_offsets(self, space): |
|
|
for t in test_types: |
|
|
tn = ffitype.type_names[t] |
|
|
sizeof_t = ffitype.lltype_sizes[t] |
|
|
with self.raises(space, 'IndexError', |
|
|
"Memory access offset=1000 size=%s is out of bounds" |
|
|
% sizeof_t): |
|
|
with self.raises( |
|
|
space, 'IndexError', |
|
|
("Memory access offset=1000 size=%s is out of bounds" % |
|
|
sizeof_t)): |
|
|
space.execute(""" |
|
|
FFI::MemoryPointer.new(:T, 3).put_T(1000, 15) |
|
|
""".replace('T', tn.lower())) |
|
|
|
|
|
|
|
|
class TestAbstractMemory_write_methods(BaseFFITest): |
|
|
def test_they_are_like_calling_put_with_0_as_1st_arg(self, space): |
|
|
for t in test_types: |
|
@@ -135,24 +144,26 @@ def test_they_are_like_calling_put_with_0_as_1st_arg(self, space): |
|
|
casted_ptr = cast_method(w_mem_ptr) |
|
|
assert casted_ptr[0] == 'y' if tn == 'INT8' else 121 |
|
|
|
|
|
|
|
|
class TestAbstractMemory_get_methods(BaseFFITest): |
|
|
def test_they_get_a_single_value_from_the_given_offset(self, space): |
|
|
for tn in [ffitype.type_names[t].lower() |
|
|
for t in test_types]: |
|
|
w_res = space.execute(get_method_test_code(tn)) |
|
|
assert self.unwrap(space, w_res) == [minval[tn], maxval[tn]] |
|
|
|
|
|
|
|
|
class TestAbstractMemory_read_methods(BaseFFITest): |
|
|
def test_they_are_like_calling_get_with_0(self, space): |
|
|
for tn in [ffitype.type_names[t].lower() |
|
|
for t in test_types]: |
|
|
for tn in [ffitype.type_names[t].lower() for t in test_types]: |
|
|
w_res = space.execute(""" |
|
|
mem_ptr = FFI::MemoryPointer.new(:T, 1) |
|
|
mem_ptr.write_T(1) |
|
|
mem_ptr.read_T |
|
|
""".replace('T', tn)) |
|
|
assert self.unwrap(space, w_res) == 1 |
|
|
|
|
|
|
|
|
class TestAbstractMemory_put_pointer(BaseFFITest): |
|
|
def test_it_puts_a_single_pointer_into_the_given_offset(self, space): |
|
|
w_mem_ptr = space.execute(""" |
|
@@ -167,6 +178,7 @@ def test_it_puts_a_single_pointer_into_the_given_offset(self, space): |
|
|
assert w_adr_ptr[0] == 88 |
|
|
assert w_adr_ptr[1] == 55 |
|
|
|
|
|
|
|
|
class TestAbstractMemory_get_pointer(BaseFFITest): |
|
|
def test_it_gets_a_single_pointer_from_the_given_offset(self, space): |
|
|
assert self.ask(space, """ |
|
@@ -196,6 +208,7 @@ def test_it_doesnt_loose_the_content(self, space): |
|
|
""") |
|
|
assert self.unwrap(space, w_res) == 300 |
|
|
|
|
|
|
|
|
class TestAbstractMemory_write_pointer(BaseFFITest): |
|
|
def test_it_is_like_calling_put_pointer_with_0_as_1st_arg(self, space): |
|
|
w_res = space.execute(""" |
|
@@ -205,6 +218,7 @@ def test_it_is_like_calling_put_pointer_with_0_as_1st_arg(self, space): |
|
|
""") |
|
|
assert self.unwrap(space, w_res) == 11 |
|
|
|
|
|
|
|
|
class TestAbstractMemory_write_uint64(BaseFFITest): |
|
|
def test_it_is_like_calling_put_uint64_with_0_as_1st_arg(self, space): |
|
|
w_res = space.execute(""" |
|
@@ -214,6 +228,7 @@ def test_it_is_like_calling_put_uint64_with_0_as_1st_arg(self, space): |
|
|
""") |
|
|
assert self.unwrap(space, w_res) == 14 |
|
|
|
|
|
|
|
|
class TestAbstractMemory_read_pointer(BaseFFITest): |
|
|
def test_it_is_like_calling_get_pointer_with_0(self, space): |
|
|
w_res = space.execute(""" |
|
@@ -223,6 +238,7 @@ def test_it_is_like_calling_get_pointer_with_0(self, space): |
|
|
""") |
|
|
assert self.unwrap(space, w_res) == 13 |
|
|
|
|
|
|
|
|
class TestAbstractMemory_read_uint64(BaseFFITest): |
|
|
def test_it_is_like_calling_get_uint64_with_0(self, space): |
|
|
w_res = space.execute(""" |
|
@@ -232,20 +248,20 @@ def test_it_is_like_calling_get_uint64_with_0(self, space): |
|
|
""") |
|
|
assert self.unwrap(space, w_res) == 12 |
|
|
|
|
|
|
|
|
class TestAbstractMemory(BaseFFITest): |
|
|
def test_it_defines_the_following_aliases(self, space): |
|
|
for aliases in [ |
|
|
('int8', 'char'), |
|
|
('uint8', 'uchar'), |
|
|
('int16', 'short'), |
|
|
('uint16', 'ushort'), |
|
|
('int32', 'int'), |
|
|
('uint32', 'uint'), |
|
|
('int64', 'long_long'), |
|
|
('uint64', 'ulong_long'), |
|
|
('float32', 'float'), |
|
|
('float64', 'double') |
|
|
]: |
|
|
('int8', 'char'), |
|
|
('uint8', 'uchar'), |
|
|
('int16', 'short'), |
|
|
('uint16', 'ushort'), |
|
|
('int32', 'int'), |
|
|
('uint32', 'uint'), |
|
|
('int64', 'long_long'), |
|
|
('uint64', 'ulong_long'), |
|
|
('float32', 'float'), |
|
|
('float64', 'double')]: |
|
|
assert self.ask(space, """ |
|
|
FFI::AbstractMemory.instance_method(:put_%s) == |
|
|
FFI::AbstractMemory.instance_method(:put_%s) |
|
@@ -269,11 +285,11 @@ def test_it_defines_long_methods_in_the_following_way(self, space): |
|
|
FFI::AbstractMemory.instance_method(:PREFIXintSIZEOF_LONG_IN_BITS) |
|
|
""".replace('SIZEOF_LONG_IN_BITS', str(8 * rffi.sizeof(rffi.LONG))) |
|
|
signed_meths = ['put_', 'get_', 'write_', 'read_'] |
|
|
unsigned_meths = [meth+'u' for meth in signed_meths] |
|
|
unsigned_meths = [meth + 'u' for meth in signed_meths] |
|
|
for prefix in signed_meths + unsigned_meths: |
|
|
assert self.ask(space, question.replace('PREFIX', prefix)) |
|
|
|
|
|
#class TestAbstractMemory__put_array_of_int32(BaseFFITest): |
|
|
# class TestAbstractMemory__put_array_of_int32(BaseFFITest): |
|
|
# def test_it_writes_into_array(self, space): |
|
|
# w_mem_ptr = space.execute(""" |
|
|
# mem_ptr = FFI::MemoryPointer.new(:int32, 10) |
|
@@ -316,7 +332,7 @@ def test_it_defines_long_methods_in_the_following_way(self, space): |
|
|
# mem_ptr.put_array_of_int32(0, [1, 2, 3]) |
|
|
# """) |
|
|
# |
|
|
#class TestAbstractMemory__get_array_of_int32(BaseFFITest): |
|
|
# class TestAbstractMemory__get_array_of_int32(BaseFFITest): |
|
|
# def test_it_reads_from_array(self, space): |
|
|
# w_res = space.execute(""" |
|
|
# mem_ptr = FFI::MemoryPointer.new(:int32, 10) |
|
|