[pypy-svn] r48112 - in pypy/dist/pypy/lang/smalltalk: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Sat Oct 27 17:06:40 CEST 2007


Author: cfbolz
Date: Sat Oct 27 17:06:39 2007
New Revision: 48112

Modified:
   pypy/dist/pypy/lang/smalltalk/interpreter.py
   pypy/dist/pypy/lang/smalltalk/primitives.py
   pypy/dist/pypy/lang/smalltalk/test/test_primitives.py
Log:
add a new "no_result" argument to expose_primitive, which defaults to False.
Make the primitive wrapper responsible for pushing the result onto the stack.


Modified: pypy/dist/pypy/lang/smalltalk/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/interpreter.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/interpreter.py	Sat Oct 27 17:06:39 2007
@@ -178,11 +178,7 @@
                     print "PRIMITIVE FAILED: %d %s" % (method.primitive, selector,)
                 pass # ignore this error and fall back to the Smalltalk version
             else:
-                # the primitive succeeded
-                # Make sure that primitives that do not want to return
-                # anything, don't have to return anything (aBlock value)
-                if w_result:
-                    self.push(w_result)
+                # the primitive pushes the result (if any) onto the stack itself
                 return
         start = len(self.stack) - argcount
         assert start >= 0  # XXX check in the Blue Book what to do in this case
@@ -346,9 +342,7 @@
         try:
             # note that argcount does not include self
             w_result = primitives.prim_table[primitive](interp, argcount)
-            if w_result: # enable primitives not to return values to
-                         # the stack
-                self.push(w_result)
+            # the primitive pushes the result (if any) onto the stack itself
         except primitives.PrimitiveFailedError:
             self._sendSelfSelector(selector, argcount, interp)
         #self._sendSelfSelector(selector, argcount, interp)

Modified: pypy/dist/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/primitives.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/primitives.py	Sat Oct 27 17:06:39 2007
@@ -58,7 +58,7 @@
 # converted to an index0 
 index1_0 = object()
 
-def expose_primitive(code, unwrap_spec=None):
+def expose_primitive(code, unwrap_spec=None, no_result=False):
     # some serious magic, don't look
     from pypy.rlib.unroll import unrolling_iterable
     # heuristics to give it a nice name
@@ -78,40 +78,46 @@
         assert code not in prim_table
         func.func_name = "prim_" + name
         if unwrap_spec is None:
-            prim_table[code] = func
-            return func
-        for spec in unwrap_spec:
-            assert spec in (int, float, object, index1_0, str)
-        len_unwrap_spec = len(unwrap_spec)
-        assert (len_unwrap_spec == len(inspect.getargspec(func)[0]) + 1,
-                "wrong number of arguments")
-        unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec))
-        def wrapped(interp, argument_count_m1):
-            argument_count = argument_count_m1 + 1 # to account for the rcvr
-            frame = interp.w_active_context
-            assert argument_count == len_unwrap_spec
-            if len(frame.stack) < len_unwrap_spec:
-                raise PrimitiveFailedError()
-            args = ()
-            for i, spec in unrolling_unwrap_spec:
-                index = -len_unwrap_spec + i
-                arg = frame.stack[index]
-                if spec is int:
-                    args += (unwrap_int(arg), )
-                elif spec is index1_0:
-                    args += (unwrap_int(arg)-1, )
-                elif spec is float:
-                    args += (unwrap_float(arg), )
-                elif spec is object:
-                    args += (arg, )
-                elif spec is str:
-                    args += (arg.as_string(), )
-                else:
-                    assert 0, "this should never happen"
-            res = func(interp, *args)
-            frame.pop_n(len_unwrap_spec)   # only if no exception occurs!
-            return res
-
+            def wrapped(interp, argument_count_m1):
+                w_result = func(interp, argument_count_m1)
+                if not no_result:
+                    assert w_result is not None
+                    interp.w_active_context.push(w_result)
+                return w_result
+        else:
+            for spec in unwrap_spec:
+                assert spec in (int, float, object, index1_0, str)
+            len_unwrap_spec = len(unwrap_spec)
+            assert (len_unwrap_spec == len(inspect.getargspec(func)[0]) + 1,
+                    "wrong number of arguments")
+            unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec))
+            def wrapped(interp, argument_count_m1):
+                argument_count = argument_count_m1 + 1 # to account for the rcvr
+                frame = interp.w_active_context
+                assert argument_count == len_unwrap_spec
+                if len(frame.stack) < len_unwrap_spec:
+                    raise PrimitiveFailedError()
+                args = ()
+                for i, spec in unrolling_unwrap_spec:
+                    index = -len_unwrap_spec + i
+                    arg = frame.stack[index]
+                    if spec is int:
+                        args += (unwrap_int(arg), )
+                    elif spec is index1_0:
+                        args += (unwrap_int(arg)-1, )
+                    elif spec is float:
+                        args += (unwrap_float(arg), )
+                    elif spec is object:
+                        args += (arg, )
+                    elif spec is str:
+                        args += (arg.as_string(), )
+                    else:
+                        assert 0, "this should never happen"
+                w_result = func(interp, *args)
+                frame.pop_n(len_unwrap_spec)   # only if no exception occurs!
+                if not no_result:
+                    assert w_result is not None
+                    interp.w_active_context.push(w_result)
         wrapped.func_name = "wrap_prim_" + name
         prim_table[code] = wrapped
         return func
@@ -479,7 +485,7 @@
 def func(interp, w_rcvr):
     raise PrimitiveNotYetWrittenError()
 
- at expose_primitive(CHANGE_CLASS, unwrap_spec=[object, object])
+ at expose_primitive(CHANGE_CLASS, unwrap_spec=[object, object], no_result=True)
 def func(interp, w_arg, w_rcvr):
     w_arg_class = w_arg.getclass()
     w_rcvr_class = w_rcvr.getclass()
@@ -493,7 +499,7 @@
         raise PrimitiveFailedError()
 
     # 2. Rcvr is an instance of a compact class and argument isn't
-    # or vice versa (?)
+    # or vice versa XXX we don't have to fail here, but for squeak it's a problem
 
     # 3. Format of rcvr is different from format of argument
     raise PrimitiveNotYetWrittenError()     # XXX needs to work in the shadows
@@ -506,7 +512,6 @@
         raise PrimitiveFailedError()
 
     w_rcvr.w_class = w_arg.w_class
-    return 
 
 # ___________________________________________________________________________
 # Squeak Miscellaneous Primitives (128-149)
@@ -655,7 +660,7 @@
     w_block_ctx.w_sender = frame
     interp.w_active_context = w_block_ctx
     
- at expose_primitive(PRIMITIVE_VALUE)
+ at expose_primitive(PRIMITIVE_VALUE, no_result=True)
 def func(interp, argument_count):
     # argument_count does NOT include the receiver.
     # This means that for argument_count == 3 the stack looks like:
@@ -681,12 +686,9 @@
 
     frame.pop()
     finalize_block_ctx(interp, w_block_ctx, frame)
-    # Value is a special case of primitive which does not return
-    # anything
-    return None
-    
     
- at expose_primitive(PRIMITIVE_VALUE_WITH_ARGS, unwrap_spec=[object, object])
+ at expose_primitive(PRIMITIVE_VALUE_WITH_ARGS, unwrap_spec=[object, object],
+                  no_result=True)
 def func(interp, w_block_ctx, w_args):
     if not isinstance(w_block_ctx, model.W_BlockContext):
         raise PrimitiveFailedError()
@@ -707,16 +709,13 @@
 
     finalize_block_ctx(interp, w_block_ctx, interp.w_active_context)
 
-    # Value: is a special case of primitive which does not return
-    # anything
-    return None
-
 @expose_primitive(PRIMITIVE_PERFORM)
 def func(interp, argcount):
     raise PrimitiveFailedError()
 
 @expose_primitive(PRIMITIVE_PERFORM_WITH_ARGS,
-                  unwrap_spec=[object, str, object])
+                  unwrap_spec=[object, str, object],
+                  no_result=True)
 def func(interp, w_rcvr, sel, w_args):
     w_method = w_rcvr.shadow_of_my_class().lookup(sel)
     assert w_method
@@ -727,9 +726,6 @@
     w_frame.w_sender = interp.w_active_context
     interp.w_active_context = w_frame
 
-    # Don't put anything on the stack
-    return None
-
 @expose_primitive(PRIMITIVE_SIGNAL, unwrap_spec=[object])
 def func(interp, w_rcvr):
     raise PrimitiveNotYetWrittenError()

Modified: pypy/dist/pypy/lang/smalltalk/test/test_primitives.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/test/test_primitives.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/test/test_primitives.py	Sat Oct 27 17:06:39 2007
@@ -32,7 +32,8 @@
 
 def prim(code, stack):
     interp, argument_count = mock(stack)
-    res = prim_table[code](interp, argument_count-1)
+    prim_table[code](interp, argument_count-1)
+    res = interp.w_active_context.pop()
     assert not len(interp.w_active_context.stack) # check args are consumed
     return res
 



More information about the Pypy-commit mailing list