[pypy-svn] r67031 - in pypy/branch/pyjitpl5/pypy/jit/backend: . test

benjamin at codespeak.net benjamin at codespeak.net
Thu Aug 20 16:23:15 CEST 2009


Author: benjamin
Date: Thu Aug 20 16:23:13 2009
New Revision: 67031

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py
   pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py
Log:
(micke, benjamin) write tests for and fix up the loop parser

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/loopparser.py	Thu Aug 20 16:23:13 2009
@@ -28,10 +28,11 @@
         self.text = text
 
 class Operation(object):
-    def __init__(self, opname, args, result=None):
+    def __init__(self, opname, args, result=None, descr=None):
         self.opname = opname
         self.args   = args
         self.result = result
+        self.descr = descr
 
     def __repr__(self):
         if self.result is None:
@@ -39,24 +40,94 @@
         return "%s = %s(%s)" % (self.result, self.opname, self.args)
 
 class GuardOperation(Operation):
+
+    @property
+    def suboperations(self):
+        return self.subblock.operations
+
+class AbstractValue(object):
+
+    def __init__(self, value):
+        self.value = int(value)
+
+class Box(AbstractValue):
+    pass
+
+class BoxInt(Box):
+    pass
+
+class BoxAddr(Box):
     pass
 
+class BoxPtr(Box):
+    pass
+
+class Const(AbstractValue):
+    pass
+
+class ConstInt(Const):
+    pass
+
+class ConstAddr(Const):
+    pass
+
+class ConstPtr(Const):
+    pass
+
+box_map = {
+    'b' : {
+        'i' : BoxInt,
+        'a' : BoxAddr,
+        'p' : BoxPtr
+        },
+    'c' : {
+        'i' : ConstInt,
+        'a' : ConstAddr,
+        'p' : ConstPtr
+        },
+}
+
+
+_arg_finder = re.compile(r"(..)\((\d+),(\d+)\)")
+
 class Parser(object):
+
     current_indentation = 0
-    
+
     def parse(self, fname):
         self.current_block = Block()
         self.blockstack = []
+        self.boxes = {}
         data = py.path.local(fname).read()
         lines = data.splitlines()
         i = 0
-        res = self._parse(lines, i)
-        assert res == len(lines)
+        length = len(lines)
+        loops = []
+        while i < length:
+             i = self._parse(lines, i)
+             loops.append(self.current_block)
+             self.boxes = {}
+             self.current_block = Block()
         assert not self.blockstack
-        return self.current_block
+        return loops
 
-    def parse_args(self, args):
-        return args
+    def _parse_boxes(self, box_string):
+        boxes = []
+        for info, iden, value in _arg_finder.findall(box_string):
+            box = self.get_box(iden, info, value)
+            boxes.append(self.get_box(int(iden), info, value))
+        return boxes
+
+    def get_box(self, key, tp_info, value):
+        try:
+            node = self.boxes[key]
+        except KeyError:
+            box_type, tp = tp_info
+            klass = box_map[box_type][tp]
+            node = klass(value)
+            self.boxes[key] = node
+        assert node.__class__ is box_map[tp_info[0]][tp_info[1]]
+        return node
 
     def parse_result(self, result):
         return result
@@ -67,7 +138,7 @@
     def parse_block(self, lines, start, guard_op):
         self.blockstack.append(self.current_block)
         block = Block()
-        guard_op.suboperations = block
+        guard_op.subblock = block
         self.current_block = block
         res = self._parse(lines, start)
         self.current_block = self.blockstack.pop()
@@ -87,9 +158,19 @@
         if line.startswith('#'):
             self.current_block.add(Comment(line[1:]))
             return i + 1
-        opname, args = line.split(" ")
+        descr = None
+        if " " in line:
+            # has arguments
+            opname, args_string = line.split(" ")
+            args = self._parse_boxes(args_string)
+            bracket = args_string.find("[")
+            if bracket != -1:
+                assert args_string[-1] == "]"
+                descr = eval(args_string[bracket:])
+        else:
+            opname = line
+            args = []
         _, opname = opname.split(":")
-        args = self.parse_args(args)
         if lines[i + 1].startswith(" " * (self.current_indentation + 2)):
             if lines[i + 1].strip().startswith('BEGIN'):
                 self.current_indentation += 2
@@ -98,11 +179,11 @@
                 return self.parse_block(lines, i + 2, guard_op)
             marker, result = lines[i + 1].strip().split(" ")
             assert marker == '=>'
-            result = self.parse_result(result)
-            self.current_block.add(Operation(opname, args, result))
+            result, = self._parse_boxes(result)
+            self.current_block.add(Operation(opname, args, result, descr))
             return i + 2
         else:
-            self.current_block.add(Operation(opname, args))
+            self.current_block.add(Operation(opname, args, descr=descr))
             return i + 1
 
     def _parse(self, lines, i):

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/test/test_loopparser.py	Thu Aug 20 16:23:13 2009
@@ -8,14 +8,61 @@
         return parser.parse(py.magic.autopath().join('..', 'loopdata', name))
 
     def test_simple_loop(self):
-        topblock = self.parse('simple.ops')
+        topblock, = self.parse('simple.ops')
         assert len(topblock.operations) == 7
         assert isinstance(topblock.operations[0], Comment)
+        assert topblock.operations[0].text == \
+            "(no jitdriver.get_printable_location!)"
         assert isinstance(topblock.operations[-2], Comment)
         assert isinstance(topblock.operations[4], GuardOperation)
         assert ([op.opname for op in topblock.operations
                  if not isinstance(op, Comment)] ==
                 ['int_add', 'int_sub', 'int_gt', 'guard_true', 'jump'])
-        subops = topblock.operations[4].suboperations.operations
+        subops = topblock.operations[4].suboperations
         assert len(subops) == 1
         assert subops[0].opname == 'fail'
+        fail = subops[0]
+        assert len(fail.args) == 3
+        assert fail.descr == []
+        add = topblock.operations[1]
+        assert len(add.args) == 2
+        assert isinstance(add.args[0], BoxInt)
+        assert add.args[0].value == 18
+        assert isinstance(add.args[1], BoxInt)
+        assert add.args[1].value == 6
+        assert isinstance(add.result, BoxInt)
+        assert isinstance(topblock.operations[2].args[1], ConstInt)
+        assert topblock.operations[2].args[1].value == 1
+        assert topblock.operations[2].result is topblock.operations[3].args[0]
+
+    def test_two_paths(self):
+        loops = self.parse("two_paths.ops")
+        assert len(loops) == 4
+        one = loops[0]
+        guard = one.operations[1]
+        assert not guard.args
+        call = loops[1].operations[3]
+        assert call.opname == "call"
+        assert len(call.args) == 4
+        assert isinstance(call.args[0], ConstAddr)
+        assert call.args[0].value == 166630900
+        for arg in call.args[1:]:
+            assert isinstance(arg, BoxInt)
+        assert call.descr == [3, 0, False]
+        last = loops[-1]
+        nested_guard = last.operations[2].suboperations[5]
+        assert isinstance(nested_guard, GuardOperation)
+        assert nested_guard.opname == "guard_true"
+        assert len(nested_guard.args) == 1
+        assert isinstance(nested_guard.args[0], BoxInt)
+
+    def test_string_loop(self):
+        loops = self.parse("string.ops")
+        assert len(loops) == 3
+        newstr = loops[1].operations[1]
+        assert newstr.opname == "newstr"
+        assert isinstance(newstr.result, BoxPtr)
+        assert len(newstr.args) == 1
+        assert isinstance(newstr.args[0], ConstInt)
+        assert newstr.result.value == 177102832
+        assert newstr.result is loops[1].operations[2].args[0]



More information about the Pypy-commit mailing list