[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