[pypy-svn] r14238 - in pypy/dist/pypy/interpreter: stablecompiler test

ludal at codespeak.net ludal at codespeak.net
Mon Jul 4 19:55:10 CEST 2005


Author: ludal
Date: Mon Jul  4 19:55:08 2005
New Revision: 14238

Modified:
   pypy/dist/pypy/interpreter/stablecompiler/pyassem.py
   pypy/dist/pypy/interpreter/test/test_interpreter.py
Log:
fixed bug of 2.4 compiler which wouldn't generate EXTENDED_ARG at all


Modified: pypy/dist/pypy/interpreter/stablecompiler/pyassem.py
==============================================================================
--- pypy/dist/pypy/interpreter/stablecompiler/pyassem.py	(original)
+++ pypy/dist/pypy/interpreter/stablecompiler/pyassem.py	Mon Jul  4 19:55:08 2005
@@ -81,6 +81,9 @@
 
         i.e. each node appears before all of its successors
         """
+        # TODO: What we need here is a topological sort that
+        
+        
         # XXX make sure every node that doesn't have an explicit next
         # is set so that next points to exit
         for b in self.blocks.elements():
@@ -244,7 +247,7 @@
         op = inst[0]
         if op[:4] == 'JUMP':
             self.outEdges.add(inst[1])
-        self.insts.append(inst)
+        self.insts.append( list(inst) )
 
     def getInstructions(self):
         return self.insts
@@ -343,6 +346,7 @@
             if isinstance(var, TupleArg):
                 self.varnames[i] = var.getName()
         self.stage = RAW
+        self.orderedblocks = []
 
     def setDocstring(self, doc):
         self.docstring = doc
@@ -366,10 +370,10 @@
         """Get a Python code object"""
         if self.stage == RAW:
             self.computeStackDepth()
-            self.flattenGraph()
-        if self.stage == FLAT:
             self.convertArgs()
         if self.stage == CONV:
+            self.flattenGraph()
+        if self.stage == FLAT:
             self.makeByteCode()
         if self.stage == DONE:
             return self.newCodeObject()
@@ -425,35 +429,64 @@
 
     def flattenGraph(self):
         """Arrange the blocks in order and resolve jumps"""
-        assert self.stage == RAW
+        assert self.stage == CONV
         self.insts = insts = []
         pc = 0
         begin = {}
         end = {}
-        for b in self.getBlocksInOrder():
+        forward_refs = []
+        for b in self.orderedblocks:
             begin[b] = pc
             for inst in b.getInstructions():
-                insts.append(inst)
                 if len(inst) == 1:
+                    insts.append(inst)
                     pc = pc + 1
                 elif inst[0] != "SET_LINENO":
-                    # arg takes 2 bytes
-                    pc = pc + 3
+                    opname, arg = inst
+                    if self.hasjrel.has_elt(opname):
+                        # relative jump - no extended arg
+                        forward_refs.append( (arg,  inst, pc ) )
+                        insts.append(inst)
+                        pc = pc + 3
+                    elif self.hasjabs.has_elt(opname):
+                        # absolute jump - can be extended if backward
+                        if arg in begin:
+                            # can only extend argument if backward
+                            offset = begin[arg]
+                            hi, lo = divmod(offset,65536)
+                            if hi>0:
+                                # extended argument
+                                insts.append( ["EXTENDED_ARG", hi ] )
+                                pc = pc + 3
+                            inst[1] = lo
+                        else:
+                            forward_refs.append( (arg,  inst, pc ) )
+                        insts.append(inst)
+                        pc = pc + 3
+                    else:
+                        # numerical arg
+                        assert type(arg)==int
+                        hi,lo = divmod(arg,65536)
+                        if hi>0:
+                            # extended argument
+                            insts.append( ["EXTENDED_ARG", hi ] )
+                            inst[1] = lo
+                            pc = pc + 3    
+                        insts.append(inst)
+                        pc = pc + 3
+                else:
+                    insts.append(inst)
             end[b] = pc
         pc = 0
-        for i in range(len(insts)):
-            inst = insts[i]
-            if len(inst) == 1:
-                pc = pc + 1
-            elif inst[0] != "SET_LINENO":
-                pc = pc + 3
-            opname = inst[0]
+
+        for arg, inst, pc in forward_refs:
+            opname, block = inst
+            abspos = begin[block]
             if self.hasjrel.has_elt(opname):
-                oparg = inst[1]
-                offset = begin[oparg] - pc
-                insts[i] = opname, offset
-            elif self.hasjabs.has_elt(opname):
-                insts[i] = opname, begin[inst[1]]
+                offset = abspos - pc - 3
+                inst[1] = offset
+            else:
+                inst[1] = abspos
         self.stage = FLAT
 
     hasjrel = misc.Set()
@@ -465,16 +498,18 @@
 
     def convertArgs(self):
         """Convert arguments from symbolic to concrete form"""
-        assert self.stage == FLAT
+        assert self.stage == RAW
+        self.orderedblocks = self.getBlocksInOrder()
         self.consts.insert(0, self.docstring)
         self.sort_cellvars()
-        for i in range(len(self.insts)):
-            t = self.insts[i]
-            if len(t) == 2:
-                opname, oparg = t
-                conv = self._converters.get(opname, None)
-                if conv:
-                    self.insts[i] = opname, conv(self, oparg)
+
+        for b in self.orderedblocks:
+            for inst in b.getInstructions():
+                if len(inst) == 2:
+                    opname, oparg = inst
+                    conv = self._converters.get(opname, None)
+                    if conv:
+                        inst[1] = conv(self, oparg)
         self.stage = CONV
 
     def sort_cellvars(self):
@@ -563,10 +598,15 @@
     del name, obj, opname
 
     def makeByteCode(self):
-        assert self.stage == CONV
+        assert self.stage == FLAT
         self.lnotab = lnotab = LineAddrTable()
         for t in self.insts:
             opname = t[0]
+            if self._debug:
+                if len(t)==1:
+                    print "x",opname
+                else:
+                    print "x",opname, t[1]
             if len(t) == 1:
                 lnotab.addCode(self.opnum[opname])
             else:

Modified: pypy/dist/pypy/interpreter/test/test_interpreter.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_interpreter.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_interpreter.py	Mon Jul  4 19:55:08 2005
@@ -241,9 +241,6 @@
         ec = self.space.getexecutioncontext() 
         ec.compiler = self.saved_compiler
 
-    def test_extended_arg(self):
-        py.test.skip("Probably hits a bug in the compiler module")
-
 class AppTestInterpreter: 
     def test_trivial(self):
         x = 42



More information about the Pypy-commit mailing list