javaclass

Changeset

43:db63432af949
2004-11-13 Paul Boddie raw files shortlog changelog graph Fixed class names in certain cases to avoid usage of fully qualified names. Removed old code. Added some method descriptions.
bytecode.py (file)
     1.1 --- a/bytecode.py	Sat Nov 13 20:59:44 2004 +0100
     1.2 +++ b/bytecode.py	Sat Nov 13 21:00:48 2004 +0100
     1.3 @@ -1351,8 +1351,10 @@
     1.4          program.start_label("is-self")
     1.5          program.pop_top()               # Stack: tuple, reference
     1.6          program.pop_top()               # Stack: tuple
     1.7 -        program.load_global(str(self.class_file.this_class.get_python_name()))
     1.8 -                                        # Stack: tuple, classref
     1.9 +        # Get the class name instead of the fully qualified name.
    1.10 +        full_class_name = str(self.class_file.this_class.get_python_name())
    1.11 +        class_name = full_class_name.split(".")[-1]
    1.12 +        program.load_global(class_name) # Stack: tuple, classref
    1.13          program.load_attr("__bases__")  # Stack: tuple, bases
    1.14          program.dup_top()               # Stack: tuple, bases, bases
    1.15          program.load_global("len")      # Stack: tuple, bases, bases, len
    1.16 @@ -1374,41 +1376,6 @@
    1.17          program.pop_top()               # Stack:
    1.18          program.start_label("done")
    1.19  
    1.20 -    """
    1.21 -    def invokespecial(self, arguments, program):
    1.22 -        # NOTE: This implementation does not perform the necessary checks for
    1.23 -        # NOTE: signature-based polymorphism.
    1.24 -        # NOTE: Java rules not specifically obeyed.
    1.25 -        index = (arguments[0] << 8) + arguments[1]
    1.26 -        target = self.class_file.constants[index - 1]
    1.27 -        target_name = target.get_python_name()
    1.28 -        # Get the number of parameters from the descriptor.
    1.29 -        count = len(target.get_descriptor()[0])
    1.30 -        # Stack: objectref, arg1, arg2, ...
    1.31 -        program.build_tuple(count + 1)  # Stack: tuple
    1.32 -        # Use the class to provide access to static methods.
    1.33 -        program.load_name("self")       # Stack: tuple, self
    1.34 -        program.load_attr("__class__")  # Stack: tuple, class
    1.35 -        program.load_attr("__bases__")  # Stack: tuple, base-classes
    1.36 -        program.dup_top()               # Stack: tuple, base-classes, base-classes
    1.37 -        program.load_global("len")      # Stack: tuple, base-classes, base-classes, len
    1.38 -        program.rot_two()               # Stack: tuple, base-classes, len, base-classes
    1.39 -        program.call_function(1)        # Stack: tuple, base-classes, count
    1.40 -        program.load_const(0)           # Stack: tuple, base-classes, count, 0
    1.41 -        program.compare_op("==")        # Stack: tuple, base-classes, result
    1.42 -        program.jump_to_label(1, "next")
    1.43 -        program.pop_top()               # Stack: tuple, base-classes
    1.44 -        program.load_const(0)           # Stack: tuple, base-classes, 0
    1.45 -        program.binary_subscr()         # Stack: tuple, superclass
    1.46 -        self._invoke(target_name, program)
    1.47 -        program.jump_to_label(None, "next2")
    1.48 -        program.start_label("next")
    1.49 -        program.pop_top()               # Stack: tuple, base-classes
    1.50 -        program.pop_top()               # Stack: tuple
    1.51 -        program.pop_top()               # Stack:
    1.52 -        program.start_label("next2")
    1.53 -    """
    1.54 -
    1.55      def invokestatic(self, arguments, program):
    1.56          # NOTE: This implementation does not perform the necessary checks for
    1.57          # NOTE: signature-based polymorphism.
    1.58 @@ -1706,17 +1673,37 @@
    1.59      disassembler.process(method, BytecodeDisassemblerProgram())
    1.60  
    1.61  class ClassTranslator:
    1.62 +
    1.63 +    """
    1.64 +    A class which provides a wrapper around a class file and the means to
    1.65 +    translate the represented class into a Python class.
    1.66 +    """
    1.67 +
    1.68      def __init__(self, class_file):
    1.69 +
    1.70 +        "Initialise the object with the given 'class_file'."
    1.71 +
    1.72          self.class_file = class_file
    1.73          self.filename = str(self.class_file.attributes[0].get_name())
    1.74  
    1.75      def translate_method(self, method):
    1.76 +
    1.77 +        "Translate the given 'method' - an object obtained from the class file."
    1.78 +
    1.79          translator = BytecodeTranslator(self.class_file)
    1.80          writer = BytecodeWriter()
    1.81          translator.process(method, writer)
    1.82          return translator, writer
    1.83  
    1.84      def make_method(self, method_name, methods, global_names, namespace):
    1.85 +
    1.86 +        """
    1.87 +        Make a dispatcher method with the given 'method_name', providing
    1.88 +        dispatch to the supplied type-sensitive 'methods', accessing the given
    1.89 +        'global_names' where necessary, and storing the new method in the
    1.90 +        'namespace' provided.
    1.91 +        """
    1.92 +
    1.93          if method_name == "<init>":
    1.94              method_name = "__init__"
    1.95          # Where only one method exists, just make an alias.
    1.96 @@ -1838,6 +1825,11 @@
    1.97          namespace[method_name] = fn
    1.98  
    1.99      def process(self, global_names):
   1.100 +
   1.101 +        """
   1.102 +        Process the class, storing it in the 'global_names' dictionary provided.
   1.103 +        """
   1.104 +
   1.105          namespace = {}
   1.106          real_methods = {}
   1.107          for method in self.class_file.methods:
   1.108 @@ -1863,11 +1855,21 @@
   1.109          # Define method dispatchers.
   1.110          for real_method_name, methods in real_methods.items():
   1.111              self.make_method(real_method_name, methods, global_names, namespace)
   1.112 -        cls = new.classobj(str(self.class_file.this_class.get_python_name()), bases, namespace)
   1.113 +        # Use only the last part of the fully qualified name.
   1.114 +        full_class_name = str(self.class_file.this_class.get_python_name())
   1.115 +        class_name = full_class_name.split(".")[-1]
   1.116 +        cls = new.classobj(class_name, bases, namespace)
   1.117          global_names[cls.__name__] = cls
   1.118          return cls
   1.119  
   1.120      def make_varnames(self, nlocals):
   1.121 +
   1.122 +        """
   1.123 +        A utility method which invents variable names for the given number -
   1.124 +        'nlocals' - of local variables in a method. Returns a list of such
   1.125 +        variable names.
   1.126 +        """
   1.127 +
   1.128          l = ["self"]
   1.129          for i in range(1, nlocals):
   1.130              l.append("_l%s" % i)