[pypy-svn] r36393 - in pypy/dist/pypy/translator: cli jvm jvm/src oosupport

niko at codespeak.net niko at codespeak.net
Wed Jan 10 00:31:32 CET 2007


Author: niko
Date: Wed Jan 10 00:31:30 2007
New Revision: 36393

Added:
   pypy/dist/pypy/translator/jvm/metavm.py
Modified:
   pypy/dist/pypy/translator/cli/metavm.py
   pypy/dist/pypy/translator/cli/opcodes.py
   pypy/dist/pypy/translator/jvm/constant.py
   pypy/dist/pypy/translator/jvm/database.py
   pypy/dist/pypy/translator/jvm/generator.py
   pypy/dist/pypy/translator/jvm/genjvm.py
   pypy/dist/pypy/translator/jvm/node.py
   pypy/dist/pypy/translator/jvm/opcodes.py
   pypy/dist/pypy/translator/jvm/src/PyPy.java
   pypy/dist/pypy/translator/oosupport/constant.py
   pypy/dist/pypy/translator/oosupport/metavm.py
Log:
(niko, antocuni)

fix all of test_class.py for the jvm backend



Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py	(original)
+++ pypy/dist/pypy/translator/cli/metavm.py	Wed Jan 10 00:31:30 2007
@@ -103,13 +103,6 @@
         generator.call_signature('object [pypylib]pypy.runtime.Utils::RuntimeNew(class [mscorlib]System.Type)')
         generator.cast_to(op.result.concretetype)
 
-class _CastTo(MicroInstruction):
-    def render(self, generator, op):
-        generator.load(op.args[0])
-        INSTANCE = op.args[1].value
-        class_name = generator.db.pending_class(INSTANCE)
-        generator.isinstance(class_name)
-
 class _OOString(MicroInstruction):
     def render(self, generator, op):
         ARGTYPE = op.args[0].concretetype
@@ -250,7 +243,6 @@
 CallMethod = _CallMethod()
 IndirectCall = _IndirectCall()
 RuntimeNew = _RuntimeNew()
-CastTo = _CastTo()
 OOString = _OOString()
 NewCustomDict = _NewCustomDict()
 CastWeakAdrToPtr = _CastWeakAdrToPtr()

Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py	(original)
+++ pypy/dist/pypy/translator/cli/opcodes.py	Wed Jan 10 00:31:30 2007
@@ -1,9 +1,9 @@
 from pypy.translator.cli.metavm import  Call, CallMethod, \
-     IndirectCall, GetField, SetField, CastTo, OOString, DownCast, NewCustomDict,\
+     IndirectCall, GetField, SetField, OOString, DownCast, NewCustomDict,\
      CastWeakAdrToPtr, MapException, Box, Unbox, NewArray, GetArrayElem, SetArrayElem,\
      TypeOf
 from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
-    New, RuntimeNew
+    New, RuntimeNew, CastTo
 from pypy.translator.cli.cts import WEAKREF
 
 # some useful instruction patterns

Modified: pypy/dist/pypy/translator/jvm/constant.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/constant.py	(original)
+++ pypy/dist/pypy/translator/jvm/constant.py	Wed Jan 10 00:31:30 2007
@@ -1,7 +1,9 @@
+from pypy.rpython.ootypesystem import ootype
 from pypy.translator.jvm.generator import \
      Field, Method
 from pypy.translator.oosupport.constant import \
-     BaseConstantGenerator, RecordConst, InstanceConst, ClassConst
+     BaseConstantGenerator, RecordConst, InstanceConst, ClassConst, \
+     StaticMethodConst
 from pypy.translator.jvm.typesystem import \
      jPyPyConst, jObject, jVoid
 
@@ -54,3 +56,21 @@
         
         gen.end_class()
     
+class JVMStaticMethodConst(StaticMethodConst):
+
+    def record_dependencies(self):
+        if self.value is ootype.null(self.value._TYPE):
+            self.delegate_impl = None
+            return
+        StaticMethodConst.record_dependencies(self)
+        self.delegate_impl = self.db.record_delegate_impl(self.value.graph)
+
+    def create_pointer(self, gen):
+        if self.delegate_impl:
+            gen.new_with_jtype(self.delegate_impl)
+        else:
+            gen.push_null(jObject)
+
+    def initialize_data(self, ilasm):
+        return
+    

Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py	(original)
+++ pypy/dist/pypy/translator/jvm/database.py	Wed Jan 10 00:31:30 2007
@@ -31,6 +31,9 @@
                            # and JvmType objects as well
         self._functions = {}      # graph -> jvmgen.Method
 
+        # (jargtypes, jrettype) -> node.StaticMethodInterface
+        self._delegates = {} 
+
         self._function_names = {} # graph --> function_name
 
         self._constants = {}      # flowmodel.Variable --> jvmgen.Const
@@ -72,6 +75,14 @@
     # Node Creation
     #
     # Creates nodes that represents classes, functions, simple constants.
+
+    def _types_for_graph(self, graph):
+        argtypes = [arg.concretetype for arg in graph.getargs()
+                    if arg.concretetype is not ootype.Void]
+        jargtypes = tuple([self.lltype_to_cts(argty) for argty in argtypes])
+        rettype = graph.getreturnvar().concretetype
+        jrettype = self.lltype_to_cts(rettype)
+        return jargtypes, jrettype        
     
     def _function_for_graph(self, classobj, funcnm, is_static, graph):
         
@@ -79,15 +90,34 @@
         Creates a node.Function object for a particular graph.  Adds
         the method to 'classobj', which should be a node.Class object.
         """
-        argtypes = [arg.concretetype for arg in graph.getargs()
-                    if arg.concretetype is not ootype.Void]
-        jargtypes = [self.lltype_to_cts(argty) for argty in argtypes]
-        rettype = graph.getreturnvar().concretetype
-        jrettype = self.lltype_to_cts(rettype)
+        jargtypes, jrettype = self._types_for_graph(graph)
         funcobj = node.Function(
             self, classobj, funcnm, jargtypes, jrettype, graph, is_static)
         return funcobj
     
+    def _translate_record(self, OOTYPE):
+        assert OOTYPE is not ootype.ROOT
+
+        # Create class object if it does not already exist:
+        if OOTYPE in self._classes:
+            return self._classes[OOTYPE]
+
+        # Create the class object first
+        clsnm = self._pkg(self._uniq('Record'))
+        clsobj = node.Class(clsnm, jObject)
+        self._classes[OOTYPE] = clsobj
+
+        # Add fields:
+        self._translate_class_fields(clsobj, OOTYPE)
+
+        # TODO --- generate equals/hash methods here
+        
+        dump_method = node.RecordDumpMethod(self, OOTYPE, clsobj)
+        clsobj.add_dump_method(dump_method)
+
+        self.pending_node(clsobj)
+        return clsobj
+    
     def _translate_instance(self, OOTYPE):
         assert isinstance(OOTYPE, ootype.Instance)
         assert OOTYPE is not ootype.ROOT
@@ -111,12 +141,8 @@
         # classes?
         
         # Add fields:
-        for fieldnm, (FIELDOOTY, fielddef) in OOTYPE._fields.iteritems():
-            if FIELDOOTY is ootype.Void: continue
-            fieldty = self.lltype_to_cts(FIELDOOTY)
-            clsobj.add_field(
-                jvmgen.Field(clsnm, fieldnm, fieldty, False, FIELDOOTY),
-                fielddef)
+        # Add fields:
+        self._translate_class_fields(clsobj, OOTYPE)
             
         # Add methods:
         for mname, mimpl in OOTYPE._methods.iteritems():
@@ -142,12 +168,20 @@
 
         # currently, we always include a special "dump" method for debugging
         # purposes
-        dump_method = node.TestDumpMethod(self, OOTYPE, clsobj)
+        dump_method = node.InstanceDumpMethod(self, OOTYPE, clsobj)
         clsobj.add_dump_method(dump_method)
 
         self.pending_node(clsobj)
         return clsobj
 
+    def _translate_class_fields(self, clsobj, OOTYPE):
+        for fieldnm, (FIELDOOTY, fielddef) in OOTYPE._fields.iteritems():
+            if FIELDOOTY is ootype.Void: continue
+            fieldty = self.lltype_to_cts(FIELDOOTY)
+            clsobj.add_field(
+                jvmgen.Field(clsobj.name, fieldnm, fieldty, False, FIELDOOTY),
+                fielddef)
+
     def pending_class(self, OOTYPE):
         return self.lltype_to_cts(OOTYPE)
 
@@ -169,6 +203,38 @@
         res = self._functions[graph] = funcobj.method()
         return res
 
+    def record_delegate(self, TYPE):
+        """ TYPE is a StaticMethod """
+
+        # Translate argument/return types into java types, check if
+        # we already have such a delegate:
+        jargs = tuple([self.lltype_to_cts(ARG) for ARG in TYPE.ARGS])
+        jret = self.lltype_to_cts(TYPE.RESULT)
+        key = (jargs, jret)
+        if key in self._delegates:
+            return self._delegates[key]
+
+        # TODO: Make an intelligent name for this interface by
+        # mangling the list of parameters
+        name = self._pkg(self._uniq('Delegate'))
+
+        # Create a new one if we do not:
+        interface = node.StaticMethodInterface(name, TYPE, jargs, jret)
+        self._delegates[key] = interface
+        self.pending_node(interface)
+        return interface
+    
+    def record_delegate_impl(self, graph):
+        """ TYPE is a StaticMethod """
+        jargtypes, jrettype = self._types_for_graph(graph)
+        key = (jargtypes, jrettype)
+        assert key in self._delegates
+        pfunc = self.pending_function(graph)
+        implnm = self._pkg(self._uniq(graph.name+'_delegate'))
+        n = node.StaticMethodImplementation(implnm, self._delegates[key], pfunc)
+        self.pending_node(n)
+        return n
+
     # _________________________________________________________________
     # Type printing functions
     #
@@ -185,6 +251,7 @@
         ootype.String:jvmgen.PYPYDUMPSTRING,
         ootype.StringBuilder:jvmgen.PYPYDUMPOBJECT,
         ootype.Void:jvmgen.PYPYDUMPVOID,
+        ootype.Char:jvmgen.PYPYDUMPCHAR
         }
 
     def generate_dump_method_for_ootype(self, OOTYPE):
@@ -264,7 +331,7 @@
         if isinstance(OOT, ootype.Record):
             return self._translate_record(OOT)
         if isinstance(OOT, ootype.StaticMethod):
-            return XXX
+            return self.record_delegate(OOT)
         
         assert False, "Untranslatable type %s!" % OOT
 
@@ -273,7 +340,7 @@
     #
     # These functions are invoked by the code in oosupport, but I
     # don't think we need them or use them otherwise.
-    
+
     def record_function(self, graph, name):
         self._function_names[graph] = name
 

Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py	(original)
+++ pypy/dist/pypy/translator/jvm/generator.py	Wed Jan 10 00:31:30 2007
@@ -325,12 +325,14 @@
                             self.method_name,
                             self.descriptor)
 
+OBJHASHCODE =           Method.v(jObject, 'hashCode', (), jInt)
 MATHIABS =              Method.s(jMath, 'abs', (jInt,), jInt)
 MATHLABS =              Method.s(jMath, 'abs', (jLong,), jLong)
 MATHDABS =              Method.s(jMath, 'abs', (jDouble,), jDouble)
 MATHFLOOR =             Method.s(jMath, 'floor', (jDouble,), jDouble)
 PRINTSTREAMPRINTSTR =   Method.v(jPrintStream, 'print', (jString,), jVoid)
 CLASSFORNAME =          Method.s(jClass, 'forName', (jString,), jClass)
+CLASSISASSIGNABLEFROM = Method.v(jClass, 'isAssignableFrom', (jClass,), jBool)
 PYPYUINTCMP =           Method.s(jPyPy, 'uint_cmp', (jInt,jInt,), jInt)
 PYPYULONGCMP =          Method.s(jPyPy, 'ulong_cmp', (jLong,jLong), jInt)
 PYPYUINTTODOUBLE =      Method.s(jPyPy, 'uint_to_double', (jInt,), jDouble)
@@ -345,6 +347,7 @@
 PYPYSTRTOCHAR =         Method.s(jPyPy, 'str_to_char', (jString,), jChar)
 PYPYDUMPINDENTED  =     Method.s(jPyPy, 'dump_indented', (jInt,jString,), jVoid)
 PYPYDUMPINT  =          Method.s(jPyPy, 'dump_int', (jInt,jInt), jVoid)
+PYPYDUMPCHAR  =         Method.s(jPyPy, 'dump_char', (jChar,jInt), jVoid)
 PYPYDUMPUINT  =         Method.s(jPyPy, 'dump_uint', (jInt,jInt), jVoid)
 PYPYDUMPLONG  =         Method.s(jPyPy, 'dump_long', (jLong,jInt), jVoid)
 PYPYDUMPDOUBLE  =       Method.s(jPyPy, 'dump_double', (jDouble,jInt), jVoid)
@@ -414,6 +417,7 @@
     def __init__(self):
         self.next_offset = 0
         self.local_vars = {}
+        self.function_arguments = []
         self.instr_counter = 0
     def add_var(self, jvar, jtype):
         """ Adds new entry for variable 'jvar', of java type 'jtype' """
@@ -422,6 +426,7 @@
         if jvar:
             assert jvar not in self.local_vars # never been added before
             self.local_vars[jvar] = idx
+        self.function_arguments.append((jtype, idx))
         return idx
     def var_offset(self, jvar, jtype):
         """ Returns offset for variable 'jvar', of java type 'jtype' """
@@ -479,6 +484,11 @@
         self.curclass = None
         self.curfunc = None
 
+    def current_type(self):
+        """ Returns the jvm type we are currently defining.  If
+        begin_class() has not been called, returns None. """
+        return self.curclass.class_type
+
     def _begin_class(self, abstract):
         """ Main implementation of begin_class """
         raise NotImplementedError
@@ -500,8 +510,8 @@
         
         superclsnm --- same Java name of super class as from begin_class
         """
-        self.begin_function("<init>", [], [self.curclass.class_type], jVoid)
-        self.load_jvm_var(self.curclass.class_type, 0)
+        self.begin_function("<init>", [], [self.current_type()], jVoid)
+        self.load_jvm_var(self.current_type(), 0)
         jmethod = Method(self.curclass.superclass_type.name, "<init>",
                          (), jVoid, opcode=INVOKESPECIAL)
         jmethod.invoke(self)
@@ -637,6 +647,12 @@
         virtual method, not static methods. """
         self.load_jvm_var(jObject, 0)
 
+    def load_function_argument(self, index):
+        """ Convenience method.  Loads function argument #index; note that
+        the this pointer is index #0. """
+        jtype, jidx = self.curfunc.function_arguments[index]
+        self.load_jvm_var(jtype, jidx)
+
     # __________________________________________________________________
     # Exception Handling
 
@@ -764,6 +780,9 @@
         jtype = self.db.lltype_to_cts(TYPE)
         self._instr(INSTANCEOF, jtype)
 
+    def isinstance(self, jtype):
+        self._instr(INSTANCEOF, jtype)
+
     def branch_unconditionally(self, target_label):
         self.goto(target_label)
 
@@ -798,6 +817,9 @@
         
     def new(self, TYPE):
         jtype = self.db.lltype_to_cts(TYPE)
+        self.new_with_jtype(jtype)
+
+    def new_with_jtype(self, jtype):
         ctor = Method(jtype.name, "<init>", (), jVoid, opcode=INVOKESPECIAL)
         self.emit(NEW, jtype)
         self.emit(DUP)
@@ -921,7 +943,10 @@
         self.mark(endlbl)
 
     is_null = lambda self: self._compare_op(IFNULL)
-    is_not_null = lambda self: self._compare_op(IFNOTNULL)
+    is_not_null = lambda self: self._compare_op(IFNONNULL)
+
+    ref_is_eq = lambda self: self._compare_op(IF_ACMPEQ)
+    ref_is_neq = lambda self: self._compare_op(IF_ACMPNEQ)
 
     logical_not = lambda self: self._compare_op(IFEQ)
     equals_zero = logical_not
@@ -989,7 +1014,7 @@
         classnm --- full Java name of the class (i.e., "java.lang.String")
         """
 
-        iclassnm = self.curclass.class_type.descriptor.int_class_name()
+        iclassnm = self.current_type().descriptor.int_class_name()
         isuper = self.curclass.superclass_type.descriptor.int_class_name()
         
         jfile = "%s/%s.j" % (self.outdir, iclassnm)
@@ -1055,8 +1080,9 @@
             return str(arg)
         strargs = [jasmin_syntax(arg) for arg in args]
         instr_text = '%s %s' % (jvmstr, " ".join(strargs))
-        self.curclass.out('    %-60s ; %d\n' % (
-            instr_text, self.curfunc.instr_counter))
+        self.curclass.out('    .line %d\n' % self.curfunc.instr_counter)
+        self.curclass.out('    %-60s\n' % (
+            instr_text,))
         self.curfunc.instr_counter+=1
 
     def _try_catch_region(self, excclsty, trystartlbl, tryendlbl, catchlbl):

Modified: pypy/dist/pypy/translator/jvm/genjvm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/genjvm.py	(original)
+++ pypy/dist/pypy/translator/jvm/genjvm.py	Wed Jan 10 00:31:30 2007
@@ -15,7 +15,8 @@
 from pypy.translator.jvm.log import log
 from pypy.translator.jvm.node import EntryPoint, Function
 from pypy.translator.jvm.opcodes import opcodes
-from pypy.translator.jvm.constant import JVMConstantGenerator
+from pypy.translator.jvm.constant import \
+     JVMConstantGenerator, JVMStaticMethodConst
 
 class JvmError(Exception):
     """ Indicates an error occurred in JVM backend """
@@ -180,6 +181,7 @@
     log = log
 
     ConstantGenerator = JVMConstantGenerator
+    StaticMethodConst = JVMStaticMethodConst
     
     def __init__(self, tmpdir, translator, entrypoint):
         """

Added: pypy/dist/pypy/translator/jvm/metavm.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/metavm.py	Wed Jan 10 00:31:30 2007
@@ -0,0 +1,10 @@
+from pypy.translator.oosupport.metavm import MicroInstruction
+
+
+class _IndirectCall(MicroInstruction):
+    def render(self, gen, op):
+        interface = gen.db.lltype_to_cts(op.args[0].concretetype)
+        method = interface.lookup_method('invoke')
+        gen.emit(method)
+IndirectCall = _IndirectCall()
+

Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py	(original)
+++ pypy/dist/pypy/translator/jvm/node.py	Wed Jan 10 00:31:30 2007
@@ -18,7 +18,7 @@
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.jvm.typesystem import \
      JvmClassType, jString, jStringArray, jVoid, jThrowable, jInt, jPyPyMain, \
-     jObject
+     jObject, JvmType
 from pypy.translator.jvm.opcodes import opcodes
 from pypy.translator.jvm.option import getoption
 from pypy.translator.oosupport.function import Function as OOFunction
@@ -175,6 +175,7 @@
 
         # Determine return type
         jrettype = lltype_to_cts(self.graph.getreturnvar().concretetype)
+
         self.ilasm.begin_function(
             self.name, jargvars, jargtypes, jrettype, static=not self.is_method)
 
@@ -233,6 +234,92 @@
             
         OOFunction._render_op(self, op)
 
+class StaticMethodInterface(Node, JvmClassType):
+    """
+    We generate an abstract base class when we need function pointers,
+    which correspond to constants of StaticMethod ootype.  We need a
+    different interface for each different set of argument/return
+    types. These abstract base classes look like:
+
+    abstract class Foo {
+      public abstract ReturnType invoke(Arg1, Arg2, ...);
+    }
+    
+    """
+    def __init__(self, name, STATIC_METHOD, jargtypes, jrettype):
+        """
+        argtypes: list of JvmTypes
+        rettype: JvmType
+        """
+        JvmClassType.__init__(self, name)
+        self.STATIC_METHOD = STATIC_METHOD
+        assert isinstance(jrettype, JvmType)
+        self.java_argument_types = [self] + list(jargtypes)
+        self.java_return_type = jrettype
+        self.dump_method = ConstantStringDumpMethod(
+            self, "StaticMethodInterface")
+        
+    def lookup_field(self, fieldnm):
+        """ Given a field name, returns a jvmgen.Field object """
+        raise KeyError(fieldnm) # no fields
+    def lookup_method(self, methodnm):
+        """ Given the method name, returns a jvmgen.Method object """
+        assert isinstance(self.java_return_type, JvmType)
+        if methodnm == 'invoke':
+            return jvmgen.Method.v(
+                self, 'invoke',
+                self.java_argument_types[1:], self.java_return_type)
+        raise KeyError(methodnm) # only one method
+    def render(self, gen):
+        assert isinstance(self.java_return_type, JvmType)
+        gen.begin_class(self, jObject, abstract=True)
+        gen.begin_constructor()
+        gen.end_constructor()
+        gen.begin_function('invoke', [], self.java_argument_types,
+                           self.java_return_type, abstract=True)
+        gen.end_function()
+        gen.end_class()
+
+class StaticMethodImplementation(Node, JvmClassType):
+    """
+    In addition to the StaticMethodInterface, we must generate an
+    implementation for each specific method that is called.  These
+    implementation objects look like:
+
+    class Bar extends Foo {
+        public ReturnType invoke(Arg1, Arg2) {
+          return SomeStaticClass.StaticMethod(Arg1, Arg2);
+        }
+    }
+    """
+    def __init__(self, name, interface, impl_method):
+        JvmClassType.__init__(self, name)        
+        self.super_class = interface
+        self.impl_method = impl_method
+        self.dump_method = ConstantStringDumpMethod(
+            self, "StaticMethodImplementation")
+    def lookup_field(self, fieldnm):
+        """ Given a field name, returns a jvmgen.Field object """
+        return self.super_class.lookup_field(fieldnm)
+    def lookup_method(self, methodnm):
+        """ Given the method name, returns a jvmgen.Method object """
+        return self.super_class.lookup_method(methodnm)
+    def render(self, gen):
+        gen.begin_class(self, self.super_class)
+        gen.begin_constructor()
+        gen.end_constructor()
+        gen.begin_function('invoke', [],
+                           self.super_class.java_argument_types,
+                           self.super_class.java_return_type)
+        for i in range(len(self.super_class.java_argument_types)):
+            if not i: continue # skip the this ptr
+            gen.load_function_argument(i)
+        gen.emit(self.impl_method)
+        if self.super_class.java_return_type is not jVoid:
+            gen.return_val(self.super_class.java_return_type)
+        gen.end_function()
+        gen.end_class()
+
 class Class(Node, JvmClassType):
 
     """ Represents a class to be emitted.  Note that currently, classes
@@ -321,7 +408,7 @@
         
         gen.end_class()
 
-class TestDumpMethod(object):
+class BaseDumpMethod(object):
 
     def __init__(self, db, OOCLASS, clsobj):
         self.db = db
@@ -336,9 +423,21 @@
         return jvmgen.Method.v(
             self.clsobj, self.name, self.jargtypes[1:], self.jrettype)
 
-    def render(self, gen):
-        clsobj = self.clsobj
+    def _increase_indent(self, gen):
+        gen.load_jvm_var(jInt, 1)
+        gen.emit(jvmgen.ICONST, 2)
+        gen.emit(jvmgen.IADD)
+        gen.store_jvm_var(jInt, 1)
+
+    def _print_field_value(self, gen, fieldnm, FIELDOOTY):
+        gen.load_this_ptr()
+        fieldobj = self.clsobj.lookup_field(fieldnm)
+        fieldobj.load(gen)
+        gen.load_jvm_var(jInt, 1)
+        dumpmethod = self.db.generate_dump_method_for_ootype(FIELDOOTY)
+        gen.emit(dumpmethod)        
 
+    def render(self, gen):
         gen.begin_function(
             self.name, (), self.jargtypes, self.jrettype, static=False)
 
@@ -350,39 +449,70 @@
             gen.load_string(str)
             jvmgen.PYPYDUMPINDENTED.invoke(gen)
 
+        self._render_guts(gen, genprint)
+
+        gen.emit(jvmgen.RETURN.for_type(jVoid))
+        gen.end_function()
+
+class InstanceDumpMethod(BaseDumpMethod):
+
+    def _render_guts(self, gen, genprint):
+        clsobj = self.clsobj
+
         # Start the dump
         genprint("InstanceWrapper([")
 
         # Increment the indent
-        gen.load_jvm_var(jInt, 1)
-        gen.emit(jvmgen.ICONST, 2)
-        gen.emit(jvmgen.IADD)
-        gen.store_jvm_var(jInt, 1)
+        self._increase_indent(gen)
 
         for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
 
             if FIELDOOTY is ootype.Void: continue
 
             genprint("(")
-            genprint(fieldnm+",")
+            genprint('"'+fieldnm+'",')
 
             print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
 
             # Print the value of the field:
-            gen.load_this_ptr()
-            fieldobj = clsobj.lookup_field(fieldnm)
-            fieldobj.load(gen)
-            gen.load_jvm_var(jInt, 1)
-            dumpmethod = self.db.generate_dump_method_for_ootype(FIELDOOTY)
-            gen.emit(dumpmethod)
+            self._print_field_value(gen, fieldnm, FIELDOOTY)
 
             genprint(")")
 
         # Decrement indent and dump close
         genprint("])", 2)
+        
+class RecordDumpMethod(BaseDumpMethod):
 
-        gen.emit(jvmgen.RETURN.for_type(jVoid))
+    def _render_guts(self, gen, genprint):
+        clsobj = self.clsobj
 
-        gen.end_function()
-        
-        
+        # Start the dump
+        genprint("StructTuple((")
+
+        # Increment the indent
+        self._increase_indent(gen)
+
+        numfields = len(self.OOCLASS._fields)
+        for i in range(numfields):
+            f_name = 'item%d' % i
+            FIELD_TYPE, f_default = self.OOCLASS._fields[f_name]
+            if FIELD_TYPE is ootype.Void:
+                continue
+
+            # Print the value of the field:
+            self._print_field_value(gen, f_name, FIELD_TYPE)
+            genprint(',')
+
+        # Decrement indent and dump close
+        genprint("))", 2)
+
+class ConstantStringDumpMethod(BaseDumpMethod):
+    """ Just prints out a string """
+
+    def __init__(self, clsobj, str):
+        BaseDumpMethod.__init__(self, None, None, clsobj)
+        self.constant_string = str
+
+    def _render_guts(self, gen, genprint):
+        genprint("'" + self.constant_string + "'")

Modified: pypy/dist/pypy/translator/jvm/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/opcodes.py	(original)
+++ pypy/dist/pypy/translator/jvm/opcodes.py	Wed Jan 10 00:31:30 2007
@@ -7,7 +7,9 @@
 
 from pypy.translator.oosupport.metavm import \
      PushArg, PushAllArgs, StoreResult, InstructionList, New, DoNothing, Call,\
-     SetField, GetField, CallMethod, DownCast, RuntimeNew, OOString
+     SetField, GetField, CallMethod, DownCast, RuntimeNew, OOString, CastTo
+from pypy.translator.jvm.metavm import \
+     IndirectCall
 import pypy.translator.jvm.generator as jvmgen
 
 def _check_zer(op):
@@ -29,12 +31,12 @@
     'oosend':                   [CallMethod, StoreResult],
     'ooupcast':                 DoNothing,
     'oodowncast':               [DownCast, StoreResult],
-    'oois':                     'is_null',
+    'oois':                     'ref_is_eq',
     'oononnull':                'is_not_null',
-    #'instanceof':               [CastTo, 'ldnull', 'cgt.un'],
-    #'subclassof':               [PushAllArgs, 'call bool [pypylib]pypy.runtime.Utils::SubclassOf(class [mscorlib]System.Type, class[mscorlib]System.Type)'],
-    #'ooidentityhash':           [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'],
-    #'oohash':                   [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'],    
+    'instanceof':               CastTo,
+    'subclassof':               [PushAllArgs, jvmgen.SWAP, jvmgen.CLASSISASSIGNABLEFROM, StoreResult],
+    'ooidentityhash':           [PushAllArgs, jvmgen.OBJHASHCODE, StoreResult], 
+    'oohash':                   [PushAllArgs, jvmgen.OBJHASHCODE, StoreResult], 
     'oostring':                 [OOString, StoreResult],
     #'ooparse_int':              [PushAllArgs, 'call int32 [pypylib]pypy.runtime.Utils::OOParseInt(string, int32)'],
     #'oonewcustomdict':          [NewCustomDict],
@@ -42,7 +44,7 @@
     'same_as':                  DoNothing,
     #'hint':                     [PushArg(0), StoreResult],
     'direct_call':              [Call, StoreResult],
-    #'indirect_call':            [IndirectCall],
+    'indirect_call':            [PushAllArgs, IndirectCall, StoreResult],
     #
     #'cast_ptr_to_weakadr':      [PushAllArgs, 'newobj instance void class %s::.ctor(object)' % WEAKREF],
     #'cast_weakadr_to_ptr':      [CastWeakAdrToPtr],

Modified: pypy/dist/pypy/translator/jvm/src/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/PyPy.java	(original)
+++ pypy/dist/pypy/translator/jvm/src/PyPy.java	Wed Jan 10 00:31:30 2007
@@ -201,6 +201,10 @@
         dump_indented(indent, Integer.toString(i));
     }
 
+    public static void dump_char(char c, int indent) {
+        dump_indented(indent, "'"+c+"'");
+    }
+
     public static void dump_uint(int i, int indent) {
         if (i >= 0)
             dump_indented(indent, Integer.toString(i));

Modified: pypy/dist/pypy/translator/oosupport/constant.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/constant.py	(original)
+++ pypy/dist/pypy/translator/oosupport/constant.py	Wed Jan 10 00:31:30 2007
@@ -367,8 +367,7 @@
         If you overload this, overload is_inline() too.
         """
         assert self.is_inline() and self.is_null()
-        return gen.push_null(EXPECTED_TYPE)
-        
+        return gen.push_null(EXPECTED_TYPE)        
 
     # ____________________________________________________________
     # Initializing the constant

Modified: pypy/dist/pypy/translator/oosupport/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/metavm.py	(original)
+++ pypy/dist/pypy/translator/oosupport/metavm.py	Wed Jan 10 00:31:30 2007
@@ -405,6 +405,12 @@
         generator.load(op.args[1])
         generator.call_oostring(ARGTYPE)
 
+class _CastTo(MicroInstruction):
+    def render(self, generator, op):
+        generator.load(op.args[0])
+        INSTANCE = op.args[1].value
+        class_name = generator.db.pending_class(INSTANCE)
+        generator.isinstance(class_name)
 
 New = _New()
 
@@ -418,3 +424,4 @@
 CallMethod = _CallMethod()
 RuntimeNew = _RuntimeNew()
 OOString = _OOString()
+CastTo = _CastTo()



More information about the Pypy-commit mailing list