[pypy-svn] r36528 - pypy/dist/pypy/translator/jvm

niko at codespeak.net niko at codespeak.net
Thu Jan 11 19:53:21 CET 2007


Author: niko
Date: Thu Jan 11 19:53:21 2007
New Revision: 36528

Added:
   pypy/dist/pypy/translator/jvm/methods.py
Log:
forgot to add this!

Added: pypy/dist/pypy/translator/jvm/methods.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/methods.py	Thu Jan 11 19:53:21 2007
@@ -0,0 +1,210 @@
+"""
+
+Special methods which we hand-generate, such as toString(), equals(), and hash().
+
+These are generally added to methods listing of node.Class, and the
+only requirement is that they must have a render(self, gen) method.
+
+"""
+
+import pypy.translator.jvm.generator as jvmgen
+import pypy.translator.jvm.typesystem as jvmtype
+from pypy.rpython.ootypesystem import ootype, rclass
+
+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 = jvmtype.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.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(jvmtype.jStringBuilder)
+        self._render_guts(gen)
+        gen.emit(jvmgen.OBJTOSTRING)
+        gen.emit(jvmgen.RETURN.for_type(jvmtype.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(")
+        genprint("'" + self.clsobj.name + "', ")
+        genprint("(")
+
+        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 + "'")
+
+class DeepEqualsMethod(object):
+
+    def __init__(self, db, OOCLASS, clsobj):
+        self.db = db
+        self.OOCLASS = OOCLASS
+        self.clsobj = clsobj
+        self.name = "equals"
+        self.jargtypes = [clsobj, jvmtype.jObject]
+        self.jrettype = jvmtype.jBool
+
+    def render(self, gen):
+        self.gen = gen
+        gen.begin_function(
+            self.name, (), self.jargtypes, self.jrettype, static=False)
+
+        # Label to branch to should the items prove to be unequal
+        unequal_lbl = gen.unique_label('unequal')
+
+        gen.add_comment('check that the argument is of the correct type')
+        gen.load_jvm_var(self.clsobj, 1)
+        gen.instanceof(self.OOCLASS)
+        gen.goto_if_false(unequal_lbl)
+
+        gen.add_comment('Cast it to the right type:')
+        gen.load_jvm_var(self.clsobj, 1)
+        gen.downcast(self.OOCLASS)
+        gen.store_jvm_var(self.clsobj, 1)
+        
+        # If so, compare field by field
+        for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
+            if FIELDOOTY is ootype.Void: continue
+            fieldobj = self.clsobj.lookup_field(fieldnm)
+
+            gen.add_comment('Compare field %s of type %s' % (fieldnm, FIELDOOTY))
+
+            # Load the field from both this and the argument:
+            gen.load_jvm_var(self.clsobj, 0)
+            gen.emit(fieldobj)
+            gen.load_jvm_var(self.clsobj, 1)
+            gen.emit(fieldobj)
+
+            # And compare them:
+            gen.compare_values(FIELDOOTY, unequal_lbl)
+
+        # Return true or false as appropriate
+        gen.push_primitive_constant(ootype.Bool, True)
+        gen.return_val(jvmtype.jBool)
+        gen.mark(unequal_lbl)
+        gen.push_primitive_constant(ootype.Bool, False)
+        gen.return_val(jvmtype.jBool)
+
+        gen.end_function()
+
+class DeepHashMethod(object):
+
+    def __init__(self, db, OOCLASS, clsobj):
+        self.db = db
+        self.OOCLASS = OOCLASS
+        self.clsobj = clsobj
+        self.name = "hashCode"
+        self.jargtypes = [clsobj]
+        self.jrettype = jvmtype.jInt
+
+    def render(self, gen):
+        self.gen = gen
+        gen.begin_function(
+            self.name, (), self.jargtypes, self.jrettype, static=False)
+
+        # Initial hash: 0
+        gen.push_primitive_constant(ootype.Signed, 0)
+
+        # Get hash of each field
+        for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
+            if FIELDOOTY is ootype.Void: continue
+            fieldobj = self.clsobj.lookup_field(fieldnm)
+
+            gen.add_comment('Hash field %s of type %s' % (fieldnm, FIELDOOTY))
+
+            # Load the field and hash it:
+            gen.load_jvm_var(self.clsobj, 0)
+            gen.emit(fieldobj)
+            gen.hash_value(FIELDOOTY)
+
+            # XOR that with the main hash
+            gen.emit(jvmgen.IXOR)
+
+        # Return the final hash
+        gen.return_val(jvmtype.jInt)
+
+        gen.end_function()
+



More information about the Pypy-commit mailing list