[pypy-svn] r62181 - in pypy/branch/spy-graphic/pypy/lang/smalltalk: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Feb 26 13:59:22 CET 2009


Author: cfbolz
Date: Thu Feb 26 13:59:20 2009
New Revision: 62181

Modified:
   pypy/branch/spy-graphic/pypy/lang/smalltalk/interpreter.py
   pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_interpreter.py
Log:
Refactor way that bytecodes calling primitives directly are done. Speeds up
translation a lot. Fix some small things.


Modified: pypy/branch/spy-graphic/pypy/lang/smalltalk/interpreter.py
==============================================================================
--- pypy/branch/spy-graphic/pypy/lang/smalltalk/interpreter.py	(original)
+++ pypy/branch/spy-graphic/pypy/lang/smalltalk/interpreter.py	Thu Feb 26 13:59:20 2009
@@ -61,7 +61,7 @@
                     cnt = 0
                     p = self.w_active_context()
                     # AK make method
-                    while p is not self.space.w_nil:
+                    while not p.is_same_object(self.space.w_nil):
                         cnt += 1
                                                   # Do not update the context
                                                   # for this action.
@@ -94,6 +94,24 @@
     def __init__(self, object):
         self.object = object
 
+def make_call_primitive_bytecode(primitive, selector, argcount):
+    def callPrimitive(self, interp):
+        # WARNING: this is used for bytecodes for which it is safe to
+        # directly call the primitive.  In general, it is not safe: for
+        # example, depending on the type of the receiver, bytecodePrimAt
+        # may invoke primitives.AT, primitives.STRING_AT, or anything
+        # else that the user put in a class in an 'at:' method.
+        # The rule of thumb is that primitives with only int and float
+        # in their unwrap_spec are safe.
+        func = primitives.prim_table[primitive]
+        try:
+            func(interp, argcount)
+            return
+        except primitives.PrimitiveFailedError:
+            pass
+        self._sendSelfSelector(selector, argcount, interp)
+    return callPrimitive
+
 # ___________________________________________________________________________
 # Bytecode Implementations:
 #
@@ -222,7 +240,7 @@
 
     def _return(self, object, interp, w_return_to):
         # for tests, when returning from the top-level context
-        if w_return_to is self.space.w_nil:
+        if w_return_to.is_same_object(self.space.w_nil):
             raise ReturnFromTopLevel(object)
         w_return_to.as_context_get_shadow(self.space).push(object)
         interp.store_w_active_context(w_return_to)
@@ -371,93 +389,23 @@
     def longJumpIfFalse(self, interp):
         self.jumpConditional(interp.space.w_false, self.longJumpPosition())
 
-    # RPython trick: specialize the following function on its second argument
-    # this makes sure that the primitive call is a direct one
-    @objectmodel.specialize.arg(1)
-    def callPrimitive(self, primitive, selector, argcount, interp):
-        # WARNING: this is used for bytecodes for which it is safe to
-        # directly call the primitive.  In general, it is not safe: for
-        # example, depending on the type of the receiver, bytecodePrimAt
-        # may invoke primitives.AT, primitives.STRING_AT, or anything
-        # else that the user put in a class in an 'at:' method.
-        # The rule of thumb is that primitives with only int and float
-        # in their unwrap_spec are safe.
-        for i, func in primitives.unrolling_prim_table:
-            if i == primitive:
-                try:
-                    func(interp, argcount)
-                    return
-                except primitives.PrimitiveFailedError:
-                    break
-        self._sendSelfSelector(selector, argcount, interp)
-
-    def callPrimitive2(self, primitive1, primitive2,
-                       selector, argcount, interp):
-        # same as callPrimitive(), but tries two primitives before falling
-        # back to the general case.
-        try:
-            primitives.prim_table[primitive1](interp, argcount)
-            # the primitive pushes the result (if any) onto the stack itself
-        except primitives.PrimitiveFailedError:
-            self.callPrimitive(primitive2, selector, argcount, interp)
-
-    def bytecodePrimAdd(self, interp):
-        self.callPrimitive(primitives.ADD,
-                           "+", 1, interp)
-
-    def bytecodePrimSubtract(self, interp):
-        self.callPrimitive(primitives.SUBTRACT,
-                           "-", 1, interp)
-
-    def bytecodePrimLessThan(self, interp):        
-        self.callPrimitive(primitives.LESSTHAN,
-                           "<", 1, interp)
-
-    def bytecodePrimGreaterThan(self, interp):
-        self.callPrimitive(primitives.GREATERTHAN,
-                          ">", 1, interp)
-
-    def bytecodePrimLessOrEqual(self, interp):
-        self.callPrimitive(primitives.LESSOREQUAL,
-                           "<=", 1, interp)
 
-    def bytecodePrimGreaterOrEqual(self, interp):
-        self.callPrimitive(primitives.GREATEROREQUAL,
-                           ">=", 1, interp)
-
-    def bytecodePrimEqual(self, interp):
-        self.callPrimitive(primitives.EQUAL,
-                            "=", 1, interp)
-
-    def bytecodePrimNotEqual(self, interp):
-        self.callPrimitive(primitives.NOTEQUAL,
-                           "~=", 1, interp)
-
-    def bytecodePrimMultiply(self, interp):
-        self.callPrimitive(primitives.MULTIPLY,
-                           "*", 1, interp)
-
-    def bytecodePrimDivide(self, interp):
-        self.callPrimitive(primitives.DIVIDE,
-                           "/", 1, interp)
-
-    def bytecodePrimMod(self, interp):
-        self.callPrimitive(primitives.MOD, "\\\\", 1, interp)
-
-    def bytecodePrimMakePoint(self, interp):
-        self.callPrimitive(primitives.MAKE_POINT, "@", 1, interp)
-
-    def bytecodePrimBitShift(self, interp):
-        self.callPrimitive(primitives.BIT_SHIFT, "bitShift:", 1, interp)
-
-    def bytecodePrimDiv(self, interp):
-        self.callPrimitive(primitives.DIV, "//", 1, interp)
-
-    def bytecodePrimBitAnd(self, interp):
-        self.callPrimitive(primitives.BIT_AND, "bitAnd:", 1, interp)
-
-    def bytecodePrimBitOr(self, interp):
-        self.callPrimitive(primitives.BIT_OR, "bitOr:", 1, interp)
+    bytecodePrimAdd = make_call_primitive_bytecode(primitives.ADD, "+", 1)
+    bytecodePrimSubtract = make_call_primitive_bytecode(primitives.SUBTRACT, "-", 1)
+    bytecodePrimLessThan = make_call_primitive_bytecode (primitives.LESSTHAN, "<", 1)
+    bytecodePrimGreaterThan = make_call_primitive_bytecode(primitives.GREATERTHAN, ">", 1)
+    bytecodePrimLessOrEqual = make_call_primitive_bytecode(primitives.LESSOREQUAL,  "<=", 1)
+    bytecodePrimGreaterOrEqual = make_call_primitive_bytecode(primitives.GREATEROREQUAL,  ">=", 1)
+    bytecodePrimEqual = make_call_primitive_bytecode(primitives.EQUAL,   "=", 1)
+    bytecodePrimNotEqual = make_call_primitive_bytecode(primitives.NOTEQUAL,  "~=", 1)
+    bytecodePrimMultiply = make_call_primitive_bytecode(primitives.MULTIPLY,  "*", 1)
+    bytecodePrimDivide = make_call_primitive_bytecode(primitives.DIVIDE,  "/", 1)
+    bytecodePrimMod = make_call_primitive_bytecode(primitives.MOD, "\\\\", 1)
+    bytecodePrimMakePoint = make_call_primitive_bytecode(primitives.MAKE_POINT, "@", 1)
+    bytecodePrimBitShift = make_call_primitive_bytecode(primitives.BIT_SHIFT, "bitShift:", 1)
+    bytecodePrimDiv = make_call_primitive_bytecode(primitives.DIV, "//", 1)
+    bytecodePrimBitAnd = make_call_primitive_bytecode(primitives.BIT_AND, "bitAnd:", 1)
+    bytecodePrimBitOr = make_call_primitive_bytecode(primitives.BIT_OR, "bitOr:", 1)
 
     def bytecodePrimAt(self, interp):
         # n.b.: depending on the type of the receiver, this may invoke
@@ -491,24 +439,10 @@
         # which cannot fail
         primitives.prim_table[primitives.CLASS](interp, 0)
 
-    def bytecodePrimBlockCopy(self, interp):
-        # the primitive checks the class of the receiver
-        self.callPrimitive(primitives.BLOCK_COPY,
-                           "blockCopy:", 1, interp)
-
-    def bytecodePrimValue(self, interp):
-        # the primitive checks the class of the receiver
-        self.callPrimitive(
-            primitives.VALUE, "value", 0, interp)
-
-    def bytecodePrimValueWithArg(self, interp):
-        # the primitive checks the class of the receiver
-        # Note that the VALUE_WITH_ARGS takes an array of
-        # arguments but this bytecode is about the one-argument case.
-        # The VALUE is general enough to take any number of
-        # arguments from the stack, so it's the one we need to use here.
-        self.callPrimitive(
-            primitives.VALUE, "value:", 1, interp)
+
+    bytecodePrimBlockCopy = make_call_primitive_bytecode(primitives.BLOCK_COPY, "blockCopy:", 1)
+    bytecodePrimValue = make_call_primitive_bytecode(primitives.VALUE, "value", 0)
+    bytecodePrimValueWithArg = make_call_primitive_bytecode(primitives.VALUE, "value:", 1)
 
     def bytecodePrimDo(self, interp):
         self._sendSelfSelector("do:", 1, interp)
@@ -527,77 +461,77 @@
 
 
 BYTECODE_RANGES = [
-            (  0,  15, ContextPartShadow.pushReceiverVariableBytecode),
-            ( 16,  31, ContextPartShadow.pushTemporaryVariableBytecode),
-            ( 32,  63, ContextPartShadow.pushLiteralConstantBytecode),
-            ( 64,  95, ContextPartShadow.pushLiteralVariableBytecode),
-            ( 96, 103, ContextPartShadow.storeAndPopReceiverVariableBytecode),
-            (104, 111, ContextPartShadow.storeAndPopTemporaryVariableBytecode),
-            (112, ContextPartShadow.pushReceiverBytecode),
-            (113, ContextPartShadow.pushConstantTrueBytecode),
-            (114, ContextPartShadow.pushConstantFalseBytecode),
-            (115, ContextPartShadow.pushConstantNilBytecode),
-            (116, ContextPartShadow.pushConstantMinusOneBytecode),
-            (117, ContextPartShadow.pushConstantZeroBytecode),
-            (118, ContextPartShadow.pushConstantOneBytecode),
-            (119, ContextPartShadow.pushConstantTwoBytecode),
-            (120, ContextPartShadow.returnReceiver),
-            (121, ContextPartShadow.returnTrue),
-            (122, ContextPartShadow.returnFalse),
-            (123, ContextPartShadow.returnNil),
-            (124, ContextPartShadow.returnTopFromMethod),
-            (125, ContextPartShadow.returnTopFromBlock),
-            (126, ContextPartShadow.unknownBytecode),
-            (127, ContextPartShadow.unknownBytecode),
-            (128, ContextPartShadow.extendedPushBytecode),
-            (129, ContextPartShadow.extendedStoreBytecode),
-            (130, ContextPartShadow.extendedStoreAndPopBytecode),
-            (131, ContextPartShadow.singleExtendedSendBytecode),
-            (132, ContextPartShadow.doubleExtendedDoAnythingBytecode),
-            (133, ContextPartShadow.singleExtendedSuperBytecode),
-            (134, ContextPartShadow.secondExtendedSendBytecode),
-            (135, ContextPartShadow.popStackBytecode),
-            (136, ContextPartShadow.duplicateTopBytecode),
-            (137, ContextPartShadow.pushActiveContextBytecode),
-            (138, 143, ContextPartShadow.experimentalBytecode),
-            (144, 151, ContextPartShadow.shortUnconditionalJump),
-            (152, 159, ContextPartShadow.shortConditionalJump),
-            (160, 167, ContextPartShadow.longUnconditionalJump),
-            (168, 171, ContextPartShadow.longJumpIfTrue),
-            (172, 175, ContextPartShadow.longJumpIfFalse),
-            (176, ContextPartShadow.bytecodePrimAdd),
-            (177, ContextPartShadow.bytecodePrimSubtract),
-            (178, ContextPartShadow.bytecodePrimLessThan),
-            (179, ContextPartShadow.bytecodePrimGreaterThan),
-            (180, ContextPartShadow.bytecodePrimLessOrEqual),
-            (181, ContextPartShadow.bytecodePrimGreaterOrEqual),
-            (182, ContextPartShadow.bytecodePrimEqual),
-            (183, ContextPartShadow.bytecodePrimNotEqual),
-            (184, ContextPartShadow.bytecodePrimMultiply),
-            (185, ContextPartShadow.bytecodePrimDivide),
-            (186, ContextPartShadow.bytecodePrimMod),
-            (187, ContextPartShadow.bytecodePrimMakePoint),
-            (188, ContextPartShadow.bytecodePrimBitShift),
-            (189, ContextPartShadow.bytecodePrimDiv),
-            (190, ContextPartShadow.bytecodePrimBitAnd),
-            (191, ContextPartShadow.bytecodePrimBitOr),
-            (192, ContextPartShadow.bytecodePrimAt),
-            (193, ContextPartShadow.bytecodePrimAtPut),
-            (194, ContextPartShadow.bytecodePrimSize),
-            (195, ContextPartShadow.bytecodePrimNext),
-            (196, ContextPartShadow.bytecodePrimNextPut),
-            (197, ContextPartShadow.bytecodePrimAtEnd),
-            (198, ContextPartShadow.bytecodePrimEquivalent),
-            (199, ContextPartShadow.bytecodePrimClass),
-            (200, ContextPartShadow.bytecodePrimBlockCopy),
-            (201, ContextPartShadow.bytecodePrimValue),
-            (202, ContextPartShadow.bytecodePrimValueWithArg),
-            (203, ContextPartShadow.bytecodePrimDo),
-            (204, ContextPartShadow.bytecodePrimNew),
-            (205, ContextPartShadow.bytecodePrimNewWithArg),
-            (206, ContextPartShadow.bytecodePrimPointX),
-            (207, ContextPartShadow.bytecodePrimPointY),
-            (208, 255, ContextPartShadow.sendLiteralSelectorBytecode),
+            (  0,  15, "pushReceiverVariableBytecode"),
+            ( 16,  31, "pushTemporaryVariableBytecode"),
+            ( 32,  63, "pushLiteralConstantBytecode"),
+            ( 64,  95, "pushLiteralVariableBytecode"),
+            ( 96, 103, "storeAndPopReceiverVariableBytecode"),
+            (104, 111, "storeAndPopTemporaryVariableBytecode"),
+            (112, "pushReceiverBytecode"),
+            (113, "pushConstantTrueBytecode"),
+            (114, "pushConstantFalseBytecode"),
+            (115, "pushConstantNilBytecode"),
+            (116, "pushConstantMinusOneBytecode"),
+            (117, "pushConstantZeroBytecode"),
+            (118, "pushConstantOneBytecode"),
+            (119, "pushConstantTwoBytecode"),
+            (120, "returnReceiver"),
+            (121, "returnTrue"),
+            (122, "returnFalse"),
+            (123, "returnNil"),
+            (124, "returnTopFromMethod"),
+            (125, "returnTopFromBlock"),
+            (126, "unknownBytecode"),
+            (127, "unknownBytecode"),
+            (128, "extendedPushBytecode"),
+            (129, "extendedStoreBytecode"),
+            (130, "extendedStoreAndPopBytecode"),
+            (131, "singleExtendedSendBytecode"),
+            (132, "doubleExtendedDoAnythingBytecode"),
+            (133, "singleExtendedSuperBytecode"),
+            (134, "secondExtendedSendBytecode"),
+            (135, "popStackBytecode"),
+            (136, "duplicateTopBytecode"),
+            (137, "pushActiveContextBytecode"),
+            (138, 143, "experimentalBytecode"),
+            (144, 151, "shortUnconditionalJump"),
+            (152, 159, "shortConditionalJump"),
+            (160, 167, "longUnconditionalJump"),
+            (168, 171, "longJumpIfTrue"),
+            (172, 175, "longJumpIfFalse"),
+            (176, "bytecodePrimAdd"),
+            (177, "bytecodePrimSubtract"),
+            (178, "bytecodePrimLessThan"),
+            (179, "bytecodePrimGreaterThan"),
+            (180, "bytecodePrimLessOrEqual"),
+            (181, "bytecodePrimGreaterOrEqual"),
+            (182, "bytecodePrimEqual"),
+            (183, "bytecodePrimNotEqual"),
+            (184, "bytecodePrimMultiply"),
+            (185, "bytecodePrimDivide"),
+            (186, "bytecodePrimMod"),
+            (187, "bytecodePrimMakePoint"),
+            (188, "bytecodePrimBitShift"),
+            (189, "bytecodePrimDiv"),
+            (190, "bytecodePrimBitAnd"),
+            (191, "bytecodePrimBitOr"),
+            (192, "bytecodePrimAt"),
+            (193, "bytecodePrimAtPut"),
+            (194, "bytecodePrimSize"),
+            (195, "bytecodePrimNext"),
+            (196, "bytecodePrimNextPut"),
+            (197, "bytecodePrimAtEnd"),
+            (198, "bytecodePrimEquivalent"),
+            (199, "bytecodePrimClass"),
+            (200, "bytecodePrimBlockCopy"),
+            (201, "bytecodePrimValue"),
+            (202, "bytecodePrimValueWithArg"),
+            (203, "bytecodePrimDo"),
+            (204, "bytecodePrimNew"),
+            (205, "bytecodePrimNewWithArg"),
+            (206, "bytecodePrimPointX"),
+            (207, "bytecodePrimPointY"),
+            (208, 255, "sendLiteralSelectorBytecode"),
             ]
 
 
@@ -609,7 +543,7 @@
         else:
             positions = range(entry[0], entry[1]+1)
         for pos in positions:
-            result[pos] = entry[-1]
+            result[pos] = getattr(ContextPartShadow, entry[-1])
     assert None not in result
     return result
 

Modified: pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_interpreter.py
==============================================================================
--- pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_interpreter.py	(original)
+++ pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_interpreter.py	Thu Feb 26 13:59:20 2009
@@ -18,7 +18,7 @@
             return chr(opcode)
         return get_opcode_chr
     for entry in interpreter.BYTECODE_RANGES:
-        name = entry[-1].__name__
+        name = entry[-1]
         if len(entry) == 2:     # no range
             globals()[name] = chr(entry[0])
         else:



More information about the Pypy-commit mailing list