[pypy-svn] r9735 - pypy/dist/pypy/interpreter

pedronis at codespeak.net pedronis at codespeak.net
Fri Mar 11 15:54:27 CET 2005


Author: pedronis
Date: Fri Mar 11 15:54:27 2005
New Revision: 9735

Modified:
   pypy/dist/pypy/interpreter/miscutils.py
   pypy/dist/pypy/interpreter/pyopcode.py
Log:
make the interpreter code more annotator friendly.

- use different table with functions with different signature,

- use closures for generic binary/unary opcode impls to avoid getattr(.,SomeString()) problem

- fix bug discovered by the annotator in INPLACE_POWER (inplace_pow has arity 2)

- Stack is used polymorphically, specialize



Modified: pypy/dist/pypy/interpreter/miscutils.py
==============================================================================
--- pypy/dist/pypy/interpreter/miscutils.py	(original)
+++ pypy/dist/pypy/interpreter/miscutils.py	Fri Mar 11 15:54:27 2005
@@ -8,6 +8,8 @@
 class Stack:
     """Utility class implementing a stack."""
 
+    _specialize_ = 'location' # polymorphic
+
     def __init__(self):
         self.items = []
 

Modified: pypy/dist/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyopcode.py	(original)
+++ pypy/dist/pypy/interpreter/pyopcode.py	Fri Mar 11 15:54:27 2005
@@ -9,47 +9,50 @@
 from pypy.interpreter import pyframe, pytraceback
 from pypy.interpreter.miscutils import InitializedClass
 from pypy.interpreter.argument import Arguments
+from pypy.tool import hack
 
-
-class unaryoperation:
-    def __init__(self, operationname):
-        self.operationname = operationname
-
-    def __call__(self, f):
-        operation = getattr(f.space, self.operationname)
+def unaryoperation(operationname):
+    """NOT_RPYTHON"""
+    def opimpl(f):
+        operation = getattr(f.space, operationname)
         w_1 = f.valuestack.pop()
         w_result = operation(w_1)
         f.valuestack.push(w_result)
 
-class binaryoperation:
-    def __init__(self, operationname):
-        self.operationname = operationname
-    def __call__(self, f):
-        operation = getattr(f.space, self.operationname)
+    return hack.func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname)
+
+def binaryoperation(operationname):
+    """NOT_RPYTHON"""    
+    def opimpl(f):
+        operation = getattr(f.space, operationname)
         w_2 = f.valuestack.pop()
         w_1 = f.valuestack.pop()
         w_result = operation(w_1, w_2)
         f.valuestack.push(w_result)
 
+    return hack.func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname)        
+
 
 class PyInterpFrame(pyframe.PyFrame):
     """A PyFrame that knows about interpretation of standard Python opcodes
     minus the ones related to nested scopes."""
     
     ### opcode dispatch ###
-
-    # 'dispatch_table' is a class attribute: a list of functions.
-    # Currently, it is always created by setup_dispatch_table in pyopcode.py
+ 
+    # 'opcode_has_arg' is a class attribute: list of True/False whether opcode takes arg
+    # 'dispatch_table_no_arg: list of functions/None
+    # 'dispatch_table_w_arg: list of functions/None 
+    # Currently, they are always setup in pyopcode.py
     # but it could be a custom table.
 
     def dispatch(self):
         opcode = self.nextop()
-        fn = self.dispatch_table[opcode]
-        if fn.has_arg:
+        if self.opcode_has_arg[opcode]:
+            fn = self.dispatch_table_w_arg[opcode]
             oparg = self.nextarg()
             fn(self, oparg)
-
         else:
+            fn = self.dispatch_table_no_arg[opcode]            
             fn(self)
 
     def nextop(self):
@@ -180,7 +183,7 @@
     def INPLACE_POWER(f):
         w_2 = f.valuestack.pop()
         w_1 = f.valuestack.pop()
-        w_result = f.space.inplace_pow(w_1, w_2, f.space.w_None)
+        w_result = f.space.inplace_pow(w_1, w_2)
         f.valuestack.push(w_result)
 
     INPLACE_MULTIPLY = binaryoperation("inplace_mul")
@@ -681,9 +684,9 @@
     def EXTENDED_ARG(f, oparg):
         opcode = f.nextop()
         oparg = oparg<<16 | f.nextarg()
-        fn = f.dispatch_table[opcode]
-        if not fn.has_arg:
-            raise pyframe.BytecodeCorruption
+        fn = f.dispatch_table_w_arg[opcode]        
+        if fn is None:
+            raise pyframe.BytecodeCorruption            
         fn(f, oparg)
 
     def MISSING_OPCODE(f, oparg=None):
@@ -691,26 +694,38 @@
 
     ### dispatch_table ###
 
-    # 'dispatch_table' is a class attribute: a list of functions
-    # it is created by 'cls.setup_dispatch_table()'.
+    # 'opcode_has_arg' is a class attribute: list of True/False whether opcode takes arg
+    # 'dispatch_table_no_arg: list of functions/None
+    # 'dispatch_table_w_arg: list of functions/None
 
     __metaclass__ = InitializedClass
     def __initclass__(cls):
         "NOT_RPYTHON"
         # create the 'cls.dispatch_table' attribute
         import dis
-        dispatch_table = []
+        opcode_has_arg = []
+        dispatch_table_no_arg = []
+        dispatch_table_w_arg = []
         missing_opcode = cls.MISSING_OPCODE
         for i in range(256):
             opname = dis.opname[i].replace('+', '_')
             fn = getattr(cls, opname, missing_opcode)
             fn = getattr(fn, 'im_func',fn)
-            fn.has_arg = i >= dis.HAVE_ARGUMENT
+            has_arg = i >= dis.HAVE_ARGUMENT
             #if fn is missing_opcode and not opname.startswith('<') and i>0:
             #    import warnings
             #    warnings.warn("* Warning, missing opcode %s" % opname)
-            dispatch_table.append(fn)
-        cls.dispatch_table = dispatch_table
+            opcode_has_arg.append(has_arg)
+            if has_arg:
+                dispatch_table_w_arg.append(fn)
+                dispatch_table_no_arg.append(None)
+            else:
+                dispatch_table_no_arg.append(fn)
+                dispatch_table_w_arg.append(None)
+
+        cls.opcode_has_arg = opcode_has_arg
+        cls.dispatch_table_no_arg = dispatch_table_no_arg
+        cls.dispatch_table_w_arg = dispatch_table_w_arg
 
 
 ### helpers written at the application-level ###



More information about the Pypy-commit mailing list