Author: Lars Wassermann <[email protected]>
Branch: 
Changeset: r240:8301476cf55c
Date: 2013-03-26 21:30 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/8301476cf55c/

Log:    merge with tip and... (because merges can not be partially committed
        and I forgot to commit directly) added tracing parameter and code to
        interpreter fixed tracing for compiling fixed problems with stack
        management in bitblt primitive and perform_with_args by adding
        another parameter to expose_primitive added capabilities to shift
        within 32bit range fixed the according tests

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -33,7 +33,7 @@
         get_printable_location=get_printable_location
     )
     
-    def __init__(self, space, image=None, image_name="",
+    def __init__(self, space, image=None, image_name="", trace=False,
                 max_stack_depth=constants.MAX_LOOP_DEPTH):
         self.space = space
         self.image = image
@@ -44,7 +44,7 @@
         self.next_wakeup_tick = 0
         self.interrupt_check_counter = constants.INTERRUPT_COUNTER_SIZE
         # 
######################################################################
-        # self.trace = True
+        self.trace = trace
 
     def interpret_with_w_frame(self, w_frame):
         try:
@@ -80,9 +80,9 @@
 
     def c_loop(self, s_context):
         # 
######################################################################
-        # if self.trace:
-        #     padding = ' ' * (self.max_stack_depth - 
self.remaining_stack_depth)
-        #     print padding + s_context.short_str()
+        if self.trace:
+            padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth)
+            print padding + s_context.short_str()
         old_pc = 0
         if not jit.we_are_jitted():
             self.quick_check_for_interrupt(s_context)
@@ -343,27 +343,31 @@
                 print "%sActually calling primitive %d" % 
(interp._last_indent, code,)
             func = primitives.prim_holder.prim_table[code]
             # 
##################################################################
-            # if interp.trace:
-            #     print "%s calling primitive %d \t(%s)" % (' ' * 
(interp.max_stack_depth - interp.remaining_stack_depth),
-            #                                             code, func.func_name)
+            if interp.trace:
+                print "%s calling primitive %d \t(in #%s)" % (
+                    ' ' * (interp.max_stack_depth - 
interp.remaining_stack_depth),
+                        code, self.w_method()._likely_methodname)
             try:
                 # note: argcount does not include rcvr
                 return func(interp, self, argcount)
             except primitives.PrimitiveFailedError:
                 # 
##############################################################
                 # if interp.trace and func.func_name != 
'raise_failing_default' and code != 83:
-                #     import pdb; pdb.set_trace()
+                #     # import pdb; pdb.set_trace()
                 #     try:
                 #         func(interp, self, argcount) # will fail again
                 #     except primitives.PrimitiveFailedError:
                 #         pass
+                if interp.trace:
+                    print "%s primitive FAILED" % (
+                    ' ' * (interp.max_stack_depth - 
interp.remaining_stack_depth),)
 
                 if interp.should_trace(True):
                     print "PRIMITIVE FAILED: %d %s" % (s_method.primitive, 
w_selector.as_string(),)
                 pass # ignore this error and fall back to the Smalltalk version
         arguments = self.pop_and_return_n(argcount)
         s_frame = s_method.create_frame(self.space, receiver, arguments, self)
-        self.pop()
+        self.pop() # receiver
         return interp.stack_frame(s_frame)
 
     def _doesNotUnderstand(self, w_selector, argcount, interp, receiver):
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -757,19 +757,23 @@
         return retval + "---------------------\n"
 
     def get_identifier_string(self):
-        try:
-            w_class = self.literals[-1]
-            if isinstance(w_class, W_PointersObject):
-                if w_class._shadow is None:
-                    classname = w_class._fetch(1)._shadow.getname()
-                else:
-                    classname = w_class._shadow.getname()
-            else:
-                classname = "<unknown>"
-        except (IndexError, AttributeError):
-            classname = "<unknown>"
+        from spyvm import shadow
+        classname = '<unknown>'
+        if len(self.literals) > 0:
+            w_candidate = self.literals[-1]
+            if isinstance(w_candidate, W_PointersObject):
+                c_shadow = w_candidate._shadow
+                if c_shadow is None:
+                    w_class = w_candidate._fetch(1)
+                    if isinstance(w_class, W_PointersObject):
+                        d_shadow = w_class._shadow
+                        if isinstance(d_shadow, shadow.ClassShadow):
+                            classname = d_shadow.getname()
+                elif isinstance(shadow, shadow.ClassShadow):
+                    classname = c_shadow.getname()
         return "%s>>#%s" % (classname, self._likely_methodname)
 
+
     def invariant(self):
         return (W_Object.invariant(self) and
                 hasattr(self, 'literals') and
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -52,7 +52,7 @@
 char = object()
 pos_32bit_int = object()
 
-def expose_primitive(code, unwrap_spec=None, no_result=False, 
result_is_new_frame=False):
+def expose_primitive(code, unwrap_spec=None, no_result=False, 
result_is_new_frame=False, clean_stack=True):
     # some serious magic, don't look
     from rpython.rlib.unroll import unrolling_iterable
     # heuristics to give it a nice name
@@ -121,13 +121,17 @@
                     s_new_frame = func(interp, s_frame, *args)
                     # After calling primitive, reload context-shadow in case it
                     # needs to be updated
-                    s_frame.pop_n(len_unwrap_spec)   # only if no exception 
occurs!
+                    if clean_stack:
+                        # happens only if no exception occurs!
+                        s_frame.pop_n(len_unwrap_spec)
                     return interp.stack_frame(s_new_frame)
                 else:
                     w_result = func(interp, s_frame, *args)
                     # After calling primitive, reload context-shadow in case it
                     # needs to be updated
-                    s_frame.pop_n(len_unwrap_spec)   # only if no exception 
occurs!
+                    if clean_stack:
+                        # happens only if no exception occurs!
+                        s_frame.pop_n(len_unwrap_spec)
                     if not no_result:
                         assert w_result is not None
                         assert isinstance(w_result, model.W_Object)
@@ -223,12 +227,20 @@
     # (http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#integer-types)
 
     # left shift, must fail if we lose bits beyond 32
+    from rpython.rlib.rarithmetic import intmask, r_uint, ovfcheck, int_between
     if argument > 0:
-        try:
-            shifted = rarithmetic.ovfcheck(receiver << argument)
-        except OverflowError:
-            raise PrimitiveFailedError()
-        return interp.space.wrap_int(shifted)
+        # argument > 0, therefore the highest bit of upperbound is not set,
+        # i.e. upperbound is positive
+        upperbound = intmask(r_uint(-1) >> argument)
+        if 0 <= receiver <= upperbound:
+            shifted = intmask(receiver << argument)
+            return interp.space.wrap_positive_32bit_int(shifted)
+        else:
+            try:
+                shifted = ovfcheck(receiver << argument)
+            except OverflowError:
+                raise PrimitiveFailedError()
+            return interp.space.wrap_int(shifted)
 
     # right shift, ok to lose bits
     else:
@@ -556,13 +568,12 @@
 def func(interp, s_frame, w_rcvr):
     raise PrimitiveNotYetWrittenError()
 
-@expose_primitive(BITBLT_COPY_BITS, unwrap_spec=[object])
+@expose_primitive(BITBLT_COPY_BITS, unwrap_spec=[object], clean_stack=False)
 def func(interp, s_frame, w_rcvr):
     if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 15:
         raise PrimitiveFailedError
 
     space = interp.space
-    s_frame.push(w_rcvr)
     s_frame._sendSelfSelector(interp.image.w_simulateCopyBits, 0, interp)
 
     w_dest_form = w_rcvr.fetch(space, 0)
@@ -571,6 +582,7 @@
         assert isinstance(w_bitmap, model.W_DisplayBitmap)
         w_bitmap.flush_to_screen()
 
+    # in case we return normally, we have to restore the removed w_rcvr
     return w_rcvr
 
 @expose_primitive(BE_CURSOR, unwrap_spec=[object])
@@ -1100,21 +1112,14 @@
 
 @expose_primitive(PERFORM_WITH_ARGS,
                   unwrap_spec=[object, object, list],
-                  no_result=True)
+                  no_result=True, clean_stack=False)
 def func(interp, s_frame, w_rcvr, w_selector, args_w):
-    stackvalues = s_frame.pop_and_return_n(3)
     argcount = len(args_w)
     # pushing the receiver and args to be popped by _sendSelector
     s_frame.push(w_rcvr)
     s_frame.push_all(args_w)
     s_frame._sendSelector(w_selector, argcount, interp,
                       w_rcvr, w_rcvr.shadow_of_my_class(interp.space))
-    # If we return in a regular way, we need to rebuild the former
-    # stack-contents to be collected by the primitive wrapper, i.a. if
-    # w_selector points to a primitive method. But if we have an exception, the
-    # wrapper will not clean. Therefore we should not put this into a finally.
-    s_frame.push_all(stackvalues)
-
 
 @expose_primitive(SIGNAL, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -167,13 +167,16 @@
     assert prim(primitives.BIT_SHIFT, [-4, 27]).value == -536870912
     
 def test_small_int_bit_shift_fail():
+    from rpython.rlib.rarithmetic import intmask
     prim_fails(primitives.BIT_SHIFT, [4, 32])
     prim_fails(primitives.BIT_SHIFT, [4, 31])
     prim_fails(primitives.BIT_SHIFT, [4, 30])
-    prim_fails(primitives.BIT_SHIFT, [4, 29])
-    w_result = prim_fails(primitives.BIT_SHIFT, [4, 28])
-    # assert isinstance(w_result, model.W_LargePositiveInteger1Word)
-    # assert w_result.value == 4 << 28
+    w_result = prim(primitives.BIT_SHIFT, [4, 29])
+    assert isinstance(w_result, model.W_LargePositiveInteger1Word)
+    assert w_result.value == intmask(4 << 29)
+    w_result = prim(primitives.BIT_SHIFT, [4, 28])
+    assert isinstance(w_result, model.W_LargePositiveInteger1Word)
+    assert w_result.value == 4 << 28
 
 def test_smallint_as_float():
     assert prim(primitives.SMALLINT_AS_FLOAT, [12]).value == 12.0
@@ -709,8 +712,7 @@
             prim_table[primitives.BITBLT_COPY_BITS](interp, 
w_frame.as_context_get_shadow(space), argument_count-1)
     finally:
         monkeypatch.undo()
-    assert w_frame._shadow.pop() is mock_bitblt # the new receiver
-    assert w_frame._shadow.pop() is mock_bitblt # previous state is still there
+    assert w_frame._shadow.pop() is mock_bitblt # the receiver
 
 # Note:
 #   primitives.NEXT is unimplemented as it is a performance optimization
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -57,6 +57,7 @@
     path = None
     number = 0
     benchmark = None
+    trace = False
 
     while idx < len(argv):
         arg = argv[idx]
@@ -76,6 +77,8 @@
             _arg_missing(argv, idx, arg)
             benchmark = argv[idx + 1]
             idx += 1
+        elif arg in ["-t", "--trace"]:
+            trace = True
         elif path is None:
             path = argv[idx]
         else:
@@ -87,7 +90,7 @@
         path = "Squeak.image"
 
     try:
-        f = open_file_as_stream(path)
+        f = open_file_as_stream(path, buffering=0)
     except OSError as e:
         os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), path))
         return 1
@@ -98,7 +101,7 @@
 
     image_reader = squeakimage.reader_for_image(space, 
squeakimage.Stream(data=imagedata))
     image = create_image(space, image_reader)
-    interp = interpreter.Interpreter(space, image, 
image_name=os.path.abspath(path))
+    interp = interpreter.Interpreter(space, image, image_name=path, 
trace=trace)
     if benchmark is not None:
         return _run_benchmark(interp, number, benchmark)
     else:
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to