[pypy-svn] r31942 - in pypy/dist/pypy/jit: codegen/llgraph codegen/llgraph/test llabstractinterp timeshifter timeshifter/test

arigo at codespeak.net arigo at codespeak.net
Sat Sep 2 12:50:24 CEST 2006


Author: arigo
Date: Sat Sep  2 12:50:18 2006
New Revision: 31942

Modified:
   pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
   pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
   pypy/dist/pypy/jit/codegen/llgraph/test/test_llimpl.py
   pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py
   pypy/dist/pypy/jit/timeshifter/rcontainer.py
   pypy/dist/pypy/jit/timeshifter/rtimeshift.py
   pypy/dist/pypy/jit/timeshifter/rtyper.py
   pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
Log:
(pedronis, arigo)

Simplify rcontainer.VirtualStruct: remove the list of
equivalent-but-differently-typed boxes.  In order to do this we had to
change the rgenop interface to no longer care about the exact pointer
types in case of GcStruct starting with a nested GcStruct.



Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py	(original)
+++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py	Sat Sep  2 12:50:18 2006
@@ -36,7 +36,7 @@
     assert block.exits == [], "block already closed"
     CONCRETE_TYPE = from_opaque_object(gv_CONCRETE_TYPE).value
     v = flowmodel.Variable()
-    v.concretetype = CONCRETE_TYPE
+    v.concretetype = lltype.erasedType(CONCRETE_TYPE)
     block.inputargs.append(v)
     return to_opaque_object(v)
 
@@ -66,6 +66,29 @@
         res.append(v)
     return res
 
+def cast(blockcontainer, gv_TYPE, gv_var):
+    TYPE = from_opaque_object(gv_TYPE).value
+    v = from_opaque_object(gv_var)
+    if TYPE != v.concretetype:
+        assert v.concretetype == lltype.erasedType(TYPE)
+        block = from_opaque_object(blockcontainer.obj)
+        v2 = flowmodel.Variable()
+        v2.concretetype = TYPE
+        op = flowmodel.SpaceOperation('cast_pointer', [v], v2)
+        block.operations.append(op)
+        v = v2
+    return to_opaque_object(v)
+
+def erasedvar(v, block):
+    T = lltype.erasedType(v.concretetype)
+    if T != v.concretetype:
+        v2 = flowmodel.Variable()
+        v2.concretetype = T
+        op = flowmodel.SpaceOperation("cast_pointer", [v], v2)
+        block.operations.append(op)
+        return v2
+    return v
+
 def genop(blockcontainer, opname, vars_gv, gv_RESULT_TYPE):
     # 'opname' is a constant string
     # gv_RESULT_TYPE comes from constTYPE
@@ -82,7 +105,7 @@
     v.concretetype = RESULT_TYPE
     op = flowmodel.SpaceOperation(opname, opvars, v)
     block.operations.append(op)
-    return to_opaque_object(v)
+    return to_opaque_object(erasedvar(v, block))
 
 def gencallableconst(name, targetcontainer, gv_FUNCTYPE):
     # 'name' is just a way to track things
@@ -91,12 +114,16 @@
     target = from_opaque_object(targetcontainer.obj)
     FUNCTYPE = from_opaque_object(gv_FUNCTYPE).value
     fptr = lltype.functionptr(FUNCTYPE, name,
-                              graph=_buildgraph(target))
+                              graph=_buildgraph(target, FUNCTYPE))
     return genconst(fptr)
 
 def genconst(llvalue):
+    T = lltype.typeOf(llvalue)
+    T1 = lltype.erasedType(T)
+    if T1 != T:
+        llvalue = lltype.cast_pointer(T1, llvalue)
     v = flowmodel.Constant(llvalue)
-    v.concretetype = lltype.typeOf(llvalue)
+    v.concretetype = T1
     if v.concretetype == lltype.Void: # XXX genconst should not really be used for Void constants
         assert not isinstance(llvalue, str) and not isinstance(llvalue, lltype.LowLevelType)
     return to_opaque_object(v)
@@ -202,8 +229,9 @@
     pseudoreturnblock.operations = ()
     _closelink(link, [returnvar], pseudoreturnblock)
 
-def _patchgraph(graph):
+def _patchgraph(graph, RESULT):
     returntype = None
+    links = []
     for link in graph.iterlinks():
         if link.target.operations == ():
             assert len(link.args) == 1    # for now
@@ -211,28 +239,59 @@
                 returntype = link.target.inputargs[0].concretetype
             else:
                 assert returntype == link.target.inputargs[0].concretetype
-            link.target = graph.returnblock
+            links.append(link)
     if returntype is None:
         returntype = lltype.Void
-    graph.returnblock.inputargs[0].concretetype = returntype
+    graph.returnblock.inputargs[0].concretetype = RESULT
+    targetblock = casting_bridge([returntype], [RESULT], graph.returnblock)
+    for link in links:
+        link.target = targetblock
 
 class PseudoRTyper(object):
     def __init__(self):
         from pypy.rpython.typesystem import LowLevelTypeSystem
         self.type_system = LowLevelTypeSystem.instance
 
-def _buildgraph(block):
-    graph = flowmodel.FunctionGraph('generated', block)
-    _patchgraph(graph)
+def casting_bridge(FROMS, TOS, target):
+    if FROMS != TOS:
+        operations = []
+        inputargs = []
+        linkargs = []
+        for FROM, TO  in zip(FROMS, TOS):
+            v = flowmodel.Variable()
+            v.concretetype = FROM
+            inputargs.append(v)
+            if FROM == TO:
+                linkargs.append(v)
+            else:
+                erasedv = flowmodel.Variable()
+                erasedv.concretetype = TO
+                operations.append(flowmodel.SpaceOperation('cast_pointer',
+                                                           [v],
+                                                           erasedv))
+                linkargs.append(erasedv)
+        bridgeblock = flowmodel.Block(inputargs)
+        bridgeblock.operations = operations
+        bridge = flowmodel.Link(linkargs, target)
+        bridgeblock.closeblock(bridge)
+        return bridgeblock
+    else:
+        return target
+        
+def _buildgraph(block, FUNCTYPE):
+    ARGS = [v.concretetype for v in block.inputargs]
+    startblock =casting_bridge(FUNCTYPE.ARGS, ARGS, block)
+    graph = flowmodel.FunctionGraph('generated', startblock)
+    _patchgraph(graph, FUNCTYPE.RESULT)
     flowmodel.checkgraph(graph)
     eliminate_empty_blocks(graph)
     join_blocks(graph)
     graph.rgenop = True
     return graph
 
-def buildgraph(blockcontainer):
+def buildgraph(blockcontainer, FUNCTYPE):
     block = from_opaque_object(blockcontainer.obj)
-    return _buildgraph(block)
+    return _buildgraph(block, FUNCTYPE)
 
 def testgengraph(gengraph, args, viewbefore=False, executor=LLInterpreter):
     if viewbefore:
@@ -240,8 +299,9 @@
     llinterp = executor(PseudoRTyper())
     return llinterp.eval_graph(gengraph, args)
     
-def runblock(blockcontainer, args, viewbefore=False, executor=LLInterpreter):
-    graph = buildgraph(blockcontainer)
+def runblock(blockcontainer, FUNCTYPE, args,
+             viewbefore=False, executor=LLInterpreter):
+    graph = buildgraph(blockcontainer, FUNCTYPE)
     return testgengraph(graph, args, viewbefore, executor)
 
 # ____________________________________________________________
@@ -310,6 +370,7 @@
 setannotation(genop, s_ConstOrVar)
 setannotation(gencallableconst, s_ConstOrVar)
 setannotation(genconst, s_ConstOrVar)
+setannotation(cast, s_ConstOrVar)
 setannotation(revealconst, lambda s_T, s_gv: annmodel.lltype_to_annotation(
                                                   s_T.const))
 setannotation(isconst, annmodel.SomeBool())

Modified: pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/llgraph/rgenop.py	Sat Sep  2 12:50:18 2006
@@ -40,18 +40,21 @@
         return LLVar(llimpl.genop(self.b, opname, vars_gv,
                                   (gv_RESULT_TYPE or gv_Void).v))
 
-    def genop_getfield(self, (gv_name, gv_FIELDTYPE), gv_ptr):
-        vars_gv = [gv_ptr.v, gv_name.v]
+    def genop_getfield(self, (gv_name, gv_PTRTYPE, gv_FIELDTYPE), gv_ptr):
+        vars_gv = [llimpl.cast(self.b, gv_PTRTYPE.v, gv_ptr.v), gv_name.v]
         return LLVar(llimpl.genop(self.b, 'getfield', vars_gv,
                                   gv_FIELDTYPE.v))        
     
-    def genop_setfield(self, (gv_name, gv_FIELDTYPE), gv_ptr, gv_value):
-        vars_gv = [gv_ptr.v, gv_name.v, gv_value.v]
+    def genop_setfield(self, (gv_name, gv_PTRTYPE, gv_FIELDTYPE), gv_ptr,
+                                                                  gv_value):
+        vars_gv = [llimpl.cast(self.b, gv_PTRTYPE.v, gv_ptr.v),
+                   gv_name.v,
+                   llimpl.cast(self.b, gv_FIELDTYPE.v, gv_value.v)]
         return LLVar(llimpl.genop(self.b, 'setfield', vars_gv,
                                   gv_Void.v))        
     
-    def genop_getsubstruct(self, (gv_name, gv_FIELDTYPE), gv_ptr):
-        vars_gv = [gv_ptr.v, gv_name.v]
+    def genop_getsubstruct(self, (gv_name, gv_PTRTYPE, gv_FIELDTYPE), gv_ptr):
+        vars_gv = [llimpl.cast(self.b, gv_PTRTYPE.v, gv_ptr.v), gv_name.v]
         return LLVar(llimpl.genop(self.b, 'getsubstruct', vars_gv,
                                   gv_FIELDTYPE.v))        
 
@@ -113,6 +116,7 @@
         if isinstance(FIELDTYPE, lltype.ContainerType):
             FIELDTYPE = lltype.Ptr(FIELDTYPE)
         return (LLConst(llimpl.constFieldName(name)),
+                LLConst(llimpl.constTYPE(lltype.Ptr(T))),
                 LLConst(llimpl.constTYPE(FIELDTYPE)))
 
     @staticmethod
@@ -156,12 +160,12 @@
 
     # Builds a real flow.model.FunctionGraph. Specific to llgraph.
     @staticmethod
-    def buildgraph(block):
+    def buildgraph(block, FUNCTYPE):
         if hasattr(block, 'b'):
             b = block.b
         else:
             b = fishllattr(block, 'b')
-        return llimpl.buildgraph(b)
+        return llimpl.buildgraph(b, FUNCTYPE)
 
     def _freeze_(self):
         return True    # no real point in using a full class in llgraph

Modified: pypy/dist/pypy/jit/codegen/llgraph/test/test_llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/test/test_llimpl.py	(original)
+++ pypy/dist/pypy/jit/codegen/llgraph/test/test_llimpl.py	Sat Sep  2 12:50:18 2006
@@ -4,6 +4,7 @@
 from pypy.rpython.module.support import from_opaque_object
 from pypy.objspace.flow import model as flowmodel
 
+F1 = FuncType([Signed], Signed)
 
 def build_square():
     """def square(v0): return v0*v0"""
@@ -16,7 +17,7 @@
 
 def test_square():
     block = build_square()
-    res = runblock(block, [17])
+    res = runblock(block, F1, [17])
     assert res == 289
 
 def test_rtype_newblock():
@@ -37,7 +38,7 @@
     
 def test_rtype_build_square():
     blockcontainer = interpret(build_square, [])
-    res = runblock(blockcontainer, [17])
+    res = runblock(blockcontainer, F1, [17])
     assert res == 289
 
 def build_if():
@@ -59,16 +60,16 @@
 
 def test_if():
     block = build_if()
-    res = runblock(block, [-1])
+    res = runblock(block, F1, [-1])
     assert res == 0
-    res = runblock(block, [42])
+    res = runblock(block, F1, [42])
     assert res == 42
 
 def test_rtype_build_if():
     blockcontainer = interpret(build_if, [])
-    res = runblock(blockcontainer, [-1])
+    res = runblock(blockcontainer, F1, [-1])
     assert res == 0
-    res = runblock(blockcontainer, [42])
+    res = runblock(blockcontainer, F1, [42])
     assert res == 42
 
 def build_loop():
@@ -101,20 +102,20 @@
 
 def test_loop():
     block = build_loop()
-    res = runblock(block, [0])
+    res = runblock(block, F1, [0])
     assert res == 1
-    res = runblock(block, [1])
+    res = runblock(block, F1, [1])
     assert res == 1
-    res = runblock(block, [7])
+    res = runblock(block, F1, [7])
     assert res == 5040
 
 def test_rtype_build_loop():
     blockcontainer = interpret(build_loop, [])
-    res = runblock(blockcontainer, [0])
+    res = runblock(blockcontainer, F1, [0])
     assert res == 1
-    res = runblock(blockcontainer, [1])
+    res = runblock(blockcontainer, F1, [1])
     assert res == 1
-    res = runblock(blockcontainer, [7])
+    res = runblock(blockcontainer, F1, [7])
     assert res == 5040
 
 def test_rtype_void_constant_construction():

Modified: pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py	(original)
+++ pypy/dist/pypy/jit/llabstractinterp/llabstractinterp.py	Sat Sep  2 12:50:18 2006
@@ -172,16 +172,19 @@
     def eval(self, origgraph, arghints):
         # 'arghints' maps argument index to a given ll value
         args_a = []
+        ARGS = []
         for i, v in enumerate(origgraph.getargs()):
             if i in arghints:
                 a = LLAbstractValue(AConstant(arghints[i]))
                 a.concrete = self.policy.concrete_args
             else:
+                ARGS.append(v.concretetype)
                 a = LLAbstractValue(AVariable(v.concretetype))
             args_a.append(a)
         graphstate = self.schedule_graph(args_a, origgraph)
         graphstate.complete()
-        return rgenop.buildgraph(graphstate.startblock)
+        FUNCTYPE = lltype.FuncType(ARGS, origgraph.getreturnvar().concretetype)
+        return rgenop.buildgraph(graphstate.startblock, FUNCTYPE)
 
     def schedule_graph(self, args_a, origgraph):
         inputstate = LLBlockState(None, args_a, origgraph.startblock)

Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py	Sat Sep  2 12:50:18 2006
@@ -34,40 +34,37 @@
         self.PTRTYPE = lltype.Ptr(TYPE)
         self.alloctoken = RGenOp.allocToken(self.TYPE)
         self.ptrkind = RGenOp.kindToken(self.PTRTYPE)
+        innermostdesc = self
 
         fielddescs = []
+        fielddesc_by_name = {}
         for name in self.TYPE._names:
             FIELDTYPE = getattr(self.TYPE, name)
             if isinstance(FIELDTYPE, lltype.ContainerType):
                 substructdesc = StructTypeDesc(RGenOp, FIELDTYPE)
                 assert name == self.TYPE._names[0], (
                     "unsupported: inlined substructures not as first field")
+                fielddescs.extend(substructdesc.fielddescs)
                 self.firstsubstructdesc = substructdesc
-                for subfielddesc in substructdesc.fielddescs:
-                    dottedname = '%s.%s' % (name, subfielddesc.fieldname)
-                    index = len(fielddescs)
-                    fielddescs.append(StructFieldDesc(RGenOp, self.PTRTYPE,
-                                                      dottedname, index))
+                innermostdesc = substructdesc.innermostdesc
             else:
                 index = len(fielddescs)
-                fielddescs.append(StructFieldDesc(RGenOp, self.PTRTYPE,
-                                                  name, index))
+                desc = StructFieldDesc(RGenOp, self.PTRTYPE, name, index)
+                fielddescs.append(desc)
+                fielddesc_by_name[name] = desc
         self.fielddescs = fielddescs
+        self.fielddesc_by_name = fielddesc_by_name
+        self.innermostdesc = innermostdesc
 
     def getfielddesc(self, name):
-        index = operator.indexOf(self.TYPE._names, name)
-        return self.fielddescs[index]
+        return self.fielddesc_by_name[name]
 
     def ll_factory(self):
         vstruct = VirtualStruct(self)
-        vstruct.substruct_boxes = []
-        typedesc = self
-        while typedesc is not None:
-            box = rvalue.PtrRedBox(typedesc.ptrkind)
-            box.content = vstruct
-            vstruct.substruct_boxes.append(box)
-            typedesc = typedesc.firstsubstructdesc
-        return vstruct.substruct_boxes[0]
+        box = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
+        box.content = vstruct
+        vstruct.ownbox = box
+        return box
 
     def _freeze_(self):
         return True
@@ -84,6 +81,7 @@
         if isinstance(RESTYPE, lltype.ContainerType):
             RESTYPE = lltype.Ptr(RESTYPE)
         self.RESTYPE = RESTYPE
+        self.ptrkind = RGenOp.kindToken(PTRTYPE)
         self.kind = RGenOp.kindToken(RESTYPE)
         self.redboxcls = rvalue.ll_redboxcls(RESTYPE)
         self.immutable = PTRTYPE.TO._hints.get('immutable', False)
@@ -95,56 +93,36 @@
 
     def __init__(self, RGenOp, PTRTYPE, name):
         FieldDesc.__init__(self, RGenOp, PTRTYPE, getattr(PTRTYPE.TO, name))
-        self.structdepth = 0
         T = self.PTRTYPE.TO
         self.fieldname = name
         self.fieldtoken = RGenOp.fieldToken(T, name)
-        while (T._names and
-               isinstance(getattr(T, T._names[0]), lltype.ContainerType)):
-            self.structdepth += 1
-            T = getattr(T, T._names[0])
 
-class ArrayFieldDesc(FieldDesc):
-    def __init__(self, RGenOp, PTRTYPE):
-        assert isinstance(PTRTYPE.TO, lltype.Array)
-        FieldDesc.__init__(self, RGenOp, PTRTYPE, PTRTYPE.TO.OF)
-        self.arraytoken = RGenOp.arrayToken(PTRTYPE.TO)
+    def compact_repr(self): # goes in ll helper names
+        return "Fld_%s_in_%s" % (self.fieldname, self.PTRTYPE._short_name())
 
-class StructFieldDesc(object):
-    __metaclass__ = cachedtype
+    def generate_get(self, builder, genvar):
+        gv_item = builder.genop_getfield(self.fieldtoken, genvar)
+        return self.redboxcls(self.kind, gv_item)
 
-    def __init__(self, RGenOp, PTRTYPE, fieldname, index):
-        assert isinstance(PTRTYPE.TO, lltype.Struct)
-        RES1 = PTRTYPE.TO
-        accessors = []
-        for component in fieldname.split('.'):
-            LASTSTRUCT = RES1
-            accessors.append((RES1, component))
-            RES1 = getattr(RES1, component)
-        assert not isinstance(RES1, lltype.ContainerType)
-        self.PTRTYPE = PTRTYPE
-        self.RESTYPE = RES1
-        self.kind = RGenOp.kindToken(RES1)
-        self.fieldname = fieldname
-        self.fieldtokens = [RGenOp.fieldToken(T, component)
-                             for T, component in accessors]
-        self.fieldindex = index
-        self.gv_default = RGenOp.constPrebuiltGlobal(RES1._defl())
-        self.redboxcls = rvalue.ll_redboxcls(RES1)
-        self.immutable = LASTSTRUCT._hints.get('immutable', False)
+    def generate_set(self, builder, genvar, box):
+        builder.genop_setfield(self.fieldtoken, genvar, box.getgenvar(builder))
 
-    def _freeze_(self):
-        return True
+    def generate_getsubstruct(self, builder, genvar):
+        gv_sub = builder.genop_getsubstruct(self.fieldtoken, genvar)
+        return self.redboxcls(self.kind, gv_sub)
 
-    def compact_repr(self): # goes in ll helper names
-        return "Fld_%s_in_%s" % (self.fieldname.replace('.','_'),
-                                 self.PTRTYPE._short_name())
+class StructFieldDesc(NamedFieldDesc):
 
-    def generate_set(self, builder, genvar, box):
-        gv_sub = genvar
-        for i in range(len(self.fieldtokens)-1):
-            gv_sub = builder.genop_getsubstruct(self.fieldtokens[i], gv_sub)
-        builder.genop_setfield(self.fieldtokens[-1], gv_sub, box.getgenvar(builder))        
+    def __init__(self, RGenOp, PTRTYPE, name, index):
+        NamedFieldDesc.__init__(self, RGenOp, PTRTYPE, name)
+        self.fieldindex = index
+        self.gv_default = RGenOp.constPrebuiltGlobal(self.RESTYPE._defl())
+
+class ArrayFieldDesc(FieldDesc):
+    def __init__(self, RGenOp, PTRTYPE):
+        assert isinstance(PTRTYPE.TO, lltype.Array)
+        FieldDesc.__init__(self, RGenOp, PTRTYPE, PTRTYPE.TO.OF)
+        self.arraytoken = RGenOp.arrayToken(PTRTYPE.TO)
 
 # ____________________________________________________________
 
@@ -159,14 +137,14 @@
         if self in contmemo:
             ok = vstruct is contmemo[self]
             if not ok:
-                outgoingvarboxes.extend(vstruct.substruct_boxes)
+                outgoingvarboxes.append(vstruct.ownbox)
             return ok
         if vstruct in contmemo:
             assert contmemo[vstruct] is not self
-            outgoingvarboxes.extend(vstruct.substruct_boxes)
+            outgoingvarboxes.append(vstruct.ownbox)
             return False
         if self.typedesc is not vstruct.typedesc:
-            outgoingvarboxes.extend(vstruct.substruct_boxes)
+            outgoingvarboxes.append(vstruct.ownbox)
             return False
         contmemo[self] = vstruct
         contmemo[vstruct] = self
@@ -189,7 +167,7 @@
         self.content_boxes = [desc.redboxcls(desc.kind,
                                              desc.gv_default)
                               for desc in typedesc.fielddescs]
-        #self.substruct_boxes = ...
+        #self.ownbox = ... set in ll_factory()
 
     def enter_block(self, newblock, incoming, memo):
         contmemo = memo.containers
@@ -203,18 +181,13 @@
         boxes = self.content_boxes
         self.content_boxes = None
         genvar = builder.genop_malloc_fixedsize(typedesc.alloctoken)
-        # force all the boxes pointing to this VirtualStruct
-        for box in self.substruct_boxes:
-            # XXX using getsubstruct would be nicer
-            op_args = [genvar]
-            box.genvar = builder.genop('cast_pointer', op_args, box.kind)
-            box.content = None
-        self.substruct_boxes = None
+        # force the box pointing to this VirtualStruct
+        self.ownbox.genvar = genvar
+        self.ownbox.content = None
         fielddescs = typedesc.fielddescs
         for i in range(len(fielddescs)):
             fielddesc = fielddescs[i]
             box = boxes[i]
-            # xxx a bit inefficient
             fielddesc.generate_set(builder, genvar, box)
 
     def freeze(self, memo):
@@ -235,8 +208,7 @@
             result = contmemo[self] = VirtualStruct(self.typedesc)
             result.content_boxes = [box.copy(memo)
                                     for box in self.content_boxes]
-            result.substruct_boxes = [box.copy(memo)
-                                      for box in self.substruct_boxes]
+            result.ownbox = self.ownbox.copy(memo)
             return result
 
     def replace(self, memo):
@@ -245,8 +217,7 @@
             contmemo[self] = None
             for i in range(len(self.content_boxes)):
                 self.content_boxes[i] = self.content_boxes[i].replace(memo)
-            for i in range(len(self.substruct_boxes)):
-                self.substruct_boxes[i] = self.substruct_boxes[i].replace(memo)
+            self.ownbox = self.ownbox.replace(memo)
 
     def op_getfield(self, jitstate, fielddesc):
         return self.content_boxes[fielddesc.fieldindex]
@@ -255,5 +226,4 @@
         self.content_boxes[fielddesc.fieldindex] = valuebox
 
     def op_getsubstruct(self, jitstate, fielddesc):
-        #assert fielddesc.fieldindex == 0
-        return self.substruct_boxes[-fielddesc.structdepth]
+        return self.ownbox

Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py	Sat Sep  2 12:50:18 2006
@@ -90,19 +90,16 @@
         return rvalue.ll_fromvalue(jitstate, res)
     assert isinstance(argbox, rvalue.PtrRedBox)
     if argbox.content is None:
-        genvar = jitstate.curbuilder.genop_getfield(fielddesc.fieldtokens[-1],
-                                                    argbox.getgenvar(jitstate.curbuilder))
-        return fielddesc.redboxcls(fielddesc.kind, genvar)        
+        gv_ptr = argbox.getgenvar(jitstate.curbuilder)
+        return fielddesc.generate_get(jitstate.curbuilder, gv_ptr)
     else:
         return argbox.content.op_getfield(jitstate, fielddesc)
 
 def ll_generate_setfield(jitstate, fielddesc, destbox, valuebox):
     assert isinstance(destbox, rvalue.PtrRedBox)
     if destbox.content is None:
-        builder = jitstate.curbuilder
-        builder.genop_setfield(fielddesc.fieldtokens[-1],
-                                destbox.getgenvar(builder),
-                                valuebox.getgenvar(builder))
+        gv_ptr = destbox.getgenvar(jitstate.curbuilder)
+        fielddesc.generate_set(jitstate.curbuilder, gv_ptr, valuebox)
     else:
         destbox.content.op_setfield(jitstate, fielddesc, valuebox)
 
@@ -113,8 +110,8 @@
         return rvalue.ll_fromvalue(jitstate, res)
     assert isinstance(argbox, rvalue.PtrRedBox)
     if argbox.content is None:
-        genvar = jitstate.curbuilder.genop_getsubstruct(fielddesc.fieldtoken, argbox.getgenvar(jitstate.curbuilder))
-        return fielddesc.redboxcls(fielddesc.kind, genvar)        
+        gv_ptr = argbox.getgenvar(jitstate.curbuilder)
+        return fielddesc.generate_getsubstruct(jitstate.curbuilder, gv_ptr)
     else:
         return argbox.content.op_getsubstruct(jitstate, fielddesc)
 

Modified: pypy/dist/pypy/jit/timeshifter/rtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtyper.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtyper.py	Sat Sep  2 12:50:18 2006
@@ -178,15 +178,14 @@
             annmodel.s_None)
 
     def translate_op_getsubstruct(self, hop):
-        if isinstance(hop.args_r[0], BlueRepr):        
-            return hop.args_r[0].timeshift_getsubstruct(hop)
-        # non virtual case
+        ##if isinstance(hop.args_r[0], BlueRepr):
+        ##    return hop.args_r[0].timeshift_getsubstruct(hop)
         ts = self.timeshifter
         PTRTYPE = originalconcretetype(hop.args_s[0])
         v_argbox, c_fieldname = hop.inputargs(self.getredrepr(PTRTYPE),
                                               green_void_repr)
         fielddesc = rcontainer.NamedFieldDesc(self.RGenOp, PTRTYPE,
-                                              c_fieldname.value) # XXX
+                                              c_fieldname.value)
         c_fielddesc = inputconst(lltype.Void, fielddesc)
         s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
         v_jitstate = hop.llops.getjitstate()
@@ -194,7 +193,11 @@
             [ts.s_JITState, s_fielddesc, ts.s_RedBox],
             [v_jitstate,    c_fielddesc, v_argbox   ],
             ts.s_RedBox)
-        
+
+    def translate_op_cast_pointer(self, hop):
+        FROM_TYPE = originalconcretetype(hop.args_s[0])
+        v_argbox = hop.inputargs(self.getredrepr(FROM_TYPE))
+        return v_argbox
 
     def translate_op_malloc(self, hop):
         r_result = hop.r_result

Modified: pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_timeshift.py	Sat Sep  2 12:50:18 2006
@@ -525,7 +525,7 @@
 
     def test_inlined_substructure(self):
         py.test.skip("blue containers: to be reimplemented")
-        S = lltype.Struct('S', ('n', lltype.Signed))
+        S = lltype.GcStruct('S', ('n', lltype.Signed))
         T = lltype.GcStruct('T', ('s', S), ('n', lltype.Float))
         def ll_function(k):
             t = lltype.malloc(T)
@@ -674,7 +674,7 @@
         self.check_insns({'int_lt': 1, 'int_mul': 1})
 
     def test_red_subcontainer(self):
-        S = lltype.Struct('S', ('n', lltype.Signed))
+        S = lltype.GcStruct('S', ('n', lltype.Signed))
         T = lltype.GcStruct('T', ('s', S), ('n', lltype.Float))
         def ll_function(k):
             t = lltype.malloc(T)



More information about the Pypy-commit mailing list