Author: Lars Wassermann <[email protected]>
Branch: 
Changeset: r376:46932f9d0142
Date: 2013-05-06 14:15 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/46932f9d0142/

Log:    added ensure:/ifCurtailed: checks when unwinding added tests to be
        executed in the benchmarks 4.5 image because this is the only one
        where there is an #ensure:-Implementation added two tests for ensure

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -75,6 +75,8 @@
                 s_new_context = s_sender
                 while s_new_context is not nlr.s_target_context:
                     s_sender = s_new_context.s_sender()
+                    if not s_new_context.is_closure_context() and 
s_new_context.s_method().primitive() == 198:
+                        s_new_context.activate_unwind_context(self)
                     s_new_context.mark_returned()
                     s_new_context = s_sender
                 s_new_context.push(nlr.value)
@@ -105,6 +107,8 @@
                 self.step(s_context)
             except Return, nlr:
                 if nlr.s_target_context is not s_context:
+                    if not s_context.is_closure_context() and 
s_context.s_method().primitive() == 198:
+                        s_context.activate_unwind_context(self)
                     s_context.mark_returned()
                     raise nlr
                 else:
@@ -414,6 +418,20 @@
             print '%s<- %s' % (interp.padding(), return_value.as_repr_string())
         raise Return(return_value, s_return_to)
 
+    def activate_unwind_context(self, interp):
+        # the first temp is executed flag for both #ensure: and #ifCurtailed:
+        if self.gettemp(1) is self.space.w_nil:
+            self.settemp(1, self.space.w_true) # mark unwound
+            self.push(self.gettemp(0)) # push the first argument
+            try:
+                self.bytecodePrimValue(interp, 0)
+            except Return, nlr:
+                if self is nlr.s_target_context:
+                    return
+                else:
+                    self.mark_returned()
+                    raise nlr
+
     def returnReceiver(self, interp, current_bytecode):
         return self._return(self.w_receiver(), interp, 
self.s_home().s_sender())
 
diff --git a/spyvm/test/test_bootstrappedimage.py 
b/spyvm/test/test_bootstrappedimage.py
--- a/spyvm/test/test_bootstrappedimage.py
+++ b/spyvm/test/test_bootstrappedimage.py
@@ -15,7 +15,7 @@
             return each
 
 def initialize_class(w_class):
-    initialize_symbol = find_symbol_in_methoddict_of("initialize", 
+    initialize_symbol = find_symbol_in_methoddict_of("initialize",
                         w_class.shadow_of_my_class(tools.space))
     perform(w_class, initialize_symbol)
 
@@ -35,7 +35,7 @@
 
 def test_retrieve_symbol():
     """asSymbol
-    "This is the only place that new Symbols are created. A Symbol is created 
+    "This is the only place that new Symbols are created. A Symbol is created
     if and only if there is not already a Symbol with its contents in 
existance."
     Symbol
         allInstancesDo: [ :sym |
diff --git a/spyvm/test/test_in_squeak_4_5_image.py 
b/spyvm/test/test_in_squeak_4_5_image.py
new file mode 100644
--- /dev/null
+++ b/spyvm/test/test_in_squeak_4_5_image.py
@@ -0,0 +1,84 @@
+import py
+from spyvm import squeakimage, model, constants
+from spyvm import interpreter, shadow, objspace
+from spyvm.test import test_miniimage as tools
+from spyvm.test.test_miniimage import perform, w
+
+tools.setup_module(tools, filename='Squeak4.5-12568.image')
+
+def find_symbol_in_methoddict_of(string, s_class):
+    s_methoddict = s_class.s_methoddict()
+    s_methoddict.sync_cache()
+    methoddict_w = s_methoddict.methoddict
+    for each in methoddict_w.keys():
+        if each.as_string() == string:
+            return each
+
+def test_all_pointers_are_valid():
+    tools.test_all_pointers_are_valid()
+    tools.test_lookup_abs_in_integer()
+
+def create_method_shadow(bytes, literals=[], islarge=0, argsize=0, tempsize=0):
+    w_method = model.W_CompiledMethod(len(bytes))
+    w_method.bytes = bytes
+    w_method.islarge = islarge
+    w_method.argsize = argsize
+    w_method.tempsize = tempsize
+
+    w_method.setliterals(literals)
+    s_method = w_method.as_compiledmethod_get_shadow(tools.space)
+    return s_method
+
+def test_ensure():
+    space = tools.space
+    #ensure
+    #    [^'b1'] ensure: [^'b2']
+    import operator
+    bytes = reduce(operator.add, map(chr, [0x8F, 0, 0, 2, 0x21, 0x7c,
+                                           0x8F, 0, 0, 2, 0x22, 0x7c,
+                                           0xe0, 0x87, 0x78]))
+
+    s_class = space.w_BlockClosure.as_class_get_shadow(space)
+    ensure_ = find_symbol_in_methoddict_of('ensure:', s_class)
+    assert ensure_ is not None, 'Using image without #ensure:-method.'
+
+    s_method = create_method_shadow(bytes, [ensure_, w('b1'), w('b2'),
+                                            w('ensure'), space.w_BlockClosure])
+
+    # create a frame for our newly crafted method with a valid sender (to 
avoid raising returnFromTop to early)
+    s_initial_frame = create_method_shadow(chr(0x7c)).create_frame(space, 
w(0), [])
+    w_frame = s_method.create_frame(space, w(0), [], 
sender=s_initial_frame).w_self()
+
+    try:
+        tools.interp.loop(w_frame)
+    except interpreter.ReturnFromTopLevel, e:
+        assert e.object.as_string() == 'b2'
+    except interpreter.StackOverflow, e:
+        assert False
+
+def test_ensure_save_original_nlr():
+    space = tools.space
+    #ensure
+    #    [^'b1'] ensure: ['b2']
+    import operator
+    bytes = reduce(operator.add, map(chr, [0x8F, 0, 0, 2, 0x21, 0x7c,
+                                           0x8F, 0, 0, 2, 0x22, 0x7d,
+                                           0xe0, 0x87, 0x78]))
+
+    s_class = space.w_BlockClosure.as_class_get_shadow(space)
+    ensure_ = find_symbol_in_methoddict_of('ensure:', s_class)
+    assert ensure_ is not None, 'Using image without #ensure:-method.'
+
+    s_method = create_method_shadow(bytes, [ensure_, w('b1'), w('b2'),
+                                            w('ensure'), space.w_BlockClosure])
+
+    # create a frame for our newly crafted method with a valid sender (to 
avoid raising returnFromTop to early)
+    s_initial_frame = create_method_shadow(chr(0x7c)).create_frame(space, 
w(0), [])
+    w_frame = s_method.create_frame(space, w(0), [], 
sender=s_initial_frame).w_self()
+
+    try:
+        tools.interp.loop(w_frame)
+    except interpreter.ReturnFromTopLevel, e:
+        assert e.object.as_string() == 'b1'
+    except interpreter.StackOverflow, e:
+        assert False
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to