[pypy-svn] r52940 - in pypy/branch/jit-hotpath/pypy/jit: codegen/llgraph rainbow rainbow/test timeshifter
antocuni at codespeak.net
antocuni at codespeak.net
Tue Mar 25 20:58:46 CET 2008
Author: antocuni
Date: Tue Mar 25 20:58:44 2008
New Revision: 52940
Modified:
pypy/branch/jit-hotpath/pypy/jit/codegen/llgraph/llimpl.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_interpreter.py
pypy/branch/jit-hotpath/pypy/jit/rainbow/typesystem.py
pypy/branch/jit-hotpath/pypy/jit/timeshifter/rcontainer.py
pypy/branch/jit-hotpath/pypy/jit/timeshifter/rtimeshift.py
pypy/branch/jit-hotpath/pypy/jit/timeshifter/rvalue.py
Log:
Implement InstanceTypeDesc & co., which share a lof of code with
StructTypeDesc & co.
test_struct_simple passes for ootype too.
Modified: pypy/branch/jit-hotpath/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/codegen/llgraph/llimpl.py Tue Mar 25 20:58:44 2008
@@ -14,6 +14,7 @@
from pypy.rpython.llinterp import LLInterpreter
from pypy.rpython.rclass import fishllattr
from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.jit.rainbow.typesystem import fieldType
def _from_opaque(opq):
return opq._obj.externalobj
@@ -351,7 +352,7 @@
def genoogetfield(block, gv_obj, gv_OBJTYPE, gv_fieldname):
OBJTYPE = _from_opaque(gv_OBJTYPE).value
c_fieldname = _from_opaque(gv_fieldname)
- RESULTTYPE = getattr(OBJTYPE.TO, c_fieldname.value) #XXX
+ RESULTTYPE = fieldType(OBJTYPE, c_fieldname.value)
v_obj = _from_opaque(gv_obj)
gv_obj = cast(block, gv_OBJTYPE, gv_obj)
vars_gv = [gv_obj, gv_fieldname]
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/codewriter.py Tue Mar 25 20:58:44 2008
@@ -13,6 +13,7 @@
from pypy.jit.timeshifter.greenkey import KeyDesc
from pypy.jit.rainbow.interpreter import JitCode, LLTypeJitInterpreter, OOTypeJitInterpreter
from pypy.jit.rainbow.interpreter import DEBUG_JITCODES, log
+from pypy.jit.rainbow.typesystem import deref
from pypy.translator.backendopt.removenoops import remove_same_as
from pypy.translator.backendopt.ssa import SSA_to_SSI
from pypy.translator.unsimplify import varoftype
@@ -146,6 +147,9 @@
class BytecodeWriter(object):
+
+ StructTypeDesc = None
+
def __init__(self, t, hannotator, RGenOp, verbose=True):
self.translator = t
self.rtyper = hannotator.base_translator.rtyper
@@ -699,7 +703,7 @@
if TYPE in self.structtypedesc_positions:
return self.structtypedesc_positions[TYPE]
self.structtypedescs.append(
- rcontainer.StructTypeDesc(self.RGenOp, TYPE))
+ self.StructTypeDesc(self.RGenOp, TYPE))
result = len(self.structtypedesc_positions)
self.structtypedesc_positions[TYPE] = result
return result
@@ -707,7 +711,7 @@
def fielddesc_position(self, TYPE, fieldname):
if (fieldname, TYPE) in self.fielddesc_positions:
return self.fielddesc_positions[fieldname, TYPE]
- structtypedesc = rcontainer.StructTypeDesc(self.RGenOp, TYPE)
+ structtypedesc = self.StructTypeDesc(self.RGenOp, TYPE)
fielddesc = structtypedesc.getfielddesc(fieldname)
if fielddesc is None:
self.fielddesc_positions[fieldname, TYPE] = -1
@@ -1242,8 +1246,9 @@
def serialize_op_keepalive(self, op):
pass
- def serialize_op_getfield(self, op):
+ def serialize_op_getfield_impl(self, op):
color = self.opcolor(op)
+ opname = op.opname
args = op.args
if args[0] == self.exceptiondesc.cexcdata:
# reading one of the exception boxes (exc_type or exc_value)
@@ -1253,13 +1258,13 @@
elif fieldname == 'exc_value':
self.emit("read_excvalue")
else:
- raise Exception("getfield(exc_data, %r)" % (fieldname,))
+ raise Exception("%s(exc_data, %r)" % (opname, fieldname,))
self.register_redvar(op.result)
return
# virtualizable access read
PTRTYPE = args[0].concretetype
- if PTRTYPE.TO._hints.get('virtualizable', False):
+ if deref(PTRTYPE)._hints.get('virtualizable', False):
assert op.args[1].value != 'vable_access'
# non virtual case
@@ -1268,18 +1273,19 @@
s_struct = self.hannotator.binding(args[0])
deepfrozen = s_struct.deepfrozen
- fielddescindex = self.fielddesc_position(PTRTYPE.TO, fieldname)
+ fielddescindex = self.fielddesc_position(deref(PTRTYPE), fieldname)
if fielddescindex == -1: # Void field
return
- self.emit("%s_getfield" % (color, ), index, fielddescindex)
+ self.emit("%s_%s" % (color, opname), index, fielddescindex)
if color == "red":
self.emit(deepfrozen)
self.register_redvar(op.result)
else:
self.register_greenvar(op.result)
- def serialize_op_setfield(self, op):
+ def serialize_op_setfield_impl(self, op):
args = op.args
+ opname = op.opname
PTRTYPE = args[0].concretetype
VALUETYPE = args[2].concretetype
if VALUETYPE is lltype.Void:
@@ -1293,16 +1299,16 @@
elif fieldname == 'exc_value':
self.emit("write_excvalue", val)
else:
- raise Exception("getfield(exc_data, %r)" % (fieldname,))
+ raise Exception("%s(exc_data, %r)" % (opname, fieldname,))
return
# non virtual case
destboxindex = self.serialize_oparg("red", args[0])
valboxindex = self.serialize_oparg("red", args[2])
fieldname = args[1].value
- fielddescindex = self.fielddesc_position(PTRTYPE.TO, fieldname)
+ fielddescindex = self.fielddesc_position(deref(PTRTYPE), fieldname)
if fielddescindex == -1: # Void field
return
- self.emit("red_setfield", destboxindex, fielddescindex, valboxindex)
+ self.emit("red_%s" % opname, destboxindex, fielddescindex, valboxindex)
def serialize_op_getarrayitem(self, op):
color = self.opcolor(op)
@@ -1587,18 +1593,31 @@
class LLTypeBytecodeWriter(BytecodeWriter):
ExceptionDesc = exception.LLTypeExceptionDesc
+ StructTypeDesc = rcontainer.StructTypeDesc
def create_interpreter(self, RGenOp):
return LLTypeJitInterpreter(self.exceptiondesc, RGenOp)
+ def serialize_op_getfield(self, op):
+ return self.serialize_op_getfield_impl(op)
+
+ def serialize_op_setfield(self, op):
+ return self.serialize_op_setfield_impl(op)
+
class OOTypeBytecodeWriter(BytecodeWriter):
ExceptionDesc = exception.OOTypeExceptionDesc
+ StructTypeDesc = rcontainer.InstanceTypeDesc
def create_interpreter(self, RGenOp):
return OOTypeJitInterpreter(self.exceptiondesc, RGenOp)
+ def serialize_op_oogetfield(self, op):
+ return self.serialize_op_getfield_impl(op)
+
+ def serialize_op_oosetfield(self, op):
+ return self.serialize_op_setfield_impl(op)
class GraphTransformer(object):
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/interpreter.py Tue Mar 25 20:58:44 2008
@@ -1028,6 +1028,11 @@
class OOTypeJitInterpreter(JitInterpreter):
ts = typesystem.oohelper
+ @arguments("red", "fielddesc", "bool", returns="red")
+ def opimpl_red_oogetfield(self, structbox, fielddesc, deepfrozen):
+ return rtimeshift.gengetfield(self.jitstate, deepfrozen, fielddesc,
+ structbox)
+
class DebugTrace(object):
def __init__(self, *args):
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_interpreter.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_interpreter.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/test/test_interpreter.py Tue Mar 25 20:58:44 2008
@@ -11,6 +11,7 @@
from pypy.jit.rainbow.test.test_serializegraph import AbstractSerializationTest
from pypy.jit.timeshifter import rtimeshift, rvalue
from pypy.rpython.lltypesystem import lltype, rstr
+from pypy.rpython.ootypesystem import ootype
from pypy.rpython.llinterp import LLInterpreter, LLException
from pypy.rpython.module.support import LLSupport
from pypy.annotation import model as annmodel
@@ -83,12 +84,30 @@
hannotator.translator.view()
return hs, hannotator, rtyper
+
class InterpretationTest(object):
RGenOp = LLRGenOp
small = False
translate_support_code = False # only works for portal tests for now
+ # these staticmethods should go to TestLLType, they are here only
+ # for compatibility with other tests that inherit from
+ # InterpretationTest
+
+ @staticmethod
+ def Ptr(T):
+ return lltype.Ptr(T)
+
+ @staticmethod
+ def Struct(name, *fields, **kwds):
+ S = lltype.GcStruct(name, *fields, **kwds)
+ return S
+
+ @staticmethod
+ def malloc(S):
+ return lltype.malloc(S)
+
def setup_class(cls):
cls.on_llgraph = cls.RGenOp is LLRGenOp
cls._cache = {}
@@ -247,10 +266,15 @@
graph = self.get_residual_graph()
self.insns = summary(graph)
if expected is not None:
+ expected = self.translate_insns(expected)
assert self.insns == expected
+ counts = self.translate_insns(counts)
for opname, count in counts.items():
assert self.insns.get(opname, 0) == count
+ def translate_insns(self, insns):
+ return insns
+
def check_oops(self, expected=None, **counts):
if not self.on_llgraph:
return
@@ -660,9 +684,11 @@
def test_simple_struct(self):
- S = lltype.GcStruct('helloworld', ('hello', lltype.Signed),
- ('world', lltype.Signed),
- hints={'immutable': True})
+ S = self.Struct('helloworld',
+ ('hello', lltype.Signed),
+ ('world', lltype.Signed),
+ hints={'immutable': True})
+ malloc = self.malloc
def ll_function(s):
return s.hello * s.world
@@ -670,7 +696,7 @@
def struct_S(string):
items = string.split(',')
assert len(items) == 2
- s1 = lltype.malloc(S)
+ s1 = malloc(S)
s1.hello = int(items[0])
s1.world = int(items[1])
return s1
@@ -1040,8 +1066,8 @@
def test_green_with_side_effects(self):
- S = lltype.GcStruct('S', ('flag', lltype.Bool))
- s = lltype.malloc(S)
+ S = self.Struct('S', ('flag', lltype.Bool))
+ s = self.malloc(S)
s.flag = False
def ll_set_flag(s):
s.flag = True
@@ -1952,18 +1978,45 @@
res = self.interpret(main2, [5, 6], policy=StopAtXPolicy(g))
assert res == 11
-
-
-class TestLLType(SimpleTests):
- type_system = "lltype"
-
class TestOOType(SimpleTests):
type_system = "ootype"
+ @staticmethod
+ def Ptr(T):
+ return T
+
+ @staticmethod
+ def Struct(name, *fields, **kwds):
+ if 'hints' in kwds:
+ kwds['_hints'] = kwds['hints']
+ del kwds['hints']
+ I = ootype.Instance(name, ootype.ROOT, dict(fields), **kwds)
+ return I
+
+ @staticmethod
+ def malloc(I):
+ return ootype.new(I)
+
+ def translate_insns(self, insns):
+ replace = {
+ 'getfield': 'oogetfield',
+ 'setfield': 'oosetfield',
+ }
+
+ insns = insns.copy()
+ for a, b in replace.iteritems():
+ if a in insns:
+ assert b not in insns
+ insns[b] = insns[a]
+ del insns[a]
+ return insns
+
def _skip(self):
py.test.skip('in progress')
+ #test_green_with_side_effects = _skip
+
test_degenerated_before_return = _skip
test_degenerated_before_return_2 = _skip
test_degenerated_at_return = _skip
@@ -2008,3 +2061,9 @@
test_learn_boolvalue = _skip
test_learn_nonzeroness = _skip
test_void_args = _skip
+
+
+class TestLLType(SimpleTests):
+ type_system = "lltype"
+
+
Modified: pypy/branch/jit-hotpath/pypy/jit/rainbow/typesystem.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/rainbow/typesystem.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/rainbow/typesystem.py Tue Mar 25 20:58:44 2008
@@ -1,6 +1,21 @@
-from pypy.rpython.lltypesystem import llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.ootypesystem import ootype
+def deref(T):
+ if isinstance(T, lltype.Ptr):
+ return T.TO
+ assert isinstance(T, (ootype.Instance, ootype.Record))
+ return T
+
+def fieldType(T, name):
+ if isinstance(T, lltype.Struct):
+ return getattr(T, name)
+ elif isinstance(T, ootype.Instance):
+ _, FIELD = T._lookup_field(name)
+ return FIELD
+ else:
+ assert False
+
class TypeSystemHelper(object):
def _freeze_(self):
Modified: pypy/branch/jit-hotpath/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/timeshifter/rcontainer.py Tue Mar 25 20:58:44 2008
@@ -1,9 +1,11 @@
import operator
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.ootypesystem import ootype
from pypy.rpython.annlowlevel import cachedtype, cast_base_ptr_to_instance
from pypy.rpython.annlowlevel import base_ptr_lltype, cast_instance_to_base_ptr
from pypy.rpython.annlowlevel import llhelper
from pypy.jit.timeshifter import rvalue, rvirtualizable
+from pypy.jit.rainbow.typesystem import deref, fieldType
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.objectmodel import we_are_translated
@@ -54,7 +56,7 @@
# ____________________________________________________________
-class StructTypeDesc(object):
+class AbstractStructTypeDesc(object):
__metaclass__ = cachedtype
VirtualStructCls = None # patched later with VirtualStruct
@@ -76,16 +78,11 @@
firstsubstructdesc = None
materialize = None
+ StructFieldDesc = None
- def __new__(cls, RGenOp, TYPE):
- if TYPE._hints.get('virtualizable', False):
- return object.__new__(VirtualizableStructTypeDesc)
- else:
- return object.__new__(StructTypeDesc)
-
def __init__(self, RGenOp, TYPE):
self.TYPE = TYPE
- self.PTRTYPE = lltype.Ptr(TYPE)
+ self.PTRTYPE = self.Ptr(TYPE)
self.name = TYPE._name
self.ptrkind = RGenOp.kindToken(self.PTRTYPE)
@@ -101,22 +98,26 @@
self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
self._compute_fielddescs(RGenOp)
+ self._define_helpers(TYPE, fixsize)
- if TYPE._gckind == 'gc': # no 'allocate' for inlined substructs
- if self.immutable and self.noidentity:
- self._define_materialize()
- if fixsize:
- self._define_devirtualize()
- self._define_allocate(fixsize)
-
+ def Ptr(self, TYPE):
+ raise NotImplementedError
+
+ def _define_helpers(self, TYPE, fixsize):
+ raise NotImplementedError
+
+ def _iter_fields(self, TYPE):
+ for name in TYPE._names:
+ FIELDTYPE = getattr(TYPE, name)
+ yield name, FIELDTYPE
+
def _compute_fielddescs(self, RGenOp):
TYPE = self.TYPE
innermostdesc = self
fielddescs = []
fielddesc_by_name = {}
- for name in TYPE._names:
- FIELDTYPE = getattr(TYPE, name)
+ for name, FIELDTYPE in self._iter_fields(TYPE):
if isinstance(FIELDTYPE, lltype.ContainerType):
if isinstance(FIELDTYPE, lltype.Array):
self.arrayfielddesc = ArrayFieldDesc(RGenOp, FIELDTYPE)
@@ -133,7 +134,7 @@
if FIELDTYPE is lltype.Void:
desc = None
else:
- desc = StructFieldDesc(RGenOp, self.PTRTYPE, name, index)
+ desc = self.StructFieldDesc(RGenOp, self.PTRTYPE, name, index)
fielddescs.append(desc)
fielddesc_by_name[name] = desc
@@ -221,6 +222,43 @@
return box
+class StructTypeDesc(AbstractStructTypeDesc):
+
+ StructFieldDesc = None # patched later with StructFieldDesc
+
+ def __new__(cls, RGenOp, TYPE):
+ if TYPE._hints.get('virtualizable', False):
+ return object.__new__(VirtualizableStructTypeDesc)
+ else:
+ return object.__new__(StructTypeDesc)
+
+ def Ptr(self, TYPE):
+ return lltype.Ptr(TYPE)
+
+ def _define_helpers(self, TYPE, fixsize):
+ if TYPE._gckind == 'gc': # no 'allocate' for inlined substructs
+ if self.immutable and self.noidentity:
+ self._define_materialize()
+ if fixsize:
+ self._define_devirtualize()
+ self._define_allocate(fixsize)
+
+
+class InstanceTypeDesc(AbstractStructTypeDesc):
+
+ StructFieldDesc = None # patched later with InstanceFieldDesc
+
+ def Ptr(self, TYPE):
+ return TYPE
+
+ def _define_helpers(self, TYPE, fixsize):
+ pass
+
+ def _iter_fields(self, TYPE):
+ for name, (FIELDTYPE, defl) in TYPE._fields.iteritems():
+ yield name, FIELDTYPE
+
+
def create_varsize(jitstate, contdesc, sizebox):
gv_size = sizebox.getgenvar(jitstate)
alloctoken = contdesc.varsizealloctoken
@@ -579,6 +617,8 @@
else:
T = None
self.fieldnonnull = PTRTYPE.TO._hints.get('shouldntbenull', False)
+ elif isinstance(RESTYPE, ootype.OOType):
+ assert False, 'XXX: TODO'
self.RESTYPE = RESTYPE
self.ptrkind = RGenOp.kindToken(PTRTYPE)
self.kind = RGenOp.kindToken(RESTYPE)
@@ -591,7 +631,7 @@
self.structdesc = StructTypeDesc(RGenOp, T)
self.redboxcls = rvalue.ll_redboxcls(RESTYPE)
- self.immutable = PTRTYPE.TO._hints.get('immutable', False)
+ self.immutable = deref(PTRTYPE)._hints.get('immutable', False)
def _freeze_(self):
return True
@@ -616,9 +656,9 @@
class NamedFieldDesc(FieldDesc):
def __init__(self, RGenOp, PTRTYPE, name):
- FIELDTYPE = getattr(PTRTYPE.TO, name)
+ FIELDTYPE = fieldType(deref(PTRTYPE), name)
FieldDesc.__init__(self, RGenOp, PTRTYPE, FIELDTYPE)
- T = self.PTRTYPE.TO
+ T = deref(self.PTRTYPE)
self.fieldname = name
self.fieldtoken = RGenOp.fieldToken(T, name)
def perform_getfield(rgenop, genvar):
@@ -663,6 +703,22 @@
NamedFieldDesc.__init__(self, RGenOp, PTRTYPE, name)
self.fieldindex = index
+class InstanceFieldDesc(NamedFieldDesc):
+
+ def __init__(self, RGenOp, PTRTYPE, name, index):
+ NamedFieldDesc.__init__(self, RGenOp, PTRTYPE, name)
+ self.fieldindex = index
+
+ def generate_get(self, jitstate, genvar):
+ builder = jitstate.curbuilder
+ gv_item = builder.genop_oogetfield(self.fieldtoken, genvar)
+ return self.makebox(jitstate, gv_item)
+
+ def generate_set(self, jitstate, genvar, gv_value):
+ builder = jitstate.curbuilder
+ builder.genop_oosetfield(self.fieldtoken, genvar, gv_value)
+
+
class ArrayFieldDesc(FieldDesc):
allow_void = True
@@ -1341,3 +1397,8 @@
return None
del data[j:]
return self
+
+
+
+StructTypeDesc.StructFieldDesc = StructFieldDesc
+InstanceTypeDesc.StructFieldDesc = InstanceFieldDesc
Modified: pypy/branch/jit-hotpath/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/timeshifter/rtimeshift.py Tue Mar 25 20:58:44 2008
@@ -158,7 +158,7 @@
return rvalue.PtrRedBox(contdesc.ptrkind, genvar, known_nonzero=True)
def gengetfield(jitstate, deepfrozen, fielddesc, argbox):
- assert isinstance(argbox, rvalue.PtrRedBox)
+ assert isinstance(argbox, (rvalue.PtrRedBox, rvalue.InstanceRedBox))
if (fielddesc.immutable or deepfrozen) and argbox.is_constant():
try:
resgv = fielddesc.perform_getfield(
Modified: pypy/branch/jit-hotpath/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/branch/jit-hotpath/pypy/jit/timeshifter/rvalue.py Tue Mar 25 20:58:44 2008
@@ -110,7 +110,7 @@
return redboxbuilder_ptr
elif TYPE is lltype.Float:
return redboxbuilder_dbl
- elif isinstance(TYPE, ootype.Instance):
+ elif isinstance(TYPE, (ootype.Instance, ootype.Record)):
return redboxbuilder_inst
else:
assert isinstance(TYPE, lltype.Primitive)
@@ -335,9 +335,6 @@
if self.content:
self.content.enter_block(incoming, memo)
-
-class PtrRedBox(AbstractPtrRedBox, LLTypeMixin):
-
def op_getfield(self, jitstate, fielddesc):
self.learn_nonzeroness(jitstate, True)
if self.content is not None:
@@ -350,6 +347,17 @@
self.remember_field(fielddesc, box)
return box
+ def remember_field(self, fielddesc, box):
+ if self.genvar.is_const:
+ return # no point in remembering field then
+ if self.content is None:
+ from pypy.jit.timeshifter import rcontainer
+ self.content = rcontainer.PartialDataStruct()
+ self.content.remember_field(fielddesc, box)
+
+
+class PtrRedBox(AbstractPtrRedBox, LLTypeMixin):
+
def op_setfield(self, jitstate, fielddesc, valuebox):
self.learn_nonzeroness(jitstate, True)
gv_ptr = self.genvar
@@ -369,14 +377,6 @@
assert self.content is not None
return self.content.op_getsubstruct(jitstate, fielddesc)
- def remember_field(self, fielddesc, box):
- if self.genvar.is_const:
- return # no point in remembering field then
- if self.content is None:
- from pypy.jit.timeshifter import rcontainer
- self.content = rcontainer.PartialDataStruct()
- self.content.remember_field(fielddesc, box)
-
class InstanceRedBox(AbstractPtrRedBox, OOTypeMixin):
More information about the Pypy-commit
mailing list