[pypy-svn] r27541 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/lltypesystem/test rpython/memory/test rpython/rctypes
arigo at codespeak.net
arigo at codespeak.net
Sun May 21 18:40:08 CEST 2006
Author: arigo
Date: Sun May 21 18:40:05 2006
New Revision: 27541
Added:
pypy/dist/pypy/rpython/rgc.py (contents, props changed)
Modified:
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
pypy/dist/pypy/rpython/memory/test/test_gctransform.py
pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py
pypy/dist/pypy/rpython/rctypes/implementation.py
pypy/dist/pypy/rpython/rexternalobj.py
pypy/dist/pypy/rpython/rmodel.py
pypy/dist/pypy/rpython/rtyper.py
Log:
(some pedronis, arigo)
* added pypy.rpython.rgc with an RPython interface to the gc_x_swap_pool
and gc_x_clone operations.
* made SomeExternalObject use the extregistry too.
* bug fixes; extended cast_opaque_ptr to also do a cast_pointer for
you.
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Sun May 21 18:40:05 2006
@@ -405,9 +405,10 @@
class SomeExternalObject(SomeObject):
- """Stands for an object of 'external' type. External types are defined
- in pypy.rpython.extfunctable.declaretype(), and represent simple types
- with some methods that need direct back-end support."""
+ """Stands for an object of 'external' type. External types have a Repr
+ controlled by pypy.rpython.extregistry; or they come from the (obsolete)
+ table created by pypy.rpython.extfunctable.declaretype() and represent
+ simple types with some methods that need direct back-end support."""
def __init__(self, knowntype):
self.knowntype = knowntype
@@ -415,7 +416,7 @@
def can_be_none(self):
return True
-class SomeCTypesObject(SomeObject):
+class SomeCTypesObject(SomeExternalObject):
"""Stands for an object of the ctypes module."""
NOMEMORY = "NOMEMORY"
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Sun May 21 18:40:05 2006
@@ -679,13 +679,10 @@
try:
container = ptr._obj.container
except AttributeError:
- raise RuntimeError("%r does not come from a container" % (ptr,))
- if typeOf(container) != PTRTYPE.TO:
- raise RuntimeError("%r contains a container of the wrong type:\n"
- "%r instead of %r" % (ptr, typeOf(container),
- PTRTYPE.TO))
+ raise InvalidCast("%r does not come from a container" % (ptr,))
solid = getattr(ptr._obj, 'solid', False)
- return _ptr(PTRTYPE, container, solid)
+ p = _ptr(Ptr(typeOf(container)), container, solid)
+ return cast_pointer(PTRTYPE, p)
elif (not isinstance(CURTYPE.TO, OpaqueType)
and isinstance(PTRTYPE.TO, OpaqueType)):
if not ptr:
@@ -699,7 +696,7 @@
try:
container = ptr._obj.container
except AttributeError:
- raise RuntimeError("%r does not come from a container" % (ptr,))
+ raise InvalidCast("%r does not come from a container" % (ptr,))
return opaqueptr(PTRTYPE.TO, 'hidden',
container = container,
solid = ptr._obj.solid)
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py Sun May 21 18:40:05 2006
@@ -470,7 +470,7 @@
py.test.raises(TypeError, "cast_opaque_ptr(Ptr(S), o1)")
py.test.raises(TypeError, "cast_opaque_ptr(Ptr(O1), s)")
S2 = Struct('S2', ('z', Signed))
- py.test.raises(RuntimeError, "cast_opaque_ptr(Ptr(S2), o1)")
+ py.test.raises(InvalidCast, "cast_opaque_ptr(Ptr(S2), o1)")
def test_is_atomic():
U = Struct('inlined', ('z', Signed))
Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py Sun May 21 18:40:05 2006
@@ -64,7 +64,7 @@
t = TranslationContext()
t.buildannotator().build_types(func, inputtypes)
if specialize:
- t.buildrtyper().specialize(t)
+ t.buildrtyper().specialize()
return t
def rtype_and_transform(func, inputtypes, transformcls, specialize=True, check=True):
@@ -442,7 +442,7 @@
pass
t = TranslationContext()
t.buildannotator().build_types(f, [])
- t.buildrtyper().specialize(t)
+ t.buildrtyper().specialize()
transformer = cls(t)
fptr = getattr(transformer, attr)(TYPE)
transformer.finish()
@@ -554,7 +554,7 @@
pass
t = TranslationContext()
t.buildannotator().build_types(f, [])
- t.buildrtyper().specialize(t)
+ t.buildrtyper().specialize()
transformer = gctransform.RefcountingGCTransformer(t)
p_S = transformer.dynamic_deallocation_funcptr_for_type(S)
p_S1 = transformer.dynamic_deallocation_funcptr_for_type(S1)
Modified: pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py Sun May 21 18:40:05 2006
@@ -170,7 +170,7 @@
t = TranslationContext()
t.buildannotator().build_types(func, inputtypes)
if specialize:
- t.buildrtyper().specialize(t)
+ t.buildrtyper().specialize()
if conftest.option.view:
t.view()
return t
@@ -382,6 +382,40 @@
res = run([])
assert res == 111222333
+ def test_cloning_highlevel(self):
+ from pypy.rpython import rgc
+ class A:
+ pass
+ class B(A):
+ pass
+ def func(n, dummy):
+ if n > 5:
+ x = A()
+ else:
+ x = B()
+ x.bvalue = 123
+ x.next = A()
+ x.next.next = x
+ y, newpool = rgc.gc_clone(x, None)
+ assert y is not x
+ assert y.next is not x
+ assert y is not x.next
+ assert y.next is not x.next
+ assert y is not y.next
+ assert y is y.next.next
+ if isinstance(y, B):
+ assert n <= 5
+ assert y.bvalue == 123
+ else:
+ assert n > 5
+ return 1
+
+ run = self.runner(func, nbargs=2)
+ res = run([3, 0])
+ assert res == 1
+ res = run([7, 0])
+ assert res == 1
+
def test_tree_cloning(self):
import os
# this makes a tree of calls. Each leaf stores its path (a linked
Modified: pypy/dist/pypy/rpython/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rpython/rctypes/implementation.py Sun May 21 18:40:05 2006
@@ -118,15 +118,3 @@
import pypy.rpython.rctypes.avoid_p
import pypy.rpython.rctypes.astringbuf
import pypy.rpython.rctypes.apyobject
-
-
-# Register the correspondance between SomeCTypesObject and the get_repr()
-# functions attached to the extregistry to create CTypesReprs
-
-class __extend__( SomeCTypesObject ):
- def rtyper_makerepr( self, rtyper ):
- entry = extregistry.lookup_type(self.knowntype)
- return entry.get_repr(rtyper, self)
-
- def rtyper_makekey( self ):
- return self.__class__, self.knowntype, self.memorystate
Modified: pypy/dist/pypy/rpython/rexternalobj.py
==============================================================================
--- pypy/dist/pypy/rpython/rexternalobj.py (original)
+++ pypy/dist/pypy/rpython/rexternalobj.py Sun May 21 18:40:05 2006
@@ -5,16 +5,33 @@
from pypy.rpython import rbuiltin
from pypy.rpython.module.support import init_opaque_object
from pypy.objspace.flow.model import Constant
+from pypy.rpython import extregistry
class __extend__(annmodel.SomeExternalObject):
+
def rtyper_makerepr(self, rtyper):
- return ExternalObjRepr(self.knowntype)
+ if self.knowntype in typetable:
+ return ExternalObjRepr(self.knowntype)
+ else:
+ # delegate to the get_repr() of the extregistrered Entry class
+ entry = extregistry.lookup_type(self.knowntype)
+ return entry.get_repr(rtyper, self)
+
def rtyper_makekey(self):
- return self.__class__, self.knowntype
+ # grab all attributes of the SomeExternalObject for the key
+ attrs = lltype.frozendict(self.__dict__)
+ if 'const' in attrs:
+ del attrs['const']
+ if 'const_box' in attrs:
+ del attrs['const_box']
+ return self.__class__, attrs
class ExternalObjRepr(Repr):
+ """Repr for the (obsolecent) extfunctable.declaretype() case.
+ If you use the extregistry instead you get to pick your own Repr.
+ """
def __init__(self, knowntype):
self.exttypeinfo = typetable[knowntype]
Added: pypy/dist/pypy/rpython/rgc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rgc.py Sun May 21 18:40:05 2006
@@ -0,0 +1,94 @@
+from pypy.rpython.extregistry import ExtRegistryEntry
+
+# ____________________________________________________________
+# Framework GC features
+
+class GcPool(object):
+ pass
+
+def gc_swap_pool(newpool):
+ """Set newpool as the current pool (create one if newpool is None).
+ All malloc'ed objects are put into the current pool;this is a
+ way to separate objects depending on when they were allocated.
+ """
+ raise NotImplementedError("only works in stacklessgc translated versions")
+
+def gc_clone(gcobject, pool):
+ """Recursively clone the gcobject and everything it points to,
+ directly or indirectly -- but stops at objects that are not
+ in the specified pool. Pool can be None to mean the current one.
+ A new pool is built to contain the copies. Return (newobject, newpool).
+ """
+ raise NotImplementedError("only works in stacklessgc translated versions")
+
+# ____________________________________________________________
+# Annotation and specialization
+
+class GcPoolEntry(ExtRegistryEntry):
+ "Link GcPool to its Repr."
+ _type_ = GcPool
+
+ def get_repr(self, rtyper, s_pool):
+ from pypy.rpython.rmodel import SimplePointerRepr
+ from pypy.rpython.memory.gc import X_POOL_PTR
+ return SimplePointerRepr(X_POOL_PTR)
+
+
+class SwapPoolFnEntry(ExtRegistryEntry):
+ "Annotation and specialization of gc_swap_pool()."
+ _about_ = gc_swap_pool
+
+ def compute_result_annotation(self, s_newpool):
+ from pypy.annotation import model as annmodel
+ return annmodel.SomeExternalObject(GcPool)
+
+ def specialize_call(self, hop):
+ from pypy.annotation import model as annmodel
+ s_pool_ptr = annmodel.SomeExternalObject(GcPool)
+ r_pool_ptr = hop.rtyper.getrepr(s_pool_ptr)
+ vlist = hop.inputargs(r_pool_ptr)
+ return hop.genop('gc_x_swap_pool', vlist, resulttype = r_pool_ptr)
+
+
+class CloneFnEntry(ExtRegistryEntry):
+ "Annotation and specialization of gc_clone()."
+ _about_ = gc_clone
+
+ def compute_result_annotation(self, s_gcobject, s_pool):
+ from pypy.annotation import model as annmodel
+ return annmodel.SomeTuple([s_gcobject,
+ annmodel.SomeExternalObject(GcPool)])
+
+ def specialize_call(self, hop):
+ from pypy.rpython.error import TyperError
+ from pypy.rpython.lltypesystem import lltype, llmemory, rtuple
+ r_gcobject = hop.args_r[0]
+ if (not isinstance(r_gcobject.lowleveltype, lltype.Ptr) or
+ not isinstance(r_gcobject.lowleveltype.TO, lltype.GC_CONTAINER)):
+ raise TyperError("gc_clone() can only clone a dynamically "
+ "allocated object;\ngot %r" % (r_gcobject,))
+ from pypy.annotation import model as annmodel
+ from pypy.rpython.memory.gc import X_CLONE, X_CLONE_PTR
+ s_pool_ptr = annmodel.SomeExternalObject(GcPool)
+ r_pool_ptr = hop.rtyper.getrepr(s_pool_ptr)
+ r_tuple = hop.r_result
+
+ c_CLONE = hop.inputconst(lltype.Void, X_CLONE)
+ c_gcobjectptr = hop.inputconst(lltype.Void, "gcobjectptr")
+ c_pool = hop.inputconst(lltype.Void, "pool")
+
+ v_gcobject, v_pool = hop.inputargs(hop.args_r[0], r_pool_ptr)
+ v_gcobjectptr = hop.genop('cast_opaque_ptr', [v_gcobject],
+ resulttype = llmemory.GCREF)
+ v_clonedata = hop.genop('malloc', [c_CLONE],
+ resulttype = X_CLONE_PTR)
+ hop.genop('setfield', [v_clonedata, c_gcobjectptr, v_gcobjectptr])
+ hop.genop('setfield', [v_clonedata, c_pool, v_pool])
+ hop.genop('gc_x_clone', [v_clonedata])
+ v_gcobjectptr = hop.genop('getfield', [v_clonedata, c_gcobjectptr],
+ resulttype = llmemory.GCREF)
+ v_pool = hop.genop('getfield', [v_clonedata, c_pool],
+ resulttype = r_pool_ptr)
+ v_gcobject = hop.genop('cast_opaque_ptr', [v_gcobjectptr],
+ resulttype = r_tuple.items_r[0])
+ return rtuple.newtuple(hop.llops, r_tuple, [v_gcobject, v_pool])
Modified: pypy/dist/pypy/rpython/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rmodel.py (original)
+++ pypy/dist/pypy/rpython/rmodel.py Sun May 21 18:40:05 2006
@@ -344,6 +344,18 @@
get_ll_fasthash_function = get_ll_hash_function
impossible_repr = VoidRepr()
+class SimplePointerRepr(Repr):
+ "Convenience Repr for simple ll pointer types with no operation on them."
+
+ def __init__(self, lowleveltype):
+ self.lowleveltype = lowleveltype
+
+ def convert_const(self, value):
+ if value is not None:
+ raise TyperError("%r only supports None as prebuilt constant, "
+ "got %r" % (self, value))
+ return lltype.nullptr(self.lowleveltype.TO)
+
# ____________________________________________________________
def inputdesc(reqtype, desc):
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Sun May 21 18:40:05 2006
@@ -158,6 +158,7 @@
"""Main entry point: specialize all annotated blocks of the program."""
self.crash_on_first_typeerror = crash_on_first_typeerror
# specialize depends on annotator simplifications
+ assert dont_simplify_again in (False, True) # safety check
if not dont_simplify_again:
self.annotator.simplify()
More information about the Pypy-commit
mailing list