Author: Anton Gulenko <[email protected]>
Branch: storage
Changeset: r908:cedc9509b5c7
Date: 2014-07-14 18:35 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/cedc9509b5c7/

Log:    - Added a parameterized --trace option to control the stack depth up
        to which the trace is performed.
        - Added helper to step through bytecode executions.

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -35,7 +35,7 @@
     )
 
     def __init__(self, space, image=None, image_name="",
-                trace=False, evented=True, interrupts=True):
+                trace_depth=-1, evented=True, interrupts=True):
         # === Initialize immutable variables
         self.space = space
         self.image = image
@@ -54,7 +54,7 @@
         # === Initialize mutable variables
         self.interrupt_check_counter = self.interrupt_counter_size
         self.next_wakeup_tick = 0
-        self.trace = objspace.ConstantFlag(trace)
+        self.trace_depth = trace_depth
         self.trace_proxy = objspace.ConstantFlag()
         self.stack_depth = 0
 
@@ -225,12 +225,36 @@
         s_frame.push_all(list(w_arguments))
         return s_frame
 
+    # ============== Methods for tracing, printing and debugging ==============
+
+    def activate_trace(self, trace_depth=0):
+        self.trace_depth = trace_depth
+        
+    def deactivate_trace(self):
+        self.trace_depth = -1
+        
     def is_tracing(self):
-        return self.trace.is_set()
+        return jit.promote(self.trace_depth) >= 0
         
-    def padding(self, symbol=' '):
-        assert self.is_tracing()
-        return symbol * self.stack_depth
+    def print_padded(self, str):
+        depth = jit.promote(self.trace_depth)
+        assert depth >= 0
+        if self.stack_depth <= depth:
+            print (' ' * self.stack_depth) + str
+    
+    def activate_debug_bytecode(self):
+        "NOT_RPYTHON"
+        def do_break(self):
+            import pdb
+            if self.break_on_bytecodes:
+                pdb.set_trace()
+        Interpreter.debug_bytecode = do_break
+        self.break_on_bytecodes = True
+    
+    def debug_bytecode(self):
+        # This is for debugging. In a pdb console, execute the following:
+        # self.activate_debug_bytecode()
+        pass
 
 class ReturnFromTopLevel(Exception):
     _attrs_ = ["object"]
@@ -287,7 +311,7 @@
                 parameters += (self.fetch_next_bytecode(), )
                 i = i + 1
             # This is a good place to step through bytecodes.
-            # import pdb; pdb.set_trace()
+            interp.debug_bytecode()
             return actual_implementation_method(self, interp, 
current_bytecode, *parameters)
         bytecode_implementation_wrapper.func_name = 
actual_implementation_method.func_name
         return bytecode_implementation_wrapper
@@ -577,7 +601,7 @@
 
         # 
######################################################################
         if interp.is_tracing():
-            print interp.padding() + s_frame.short_str()
+            interp.print_padded('-> ' + s_frame.short_str())
 
         return interp.stack_frame(s_frame, self)
 
@@ -594,7 +618,7 @@
 
         # 
######################################################################
         if interp.is_tracing():
-            print '%s %s %s: #%s' % (interp.padding('#'), special_selector, 
s_frame.short_str(), w_args)
+            interp.print_padded('-> %s %s' % (special_selector, 
s_frame.short_str()))
             if not objectmodel.we_are_translated():
                 import pdb; pdb.set_trace()
 
@@ -625,8 +649,8 @@
     def _call_primitive(self, code, interp, argcount, w_method, w_selector):
         # ##################################################################
         if interp.is_tracing():
-            print "%s-> primitive %d \t(in %s, named #%s)" % (
-                    interp.padding(), code, 
self.w_method().get_identifier_string(), w_selector.str_content())
+            interp.print_padded("-> primitive %d \t(in %s, named #%s)" % (
+                                    code, 
self.w_method().get_identifier_string(), w_selector.str_content()))
         func = primitives.prim_holder.prim_table[code]
         try:
             # note: argcount does not include rcvr
@@ -634,8 +658,8 @@
             return func(interp, self, argcount, w_method)
         except primitives.PrimitiveFailedError, e:
             if interp.is_tracing():
-                print "%s primitive %d FAILED\t (in %s, named %s)" % (
-                    interp.padding(), code, w_method.safe_identifier_string(), 
w_selector.str_content())
+                interp.print_padded("-- primitive %d FAILED\t (in %s, named 
%s)" % (
+                            code, w_method.safe_identifier_string(), 
w_selector.str_content()))
             raise e
 
     def _return(self, return_value, interp, local_return=False):
@@ -644,7 +668,7 @@
 
         # ##################################################################
         if interp.is_tracing():
-            print '%s<- %s' % (interp.padding(), return_value.as_repr_string())
+            interp.print_padded('<- ' + return_value.as_repr_string())
 
         if self.home_is_self() or local_return:
             # a local return just needs to go up the stack once. there
diff --git a/spyvm/interpreter_proxy.py b/spyvm/interpreter_proxy.py
--- a/spyvm/interpreter_proxy.py
+++ b/spyvm/interpreter_proxy.py
@@ -1016,8 +1016,8 @@
             # eventual errors are caught by the calling function 
(EXTERNAL_CALL)
             external_function = rffi.cast(func_bool_void,
                             self.loadFunctionFrom(signature[0], signature[1]))
-            if interp.trace:
-                print "%sCalling %s >> %s" % (interp.padding(), signature[0], 
signature[1])
+            if interp.is_tracing():
+                interp.print_padded("Calling %s >> %s" % (signature[0], 
signature[1]))
             external_function()
 
             if not self.fail_reason == 0:
diff --git a/spyvm/plugins/vmdebugging.py b/spyvm/plugins/vmdebugging.py
--- a/spyvm/plugins/vmdebugging.py
+++ b/spyvm/plugins/vmdebugging.py
@@ -10,12 +10,12 @@
 
 @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
 def trace(interp, s_frame, w_rcvr):
-    interp.trace.set()
+    interp.activate_trace()
     return w_rcvr
 
 @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
 def untrace(interp, s_frame, w_rcvr):
-    interp.trace.unset()
+    interp.deactivate_trace()
     return w_rcvr
 
 @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
diff --git a/spyvm/test/test_largeinteger.py b/spyvm/test/test_largeinteger.py
--- a/spyvm/test/test_largeinteger.py
+++ b/spyvm/test/test_largeinteger.py
@@ -8,7 +8,7 @@
     space, interp, _, _ = read_image('bootstrapped.image')
     w = space.w
     copy_to_module(locals(), __name__)
-    interp.trace.unset()
+    interp.deactivate_trace()
     space.initialize_class(space.w_String, interp)
 
 def teardown_module():
@@ -38,7 +38,10 @@
     except Exception:
         w_selector = find_symbol_in_methoddict_of(selector, 
w(intmask(candidates[0])).getclass(space).shadow)
     
-    interp.trace.set_to(trace)
+    if trace:
+        interp.activate_trace()
+    else:
+        interp.deactivate_trace()
     for i, v in enumerate(candidates):
         x = w_l(v)
         if j is None:
@@ -50,7 +53,7 @@
                 y = w_l(j)
         z = perform_primitive(x, w_selector, y)
         assert r_uint(z.value) == r_uint(operation(v, y.value))
-    interp.trace.unset()
+    interp.deactivate_trace()
 
 def test_bitAnd():
     do_primitive("bitAnd:", operator.and_)
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -12,7 +12,7 @@
 
 def _usage(argv):
     print """
-    Usage: %s <path> [-r|-m|-h] [-naPu] [-jpiS] [-tlLE]
+    Usage: %s <path> [-r|-m|-h] [-naPu] [-jpiS] [-tTlLE]
             <path> - image path (default: Squeak.image)
 
           Execution mode:
@@ -39,6 +39,7 @@
             
           Logging parameters:
             -t|--trace                 - Output a trace of each message, 
primitive, return value and process switch.
+            -T <depth>                 - Like -t, but limit the stack depth 
for the trace to <depth>.
             -l|--storage-log           - Output a log of storage operations.
             -L|--storage-log-aggregate - Output an aggregated storage log at 
the end of execution.
             -E|--storage-log-elements  - Include classnames of elements into 
the storage log.
@@ -75,7 +76,7 @@
     # == Other parameters
     poll = False
     interrupts = True
-    trace = False
+    trace_depth = -1
     
     space = prebuilt_space
     idx = 1
@@ -95,7 +96,11 @@
             elif arg in ["-m", "--method"]:
                 selector, idx = get_parameter(argv, idx, arg)
             elif arg in ["-t", "--trace"]:
-                trace = True
+                trace_depth = sys.maxint
+            elif arg in ["-T"]:
+                trace_depth, idx = get_int_parameter(argv, idx, arg)
+                if trace_depth < 0:
+                    raise error.Exit("Need argument >= 0 for -T.")
             elif arg in ["-p", "--poll"]:
                 poll = True
             elif arg in ["-a", "--arg"]:
@@ -146,7 +151,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=path,
-                trace=trace, evented=not poll,
+                trace_depth=trace_depth, evented=not poll,
                 interrupts=interrupts)
     space.runtime_setup(argv[0])
     print_error("") # Line break after image-loading characters
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to