8
8
import subprocess
9
9
import dis
10
10
from symtable import symtable
11
-
12
- # FIXME test errors too
11
+ try :
12
+ # run ./build.sh in the readsymtab directory to create this module
13
+ from readsymtab import readsymtab
14
+ use_readsymtab = True
15
+ except ImportError :
16
+ import ctypes
17
+ use_readsymtab = False
18
+ print ("Using compiler dependent code to read bitfields - compile readsymtab module to be sure!" )
13
19
14
20
inp = [
15
21
('''1''' , "eval" ),
@@ -103,12 +109,36 @@ def dump_symtable(st):
103
109
out += 'Lineno:%s,\n ' % st .get_lineno () # Return the number of the first line in the block this table represents.
104
110
out += 'Unoptimized:%s,\n ' % dump_flags (st ._table .optimized , OPT_FLAGS ) # Return False if the locals in this table can be optimized.
105
111
out += 'Nested:%s,\n ' % dump_bool (st .is_nested ()) # Return True if the block is a nested class or function.
112
+
113
+ if use_readsymtab :
114
+ # Use readsymtab modules to read the bitfields which aren't normally exported
115
+ free , child_free , generator , varargs , varkeywords , returns_value , needs_class_closure = readsymtab (st ._table )
116
+ out += 'Free:%s,\n ' % dump_bool (free )
117
+ out += 'ChildFree:%s,\n ' % dump_bool (child_free )
118
+ out += 'Generator:%s,\n ' % dump_bool (generator )
119
+ out += 'Varargs:%s,\n ' % dump_bool (varargs )
120
+ out += 'Varkeywords:%s,\n ' % dump_bool (varkeywords )
121
+ out += 'ReturnsValue:%s,\n ' % dump_bool (returns_value )
122
+ out += 'NeedsClassClosure:%s,\n ' % dump_bool (needs_class_closure )
123
+ else :
124
+ # Use ctypes to read the bitfields which aren't normally exported
125
+ # FIXME compiler dependent!
126
+ base_addr = id (st ._table ) + ctypes .sizeof (ctypes .c_long )* 8 + ctypes .sizeof (ctypes .c_int )* 3
127
+ flags = int .from_bytes (ctypes .c_int .from_address (base_addr ), sys .byteorder )
128
+ out += 'Free:%s,\n ' % dump_bool (flags & (1 << 0 ))
129
+ out += 'ChildFree:%s,\n ' % dump_bool (flags & (1 << 1 ))
130
+ out += 'Generator:%s,\n ' % dump_bool (flags & (1 << 2 ))
131
+ out += 'Varargs:%s,\n ' % dump_bool (flags & (1 << 3 ))
132
+ out += 'Varkeywords:%s,\n ' % dump_bool (flags & (1 << 4 ))
133
+ out += 'ReturnsValue:%s,\n ' % dump_bool (flags & (1 << 5 ))
134
+ out += 'NeedsClassClosure:%s,\n ' % dump_bool (flags & (1 << 6 ))
135
+
106
136
#out += 'Exec:%s,\n' % dump_bool(st.has_exec()) # Return True if the block uses exec.
107
137
#out += 'ImportStar:%s,\n' % dump_bool(st.has_import_star()) # Return True if the block uses a starred from-import.
108
138
out += 'Varnames:%s,\n ' % dump_strings (st ._table .varnames )
109
139
out += 'Symbols: Symbols{\n '
110
140
children = dict ()
111
- for name in st .get_identifiers ():
141
+ for name in sorted ( st .get_identifiers () ):
112
142
s = st .lookup (name )
113
143
out += '"%s":%s,\n ' % (name , dump_symbol (s ))
114
144
ns = s .get_namespaces ()
@@ -120,7 +150,7 @@ def dump_symtable(st):
120
150
raise AssertionError ("More than one namespace" )
121
151
out += '},\n '
122
152
out += 'Children:map[string]*SymTable{\n '
123
- for name , symtable in children .items ():
153
+ for name , symtable in sorted ( children .items () ):
124
154
out += '"%s":%s,\n ' % (name , dump_symtable (symtable ))
125
155
out += '},\n '
126
156
out += "}"
0 commit comments