Changeset 37
- Timestamp:
- 03/19/07 13:32:25
- Files:
-
- trunk/geniusql/codewalk.py (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/geniusql/codewalk.py
r36 r37 124 124 125 125 class Visitor(object): 126 """Visitor(obj=function, code object, string, or list of opcodes).""" 126 """A visitor class for bytecode sequences. 127 128 obj: a function, code object, string, or list of opcodes. 129 """ 127 130 128 131 def __init__(self, obj): … … 133 136 obj = obj.im_func 134 137 if isinstance(obj, FunctionType): 138 self._func = obj 135 139 obj = obj.func_code 140 141 # Copy code object attributes (if present). 142 selfdict = self.__dict__ 143 try: 144 for name, _type in _co_code_attrs.iteritems(): 145 value = getattr(obj, name) 146 if _type is tuple: 147 value = list(value) 148 selfdict[name] = value 149 except AttributeError: 150 pass 151 136 152 try: 137 153 obj = obj.co_code … … 141 157 # Map the code block string to a list of opcode numbers. 142 158 if isinstance(obj, basestring): 143 obj= map(ord, obj)159 bytecode = map(ord, obj) 144 160 elif isinstance(obj, list): 145 obj = obj[:] 146 147 self._bytecode = obj 161 bytecode = obj[:] 162 else: 163 raise TypeError("obj arg of incorrect type '%s'" % type(obj)) 164 165 self._bytecode = bytecode 148 166 149 167 def debug(self, *messages): … … 178 196 self.visit_instruction(op, *args) 179 197 180 handler = getattr(self, 'visit_' + _visit_map[op], None) 198 instruction = _visit_map[op] 199 handler = getattr(self, 'visit_' + instruction, None) 181 200 if handler: 182 201 if verbose: 183 self.debug("=> %s%s" % ( _visit_map[op], repr(args)))202 self.debug("=> %s%s" % (instruction, repr(args))) 184 203 handler(*args) 204 if verbose: 205 self.debug("\n %r" % self.stack) 185 206 186 207 def visit_instruction(self, op, lo=None, hi=None): … … 266 287 string or list of opcodes as an initial argument. 267 288 """ 268 269 def __init__(self, obj):270 self.verbose = False271 272 if isinstance(obj, MethodType):273 obj = obj.im_func274 if isinstance(obj, FunctionType):275 self._func = obj276 obj = obj.func_code277 278 # Copy code object attributes.279 selfdict = self.__dict__280 for name, _type in _co_code_attrs.iteritems():281 value = getattr(obj, name)282 if _type is tuple:283 value = list(value)284 selfdict[name] = value285 286 try:287 obj = obj.co_code288 except AttributeError:289 pass290 291 # Map the code block to a list of opcode numbers.292 if isinstance(obj, basestring):293 bytecode = map(ord, obj)294 elif isinstance(obj, list):295 bytecode = obj[:]296 else:297 raise TypeError("obj arg of incorrect type '%s'" % type(obj))298 299 self._bytecode = bytecode300 289 301 290 def bytecode(self): … … 719 708 Produce decompiled Python code (as a string) from a supplied lambda.""" 720 709 721 def __init__(self, obj):722 self.verbose = False723 724 # Distill supplied 'obj' arg to a code block string.725 if isinstance(obj, MethodType):726 obj = obj.im_func727 if isinstance(obj, FunctionType):728 obj = obj.func_code729 730 # Copy code object attributes.731 selfdict = self.__dict__732 for name, _type in _co_code_attrs.iteritems():733 value = getattr(obj, name)734 if _type is tuple:735 value = list(value)736 selfdict[name] = value737 738 try:739 obj = obj.co_code740 except AttributeError:741 pass742 743 # Map the code block to a list of opcode numbers.744 if isinstance(obj, basestring):745 obj = map(ord, obj)746 elif isinstance(obj, list):747 obj = obj[:]748 749 self._bytecode = obj750 751 710 def code(self, include_func_header=True): 752 711 self.walk() … … 807 766 808 767 def visit_BUILD_LIST(self, lo, hi): 809 terms = ", ".join([self.stack.pop() for i in range(lo + hi << 8)]) 810 self.stack.append("[%s]" % terms) 768 terms = [self.stack.pop() for i in range(lo + (hi << 8))] 769 terms.reverse() 770 self.stack.append("[%s]" % ", ".join(terms)) 811 771 812 772 def visit_BUILD_MAP(self, lo, hi): … … 816 776 817 777 def visit_BUILD_TUPLE(self, lo, hi): 818 terms = ", ".join([self.stack.pop() for i in range(lo + hi << 8)]) 819 self.stack.append("(%s)" % terms) 778 terms = [self.stack.pop() for i in range(lo + (hi << 8))] 779 terms.reverse() 780 self.stack.append("(%s)" % ", ".join(terms)) 820 781 821 782 def visit_CALL_FUNCTION(self, lo, hi):
