1. Tobias Pape
  2. pypy

Commits

Armin Rigo  committed bc27ffd

Have a limited subset of "__pytrace__=1" work: dumping bytecodes as they
are executed. Sorry, not tested (how..?)

  • Participants
  • Parent commits 76a313c
  • Branches default

Comments (0)

Files changed (2)

File pypy/doc/getting-started-dev.rst

View file
 
 .. _`trace example`:
 
-Tracing bytecode and operations on objects
-++++++++++++++++++++++++++++++++++++++++++
+Tracing bytecodes
++++++++++++++++++
 
-You can use the trace object space to monitor the interpretation
-of bytecodes in connection with object space operations.  To enable
-it, set ``__pytrace__=1`` on the interactive PyPy console::
+You can use a simple tracing mode to monitor the interpretation of
+bytecodes.  To enable it, set ``__pytrace__ = 1`` on the interactive
+PyPy console::
 
     >>>> __pytrace__ = 1
     Tracing enabled
-    >>>> a = 1 + 2
-    |- <<<< enter <inline>a = 1 + 2 @ 1 >>>>
-    |- 0    LOAD_CONST    0 (W_IntObject(1))
-    |- 3    LOAD_CONST    1 (W_IntObject(2))
-    |- 6    BINARY_ADD
-      |-    add(W_IntObject(1), W_IntObject(2))   -> W_IntObject(3)
-    |- 7    STORE_NAME    0 (a)
-      |-    hash(W_StringObject('a'))   -> W_IntObject(-468864544)
-      |-    int_w(W_IntObject(-468864544))   -> -468864544
-    |-10    LOAD_CONST    2 (<W_NoneObject()>)
-    |-13    RETURN_VALUE
-    |- <<<< leave <inline>a = 1 + 2 @ 1 >>>>
+    >>>> x = 5
+            <module>:           LOAD_CONST    0 (5)
+            <module>:           STORE_NAME    0 (x)
+            <module>:           LOAD_CONST    1 (None)
+            <module>:           RETURN_VALUE    0 
+    >>>> x
+            <module>:           LOAD_NAME    0 (x)
+            <module>:           PRINT_EXPR    0 
+    5
+            <module>:           LOAD_CONST    0 (None)
+            <module>:           RETURN_VALUE    0 
+    >>>>
 
 Demos
 -------

File pypy/interpreter/interactive.py

View file
             try:
                 code.exec_code(self.space, self.w_globals, self.w_globals)
             finally:
-                if self.tracelevel:
-                    self.space.unsettrace()
+                self.unsettrace()
             self.checktrace()
 
         # run doit() in an exception-catching box
 
     def settrace(self):
         if self.tracelevel:
-            self.space.settrace()
+            ec = self.space.getexecutioncontext()
+            if not hasattr(self, '_orig_bytecode_only_trace'):
+                self._orig_bytecode_only_trace = ec.bytecode_only_trace
+            ec.bytecode_only_trace = self._do_bytecode_only_trace
+
+    def unsettrace(self):
+        if self.tracelevel:
+            ec = self.space.getexecutioncontext()
+            ec.bytecode_only_trace = self._orig_bytecode_only_trace
+
+    def _do_bytecode_only_trace(self, frame):
+        from pypy.tool.pydis import Bytecode, HAVE_ARGUMENT
+
+        if frame.hide():
+            return
+
+        self.unsettrace()
+        next_instr = frame.last_instr
+        opcode = ord(frame.pycode.co_code[next_instr])
+
+        oparg = 0
+        if opcode >= HAVE_ARGUMENT:
+            lo = ord(frame.pycode.co_code[next_instr+1])
+            hi = ord(frame.pycode.co_code[next_instr+2])
+            oparg = (hi * 256) | lo
+
+        class fake:
+            code = frame.pycode
+        bytecode = Bytecode(fake, next_instr, oparg, 0)
+        print '\t%-19s %s' % (str(frame.pycode.co_name) + ':',
+                              bytecode.repr_with_space(self.space))
+        self.settrace()
 
     def checktrace(self):
         s = self.space
                                        s.wrap("__pytrace__")))
 
         if self.tracelevel > 0 and tracelevel == 0:
-            s.reset_trace()
+            self.unsettrace()
             print "Tracing disabled"
 
         if self.tracelevel == 0 and tracelevel > 0:
-            self.space.unsettrace()
+            self.unsettrace()
             print "Tracing enabled"
 
         self.tracelevel = tracelevel