[pypy-svn] r36527 - in pypy/dist/pypy/translator/jvm: . test

niko at codespeak.net niko at codespeak.net
Thu Jan 11 19:50:15 CET 2007


Author: niko
Date: Thu Jan 11 19:50:14 2007
New Revision: 36527

Modified:
   pypy/dist/pypy/translator/jvm/database.py
   pypy/dist/pypy/translator/jvm/generator.py
   pypy/dist/pypy/translator/jvm/node.py
   pypy/dist/pypy/translator/jvm/test/runtest.py
   pypy/dist/pypy/translator/jvm/test/test_dict.py
Log:
(antocuni, niko)

various fixes: we now support test_dict almost in its
entirety



Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py	(original)
+++ pypy/dist/pypy/translator/jvm/database.py	Thu Jan 11 19:50:14 2007
@@ -7,7 +7,7 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.ootypesystem import ootype
 from pypy.translator.jvm import typesystem as jvmtype
-from pypy.translator.jvm import node
+from pypy.translator.jvm import node, methods
 from pypy.translator.jvm.option import getoption
 import pypy.translator.jvm.generator as jvmgen
 import pypy.translator.jvm.constant as jvmconst
@@ -110,10 +110,15 @@
         # 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)
+        # generate toString
+        dump_method = methods.RecordDumpMethod(self, OOTYPE, clsobj)
+        clsobj.add_method(dump_method)
+
+        # generate equals and hash
+        equals_method = methods.DeepEqualsMethod(self, OOTYPE, clsobj)
+        clsobj.add_method(equals_method)
+        hash_method = methods.DeepHashMethod(self, OOTYPE, clsobj)
+        clsobj.add_method(hash_method)
 
         self.pending_node(clsobj)
         return clsobj
@@ -169,7 +174,7 @@
         # currently, we always include a special "dump" method for debugging
         # purposes
         dump_method = node.InstanceDumpMethod(self, OOTYPE, clsobj)
-        clsobj.add_dump_method(dump_method)
+        clsobj.add_method(dump_method)
 
         self.pending_node(clsobj)
         return clsobj
@@ -236,10 +241,10 @@
         return n
 
     # _________________________________________________________________
-    # Type printing functions
+    # toString functions
     #
-    # Returns a method that prints details about the value out to
-    # stdout.  Should generalize to make it allow for stderr as well.
+    # Obtains an appropriate method for serializing an object of
+    # any type.
     
     _toString_methods = {
         ootype.Signed:jvmgen.INTTOSTRINGI,
@@ -252,7 +257,7 @@
         ootype.String:jvmgen.PYPYESCAPEDSTRING,
         }
 
-    def generate_toString_method_for_ootype(self, OOTYPE):
+    def toString_method_for_ootype(self, OOTYPE):
         """
         Assuming than an instance of type OOTYPE is pushed on the
         stack, returns a Method object that you can invoke.  This method
@@ -261,7 +266,7 @@
         Do something like:
         
         > gen.load(var)
-        > mthd = db.generate_toString_method_for_ootype(var.concretetype)
+        > mthd = db.toString_method_for_ootype(var.concretetype)
         > mthd.invoke(gen)
 
         to print the value of 'var'.

Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py	(original)
+++ pypy/dist/pypy/translator/jvm/generator.py	Thu Jan 11 19:50:14 2007
@@ -181,6 +181,7 @@
 LDC2 =      Opcode('ldc2_w')    # double-word types: doubles and longs
 GOTO =      Opcode('goto')
 ICONST =    IntConstOpcode('iconst')
+ICONST_0 =  Opcode('iconst_0')  # sometimes convenient to refer to this directly
 ACONST_NULL=Opcode('aconst_null')
 DCONST_0 =  Opcode('dconst_0')
 DCONST_1 =  Opcode('dconst_0')
@@ -203,6 +204,7 @@
 ISHL =      Opcode('ishl')
 ISHR =      Opcode('ishr')
 IUSHR =     Opcode('iushr')
+LCMP =      Opcode('lcmp')
 DCMPG =     Opcode('dcmpg')
 DCMPL =     Opcode('dcmpl')
 NOP =       Opcode('nop')
@@ -332,6 +334,7 @@
 
 OBJHASHCODE =           Method.v(jObject, 'hashCode', (), jInt)
 OBJTOSTRING =           Method.v(jObject, 'toString', (), jString)
+OBJEQUALS =             Method.v(jObject, 'equals', (jObject,), jBool)
 INTTOSTRINGI =          Method.s(jIntegerClass, 'toString', (jInt,), jString)
 LONGTOSTRINGL =         Method.s(jLongClass, 'toString', (jLong,), jString)
 DOUBLETOSTRINGD =       Method.s(jDoubleClass, 'toString', (jDouble,), jString)
@@ -756,7 +759,49 @@
         'catchlbl' --- label marking beginning of catch region
         """
         unimplemented
-        
+
+    _equals = {
+        ootype.Void:             (None,None),
+        ootype.SignedLongLong:   (LCMP,IFEQ),
+        ootype.UnsignedLongLong: (LCMP,IFEQ),
+        ootype.Float:            (DCMPG,IFEQ),
+        ootype.Signed:           (None,IF_ICMPNE),
+        ootype.Unsigned:         (None,IF_ICMPNE),
+        ootype.Bool:             (None,IF_ICMPNE),
+        ootype.Char:             (None,IF_ICMPNE),
+        ootype.UniChar:          (None,IF_ICMPNE),
+        }
+    def compare_values(self, OOTYPE, unequal_lbl):
+        """ Assumes that two instances of OOTYPE are pushed on the stack;
+        compares them and jumps to 'unequal_lbl' if they are unequal """
+        if OOTYPE in self._equals:
+            i1, i2 = self._equals[OOTYPE]
+            if i1: self.emit(i1)
+            if i2: self.emit(i2, unequal_lbl)
+            return
+        self.emit(OBJEQUALS)
+        self.emit(IFEQ, unequal_lbl)
+
+    _hash = {
+        ootype.Void:             ICONST_0,
+        ootype.SignedLongLong:   L2I,
+        ootype.UnsignedLongLong: L2I,
+        ootype.Float:            D2I,
+        ootype.Signed:           None,
+        ootype.Unsigned:         None,
+        ootype.Bool:             None,
+        ootype.Char:             None,
+        ootype.UniChar:          None,
+        }
+    def hash_value(self, OOTYPE):
+        """ Assumes that an instance of OOTYPE is pushed on the stack.
+        When finished, an int will be on the stack as a hash value. """
+        if OOTYPE in self._hash:
+            i1 = self._hash[OOTYPE]
+            if i1: self.emit(i1)
+            return
+        self.emit(OBJHASHCODE)
+
     # __________________________________________________________________
     # Generator methods and others that are invoked by MicroInstructions
     # 
@@ -991,6 +1036,10 @@
         """ Jumps if the top of stack is true """
         self._instr(IFNE, label)
 
+    def goto_if_false(self, label):
+        """ Jumps if the top of stack is false """
+        self._instr(IFEQ, label)
+
     ##### Comparison methods
     
     def _compare_op(self, cmpopcode):

Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py	(original)
+++ pypy/dist/pypy/translator/jvm/node.py	Thu Jan 11 19:50:14 2007
@@ -14,16 +14,26 @@
 """
 
 
-from pypy.objspace.flow import model as flowmodel
-from pypy.rpython.lltypesystem import lltype
-from pypy.rpython.ootypesystem import ootype, rclass
+from pypy.objspace.flow import \
+     model as flowmodel
+from pypy.rpython.lltypesystem import \
+     lltype
+from pypy.rpython.ootypesystem import \
+     ootype, rclass
 from pypy.translator.jvm.typesystem import \
      JvmClassType, jString, jStringArray, jVoid, jThrowable, jInt, jPyPyMain, \
      jObject, JvmType, jStringBuilder
-from pypy.translator.jvm.opcodes import opcodes
-from pypy.translator.jvm.option import getoption
-from pypy.translator.oosupport.function import Function as OOFunction
-from pypy.translator.oosupport.constant import push_constant
+from pypy.translator.jvm.opcodes import \
+     opcodes
+from pypy.translator.jvm.option import \
+     getoption
+from pypy.translator.jvm.methods import \
+     BaseDumpMethod, InstanceDumpMethod, RecordDumpMethod, ConstantStringDumpMethod
+from pypy.translator.oosupport.function import \
+     Function as OOFunction
+from pypy.translator.oosupport.constant import \
+     push_constant
+
 import pypy.translator.jvm.generator as jvmgen
 
 class Node(object):
@@ -114,7 +124,7 @@
         if self.print_result:
             done_printing = gen.unique_label('done_printing')
             RESOOTYPE = self.graph.getreturnvar().concretetype
-            dumpmethod = self.db.generate_toString_method_for_ootype(RESOOTYPE)
+            dumpmethod = self.db.toString_method_for_ootype(RESOOTYPE)
             gen.add_comment('Invoking dump method for result of type '
                             +str(RESOOTYPE))
             gen.emit(dumpmethod)      # generate the string
@@ -256,26 +266,58 @@
         self.generator.load_string(str)
         jvmgen.PRINTSTREAMPRINTSTR.invoke(self.generator)
 
+    def _is_printable(self, res):
+
+        if res.concretetype in (
+            ootype.Instance,
+            ootype.Signed,
+            ootype.Unsigned,
+            ootype.SignedLongLong,
+            ootype.UnsignedLongLong,
+            ootype.Bool,
+            ootype.Float,
+            ootype.Char,
+            ootype.UniChar,
+            ootype.String,
+            ootype.StringBuilder,
+            ootype.Class):
+            return True
+
+        if isinstance(res.concretetype, (
+            ootype.Instance,
+            ootype.Record,
+            ootype.List,
+            ootype.Dict,
+            ootype.DictItemsIterator)):
+            return True
+
+        return False
+
+    def _trace_value(self, prompt, res):
+        if res and self._is_printable(res):
+            jmethod = self.db.toString_method_for_ootype(
+                res.concretetype)
+            
+            self._trace("  "+prompt+": ")
+            self.generator.emit(jvmgen.SYSTEMERR)
+            self.generator.load(res)
+            self.generator.emit(jmethod)
+            self.generator.emit(jvmgen.PRINTSTREAMPRINTSTR)
+            self._trace("\n")
+
     def _render_op(self, op):
         self.generator.add_comment(str(op))
         
         if getoption('trace'):
             self._trace(str(op)+"\n")
 
+            for i, arg in enumerate(op.args):
+                self._trace_value('Arg %02d' % i, arg)
+
         OOFunction._render_op(self, op)
 
-        if (getoption('trace')
-            and op.result
-            and op.result.concretetype is not ootype.Void):
-            self._trace("  Result: ")
-            res = op.result
-            jmethod = self.db.generate_toString_method_for_ootype(
-                res.concretetype)
-            jvmgen.SYSTEMERR.load(self.generator)
-            self.generator.load(res)
-            self.generator.emit(jmethod)
-            jvmgen.PRINTSTREAMPRINTSTR.invoke(self.generator)
-            self._trace("\n")
+        if getoption('trace'):
+            self._trace_value('Result', op.result)
 
 class StaticMethodInterface(Node, JvmClassType):
     """
@@ -417,10 +459,6 @@
         self.abstract = True
         self.abstract_methods[jmethod.method_name] = jmethod
 
-    def add_dump_method(self, dm):
-        self.dump_method = dm # public attribute for reading
-        self.add_method(dm)
-        
     def render(self, gen):
         self.rendered = True
         gen.begin_class(self, self.super_class, abstract=self.abstract)
@@ -451,107 +489,3 @@
             gen.end_function()
         
         gen.end_class()
-
-class BaseDumpMethod(object):
-
-    def __init__(self, db, OOCLASS, clsobj):
-        self.db = db
-        self.OOCLASS = OOCLASS
-        self.clsobj = clsobj
-        self.name = "toString"
-        self.jargtypes = [clsobj]
-        self.jrettype = jString
-
-    def _print_field_value(self, fieldnm, FIELDOOTY):
-        self.gen.emit(jvmgen.DUP)
-        self.gen.load_this_ptr()
-        fieldobj = self.clsobj.lookup_field(fieldnm)
-        fieldobj.load(self.gen)
-        dumpmethod = self.db.generate_toString_method_for_ootype(FIELDOOTY)
-        self.gen.emit(dumpmethod)
-        self.gen.emit(jvmgen.PYPYAPPEND)
-
-    def _print(self, str):
-        self.gen.emit(jvmgen.DUP)
-        self.gen.load_string(str)
-        self.gen.emit(jvmgen.PYPYAPPEND)
-
-    def render(self, gen):
-        self.gen = gen
-        gen.begin_function(
-            self.name, (), self.jargtypes, self.jrettype, static=False)
-
-        gen.new_with_jtype(jStringBuilder)
-        self._render_guts(gen)
-        gen.emit(jvmgen.OBJTOSTRING)
-        gen.emit(jvmgen.RETURN.for_type(jString))
-        gen.end_function()
-        self.gen = None
-
-class InstanceDumpMethod(BaseDumpMethod):
-
-    def _render_guts(self, gen):
-        clsobj = self.clsobj
-        genprint = self._print
-
-        # Start the dump
-        genprint("InstanceWrapper(")
-        genprint("'" + self.OOCLASS._name + "', ")
-        genprint("{")
-
-        for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
-
-            if FIELDOOTY is ootype.Void: continue
-
-            genprint('"'+fieldnm+'":')
-
-            print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
-
-            # Print the value of the field:
-            self._print_field_value(fieldnm, FIELDOOTY)
-
-        # Dump close
-        genprint("})")
-        
-class RecordDumpMethod(BaseDumpMethod):
-
-    def _render_guts(self, gen):
-        clsobj = self.clsobj
-        genprint = self._print
-
-        # We only render records that represent tuples:
-        # In that case, the field names look like item0, item1, etc
-        # Otherwise, we just do nothing... this is because we
-        # never return records that do not represent tuples from
-        # a testing function
-        for f_name in self.OOCLASS._fields:
-            if not f_name.startswith('item'):
-                return
-
-        # Start the dump
-        genprint("StructTuple((")
-
-        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(f_name, FIELD_TYPE)
-            genprint(',')
-
-        # Decrement indent and dump close
-        genprint("))")
-
-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 = self._print
-        genprint("'" + self.constant_string + "'")

Modified: pypy/dist/pypy/translator/jvm/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/jvm/test/runtest.py	Thu Jan 11 19:50:14 2007
@@ -15,8 +15,9 @@
 
 FLOAT_PRECISION = 8
 
-# CLI duplicate
 class StructTuple(tuple):
+    def __init__(self, class_name, value):
+        tuple.__init__(self, value)
     def __getattr__(self, name):
         if name.startswith('item'):
             i = int(name[len('item'):])

Modified: pypy/dist/pypy/translator/jvm/test/test_dict.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/test_dict.py	(original)
+++ pypy/dist/pypy/translator/jvm/test/test_dict.py	Thu Jan 11 19:50:14 2007
@@ -1,8 +1,10 @@
+import py
 from pypy.translator.jvm.test.runtest import JvmTest
 import pypy.translator.oosupport.test_template.dict as oodict
 
 class TestJvmDict(JvmTest, oodict.BaseTestDict):
-    pass
+    def test_invalid_iterator(self):
+        py.test.skip("test_invalid_iterator() doesn't work yet")
 
 class TestJvmEmptyDict(JvmTest, oodict.BaseTestEmptyDict):
     pass



More information about the Pypy-commit mailing list