[pypy-svn] r26680 - in pypy/dist/pypy: annotation rpython/rctypes rpython/rctypes/test translator/backendopt translator/backendopt/test
arigo at codespeak.net
arigo at codespeak.net
Tue May 2 19:11:57 CEST 2006
Author: arigo
Date: Tue May 2 19:11:55 2006
New Revision: 26680
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/rpython/rctypes/rpyobject.py
pypy/dist/pypy/rpython/rctypes/test/test_overhead.py
pypy/dist/pypy/rpython/rctypes/test/test_rpyobject.py
pypy/dist/pypy/translator/backendopt/malloc.py
pypy/dist/pypy/translator/backendopt/test/test_malloc.py
Log:
(pedronis, arigo) Support for mixing None and py_object() -- not other
ctypes objects, only py_object, because the rules for what 'None' means
when in ctypes are, let's say, interesting.
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Tue May 2 19:11:55 2006
@@ -810,3 +810,17 @@
return SomeCTypesObject(s_cto1.knowntype, state)
else:
return SomeObject()
+
+class __extend__(pairtype(SomeCTypesObject, SomePBC)):
+ def union((obj, pbc)):
+ if pbc.isNone() and obj.can_be_none():
+ return obj
+ else:
+ return SomeObject()
+
+class __extend__(pairtype(SomePBC, SomeCTypesObject)):
+ def union((pbc, obj)):
+ if pbc.isNone() and obj.can_be_none():
+ return obj
+ else:
+ return SomeObject()
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Tue May 2 19:11:55 2006
@@ -427,7 +427,9 @@
self.memorystate = memorystate
def can_be_none(self):
- return False
+ # only 'py_object' can also be None
+ import ctypes
+ return issubclass(self.knowntype, ctypes.py_object)
def return_annotation(self):
"""Returns either 'self' or the annotation of the unwrapped version
Modified: pypy/dist/pypy/rpython/rctypes/rpyobject.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rpyobject.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rpyobject.py Tue May 2 19:11:55 2006
@@ -7,6 +7,12 @@
class CTypesPyObjRepr(CTypesValueRepr):
+ def convert_const(self, value):
+ if value is None:
+ return lltype.nullptr(self.lowleveltype.TO)
+ else:
+ return super(CTypesPyObjRepr, self).convert_const(value)
+
def initialize_const(self, p, value):
if isinstance(value, self.ctype):
value = value.value
@@ -29,6 +35,13 @@
pyobj_repr)
self.setvalue(hop.llops, v_pyobj, v_newvalue)
+ def rtype_is_true(self, hop):
+ [v_box] = hop.inputargs(self)
+ return hop.gendirectcall(ll_pyobjbox_is_true, v_box)
+
+def ll_pyobjbox_is_true(box):
+ return bool(box) and bool(box.c_data[0])
+
class __extend__(pairtype(CTypesPyObjRepr, PyObjRepr)):
# conversion used by wrapper.py in genc when returning a py_object
Modified: pypy/dist/pypy/rpython/rctypes/test/test_overhead.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_overhead.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_overhead.py Tue May 2 19:11:55 2006
@@ -9,7 +9,7 @@
from pypy.rpython.test.test_llinterp import gengraph
from pypy.translator.backendopt.all import backend_optimizations
-from ctypes import c_int, Structure, pointer, POINTER
+from ctypes import c_int, Structure, pointer, POINTER, py_object
def find_mallocs(func, argtypes):
@@ -92,3 +92,16 @@
mallocs = find_mallocs(func, [])
assert not mallocs # depends on inlining
+
+def test_using_pyobject():
+ def g(n):
+ if n == 2:
+ w = py_object()
+ else:
+ w = py_object(n)
+ return w
+ def func(n):
+ return bool(g(n))
+
+ mallocs = find_mallocs(func, [int])
+ assert not mallocs # depends on inlining
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rpyobject.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rpyobject.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rpyobject.py Tue May 2 19:11:55 2006
@@ -13,7 +13,7 @@
from pypy.rpython.test.test_llinterp import interpret
from pypy.rpython.lltypesystem import lltype
-from ctypes import py_object
+from ctypes import py_object, CFUNCTYPE, c_int
class Test_annotation:
@@ -46,6 +46,23 @@
if conftest.option.view:
a.translator.view()
+ def test_annotate_mix_with_None(self):
+ def fn(i):
+ if i == 1:
+ p = py_object(123)
+ elif i == 2:
+ p = py_object()
+ else:
+ p = None
+ return p
+
+ a = RPythonAnnotator()
+ s = a.build_types(fn, [int])
+ assert s.knowntype == py_object
+ assert s.can_be_none() # NB. it's actually always True for now
+ if conftest.option.view:
+ a.translator.view()
+
class Test_specialization:
def test_specialize_wrapping(self):
def wrap(x):
@@ -75,3 +92,23 @@
assert res.c_data[0]._obj.value == 5
res = interpret(fn, [1])
assert res.c_data[0]._obj.value == "hello"
+
+ def test_specialize_with_none(self):
+ def g(i):
+ if i == 1:
+ p = py_object(123)
+ elif i == 2:
+ p = py_object()
+ else:
+ p = None
+ return p
+ def fn(i):
+ p = g(i)
+ return bool(p), p is None
+
+ res = interpret(fn, [1])
+ assert (res.item0, res.item1) == (True, False)
+ res = interpret(fn, [2])
+ assert (res.item0, res.item1) == (False, False)
+ res = interpret(fn, [3])
+ assert (res.item0, res.item1) == (False, True)
Modified: pypy/dist/pypy/translator/backendopt/malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/malloc.py Tue May 2 19:11:55 2006
@@ -136,11 +136,13 @@
assert isinstance(STRUCT, lltype.GcStruct)
# must be only ever accessed via getfield/setfield/getsubstruct/
- # direct_fieldptr, or touched by keepalive. Note that same_as and
- # cast_pointer are not recorded in usepoints.
+ # direct_fieldptr, or touched by keepalive or ptr_iszero/ptr_nonzero.
+ # Note that same_as and cast_pointer are not recorded in usepoints.
FIELD_ACCESS = dict.fromkeys(["getfield",
"setfield",
"keepalive",
+ "ptr_iszero",
+ "ptr_nonzero",
"getarrayitem",
"setarrayitem"])
SUBSTRUCT_ACCESS = dict.fromkeys(["getsubstruct",
@@ -327,6 +329,12 @@
[v, cname],
op.result)
newops.append(newop)
+ elif op.opname in ("ptr_iszero", "ptr_nonzero"):
+ # we know the pointer is not NULL if it comes from
+ # a successful malloc
+ c = Constant(op.opname == "ptr_nonzero", lltype.Bool)
+ newop = SpaceOperation('same_as', [c], op.result)
+ newops.append(newop)
else:
raise AssertionError, op.opname
elif op.result in vars:
Modified: pypy/dist/pypy/translator/backendopt/test/test_malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_malloc.py Tue May 2 19:11:55 2006
@@ -252,3 +252,11 @@
s.a[index].n = 12
return s.a[index].n
check(fn, [], [], 12)
+
+def test_ptr_nonzero():
+ from pypy.rpython.lltypesystem import lltype
+ S = lltype.GcStruct('S')
+ def fn():
+ s = lltype.malloc(S)
+ return bool(s)
+ check(fn, [], [], True)
More information about the Pypy-commit
mailing list