[pypy-commit] lang-smalltalk default: fixed #perform:withArgs:-primitive: The problem was that simply pushing the arguments might overflow the stack. Therefore, do what ContextPartShadow._sendSelector would do, except for argument-retrieval

lwassermann noreply at buildbot.pypy.org
Fri May 31 11:55:01 CEST 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r426:870c8de33664
Date: 2013-05-30 15:36 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/870c8de33664/

Log:	fixed #perform:withArgs:-primitive: The problem was that simply
	pushing the arguments might overflow the stack. Therefore, do what
	ContextPartShadow._sendSelector would do, except for argument-
	retrieval

diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -1249,12 +1249,27 @@
                   unwrap_spec=[object, object, list],
                   no_result=True, clean_stack=False)
 def func(interp, s_frame, w_rcvr, w_selector, args_w):
+    from spyvm.shadow import MethodNotFound
     argcount = len(args_w)
-    s_frame.pop_n(2) # removing our arguments to be substituted with args_w
-    # pushing the args to be popped by _sendSelector
-    s_frame.push_all(args_w)
-    s_frame._sendSelector(w_selector, argcount, interp,
-                      w_rcvr, w_rcvr.shadow_of_my_class(interp.space))
+    s_frame.pop_n(2) # removing our arguments
+
+    assert isinstance(w_selector, model.W_BytesObject)
+
+    try:
+        s_method = w_rcvr.shadow_of_my_class(interp.space).lookup(w_selector)
+    except MethodNotFound:
+        return s_frame._doesNotUnderstand(w_selector, argcount, interp, w_rcvr)
+
+    code = s_method.primitive()
+    if code:
+        s_frame.push_all(args_w)
+        try:
+            return s_frame._call_primitive(code, interp, argcount, s_method, w_selector)
+        except PrimitiveFailedError:
+            pass # ignore this error and fall back to the Smalltalk version
+    s_new_frame = s_method.create_frame(interp.space, w_rcvr, args_w, s_frame)
+    s_frame.pop()
+    return interp.stack_frame(s_new_frame)
 
 @expose_primitive(SIGNAL, unwrap_spec=[object], clean_stack=False, no_result=True)
 def func(interp, s_frame, w_rcvr):
diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py
--- a/spyvm/wrapper.py
+++ b/spyvm/wrapper.py
@@ -257,7 +257,7 @@
     def tempsize(self):
         # We ignore the number of temps a block has, because the first
         # bytecodes of the block will initialize them for us. We will only
-        # use this information for decinding where the stack pointer should be
+        # use this information for deciding where the stack pointer should be
         # initialy.
         # For a finding the correct number, see BlockClosure>#numTemps in an Image.
         return self.size() + self.numArgs()
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -52,7 +52,6 @@
         return 0
     return -1
 
-
 def _run_image(interp):
     ap = wrapper.ProcessWrapper(space, wrapper.scheduler(space).active_process())
     w_ctx = ap.suspended_context()


More information about the pypy-commit mailing list