3 # This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
5 # This file is part of the Python-on-a-Chip program.
6 # Python-on-a-Chip is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
9 # Python-on-a-Chip is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 # A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
13 # is seen in the file COPYING in this directory.
16 Dismantles a .py file by compiling it
17 into a code object and recursively dismantling
18 and disassembling the code object.
22 dismantle.py sourcefilename.py
26 # @copybrief dismantle
29 # @brief Dismantles a .py file by compiling it
30 # into a code object and recursively dismantling
31 # and disassembling the code object.
37 import dis
, sys
, types
, py_compile
, time
40 def dismantle_file(fn
):
41 """Dismantles the .py file, fn. Returns the root code object.
48 return dismantle(source
, fn
)
51 def dismantle(source
, fn
=""):
53 # If no filename given, just dismantle source, skip magic and ignore
61 # Compile to .pyc and open
62 py_compile
.compile(fn
)
63 f
= open(fn
+ 'c','rb')
67 # Check for magic number
68 magic
= int((ord(pyc
[0]) ) |
(ord(pyc
[1]) << 8) |
69 (ord(pyc
[2]) << 16) |
(ord(pyc
[3]) << 24))
71 # Grab the next 4 bytes (don't know what they do)
72 ignore
= int((ord(pyc
[4]) ) |
(ord(pyc
[5]) << 8) |
73 (ord(pyc
[6]) << 16) |
(ord(pyc
[7]) << 24))
75 code
= compile(source
, fn
, "exec")
78 print "BEGIN DISMANTLE"
79 print "date: \t", time
.ctime(time
.time())
80 print "src file: \t", fn
81 print "src file size: \t", len(source
), "bytes"
82 print "pyc file size: \t", len(pyc
), "bytes"
84 print "magic: \t0x%08x" % magic
85 print "ignore: \t0x%08x" % ignore
88 # Recurse into the code object
95 def rdismantle(co
, parent
= None):
96 """Dismantles the code object, co. Prints the co_* field values and
97 the co_code disassembly for each code object in the file and recurses
98 into any code objects in the constant pool.
103 fullname
= parent
+ "." + co
.co_name
105 fullname
= co
.co_name
107 # Print object fields and values
108 print "fullname: \t", fullname
109 print " co_name: \t", co
.co_name
110 print " co_filename: \t", co
.co_filename
111 print " co_firstlineno:\t", co
.co_firstlineno
112 print " co_flags: \t0x%04x" % co
.co_flags
113 print " co_stacksize: \t", co
.co_stacksize
114 print " co_lnotab[%3d]:\t%s" % \
115 (len(co
.co_lnotab
), repr(co
.co_lnotab
[:8]))
116 print " co_argcount: \t", co
.co_argcount
117 print " co_nlocals: \t", co
.co_nlocals
118 print " co_freevars: \t", co
.co_freevars
119 print " co_cellvars: \t", co
.co_cellvars
121 # Print vital compound components
124 print " co_varnames:"
126 for item
in co
.co_varnames
:
127 print tabspacing
, i
, ":\t", item
132 for item
in co
.co_names
:
133 print tabspacing
, i
, ":\t", item
138 for item
in co
.co_consts
:
139 if type(item
) == types
.StringType
and \
140 len(item
) > STRINGTOOLONG
:
141 print tabspacing
, i
, ":\t", repr(item
[:STRINGTOOLONG
]), "..."
143 print tabspacing
, i
, ":\t", repr(item
)
151 # Dismantle code objects in constant pool
152 for obj
in co
.co_consts
:
153 if type(obj
) == types
.CodeType
:
154 rdismantle(obj
, fullname
)
159 """Dismantles the source file given as an arg.
162 if len(sys
.argv
) == 2:
163 return dismantle_file(sys
.argv
[1])
168 if __name__
== "__main__":