1.1 --- a/bytecode.py Mon Nov 15 01:00:53 2004 +0100
1.2 +++ b/bytecode.py Fri Nov 19 15:43:43 2004 +0100
1.3 @@ -892,6 +892,27 @@
1.4 def generic(self, arguments, program):
1.5 print arguments
1.6
1.7 + def lookupswitch(self, code, program):
1.8 + print "%5s lookupswitch" % (self.java_position,),
1.9 + d, r = divmod(self.java_position + 1, 4)
1.10 + to_boundary = (4 - r) % 4
1.11 + code = code[to_boundary:]
1.12 + default = classfile.u4(code[0:4])
1.13 + npairs = classfile.u4(code[4:8])
1.14 + print default, npairs
1.15 + return to_boundary + 8 + npairs * 8
1.16 +
1.17 + def tableswitch(self, code, program):
1.18 + print "%5s tableswitch" % (self.java_position,),
1.19 + d, r = divmod(self.java_position + 1, 4)
1.20 + to_boundary = (4 - r) % 4
1.21 + code = code[to_boundary:]
1.22 + default = classfile.u4(code[0:4])
1.23 + low = classfile.u4(code[4:8])
1.24 + high = classfile.u4(code[8:12])
1.25 + print default, low, high
1.26 + return to_boundary + 12 + (high - low + 1) * 4
1.27 +
1.28 class BytecodeDisassemblerProgram:
1.29 position = 0
1.30 def setup_except(self, target):
1.31 @@ -1557,10 +1578,10 @@
1.32 lconst_1 = iconst_1
1.33
1.34 def ldc(self, arguments, program):
1.35 - program.load_const(self.class_file.constants[arguments[0] - 1])
1.36 + program.load_const(self.class_file.constants[arguments[0] - 1].get_value())
1.37
1.38 def ldc_w(self, arguments, program):
1.39 - program.load_const(self.class_file.constants[(arguments[0] << 8) + arguments[1] - 1])
1.40 + program.load_const(self.class_file.constants[(arguments[0] << 8) + arguments[1] - 1].get_value())
1.41
1.42 ldc2_w = ldc_w
1.43 ldiv = idiv
1.44 @@ -1572,28 +1593,26 @@
1.45 lmul = imul
1.46 lneg = ineg
1.47
1.48 - def lookupswitch(self, arguments, program):
1.49 + def lookupswitch(self, code, program):
1.50
1.51 # Find the offset to the next 4 byte boundary in the code.
1.52
1.53 - d, r = divmod(self.java_position, 4)
1.54 + d, r = divmod(self.java_position + 1, 4)
1.55 to_boundary = (4 - r) % 4
1.56
1.57 # Get the pertinent arguments.
1.58
1.59 - arguments = arguments[to_boundary:]
1.60 - default = (arguments[0] << 24) + (arguments[1] << 16) + (arguments[2] << 8) + arguments[3]
1.61 - npairs = (arguments[4] << 24) + (arguments[5] << 16) + (arguments[6] << 8) + arguments[7]
1.62 + code = code[to_boundary:]
1.63 + default = classfile.u4(code[0:4])
1.64 + npairs = classfile.u4(code[4:8])
1.65
1.66 # Process the pairs.
1.67 # NOTE: This is not the most optimal implementation.
1.68
1.69 pair_index = 8
1.70 for pair in range(0, npairs):
1.71 - match = ((arguments[pair_index] << 24) + (arguments[pair_index + 1] << 16) +
1.72 - (arguments[pair_index + 2] << 8) + arguments[pair_index + 3])
1.73 - offset = signed4((arguments[pair_index + 4] << 24) + (arguments[pair_index + 5] << 16) +
1.74 - (arguments[pair_index + 6] << 8) + arguments[pair_index + 7])
1.75 + match = classfile.u4(code[pair_index:pair_index+4])
1.76 + offset = classfile.s4(code[pair_index+4:pair_index+8])
1.77 # Calculate the branch target.
1.78 java_absolute = self.java_position + offset
1.79 # Generate branching code.
1.80 @@ -1608,12 +1627,13 @@
1.81 program.start_label("end")
1.82 program.pop_top() # Stack: key
1.83 # Update the index.
1.84 - pair_index += 8
1.85 + pair_index += 4
1.86
1.87 # Generate the default.
1.88
1.89 java_absolute = self.java_position + default
1.90 program.jump_absolute(self.position_mapping[java_absolute])
1.91 + return pair_index + to_boundary
1.92
1.93 lor = ior
1.94 lrem = irem
1.95 @@ -1734,27 +1754,26 @@
1.96 def swap(self, arguments, program):
1.97 program.rot_two()
1.98
1.99 - def tableswitch(self, arguments, program):
1.100 + def tableswitch(self, code, program):
1.101
1.102 # Find the offset to the next 4 byte boundary in the code.
1.103
1.104 - d, r = divmod(self.java_position, 4)
1.105 + d, r = divmod(self.java_position + 1, 4)
1.106 to_boundary = (4 - r) % 4
1.107
1.108 # Get the pertinent arguments.
1.109
1.110 - arguments = arguments[to_boundary:]
1.111 - default = (arguments[0] << 24) + (arguments[1] << 16) + (arguments[2] << 8) + arguments[3]
1.112 - low = (arguments[4] << 24) + (arguments[5] << 16) + (arguments[6] << 8) + arguments[7]
1.113 - high = (arguments[8] << 24) + (arguments[9] << 16) + (arguments[10] << 8) + arguments[11]
1.114 + code = code[to_boundary:]
1.115 + default = classfile.u4(code[0:4])
1.116 + low = classfile.u4(code[4:8])
1.117 + high = classfile.u4(code[8:12])
1.118
1.119 # Process the jump entries.
1.120 # NOTE: This is not the most optimal implementation.
1.121
1.122 - jump_index = 8
1.123 + jump_index = 12
1.124 for jump in range(low, high + 1):
1.125 - offset = signed4((arguments[jump_index] << 24) + (arguments[jump_index + 1] << 16) +
1.126 - (arguments[jump_index + 2] << 8) + arguments[jump_index + 3])
1.127 + offset = classfile.s4(code[jump_index:jump_index + 4])
1.128
1.129 # Calculate the branch target.
1.130
1.131 @@ -1777,12 +1796,13 @@
1.132
1.133 # Update the index.
1.134
1.135 - jump_index += 8
1.136 + jump_index += 4
1.137
1.138 # Generate the default.
1.139
1.140 java_absolute = self.java_position + default
1.141 program.jump_absolute(self.position_mapping[java_absolute])
1.142 + return jump_index + to_boundary
1.143
1.144 def wide(self, code, program):
1.145 # NOTE: To be implemented.
1.146 @@ -2035,18 +2055,23 @@
1.147 if original_name in ("java/lang/Object", "java/lang/Exception"):
1.148 return ()
1.149 else:
1.150 - full_class_name = str(self.class_file.super_class.get_python_name())
1.151 - class_name_parts = full_class_name.split(".")
1.152 - class_name = class_name_parts[-1]
1.153 - class_module_name = ".".join(class_name_parts[:-1])
1.154 - if class_module_name == "":
1.155 - obj = global_names[class_name]
1.156 + full_this_class_name = str(self.class_file.this_class.get_python_name())
1.157 + this_class_name_parts = full_this_class_name.split(".")
1.158 + this_class_module_name = ".".join(this_class_name_parts[:-1])
1.159 + full_super_class_name = str(self.class_file.super_class.get_python_name())
1.160 + super_class_name_parts = full_super_class_name.split(".")
1.161 + super_class_name = super_class_name_parts[-1]
1.162 + super_class_module_name = ".".join(super_class_name_parts[:-1])
1.163 + if super_class_module_name == "":
1.164 + obj = global_names[super_class_name]
1.165 + elif super_class_module_name == this_class_module_name:
1.166 + obj = global_names[super_class_name]
1.167 else:
1.168 - print "Importing", class_module_name, class_name
1.169 - obj = __import__(class_module_name, global_names, {}, [])
1.170 - for class_name_part in class_name_parts[1:] or [class_name]:
1.171 - print "*", obj, class_name_part
1.172 - obj = getattr(obj, class_name_part)
1.173 + print "Importing", super_class_module_name, super_class_name
1.174 + obj = __import__(super_class_module_name, global_names, {}, [])
1.175 + for super_class_name_part in super_class_name_parts[1:] or [super_class_name]:
1.176 + print "*", obj, super_class_name_part
1.177 + obj = getattr(obj, super_class_name_part)
1.178 return (obj,)
1.179
1.180 def make_varnames(self, nlocals):