[pypy-svn] r9937 - in pypy/dist: lib-python-2.3.4/test pypy/interpreter pypy/module/sys2 pypy/objspace
ac at codespeak.net
ac at codespeak.net
Sun Mar 20 18:13:18 CET 2005
Author: ac
Date: Sun Mar 20 18:13:18 2005
New Revision: 9937
Modified:
pypy/dist/lib-python-2.3.4/test/test_scope.py
pypy/dist/pypy/interpreter/eval.py
pypy/dist/pypy/interpreter/executioncontext.py
pypy/dist/pypy/interpreter/pyframe.py
pypy/dist/pypy/interpreter/typedef.py
pypy/dist/pypy/module/sys2/__init__.py
pypy/dist/pypy/module/sys2/vm.py
pypy/dist/pypy/objspace/trace.py
Log:
Preliminary work on sys.settrace() functionality. Stay tuned for more checkins.
Modified: pypy/dist/lib-python-2.3.4/test/test_scope.py
==============================================================================
--- pypy/dist/lib-python-2.3.4/test/test_scope.py (original)
+++ pypy/dist/lib-python-2.3.4/test/test_scope.py Sun Mar 20 18:13:18 2005
@@ -437,6 +437,7 @@
d = f(2)(4)
verify(d.has_key('h'))
del d['h']
+print d
verify(d == {'x': 2, 'y': 7, 'w': 6})
print "19. var is bound and free in class"
Modified: pypy/dist/pypy/interpreter/eval.py
==============================================================================
--- pypy/dist/pypy/interpreter/eval.py (original)
+++ pypy/dist/pypy/interpreter/eval.py Sun Mar 20 18:13:18 2005
@@ -65,12 +65,7 @@
def resume(self):
"Resume the execution of the frame from its current state."
executioncontext = self.space.getexecutioncontext()
- previous = executioncontext.enter(self)
- try:
- result = self.eval(executioncontext)
- finally:
- executioncontext.leave(previous)
- return result
+ return self.eval(executioncontext)
# running a frame is usually the same as resuming it from its
# initial state, but not for generator frames
Modified: pypy/dist/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/dist/pypy/interpreter/executioncontext.py (original)
+++ pypy/dist/pypy/interpreter/executioncontext.py Sun Mar 20 18:13:18 2005
@@ -10,7 +10,9 @@
self.space = space
self.framestack = Stack()
self.stateDict = {}
-
+ self.w_tracefunc = None
+ self.is_tracing = 0
+
def enter(self, frame):
if self.framestack.depth() > self.space.sys.recursionlimit:
raise OperationError(self.space.w_RuntimeError,
@@ -18,10 +20,17 @@
locals = getthreadlocals()
previous_ec = locals.executioncontext
locals.executioncontext = self
+ if self.framestack.empty():
+ frame.f_back = None
+ else:
+ frame.f_back = self.framestack.top()
self.framestack.push(frame)
+ self.call_trace(frame, 'call', self.space.w_None)
return previous_ec
- def leave(self, previous_ec):
+ def leave(self, previous_ec, w_retval=None):
+ if w_retval is not None:
+ self.call_trace(self.framestack.top(), 'return', w_retval)
self.framestack.pop()
locals = getthreadlocals()
locals.executioncontext = previous_ec
@@ -46,6 +55,8 @@
def exception_trace(self, operationerr):
"Trace function called upon OperationError."
operationerr.record_interpreter_traceback()
+ self.call_trace(self.framestack.top(), 'exception',
+ self.sys_exc_info())
#operationerr.print_detailed_traceback(self.space)
def sys_exc_info(self):
@@ -62,3 +73,32 @@
Similar to cpython's PyThreadState_GetDict.
"""
return self.stateDict
+
+ def settrace(self, w_func):
+ """Set the global trace function."""
+ if self.space.is_(w_func, self.space.w_None):
+ self.w_tracefunc = None
+ else:
+ self.w_tracefunc = w_func
+
+ def call_trace(self, frame, event, w_arg):
+ if event == 'call':
+ w_callback = self.w_tracefunc
+ else:
+ w_callback = frame.w_f_trace
+ if self.is_tracing or w_callback is None:
+ return
+ self.is_tracing += 1
+ try:
+ try:
+ w_result = self.space.call(w_callback, self.space.wrap(frame), self.space.wrap(event), w_arg)
+ if self.space.is_(w_result, self.space.w_None):
+ frame.w_f_trace = None
+ else:
+ frame.w_f_trace = w_result
+ except:
+ self.settrace(self.space.w_None)
+ frame.w_f_trace = None
+ finally:
+ self.is_traceing -= 1
+
Modified: pypy/dist/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyframe.py (original)
+++ pypy/dist/pypy/interpreter/pyframe.py Sun Mar 20 18:13:18 2005
@@ -40,7 +40,10 @@
self.w_locals = space.newdict([]) # set to None by Frame.__init__
self.fastlocals_w = [None]*self.numlocals
-
+ self.w_f_trace = None
+ self.last_instr = -1
+ self.f_back = None
+
def getfastscope(self):
"Get the fast locals as a list."
return self.fastlocals_w
@@ -60,8 +63,9 @@
def eval(self, executioncontext):
"Interpreter main loop!"
+ previous = executioncontext.enter(self)
try:
- last_instr = -1
+ self.last_instr = -1
while True:
try:
try:
@@ -70,7 +74,7 @@
# fetch and dispatch the next opcode
# dispatch() is abstract, see pyopcode.
executioncontext.bytecode_trace(self)
- last_instr = self.next_instr
+ self.last_instr = self.next_instr
self.dispatch()
# catch asynchronous exceptions and turn them
# into OperationErrors
@@ -89,7 +93,7 @@
except OperationError, e:
pytraceback.record_application_traceback(
- self.space, e, self, last_instr)
+ self.space, e, self, self.last_instr)
executioncontext.exception_trace(e)
# convert an OperationError into a control flow
# exception
@@ -100,13 +104,17 @@
except ControlFlowException, ctlflowexc:
# we have a reason to change the control flow
# (typically unroll the stack)
- ctlflowexc.action(self, last_instr, executioncontext)
+ ctlflowexc.action(self, self.last_instr, executioncontext)
except ExitFrame, e:
# leave that frame
w_exitvalue = e.args[0]
+ executioncontext.leave(previous, w_exitvalue)
return w_exitvalue
-
+ except:
+ executioncontext.leave(previous)
+ raise
+
### exception stack ###
def clean_exceptionstack(self):
@@ -138,7 +146,22 @@
self = space.interpclass_w(w_self)
return self.builtin.getdict()
+ def fget_f_back(space, w_self):
+ self = space.interpclass_w(w_self)
+ return self.space.wrap(self.f_back)
+ def fget_f_lasti(space, w_self):
+ self = space.interpclass_w(w_self)
+ return self.space.wrap(self.last_instr)
+
+ def fget_f_trace(space, w_self):
+ self = space.interpclass_w(w_self)
+ return self.w_f_trace
+
+ def fset_f_trace(space, w_self, w_trace):
+ self = space.interpclass_w(w_self)
+ self.w_f_trace = w_trace
+
### Frame Blocks ###
class FrameBlock:
Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py (original)
+++ pypy/dist/pypy/interpreter/typedef.py Sun Mar 20 18:13:18 2005
@@ -325,6 +325,9 @@
PyFrame.typedef = TypeDef('frame',
f_builtins = GetSetProperty(PyFrame.fget_f_builtins),
f_lineno = GetSetProperty(PyFrame.fget_f_lineno),
+ f_back = GetSetProperty(PyFrame.fget_f_back),
+ f_lasti = GetSetProperty(PyFrame.fget_f_lasti),
+ f_trace = GetSetProperty(PyFrame.fget_f_trace, PyFrame.fset_f_trace),
**Frame.typedef.rawdict)
Module.typedef = TypeDef("module",
Modified: pypy/dist/pypy/module/sys2/__init__.py
==============================================================================
--- pypy/dist/pypy/module/sys2/__init__.py (original)
+++ pypy/dist/pypy/module/sys2/__init__.py Sun Mar 20 18:13:18 2005
@@ -42,7 +42,9 @@
'getcheckinterval' : 'vm.getcheckinterval',
'exc_info' : 'vm.exc_info',
'exc_clear' : 'vm.exc_clear',
-
+ 'settrace' : 'vm.settrace',
+ 'setprofile' : 'vm.setprofile',
+
'executable' : 'space.wrap("py.py")',
'copyright' : 'space.wrap("MIT-License")',
'api_version' : 'space.wrap(1012)',
Modified: pypy/dist/pypy/module/sys2/vm.py
==============================================================================
--- pypy/dist/pypy/module/sys2/vm.py (original)
+++ pypy/dist/pypy/module/sys2/vm.py Sun Mar 20 18:13:18 2005
@@ -93,3 +93,17 @@
# value of 6 to get results comparable to cpythons. /Arre
return space.wrap(sys.getrefcount(w_obj) - 6)
+def settrace(space, w_func):
+ """settrace(function)
+
+Set the global debug tracing function. It will be called on each
+function call. See the debugger chapter in the library manual.
+"""
+
+def setprofile(space, w_func):
+ """setprofile(function)
+
+Set the profiling function. It will be called on each function call
+and return. See the profiler chapter in the library manual.
+"""
+
Modified: pypy/dist/pypy/objspace/trace.py
==============================================================================
--- pypy/dist/pypy/objspace/trace.py (original)
+++ pypy/dist/pypy/objspace/trace.py Sun Mar 20 18:13:18 2005
@@ -103,11 +103,11 @@
self.result.append(EnterFrame(frame))
return self.ec.enter(frame)
- def leave(self, previous_ec):
+ def leave(self, previous_ec, w_exitval=None):
""" called just after evaluating of a frame is suspended/finished. """
frame = self.ec.framestack.top()
self.result.append(LeaveFrame(frame))
- return self.ec.leave(previous_ec)
+ return self.ec.leave(previous_ec, w_exitval)
def bytecode_trace(self, frame):
""" called just before execution of a bytecode. """
More information about the Pypy-commit
mailing list