[pypy-commit] lang-smalltalk default: (cfbolz, lwassermann): refactored the step function to have an unfolding loop instead of creating the methods source as string and compiling it.

lwassermann noreply at buildbot.pypy.org
Wed Apr 3 13:49:02 CEST 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r243:626d7d57e4ab
Date: 2013-03-28 14:28 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/626d7d57e4ab/

Log:	(cfbolz, lwassermann): refactored the step function to have an
	unfolding loop instead of creating the methods source as string and
	compiling it.

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -781,38 +781,23 @@
     assert None not in result
     return result
 
-
+# this table is only used for creating named bytecodes in tests and printing
 BYTECODE_TABLE = initialize_bytecode_table()
 
+from rpython.rlib.unroll import unrolling_iterable
+unrolling_ranges = unrolling_iterable(BYTECODE_RANGES)
+def bytecode_step_translated(self, context):
+    bytecode = context.getbytecode()
+    for entry in unrolling_ranges:
+        if len(entry) == 2:
+            bc, methname = entry
+            if bytecode == bc:
+                return getattr(context, methname)(self, bytecode)
+        else:
+            start, stop, methname = entry
+            if start <= bytecode <= stop:
+                return getattr(context, methname)(self, bytecode)
+    assert 0, "unreachable"
 
-def make_bytecode_dispatch_translated():
-    # this is a performance optimization: when translating the
-    # interpreter, the bytecode dispatching is not implemented as a
-    # list lookup and an indirect call but as a switch.
-
-    code = ["def bytecode_step_translated(self, context):"]
-    code.append("    bytecode = context.getbytecode()")
-    prefix = ""
-    for entry in BYTECODE_RANGES:
-        if len(entry) == 2:
-            numbers = [entry[0]]
-        else:
-            numbers = range(entry[0], entry[1]+1)
-        cond = " or ".join(["bytecode == %s" % (i, )
-                                for i in numbers])
-        code.append("    %sif %s:" % (prefix, cond, ))
-        code.append("        return context.%s(self, bytecode)" % (entry[-1], ))
-        prefix = "el"
-    source = py.code.Source("\n".join(code))
-    #print source
-    miniglob = {}
-    exec source.compile() in miniglob
-    return miniglob["bytecode_step_translated"]
-    
-bytecode_step_translated = make_bytecode_dispatch_translated()
-
-# we_are_translated returns false on top of CPython and true when
-# translating the interpreter
-# if objectmodel.we_are_translated():
 Interpreter.step = bytecode_step_translated
 
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -235,7 +235,7 @@
         if isinstance(w_value, model.W_SmallInteger):
             return w_value.value
         elif isinstance(w_value, model.W_LargePositiveInteger1Word):
-            if w_value.value > 0:
+            if w_value.value >= 0:
                 return w_value.value
             else:
                 raise UnwrappingError("The value is negative when interpreted as 32bit value.")


More information about the pypy-commit mailing list