[pypy-svn] r51723 - in pypy/branch/unified-rtti/pypy: rpython/lltypesystem rpython/memory rpython/memory/gctransform translator/c translator/c/src
arigo at codespeak.net
arigo at codespeak.net
Thu Feb 21 15:26:33 CET 2008
Author: arigo
Date: Thu Feb 21 15:26:33 2008
New Revision: 51723
Modified:
pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py
pypy/branch/unified-rtti/pypy/rpython/memory/gcheader.py
pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py
pypy/branch/unified-rtti/pypy/translator/c/database.py
pypy/branch/unified-rtti/pypy/translator/c/gc.py
pypy/branch/unified-rtti/pypy/translator/c/node.py
pypy/branch/unified-rtti/pypy/translator/c/primitive.py
pypy/branch/unified-rtti/pypy/translator/c/src/exception.h
Log:
First test translating to C passes!
Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py Thu Feb 21 15:26:33 2008
@@ -1824,6 +1824,13 @@
return rttiptr
getRuntimeTypeInfo._annspecialcase_ = 'specialize:memo'
+def getGcTypeForRtti(rttiptr):
+ assert typeOf(rttiptr) == Ptr(RuntimeTypeInfo)
+ if not hasattr(rttiptr._obj, '_GCTYPE'):
+ raise TypeError("rtti object %r is not attached to any type" % (
+ rttiptr,))
+ return rttiptr._obj._GCTYPE
+
def _install_rtti(STRUCT, runtime_type_info):
if not isinstance(STRUCT, GcStruct):
raise TypeError("can only attach a runtime_type_info to a GcStruct")
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gcheader.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gcheader.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gcheader.py Thu Feb 21 15:26:33 2008
@@ -51,6 +51,15 @@
rttiptr)
return self.rtti2typeinfo[rttiptr._obj]
+ def new_typeinfo(self, rttiptr):
+ rttiptr = lltype.cast_pointer(lltype.Ptr(lltype.RuntimeTypeInfo),
+ rttiptr)
+ rtti = rttiptr._obj
+ assert rtti not in self.rtti2typeinfo
+ typeinfo = lltype.malloc(self.TYPEINFO, immortal=True)
+ self.rtti2typeinfo[rtti] = typeinfo
+ return typeinfo
+
def cast_rtti_to_typeinfo(self, rttiptr):
# this is RPython
addr = llmemory.cast_ptr_to_adr(rttiptr)
Modified: pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/memory/gctransform/refcounting.py Thu Feb 21 15:26:33 2008
@@ -175,6 +175,23 @@
resulttype=llmemory.Address)
return v_raw
+ def gct_gc_runtime_type_info(self, hop):
+ # generate inline code equivalent to:
+ # gcheader = llmemory.cast_adr_to_ptr(adr - gc_header_offset, HDRPTR)
+ # return gcheader.typeptr
+ [v_ptr] = hop.spaceop.args
+ v_adr = hop.genop("cast_ptr_to_adr", [v_ptr],
+ resulttype=llmemory.Address)
+ c_gc_header_offset = rmodel.inputconst(lltype.Signed,
+ self.gcheaderbuilder.size_gc_header)
+ v_adr = hop.genop("adr_sub", [v_adr, c_gc_header_offset],
+ resulttype=llmemory.Address)
+ v_hdr = hop.genop("cast_adr_to_ptr", [v_adr],
+ resulttype=lltype.Ptr(self.HDR))
+ c_typeptr = rmodel.inputconst(lltype.Void, "typeptr")
+ hop.genop("getfield", [v_hdr, c_typeptr],
+ resultvar=hop.spaceop.result)
+
def consider_constant(self, TYPE, value):
if value is not lltype.top_container(value):
return
@@ -260,3 +277,13 @@
for p in find_gc_ptrs_in_type(TYPE):
self.static_deallocation_funcptr_for_type(p.TO)
return fptr
+
+ def convert_rtti(self, rtti):
+ rtti = rtti._as_ptr()
+ try:
+ return self.gcheaderbuilder.typeinfo_from_rtti(rtti)
+ except KeyError:
+ TYPE = lltype.getGcTypeForRtti(rtti)
+ typeinfo = self.gcheaderbuilder.new_typeinfo(rtti)
+ typeinfo.dealloc = self.static_deallocation_funcptr_for_type(TYPE)
+ return typeinfo
Modified: pypy/branch/unified-rtti/pypy/translator/c/database.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/database.py (original)
+++ pypy/branch/unified-rtti/pypy/translator/c/database.py Thu Feb 21 15:26:33 2008
@@ -1,5 +1,5 @@
from pypy.rpython.lltypesystem.lltype import \
- Primitive, Ptr, typeOf, RuntimeTypeInfo, \
+ Primitive, Ptr, typeOf, RuntimeTypeInfo, RuntimeTypeInfoType, \
Struct, Array, FuncType, PyObject, Void, \
ContainerType, OpaqueType, FixedSizeArray, _uninitialized
from pypy.rpython.lltypesystem import lltype
@@ -88,6 +88,9 @@
elif T == WeakRef:
REALT = self.gcpolicy.get_real_weakref_type()
node = self.gettypedefnode(REALT)
+ elif T == RuntimeTypeInfo:
+ REALT = self.gcpolicy.get_real_rtti_type()
+ node = self.gettypedefnode(REALT)
else:
raise NoCorrespondingNode("don't know about %r" % (T,))
self.structdefnodes[key] = node
@@ -107,7 +110,7 @@
return node.getptrtype() # special-casing because of C
typename = self.gettype(T.TO) # who_asks not propagated
return typename.replace('@', '*@')
- elif isinstance(T, (Struct, Array, _WeakRefType)):
+ elif isinstance(T, (Struct, Array, _WeakRefType, RuntimeTypeInfoType)):
node = self.gettypedefnode(T, varlength=varlength)
if who_asks is not None:
who_asks.dependencies[node] = True
Modified: pypy/branch/unified-rtti/pypy/translator/c/gc.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/gc.py (original)
+++ pypy/branch/unified-rtti/pypy/translator/c/gc.py Thu Feb 21 15:26:33 2008
@@ -2,8 +2,7 @@
from pypy.translator.c.support import cdecl
from pypy.translator.c.node import ContainerNode
from pypy.rpython.lltypesystem.lltype import \
- typeOf, Ptr, ContainerType, \
- RuntimeTypeInfo, getRuntimeTypeInfo, top_container
+ typeOf, Ptr, ContainerType, top_container
from pypy.rpython.memory.gctransform import \
refcounting, boehm, framework, stacklessframework, llvmgcroot, asmgcroot
from pypy.rpython.lltypesystem import lltype, llmemory
@@ -48,14 +47,12 @@
def gc_startup_code(self):
return []
- def struct_setup(self, structdefnode, rtti):
- return None
-
- def array_setup(self, arraydefnode):
- return None
+ # for rtti node
+ def get_real_rtti_type(self):
+ return self.transformerclass.TYPEINFO
- def rtti_type(self):
- return ''
+ def convert_rtti(self, obj):
+ return self.db.gctransformer.convert_rtti(obj)
def OP_GC_PUSH_ALIVE_PYOBJ(self, funcgen, op):
expr = funcgen.expr(op.args[0])
@@ -71,11 +68,6 @@
return ''
-class RefcountingInfo:
- static_deallocator = None
-
-from pypy.rlib.objectmodel import CDefinedIntSymbolic
-
class RefcountingGcPolicy(BasicGcPolicy):
transformerclass = refcounting.RefcountingGCTransformer
@@ -95,29 +87,6 @@
else:
return []
- # for structs
-
- def struct_setup(self, structdefnode, rtti):
- if rtti is not None:
- transformer = structdefnode.db.gctransformer
- fptr = transformer.static_deallocation_funcptr_for_type(
- structdefnode.STRUCT)
- structdefnode.gcinfo = RefcountingInfo()
- structdefnode.gcinfo.static_deallocator = structdefnode.db.get(fptr)
-
- # for arrays
-
- def array_setup(self, arraydefnode):
- pass
-
- # for rtti node
-
- def rtti_type(self):
- return 'void (@)(void *)' # void dealloc_xx(struct xx *)
-
- def rtti_node_factory(self):
- return RefcountingRuntimeTypeInfo_OpaqueNode
-
# zero malloc impl
def OP_GC_CALL_RTTI_DESTRUCTOR(self, funcgen, op):
@@ -129,49 +98,9 @@
return ''
-class RefcountingRuntimeTypeInfo_OpaqueNode(ContainerNode):
- nodekind = 'refcnt rtti'
- globalcontainer = True
- typename = 'void (@)(void *)'
-
- def __init__(self, db, T, obj):
- assert T == RuntimeTypeInfo
- assert isinstance(obj.about, GcStruct)
- self.db = db
- self.T = T
- self.obj = obj
- defnode = db.gettypedefnode(obj.about)
- self.implementationtypename = 'void (@)(void *)'
- self.name = defnode.gcinfo.static_deallocator
- self.ptrname = '((void (*)(void *)) %s)' % (self.name,)
-
- def enum_dependencies(self):
- return []
-
- def implementation(self):
- return []
-
-
-
-class BoehmInfo:
- finalizer = None
-
-
class BoehmGcPolicy(BasicGcPolicy):
transformerclass = boehm.BoehmGCTransformer
- def array_setup(self, arraydefnode):
- pass
-
- def struct_setup(self, structdefnode, rtti):
- pass
-
- def rtti_type(self):
- return BoehmGcRuntimeTypeInfo_OpaqueNode.typename
-
- def rtti_node_factory(self):
- return BoehmGcRuntimeTypeInfo_OpaqueNode
-
def gc_libraries(self):
if sys.platform == 'win32':
return ['gc_pypy']
@@ -210,31 +139,6 @@
nbytes = funcgen.expr(op.args[0])
return 'GC_set_max_heap_size(%s);' % (nbytes,)
-class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode):
- nodekind = 'boehm rtti'
- globalcontainer = True
- typename = 'char @'
-
- def __init__(self, db, T, obj):
- assert T == RuntimeTypeInfo
- assert isinstance(obj.about, GcStruct)
- self.db = db
- self.T = T
- self.obj = obj
- defnode = db.gettypedefnode(obj.about)
- self.implementationtypename = self.typename
- self.name = self.db.namespace.uniquename('g_rtti_v_'+ defnode.barename)
- self.ptrname = '(&%s)' % (self.name,)
-
- def enum_dependencies(self):
- return []
-
- def implementation(self):
- yield 'char %s /* uninitialized */;' % self.name
-
-class FrameworkGcRuntimeTypeInfo_OpaqueNode(BoehmGcRuntimeTypeInfo_OpaqueNode):
- nodekind = 'framework rtti'
-
# to get an idea how it looks like with no refcount/gc at all
@@ -250,29 +154,6 @@
class FrameworkGcPolicy(BasicGcPolicy):
transformerclass = framework.FrameworkGCTransformer
- def struct_setup(self, structdefnode, rtti):
- if rtti is not None and hasattr(rtti._obj, 'destructor_funcptr'):
- destrptr = rtti._obj.destructor_funcptr
- # make sure this is seen by the database early, i.e. before
- # finish_helpers() on the gctransformer
- self.db.get(destrptr)
- # the following, on the other hand, will only discover ll_finalizer
- # helpers. The get() sees and records a delayed pointer. It is
- # still important to see it so that it can be followed as soon as
- # the mixlevelannotator resolves it.
- gctransf = self.db.gctransformer
- fptr = gctransf.finalizer_funcptr_for_type(structdefnode.STRUCT)
- self.db.get(fptr)
-
- def array_setup(self, arraydefnode):
- pass
-
- def rtti_type(self):
- return FrameworkGcRuntimeTypeInfo_OpaqueNode.typename
-
- def rtti_node_factory(self):
- return FrameworkGcRuntimeTypeInfo_OpaqueNode
-
def pre_pre_gc_code(self):
yield '#define USING_FRAMEWORK_GC'
Modified: pypy/branch/unified-rtti/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/node.py (original)
+++ pypy/branch/unified-rtti/pypy/translator/c/node.py Thu Feb 21 15:26:33 2008
@@ -4,7 +4,7 @@
GcStruct, GcArray, ContainerType, \
parentlink, Ptr, PyObject, Void, OpaqueType, Float, \
RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray
-from pypy.rpython.lltypesystem import llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.translator.c.funcgen import FunctionCodeGenerator
from pypy.translator.c.external import CExternalFunctionCodeGenerator
from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
@@ -25,15 +25,6 @@
return False # gcheader already in the first field
return True
-class defaultproperty(object):
- def __init__(self, fget):
- self.fget = fget
- def __get__(self, obj, cls=None):
- if obj is None:
- return self
- else:
- return self.fget(obj)
-
class StructDefNode:
typetag = 'struct'
@@ -88,23 +79,6 @@
else:
typename = db.gettype(T, who_asks=self)
self.fields.append((self.c_struct_field_name(name), typename))
- self.gcinfo # force it to be computed
-
- def computegcinfo(self):
- # let the gcpolicy do its own setup
- self.gcinfo = None # unless overwritten below
- rtti = None
- STRUCT = self.STRUCT
- if isinstance(STRUCT, GcStruct):
- XXX
- try:
- rtti = getRuntimeTypeInfo(STRUCT)
- except ValueError:
- pass
- if self.varlength == 1:
- self.db.gcpolicy.struct_setup(self, rtti)
- return self.gcinfo
- gcinfo = defaultproperty(computegcinfo)
def gettype(self):
return '%s %s @' % (self.typetag, self.name)
@@ -222,20 +196,11 @@
return # setup() was already called, likely by __init__
db = self.db
ARRAY = self.ARRAY
- self.gcinfo # force it to be computed
if needs_gcheader(ARRAY):
for fname, T in db.gcpolicy.array_gcheader_definition(self):
self.gcfields.append((fname, db.gettype(T, who_asks=self)))
self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
- def computegcinfo(self):
- # let the gcpolicy do its own setup
- self.gcinfo = None # unless overwritten below
- if self.varlength == 1:
- self.db.gcpolicy.array_setup(self)
- return self.gcinfo
- gcinfo = defaultproperty(computegcinfo)
-
def gettype(self):
return '%s %s @' % (self.typetag, self.name)
@@ -313,7 +278,6 @@
Implemented directly as a C array instead of a struct with an items field.
rffi kind of expects such arrays to be 'bare' C arrays.
"""
- gcinfo = None
name = None
forward_decl = None
@@ -360,7 +324,6 @@
class FixedSizeArrayDefNode:
- gcinfo = None
name = None
typetag = 'struct'
@@ -912,6 +875,13 @@
obj._converted_weakref = container # hack for genllvm :-/
return db.getcontainernode(container, _dont_write_c_code=False)
+def rttinode_factory(db, T, obj):
+ assert isinstance(obj, lltype._rtti)
+ wrapper = db.gcpolicy.convert_rtti(obj)
+ container = wrapper._obj
+ #obj._converted_rtti = container # hack for genllvm :-/
+ return db.getcontainernode(container, _dont_write_c_code=False)
+
ContainerNodeFactory = {
Struct: StructNode,
@@ -923,4 +893,5 @@
OpaqueType: opaquenode_factory,
PyObjectType: PyObjectNode,
llmemory._WeakRefType: weakrefnode_factory,
+ lltype.RuntimeTypeInfoType: rttinode_factory,
}
Modified: pypy/branch/unified-rtti/pypy/translator/c/primitive.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/primitive.py (original)
+++ pypy/branch/unified-rtti/pypy/translator/c/primitive.py Thu Feb 21 15:26:33 2008
@@ -7,7 +7,7 @@
from pypy.rpython.lltypesystem.llmemory import Address, \
AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset, \
CompositeOffset, ArrayLengthOffset, \
- GCHeaderOffset
+ GCHeaderOffset, GCTypeInfoOffset
from pypy.rpython.lltypesystem.llarena import RoundedUpForAllocation
from pypy.translator.c.support import cdecl, barebonearray
@@ -49,6 +49,8 @@
return '0'
elif type(value) == GCHeaderOffset:
return '0'
+ elif type(value) == GCTypeInfoOffset:
+ return '0'
elif type(value) == RoundedUpForAllocation:
return 'ROUND_UP_FOR_ALLOCATION(%s)' % (
name_signed(value.basesize, db))
Modified: pypy/branch/unified-rtti/pypy/translator/c/src/exception.h
==============================================================================
--- pypy/branch/unified-rtti/pypy/translator/c/src/exception.h (original)
+++ pypy/branch/unified-rtti/pypy/translator/c/src/exception.h Thu Feb 21 15:26:33 2008
@@ -39,7 +39,7 @@
long lineno, const char *functionname)
{
fprintf(stderr, "%s %s: %s:%ld %s\n", msg,
- RPyFetchExceptionType()->ov_name->items,
+ RPyFetchExceptionType()->ov_name,
filename, lineno, functionname);
}
#endif
@@ -98,7 +98,7 @@
PyObject *pycls, *v, *tb;
assert(RPyExceptionOccurred());
assert(!PyErr_Occurred());
- clsname = RPyFetchExceptionType()->ov_name->items;
+ clsname = RPyFetchExceptionType()->ov_name;
pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname);
if (pycls != NULL && PyExceptionClass_Check(pycls) &&
PyObject_IsSubclass(pycls, PyExc_Exception)) {
More information about the Pypy-commit
mailing list