javaclass

Change of bytecode.py

60:6dda8e27def2
bytecode.py
     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):