[pypy-svn] r50585 - pypy/branch/fixed-list-ootype/pypy/translator/jvm

atobe at codespeak.net atobe at codespeak.net
Mon Jan 14 13:10:01 CET 2008


Author: atobe
Date: Mon Jan 14 13:10:01 2008
New Revision: 50585

Modified:
   pypy/branch/fixed-list-ootype/pypy/translator/jvm/database.py
   pypy/branch/fixed-list-ootype/pypy/translator/jvm/generator.py
   pypy/branch/fixed-list-ootype/pypy/translator/jvm/opcodes.py
   pypy/branch/fixed-list-ootype/pypy/translator/jvm/typesystem.py
Log:
(cfbolz,atobe): Implementing Array in JVM backend. Several tests pass.

Modified: pypy/branch/fixed-list-ootype/pypy/translator/jvm/database.py
==============================================================================
--- pypy/branch/fixed-list-ootype/pypy/translator/jvm/database.py	(original)
+++ pypy/branch/fixed-list-ootype/pypy/translator/jvm/database.py	Mon Jan 14 13:10:01 2008
@@ -513,6 +513,8 @@
             return jObject
         if OOT in self.ootype_to_builtin:
             return JvmBuiltInType(self, self.ootype_to_builtin[OOT], OOT)
+        if isinstance(OOT, ootype.Array):
+            return self._array_type(OOT.ITEM)
         if OOT.__class__ in self.ootype_to_builtin:
             return JvmBuiltInType(
                 self, self.ootype_to_builtin[OOT.__class__], OOT)
@@ -533,6 +535,20 @@
         
         assert False, "Untranslatable type %s!" % OOT
 
+    ooitemtype_to_array = {
+        ootype.Signed   : jvmtype.jIntArray,
+        ootype.Unsigned : jvmtype.jIntArray,
+        ootype.Char     : jvmtype.jCharArray,
+        ootype.Bool     : jvmtype.jByteArray,
+        ootype.UniChar  : jvmtype.jCharArray,
+        ootype.String   : jvmtype.jStringArray,
+    }
+
+    def _array_type(self, ITEM):
+        if ITEM in self.ooitemtype_to_array:
+            return self.ooitemtype_to_array[ITEM]
+        return jvmtype.jObjectArray
+
     def annotation_to_cts(self, _tp):
         s_tp = annotation(_tp)
         TP = annotation_to_lltype(s_tp)

Modified: pypy/branch/fixed-list-ootype/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/branch/fixed-list-ootype/pypy/translator/jvm/generator.py	(original)
+++ pypy/branch/fixed-list-ootype/pypy/translator/jvm/generator.py	Mon Jan 14 13:10:01 2008
@@ -137,6 +137,32 @@
         if desc == 'Z':    return self._o("b")   # Boolean (access as bytes)
         return OpcodeFamily.for_type(self, argtype)
 
+class NewArrayOpcodeFamily(object):
+    def __init__(self):
+        self.cache = {}
+
+    def for_type(self, arraytype):
+        try:
+            return self.cache[arraytype]
+        except KeyError:
+            pass
+        desc = arraytype.descriptor
+        if desc == '[I':
+            s = "newarray int"
+        elif desc == '[D':
+            s = "newarray double"
+        elif desc == '[C':
+            s = "newarray char"
+        elif desc == '[B':
+            s = "newarray byte"
+        else:
+            s = "anewarray"
+        self.cache[arraytype] = obj = Opcode(s)
+        return obj
+
+NEWARRAY = NewArrayOpcodeFamily()
+ARRAYLENGTH = Opcode("arraylength")
+
 # Define the opcodes for IFNE, IFEQ, IFLT, IF_ICMPLT, etc.  The IFxx
 # variants compare a single integer arg against 0, and the IF_ICMPxx
 # variants compare 2 integer arguments against each other.
@@ -410,6 +436,47 @@
 PYPYWEAKREFCREATE =     Method.s(jPyPyWeakRef, 'create', (jObject,), jPyPyWeakRef)
 PYPYWEAKREFGET =        Method.s(jPyPyWeakRef, 'll_get', (), jObject)
 
+
+# special methods for arrays that are not really methods in the JVM
+# XXX slightly hackish
+class ArrayMethod(Method):
+    def __init__(self, arraytype, methodname):
+        self.arraytype = arraytype
+        self.ootype_methodname = methodname
+        Method.__init__(self, "<dummy>", "<dummy>", self._argtypes(), self._rettype(),
+                        opcode=None)
+
+    def _argtypes(self):
+        if self.ootype_methodname == "ll_length":
+            return []
+        elif self.ootype_methodname == "ll_getitem_fast":
+            return [jInt]
+        elif self.ootype_methodname == "ll_setitem_fast":
+            return [jInt, self.arraytype.element_type]
+        else:
+            assert 0, "unknown array method"
+
+    def _rettype(self):
+        if self.ootype_methodname == "ll_length":
+            return jInt
+        elif self.ootype_methodname == "ll_getitem_fast":
+            return self.arraytype.element_type
+        elif self.ootype_methodname == "ll_setitem_fast":
+            return jVoid
+        else:
+            assert 0, "unknown array method"
+
+    def invoke(self, gen):
+        if self.ootype_methodname == "ll_length":
+            gen._instr(ARRAYLENGTH)
+        elif self.ootype_methodname == "ll_getitem_fast":
+            gen._instr(ARRLOAD.for_type(self.arraytype.element_type))
+        elif self.ootype_methodname == "ll_setitem_fast":
+            gen._instr(ARRSTORE.for_type(self.arraytype.element_type))
+        else:
+            assert 0, "unknown array method"
+        
+
 # ___________________________________________________________________________
 # Fields
 #
@@ -1117,6 +1184,11 @@
         self.emit(DUP)
         self.emit(ctor)
         
+    def oonewarray(self, TYPE, length):
+        jtype = self.db.lltype_to_cts(TYPE)
+        self.load(length)
+        self.emit(NEWARRAY.for_type(jtype))
+
     def instantiate(self):
         self.emit(PYPYRUNTIMENEW)
 

Modified: pypy/branch/fixed-list-ootype/pypy/translator/jvm/opcodes.py
==============================================================================
--- pypy/branch/fixed-list-ootype/pypy/translator/jvm/opcodes.py	(original)
+++ pypy/branch/fixed-list-ootype/pypy/translator/jvm/opcodes.py	Mon Jan 14 13:10:01 2008
@@ -6,7 +6,7 @@
 """
 
 from pypy.translator.oosupport.metavm import \
-     PushArg, PushAllArgs, StoreResult, InstructionList, New, DoNothing, Call,\
+     PushArg, PushAllArgs, StoreResult, InstructionList, New, OONewArray, DoNothing, Call,\
      SetField, GetField, DownCast, RuntimeNew, OOString, OOUnicode, \
      CastTo, PushPrimitive
 from pypy.translator.jvm.metavm import \
@@ -63,6 +63,7 @@
 opcodes = _proc_dict({
     # __________ object oriented operations __________
     'new':                      [New, StoreResult],
+    'oonewarray':               [OONewArray, StoreResult],
     'runtimenew':               [RuntimeNew, StoreResult],
     'oosetfield':               [SetField],
     'oogetfield':               [GetField, StoreResult],

Modified: pypy/branch/fixed-list-ootype/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/branch/fixed-list-ootype/pypy/translator/jvm/typesystem.py	(original)
+++ pypy/branch/fixed-list-ootype/pypy/translator/jvm/typesystem.py	Mon Jan 14 13:10:01 2008
@@ -232,12 +232,17 @@
         self.element_type = elemtype
     def lookup_field(self, fieldnm):
         raise KeyError(fieldnm)  # TODO adjust interface to permit opcode here
-    def lookup_method(self, methodnm): 
-        raise KeyError(methodnm) # Arrays have no methods
-    
+    def lookup_method(self, methodnm):
+        # Arrays don't have methods in Java, but they do in the ootype system
+        from pypy.translator.jvm.generator import ArrayMethod
+        return ArrayMethod(self, methodnm)
+        
 jByteArray = JvmArrayType(jByte)
 jObjectArray = JvmArrayType(jObject)
 jStringArray = JvmArrayType(jString)
+jDoubleArray = JvmArrayType(jDouble)
+jCharArray = JvmArrayType(jChar)
+jIntArray = JvmArrayType(jInt)
 
 class Generifier(object):
 



More information about the Pypy-commit mailing list