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