[pypy-svn] r34051 - in pypy/dist/pypy/translator/jvm: . src

niko at codespeak.net niko at codespeak.net
Thu Nov 2 00:23:26 CET 2006


Author: niko
Date: Thu Nov  2 00:23:25 2006
New Revision: 34051

Modified:
   pypy/dist/pypy/translator/jvm/conftest.py
   pypy/dist/pypy/translator/jvm/database.py
   pypy/dist/pypy/translator/jvm/generator.py
   pypy/dist/pypy/translator/jvm/option.py
   pypy/dist/pypy/translator/jvm/src/PyPy.java
   pypy/dist/pypy/translator/jvm/typesystem.py
Log:
Because I can't seem to sleep...

1. Add an option to choose between native strings and byte arrays
2. Add ability to rename built-in methods like ll_append_char etc,
   so that string builders work.  As a result, so does test_bool
   



Modified: pypy/dist/pypy/translator/jvm/conftest.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/conftest.py	(original)
+++ pypy/dist/pypy/translator/jvm/conftest.py	Thu Nov  2 00:23:25 2006
@@ -16,5 +16,7 @@
     Option('--package', action='store', dest='package', default='pypy',
            help='Package to output generated classes into'),
     Option('--trace', action='store_true', dest='trace', default=False,
-           help='Trace execution of generated code')
+           help='Trace execution of generated code'),
+    Option('--byte-arrays', action='store_true', dest='byte-arrays',
+           default=False, help='Use byte arrays rather than native strings'),
     )

Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py	(original)
+++ pypy/dist/pypy/translator/jvm/database.py	Thu Nov  2 00:23:25 2006
@@ -10,7 +10,40 @@
 from pypy.translator.jvm import node
 from pypy.translator.jvm.option import getoption
 import pypy.translator.jvm.generator as jvmgen
-import pypy.translator.jvm.typesystem as jvmtypes
+from pypy.translator.jvm.typesystem import \
+     jStringBuilder, jInt, jVoid, jString, jOOString, jChar
+
+# When we lookup a method on a  BuiltInClassNode, we first check
+# the 'built_in_methods' table.  This allows us to redirect to other
+# methods if we like.
+
+def _ll_build_method():
+    # Choose an appropriate ll_build depending on what representation
+    # we are using for ootype.String:
+    if jOOString == jString:
+        return jvmgen.Method.v(
+            jStringBuilder.class_name(), "toString", (),jString)
+    return jvmgen.Method.s(
+        jvmgen.PYPYJAVA, "ll_build", (jStringBuilder,), jOOString)
+
+built_in_methods = {
+    (ootype.StringBuilder.__class__, "ll_allocate"):
+    jvmgen.Method.v(jStringBuilder.class_name(), "ensureCapacity",
+                    (jInt,), jVoid),
+    
+    (ootype.StringBuilder.__class__, "ll_append_char"):
+    jvmgen.Method.s(jvmgen.PYPYJAVA, "ll_append_char",
+                    (jStringBuilder, jChar), jVoid),
+    
+    (ootype.StringBuilder.__class__, "ll_append"):
+    jvmgen.Method.s(jvmgen.PYPYJAVA, "ll_append",
+                    (jStringBuilder, jOOString), jVoid),
+
+    # XXX will not work with --byte-arrays
+    (ootype.StringBuilder.__class__, "ll_build"):
+    _ll_build_method()
+    
+    }
 
 class BuiltInClassNode(object):
 
@@ -58,6 +91,14 @@
     def lookup_method(self, methodnm):
         """ Given the method name, returns a jvmgen.Method object """
 
+        # Look for a shortcut method
+        try:
+            key = (self.OOTYPE.__class__, methodnm)
+            print "key=%r" % (key,)
+            print "hash=%r" % (built_in_methods,)
+            return built_in_methods[key]
+        except KeyError: pass
+
         # Lookup the generic method by name.
         GENMETH = self.OOTYPE._GENERIC_METHODS[methodnm]
 

Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py	(original)
+++ pypy/dist/pypy/translator/jvm/generator.py	Thu Nov  2 00:23:25 2006
@@ -3,10 +3,15 @@
 from pypy.translator.oosupport.metavm import Generator
 from pypy.translator.jvm.typesystem import \
      JvmType, jObject, jPrintStream, jvm_for_class, jVoid, jvm_method_desc, \
-     jInt, jByteArray
+     jInt, jByteArray, jOOString, jString, jStringBuilder
 from pypy.rpython.ootypesystem import ootype
 
 # ___________________________________________________________________________
+# Helper class string constants
+
+PYPYJAVA = "pypy.PyPy"
+
+# ___________________________________________________________________________
 # JVM Opcode Flags:
 #
 #   Indicates certain properties of each opcode.  Used mainly for debugging
@@ -221,6 +226,16 @@
 # methobj is its Method instance.
 
 class Method(object):
+    
+    def v(classnm, methnm, argtypes, rettype):
+        return Method(classnm, methnm, jvm_method_desc(argtypes, rettype),
+                      opcode=INVOKEVIRTUAL)
+    v = staticmethod(v)
+    
+    def s(classnm, methnm, argtypes, rettype):
+        return Method(classnm, methnm, jvm_method_desc(argtypes, rettype))
+    s = staticmethod(s)
+    
     def __init__(self, classnm, methnm, desc, opcode=INVOKESTATIC):
         self.opcode = opcode
         self.class_name = classnm  # String, ie. "java.lang.Math"
@@ -239,39 +254,42 @@
 MATHFLOOR =             Method('java.lang.Math', 'floor', '(D)D')
 PRINTSTREAMPRINTSTR =   Method('java.io.PrintStream', 'print',
                                '(Ljava/lang/String;)V', opcode=INVOKEVIRTUAL)
-PYPYUINTCMP =           Method('pypy.PyPy', 'uint_cmp', '(II)I')
-PYPYULONGCMP =          Method('pypy.PyPy', 'ulong', '(LL)I')
-PYPYUINTTODOUBLE =      Method('pypy.PyPy', 'uint_to_double', '(I)D')
-PYPYDOUBLETOUINT =      Method('pypy.PyPy', 'double_to_uint', '(D)I')
-PYPYLONGBITWISENEGATE = Method('pypy.PyPy', 'long_bitwise_negate', '(L)L')
-PYPYARRAYTOLIST =       Method('pypy.PyPy', 'array_to_list',
+PYPYUINTCMP =           Method(PYPYJAVA, 'uint_cmp', '(II)I')
+PYPYULONGCMP =          Method(PYPYJAVA, 'ulong', '(LL)I')
+PYPYUINTTODOUBLE =      Method(PYPYJAVA, 'uint_to_double', '(I)D')
+PYPYDOUBLETOUINT =      Method(PYPYJAVA, 'double_to_uint', '(D)I')
+PYPYLONGBITWISENEGATE = Method(PYPYJAVA, 'long_bitwise_negate', '(L)L')
+PYPYARRAYTOLIST =       Method(PYPYJAVA, 'array_to_list',
                                '([Ljava/lang/Object;)Ljava/util/List;')
-PYPYSTRTOINT =          Method('pypy.PyPy', 'str_to_int',
+PYPYSTRTOINT =          Method(PYPYJAVA, 'str_to_int',
                                '(Ljava/lang/String;)I')
-PYPYSTRTOUINT =         Method('pypy.PyPy', 'str_to_uint',
+PYPYSTRTOUINT =         Method(PYPYJAVA, 'str_to_uint',
                                '(Ljava/lang/String;)I')
-PYPYSTRTOLONG =         Method('pypy.PyPy', 'str_to_long',
+PYPYSTRTOLONG =         Method(PYPYJAVA, 'str_to_long',
                                '(Ljava/lang/String;)J')
-PYPYSTRTOULONG =        Method('pypy.PyPy', 'str_to_ulong',
+PYPYSTRTOULONG =        Method(PYPYJAVA, 'str_to_ulong',
                                '(Ljava/lang/String;)J')
-PYPYSTRTOBOOL =         Method('pypy.PyPy', 'str_to_bool',
+PYPYSTRTOBOOL =         Method(PYPYJAVA, 'str_to_bool',
                                '(Ljava/lang/String;)Z')
-PYPYSTRTODOUBLE =       Method('pypy.PyPy', 'str_to_double',
+PYPYSTRTODOUBLE =       Method(PYPYJAVA, 'str_to_double',
                                '(Ljava/lang/String;)D')
-PYPYSTRTOCHAR =         Method('pypy.PyPy', 'str_to_char',
+PYPYSTRTOCHAR =         Method(PYPYJAVA, 'str_to_char',
                                '(Ljava/lang/String;)C')
-PYPYDUMPINDENTED  =     Method('pypy.PyPy', 'dump_indented',
+PYPYDUMPINDENTED  =     Method(PYPYJAVA, 'dump_indented',
                                  '(ILjava/lang/String;)V')
-PYPYDUMPINT  =          Method('pypy.PyPy', 'dump_int', '(II)V')
-PYPYDUMPUINT  =         Method('pypy.PyPy', 'dump_uint', '(II)V')
-PYPYDUMPLONG  =         Method('pypy.PyPy', 'dump_long', '(LI)V')
-PYPYDUMPDOUBLE  =       Method('pypy.PyPy', 'dump_double', '(DI)V')
-PYPYDUMPSTRING  =       Method('pypy.PyPy', 'dump_string', '([BI)V')
-PYPYDUMPBOOLEAN =       Method('pypy.PyPy', 'dump_boolean', '(ZI)V')
-PYPYDUMPOBJECT =        Method('pypy.PyPy', 'dump_object',
+PYPYDUMPINT  =          Method(PYPYJAVA, 'dump_int', '(II)V')
+PYPYDUMPUINT  =         Method(PYPYJAVA, 'dump_uint', '(II)V')
+PYPYDUMPLONG  =         Method(PYPYJAVA, 'dump_long', '(LI)V')
+PYPYDUMPDOUBLE  =       Method(PYPYJAVA, 'dump_double', '(DI)V')
+PYPYDUMPSTRING  =       Method(PYPYJAVA, 'dump_string',
+                               jvm_method_desc((jOOString,jInt),jVoid))
+PYPYDUMPBOOLEAN =       Method(PYPYJAVA, 'dump_boolean', '(ZI)V')
+PYPYDUMPOBJECT =        Method(PYPYJAVA, 'dump_object',
                                '(Ljava/lang/Object;I)V')
-PYPYRUNTIMENEW =        Method('pypy.PyPy', 'RuntimeNew',
+PYPYRUNTIMENEW =        Method(PYPYJAVA, 'RuntimeNew',
                                '(Ljava/lang/Class;)Ljava/lang/Object;')
+PYPYSTRING2BYTES =      Method(PYPYJAVA, 'string2bytes',
+                               jvm_method_desc((jString),jByteArray))
 
 
 # ___________________________________________________________________________
@@ -798,8 +816,14 @@
 
     def call_oostring(self, OOTYPE):
         cts_type = self.db.lltype_to_cts(OOTYPE)
-        mthd = Method('pypy.PyPy', 'oostring', jvm_method_desc([cts_type, jInt], jByteArray))
-        self.emit(mthd)
+        if cts_type != jByteArray:
+            mthd = Method.s(PYPYJAVA, 'oostring', [cts_type, jInt], jString)
+            self.emit(mthd)
+            if jOOString == jByteArray:
+                self.emit(PYPYSTRING2BYTES)
+        else:
+            mthd = Method.s(PYPYJAVA, 'oostring',
+                            [jByteArray, jInt], jByteArray)
         
     def new(self, TYPE):
         jtype = self.db.lltype_to_cts(TYPE)

Modified: pypy/dist/pypy/translator/jvm/option.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/option.py	(original)
+++ pypy/dist/pypy/translator/jvm/option.py	Thu Nov  2 00:23:25 2006
@@ -9,7 +9,8 @@
     'package':'pypy',
     'wd':False,
     'norun':False,
-    'trace':False
+    'trace':False,
+    'byte-arrays':False
     }
 
 def getoption(name):

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	Thu Nov  2 00:23:25 2006
@@ -5,6 +5,10 @@
 
 /**
  * Class with a number of utility routines.
+ * 
+ * I apologize for the Python-esque naming conventions, but it seems
+ * I can't switch my mind to camelCase when working so closely with 
+ * Python mere minutes before.
  */
 public class PyPy {
     /** 
@@ -220,15 +224,30 @@
         dump_indented(indent, Double.toString(d));
     }
 
+    public static void _append_char(StringBuffer sb, char c) {
+        if (c == '"') 
+            sb.append("\\\"");
+        else
+            sb.append(c);
+    }
+
     public static void dump_string(byte[] b, int indent) {
         StringBuffer sb = new StringBuffer();
         sb.append('"');
         for (byte _c : b) {
             char c = (char)_c;
-            if (c == '"') 
-                sb.append("\\\"");
-            else
-                sb.append(c);
+            _append_char(sb, c);
+        }
+        sb.append('"');
+        dump_indented(indent, sb.toString());
+    }
+
+    public static void dump_string(String b, int indent) {
+        StringBuffer sb = new StringBuffer();
+        sb.append('"');
+        for (int i = 0; i < b.length(); i++) {
+            char c = b.charAt(i);
+            _append_char(sb, c);
         }
         sb.append('"');
         dump_indented(indent, sb.toString());
@@ -239,6 +258,37 @@
     }
 
     // ----------------------------------------------------------------------
+    // StringBuffer
+
+    public static void ll_append_char(StringBuilder sb, char c) {
+        // annoyingly, the actual return code is StringBuilder, so I have
+        // to make this wrapper to ignore the return value
+        sb.append(c);
+    }
+
+    public static void ll_append(StringBuilder sb, String s) {
+        // annoyingly, the actual return code is StringBuilder, so I have
+        // to make this wrapper to ignore the return value
+        sb.append(s);
+    }
+
+    public static void ll_append(StringBuilder sb, byte[] s) {
+        // This is only used when we are using byte arrays instead of
+        // strings.  We should really replace StringBuilder with some
+        // kind of ByteBuilder in that case...
+        for (byte b : s) {
+            sb.append((char)b);
+        }
+    }
+
+    public static byte[] ll_build(StringBuilder sb) {
+        // This is only used when we are using byte arrays instead of
+        // strings.  We should really replace StringBuilder with some
+        // kind of ByteBuilder in that case...
+        return string2bytes(sb.toString());
+    }
+
+    // ----------------------------------------------------------------------
     // Type Manipulation Routines
 
     public static Object RuntimeNew(Class c) {
@@ -260,28 +310,28 @@
     // ----------------------------------------------------------------------
     // OOString support
     
-    public static byte[] oostring(int n, int base_) {
+    public static String oostring(int n, int base_) {
     	// XXX needs special case for unsigned ints
         if (base_ == -1)
             base_ = 10;
         if (n < 0 && base_ != 10)
-            return string2bytes("-" + Integer.toString(-n, base_));
+            return "-" + Integer.toString(-n, base_);
         else
-            return string2bytes(Integer.toString(n, base_));
+            return Integer.toString(n, base_);
     }
 
-    public static byte[] oostring(double d, int base_) {
-        return string2bytes(new Double(d).toString());
+    public static String oostring(double d, int base_) {
+        return new Double(d).toString();
     }
 
-    public static byte[] oostring(Object obj, int base_)
+    public static String oostring(Object obj, int base_)
     {
-        return string2bytes(String.format("<%s object>", new Object[] { obj.getClass().getName() }));
+        return String.format("<%s object>", new Object[] { obj.getClass().getName() });
     }
 
-    public static byte[] oostring(char ch, int base_)
+    public static String oostring(char ch, int base_)
     {
-        return string2bytes(new Character(ch).toString());
+        return new Character(ch).toString();
     }
 
     public static byte[] oostring(byte[] s, int base_)
@@ -289,14 +339,15 @@
         return s;
     }
 
-    public static final byte[] trueString = new byte[] {
-        (byte)'T', (byte)'r', (byte)'u', (byte)'e' };
-    public static final byte[] falseString = new byte[] {
-        (byte)'F', (byte)'a', (byte)'l', (byte)'s', (byte)'e' };
-    public static byte[] oostring(boolean b, int base_)
+    public static String oostring(String s, int base_)
+    {
+        return s;
+    }
+
+    public static String oostring(boolean b, int base_)
     {
-        if (b) return trueString;
-        return falseString;
+        if (b) return "True";
+        return "False";
     }
 
     // ----------------------------------------------------------------------

Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py	(original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py	Thu Nov  2 00:23:25 2006
@@ -111,7 +111,7 @@
     ootype.Float:            jDouble,
     ootype.Char:             jByte,
     ootype.UniChar:          jChar,
-    ootype.String:           jByteArray,
+    ootype.String:           jString,
     ootype.ROOT:             jObject,
 
     # We may want to use PyPy wrappers here later:
@@ -123,6 +123,11 @@
     ootype.DictItemsIterator:jIterator
     }
 
+# Determine which class we will use to represent strings:
+if getoption('byte-arrays'):
+    ootype_to_jvm[ootype.String] = jByteArray
+jOOString = ootype_to_jvm[ootype.String]
+
 # Method descriptor construction
 def jvm_method_desc(argtypes, rettype):
     """ A Java method has a descriptor, which is a string specified


More information about the pypy-svn mailing list