[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