[pypy-svn] r25107 - pypy/dist/pypy/translator/cli

antocuni at codespeak.net antocuni at codespeak.net
Wed Mar 29 15:53:50 CEST 2006


Author: antocuni
Date: Wed Mar 29 15:53:43 2006
New Revision: 25107

Added:
   pypy/dist/pypy/translator/cli/metavm.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/cli/function.py
   pypy/dist/pypy/translator/cli/opcodes.py
Log:
More opcodes refactoring


Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py	(original)
+++ pypy/dist/pypy/translator/cli/function.py	Wed Mar 29 15:53:43 2006
@@ -2,7 +2,8 @@
 from pypy.rpython.lltypesystem.lltype import Void
 from pypy.translator.cli.option import getoption
 from pypy.translator.cli import cts
-from pypy.translator.cli.opcodes import opcodes, MicroInstruction, PushAllArgs, Literal
+from pypy.translator.cli.opcodes import opcodes
+from pypy.translator.cli.metavm import InstructionList, Generator
 
 from pypy.tool.ansi_print import ansi_log
 import py
@@ -18,7 +19,7 @@
         pass
     
 
-class Function(Node):
+class Function(Node, Generator):
     def __init__(self, graph, is_entrypoint = False):
         self.graph = graph
         self.is_entrypoint = is_entrypoint
@@ -179,13 +180,10 @@
         return 'block%s' % self.blocknum[block]
 
     def _render_op(self, op):
-        opname = op.opname
-
-        cli_opcode = opcodes.get(opname, None)
-        if cli_opcode is not None:
-            self._render_cli_opcode(cli_opcode, op)
-        elif opname == 'direct_call':
-            self._call(op)
+        instr_list = opcodes.get(op.opname, None)
+        if instr_list is not None:
+            assert isinstance(instr_list, InstructionList)
+            instr_list.render(self, op)
         else:
             if getoption('nostop'):
                 log.WARNING('Unknown opcode: %s ' % op)
@@ -193,35 +191,17 @@
             else:
                 assert False, 'Unknown opcode: %s ' % op
 
-    def _render_cli_opcode(self, cli_opcode, op):
-        if type(cli_opcode) is str:
-            instructions = [PushAllArgs(), cli_opcode]
-        else:
-            instructions = cli_opcode
-
-        for instr in instructions:
-            if type(instr) is str:
-                instr = Literal(instr)
-
-            assert isinstance(instr, MicroInstruction)
-            instr.render(self, op)
-
-        self.store(op.result)
-
+    # following methods belongs to the Generator interface
 
-    def _call(self, op):
-        func_name = cts.graph_to_signature(op.args[0].value.graph)
-
-        # push parameters
-        for func_arg in op.args[1:]:
-            self.load(func_arg)
-
-        self.ilasm.call(func_name)
-        self.store(op.result)
+    def function_name(self, graph):
+        return cts.graph_to_signature(graph)
 
     def emit(self, instr, *args):
         self.ilasm.opcode(instr, *args)
 
+    def call(self, func_name):
+        self.ilasm.call(func_name)
+
     def load(self, v):
         if isinstance(v, flowmodel.Variable):
             if v.name in self.argset:

Added: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/cli/metavm.py	Wed Mar 29 15:53:43 2006
@@ -0,0 +1,63 @@
+class Generator(object):
+    def function_name(self, graph):
+        pass
+
+    def emit(self, instr, *args):
+        pass
+
+    def call(self, func_name):
+        pass
+
+    def load(self, v):
+        pass
+
+    def store(self, v):
+        pass
+
+
+class InstructionList(list):
+    def render(self, generator, op):
+        for instr in self:
+            if isinstance(instr, MicroInstruction):
+                instr.render(generator, op)
+            else:
+                generator.emit(instr)
+
+
+class MicroInstruction(object):
+    def render(self, generator, op):
+        pass
+
+
+class PushArg(MicroInstruction):
+    def __init__(self, n):
+        self.n = n
+
+    def render(self, generator, op):
+        generator.load(op.args[self.n])
+
+
+class _PushAllArgs(MicroInstruction):
+    def render(self, generator, op):
+        for arg in op.args:
+            generator.load(arg)
+
+
+class _StoreResult(MicroInstruction):
+    def render(self, generator, op):
+        generator.store(op.result)
+
+
+class _Call(MicroInstruction):
+    def render(self, generator, op):
+        func_name = generator.function_name(op.args[0].value.graph)
+
+        # push parameters
+        for func_arg in op.args[1:]:
+            generator.load(func_arg)
+
+        generator.call(func_name)
+
+PushAllArgs = _PushAllArgs()
+StoreResult = _StoreResult()
+Call = _Call()

Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py	(original)
+++ pypy/dist/pypy/translator/cli/opcodes.py	Wed Mar 29 15:53:43 2006
@@ -1,42 +1,17 @@
-class MicroInstruction(object):
-    def render(self, generator, op):
-        pass
-
-
-class Literal(MicroInstruction):
-    def __init__(self, instr):
-        self.instr = instr
-
-    def render(self, generator, op):
-        generator.emit(self.instr)
-
-
-class PushArg(MicroInstruction):
-    def __init__(self, n):
-        self.n = n
-
-    def render(self, generator, op):
-        generator.load(op.args[self.n])
-
-
-class PushAllArgs(MicroInstruction):
-    def render(self, generator, op):
-        for arg in op.args:
-            generator.load(arg)
-
+from pypy.translator.cli.metavm import PushArg, PushAllArgs, StoreResult, Call, InstructionList
 
 # some useful instruction patterns
 Not = ['ldc.i4.0', 'ceq']
-DoNothing = [PushAllArgs()]
+DoNothing = [PushAllArgs]
 
 def _not(op):
-    return [PushAllArgs(), op]+Not
+    return [PushAllArgs, op]+Not
 
 
 opcodes = {
     'same_as':                  DoNothing, # TODO: does same_as really do nothing else than renaming?    
-    'direct_call':              None,      # for now it's a special case
-    'indirect_call':            None,      # when it's generated?
+    'direct_call':              [Call],
+    'indirect_call':            None,      # when is it generated?
 
     # __________ numeric operations __________
 
@@ -54,7 +29,7 @@
 
     'int_is_true':              DoNothing,
     'int_neg':                  'neg',
-    'int_neg_ovf':              ['ldc.i4.0', PushAllArgs(), 'sub.ovf'],
+    'int_neg_ovf':              ['ldc.i4.0', PushAllArgs, 'sub.ovf'],
     'int_abs':                  None, # TODO
     'int_abs_ovf':              None, # TODO
     'int_invert':               'not',
@@ -124,7 +99,7 @@
     'uint_rshift':              'shr.un',
     'uint_xor':                 'xor',
 
-    'float_is_true':            [PushAllArgs(), 'ldc.r8 0', 'ceq']+Not,
+    'float_is_true':            [PushAllArgs, 'ldc.r8 0', 'ceq']+Not,
     'float_neg':                'neg',
     'float_abs':                None, # TODO
 
@@ -144,7 +119,7 @@
     'float_floor':              None, # TODO
     'float_fmod':               None, # TODO
 
-    'llong_is_true':            [PushAllArgs(), 'ldc.i8 0', 'ceq']+Not,
+    'llong_is_true':            [PushAllArgs, 'ldc.i8 0', 'ceq']+Not,
     'llong_neg':                'neg',
     'llong_abs':                None, # TODO
     'llong_invert':             'not',
@@ -163,7 +138,7 @@
     'llong_gt':                 'cgt',
     'llong_ge':                 _not('clt'),
 
-    'ullong_is_true':            [PushAllArgs(), 'ldc.i8 0', 'ceq']+Not,
+    'ullong_is_true':            [PushAllArgs, 'ldc.i8 0', 'ceq']+Not,
     'ullong_neg':                None,
     'ullong_abs':                None, # TODO
     'ullong_invert':             'not',
@@ -186,9 +161,9 @@
     # to 1: we can't simply DoNothing, because the CLI stack could
     # contains a truth value not equal to 1, so we should use the !=0
     # trick.
-    'cast_bool_to_int':         [PushAllArgs(), 'ldc.i4.0', 'ceq']+Not,
-    'cast_bool_to_uint':        [PushAllArgs(), 'ldc.i4.0', 'ceq']+Not,
-    'cast_bool_to_float':       [PushAllArgs(), 'ldc.i4 0', 'ceq']+Not+['conv.r8'],
+    'cast_bool_to_int':         [PushAllArgs, 'ldc.i4.0', 'ceq']+Not,
+    'cast_bool_to_uint':        [PushAllArgs, 'ldc.i4.0', 'ceq']+Not,
+    'cast_bool_to_float':       [PushAllArgs, 'ldc.i4 0', 'ceq']+Not+['conv.r8'],
     'cast_char_to_int':         None,
     'cast_unichar_to_int':      None,
     'cast_int_to_char':         None,
@@ -201,3 +176,12 @@
     'cast_float_to_uint':       'conv.i4',
     'truncate_longlong_to_int': 'conv.i4',
 }
+
+for key, value in opcodes.iteritems():
+    if type(value) is str:
+        value = InstructionList([PushAllArgs, value, StoreResult])
+    elif value is not None:
+        value = InstructionList(value + [StoreResult])
+        
+    opcodes[key] = value
+



More information about the Pypy-commit mailing list