[pypy-svn] r36518 - in pypy/dist/pypy/translator: cli jvm jvm/src jvm/src/pypy jvm/test oosupport oosupport/test_template
niko at codespeak.net
niko at codespeak.net
Thu Jan 11 18:15:13 CET 2007
Author: niko
Date: Thu Jan 11 18:15:11 2007
New Revision: 36518
Added:
pypy/dist/pypy/translator/jvm/src/pypy/
pypy/dist/pypy/translator/jvm/src/pypy/DictItemsIterator.java
pypy/dist/pypy/translator/jvm/src/pypy/ExceptionWrapper.java
pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
pypy/dist/pypy/translator/jvm/test/test_dict.py
pypy/dist/pypy/translator/oosupport/test_template/dict.py
Removed:
pypy/dist/pypy/translator/jvm/src/ExceptionWrapper.java
pypy/dist/pypy/translator/jvm/src/PyPy.java
Modified:
pypy/dist/pypy/translator/cli/class_.py
pypy/dist/pypy/translator/cli/function.py
pypy/dist/pypy/translator/jvm/builtin.py
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/genjvm.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/test/runtest.py
pypy/dist/pypy/translator/jvm/typesystem.py
pypy/dist/pypy/translator/oosupport/constant.py
pypy/dist/pypy/translator/oosupport/genoo.py
Log:
(antocuni, niko)
fix a number of errors from test_dict
Modified: pypy/dist/pypy/translator/cli/class_.py
==============================================================================
--- pypy/dist/pypy/translator/cli/class_.py (original)
+++ pypy/dist/pypy/translator/cli/class_.py Thu Jan 11 18:15:11 2007
@@ -132,6 +132,7 @@
f_name = self.cts.escape_name(f_name)
if cts_type != 'void':
self.ilasm.opcode('ldarg.0')
+ print "%s f_default=%s" % (self.name, f_default)
push_constant(self.db, F_TYPE, f_default, self.gen)
class_name = self.db.class_name(self.INSTANCE)
self.ilasm.set_field((cts_type, class_name, f_name))
Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py (original)
+++ pypy/dist/pypy/translator/cli/function.py Thu Jan 11 18:15:11 2007
@@ -17,7 +17,7 @@
from pypy.translator.cli.support import log
from pypy.translator.cli.ilgenerator import CLIBaseGenerator
-USE_LAST = True
+USE_LAST = False
class NativeExceptionHandler(object):
def begin_try(self):
Modified: pypy/dist/pypy/translator/jvm/builtin.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/builtin.py (original)
+++ pypy/dist/pypy/translator/jvm/builtin.py Thu Jan 11 18:15:11 2007
@@ -3,7 +3,7 @@
from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm.typesystem import \
jInt, jVoid, jStringBuilder, jString, jPyPy, jChar, jArrayList, jObject, \
- jBool
+ jBool, jHashMap, jPyPyDictItemsIterator, Generifier
# ______________________________________________________________________
# Mapping of built-in OOTypes to JVM types
@@ -19,20 +19,9 @@
def __init__(self, db, classty, OOTYPE):
jvmtype.JvmClassType.__init__(self, classty.name)
self.db = db
- self.OOTYPE = OOTYPE # might be None
+ self.OOTYPE = OOTYPE
+ self.gen = Generifier(OOTYPE)
- # We need to create a mapping for any generic parameters this
- # OOTYPE may have. Other than SELFTYPE_T, we map each generic
- # argument to ootype.ROOT. We use a hack here where we assume
- # that the only generic parameters are named SELFTYPE_T,
- # ITEMTYPE_T, KEYTYPE_T, or VALUETYPE_T.
- self.generics = {}
- if hasattr(self.OOTYPE, 'SELFTYPE_T'):
- self.generics[self.OOTYPE.SELFTYPE_T] = self.OOTYPE
- for param in ('ITEMTYPE_T', 'KEYTYPE_T', 'VALUETYPE_T'):
- if hasattr(self.OOTYPE, param):
- self.generics[getattr(self.OOTYPE, param)] = ootype.ROOT
-
def __eq__(self, other):
return isinstance(other, JvmBuiltInType) and other.name == self.name
@@ -46,16 +35,10 @@
return jvmgen.Field(
self.descriptor.class_name(), fieldnm, jfieldty, False)
- def _map(self, ARG):
- """ Maps ootype ARG to a java type. If arg is one of our
- generic arguments, substitutes the appropriate type before
- performing the mapping. """
- return self.db.lltype_to_cts(self.generics.get(ARG,ARG))
-
def lookup_method(self, methodnm):
""" Given the method name, returns a jvmgen.Method object """
- # Look for a shortcut method
+ # Look for a shortcut method in our table of remappings:
try:
key = (self.OOTYPE.__class__, methodnm)
print "key=%r" % (key,)
@@ -63,20 +46,33 @@
return built_in_methods[key]
except KeyError: pass
- # Lookup the generic method by name.
- GENMETH = self.OOTYPE._GENERIC_METHODS[methodnm]
-
- # By default, we assume it is a static method on the PyPy
- # object, that takes an instance of this object as the first
- # argument. The other arguments we just convert to java versions,
- # except for generics.
- jargtypes = [self] + [self._map(P) for P in GENMETH.ARGS]
- jrettype = self._map(GENMETH.RESULT)
- return jvmgen.Method.s(jPyPy, methodnm, jargtypes, jrettype)
-
-# 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.
+ # Otherwise, determine the Method object automagically
+ # First, map the OOTYPE arguments and results to
+ # the java types they will be at runtime. Note that
+ # we must use the erased types for this.
+ ARGS, RESULT = self.gen.erased_types(methodnm)
+ jargtypes = [self.db.lltype_to_cts(P) for P in ARGS]
+ jrettype = self.db.lltype_to_cts(RESULT)
+
+ if self.OOTYPE.__class__ in bridged_objects:
+ # Bridged objects are ones where we have written a java class
+ # that has methods with the correct names and types already
+ return jvmgen.Method.v(self, methodnm, jargtypes, jrettype)
+ else:
+ # By default, we assume it is a static method on the PyPy
+ # object, that takes an instance of this object as the first
+ # argument. The other arguments we just convert to java versions,
+ # except for generics.
+ jargtypes = [self] + jargtypes
+ return jvmgen.Method.s(jPyPy, methodnm, jargtypes, jrettype)
+
+# When we lookup a method on a BuiltInClassNode, we first check the
+# 'built_in_methods' and 'bridged_objects' tables. This allows us to
+# redirect to other methods if we like.
+
+bridged_objects = (
+ ootype.DictItemsIterator,
+ )
built_in_methods = {
@@ -94,6 +90,24 @@
(ootype.String.__class__, "ll_strlen"):
jvmgen.Method.v(jString, "length", (), jInt),
+
+ (ootype.String.__class__, "ll_stritem_nonneg"):
+ jvmgen.Method.v(jString, "charAt", (jInt,), jChar),
+
+ (ootype.Dict, "ll_set"):
+ jvmgen.Method.v(jHashMap, "put", (jObject, jObject), jObject),
+
+ (ootype.Dict, "ll_get"):
+ jvmgen.Method.v(jHashMap, "get", (jObject,), jObject),
+
+ (ootype.Dict, "ll_contains"):
+ jvmgen.Method.v(jHashMap, "containsKey", (jObject,), jBool),
+
+ (ootype.Dict, "ll_length"):
+ jvmgen.Method.v(jHashMap, "size", (), jInt),
+
+ (ootype.Dict, "ll_clear"):
+ jvmgen.Method.v(jHashMap, "clear", (), jVoid),
(ootype.List, "ll_length"):
jvmgen.Method.v(jArrayList, "size", (), jInt),
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 18:15:11 2007
@@ -293,7 +293,7 @@
ootype.UnsignedLongLong: jvmtype.jLong,
ootype.Bool: jvmtype.jBool,
ootype.Float: jvmtype.jDouble,
- ootype.Char: jvmtype.jByte,
+ ootype.Char: jvmtype.jChar, # byte would be sufficient, but harder
ootype.UniChar: jvmtype.jChar,
ootype.Class: jvmtype.jClass,
ootype.ROOT: jvmtype.jObject, # count this as a scalar...
@@ -304,7 +304,9 @@
ootype_to_builtin = {
ootype.String: jvmtype.jString,
ootype.StringBuilder: jvmtype.jStringBuilder,
- ootype.List: jvmtype.jArrayList
+ ootype.List: jvmtype.jArrayList,
+ ootype.Dict: jvmtype.jHashMap,
+ ootype.DictItemsIterator:jvmtype.jPyPyDictItemsIterator,
}
def lltype_to_cts(self, OOT):
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 18:15:11 2007
@@ -851,6 +851,16 @@
mthd = clsobj.lookup_method(method_name)
mthd.invoke(self)
+ # Check if we have to convert the result type at all:
+ gener = jvmtype.Generifier(OOCLASS)
+ RETTYPE = gener.full_types(method_name)[1]
+ jrettype = self.db.lltype_to_cts(RETTYPE)
+ if jrettype != mthd.return_type:
+ # if the intended return type is not the same as the
+ # actual return type in the JVM (mthd.return_type),
+ # we have to "deal with it"
+ self.prepare_generic_result(RETTYPE)
+
def call_primitive(self, graph):
raise NotImplementedError
Modified: pypy/dist/pypy/translator/jvm/genjvm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/genjvm.py (original)
+++ pypy/dist/pypy/translator/jvm/genjvm.py Thu Jan 11 18:15:11 2007
@@ -95,17 +95,22 @@
raise JvmSubprogramError(res, args, stdout, stderr)
return stdout, stderr
- def _compile_helper(self, clsnm):
+ def _compile_helper(self, clsnms):
# HACK: compile the Java helper class. Should eventually
# use rte.py
- pypycls = self.classdir.join(clsnm + '.class')
- if not os.path.exists(str(pypycls)):
+ tocompile = []
+ for clsnm in clsnms:
+ pypycls = self.classdir.join(clsnm + '.class')
+ if not os.path.exists(str(pypycls)):
+ tocompile.append(clsnm)
+ if tocompile:
sl = __file__.rindex('/')
- javasrc = __file__[:sl]+("/src/%s.java" % clsnm)
+ javasrcs = [__file__[:sl]+("/src/pypy/%s.java" % clsnm) for
+ clsnm in tocompile]
self._invoke([getoption('javac'),
'-nowarn',
- '-d', str(self.classdir),
- javasrc],
+ '-d', str(self.classdir)]+
+ javasrcs,
True)
@@ -119,8 +124,9 @@
self._invoke(jascmd+list(self.jasmin_files), False)
self.compiled = True
- self._compile_helper('PyPy')
- self._compile_helper('ExceptionWrapper')
+ self._compile_helper(('DictItemsIterator',
+ 'PyPy',
+ 'ExceptionWrapper'))
def execute(self, args):
"""
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 18:15:11 2007
@@ -367,7 +367,7 @@
""" Represents a class to be emitted. Note that currently, classes
are emitted all in one shot, not piecemeal. """
- def __init__(self, name, supercls=None):
+ def __init__(self, name, supercls=None, initialize_fields=True):
"""
'name' should be a fully qualified Java class name like
"java.lang.String", supercls is a Class object
@@ -435,6 +435,8 @@
if field.jtype is not jVoid:
gen.load_jvm_var(self, 0) # load this ptr
# load default value of field
+ print "%s f_name=%s f_default=%s" % (
+ self.name, field.field_name, f_default)
push_constant(gen.db, field.OOTYPE, f_default, gen)
field.store(gen) # store value into field
gen.end_constructor()
@@ -495,24 +497,21 @@
# Start the dump
genprint("InstanceWrapper(")
genprint("'" + self.OOCLASS._name + "', ")
- genprint("[")
+ genprint("{")
for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
if FIELDOOTY is ootype.Void: continue
- genprint("(")
- genprint('"'+fieldnm+'",')
+ genprint('"'+fieldnm+'":')
print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
# Print the value of the field:
self._print_field_value(fieldnm, FIELDOOTY)
- genprint(")")
-
# Dump close
- genprint("])")
+ genprint("})")
class RecordDumpMethod(BaseDumpMethod):
Added: pypy/dist/pypy/translator/jvm/src/pypy/DictItemsIterator.java
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/src/pypy/DictItemsIterator.java Thu Jan 11 18:15:11 2007
@@ -0,0 +1,29 @@
+package pypy;
+
+import java.util.Map;
+import java.util.Iterator;
+
+public class DictItemsIterator
+{
+ private Iterator<Map.Entry> iterator;
+ private Map.Entry current;
+
+ public DictItemsIterator(Map map) {
+ this.iterator = map.entrySet().iterator();
+ }
+
+ public boolean ll_go_next() {
+ if (!this.iterator.hasNext())
+ return false;
+ this.current = this.iterator.next();
+ return true;
+ }
+
+ public Object ll_current_key() {
+ return this.current.getKey();
+ }
+
+ public Object ll_current_value() {
+ return this.current.getValue();
+ }
+}
\ No newline at end of file
Added: pypy/dist/pypy/translator/jvm/src/pypy/ExceptionWrapper.java
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/src/pypy/ExceptionWrapper.java Thu Jan 11 18:15:11 2007
@@ -0,0 +1,13 @@
+package pypy;
+
+public class ExceptionWrapper extends RuntimeException {
+ public final Object object;
+
+ ExceptionWrapper (Object object) {
+ this.object = object;
+ }
+
+ public static ExceptionWrapper wrap(Object object) {
+ return new ExceptionWrapper(object);
+ }
+}
\ No newline at end of file
Added: pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java Thu Jan 11 18:15:11 2007
@@ -0,0 +1,475 @@
+package pypy;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * 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 {
+ /**
+ * Compares two unsigned integers (value1 and value2) and returns
+ * a value greater than, equal to, or less than zero if value 1 is
+ * respectively greater than, equal to, or less than value2. The
+ * idea is that you can do the following:
+ *
+ * Call uint_cmp(value1, value2)
+ * IFLT ... // jumps if value1 < value2
+ * IFEQ ... // jumps if value1 == value2
+ * IFGT ... // jumps if value1 > value2
+ * etc
+ */
+ public static int uint_cmp(int value1, int value2) {
+ final int VALUE1BIGGER = 1;
+ final int VALUE2BIGGER = -1;
+ final int EQUAL = 0;
+
+ if (((value1 | value2) & Integer.MIN_VALUE) == 0) {
+ // neither is negative, presumably the common case
+ return value1 - value2;
+ }
+
+ if (value1 == value2)
+ return EQUAL;
+
+ if (value1 < 0) {
+ if (value2 < 0) {
+ // both are negative
+ if (value1 > value2)
+ // example: value1 == -1 (0xFFFF), value2 == -2 (0xFFFE)
+ return VALUE1BIGGER;
+ return VALUE2BIGGER;
+ }
+ else {
+ // value1 is neg, value 2 is not
+ return VALUE1BIGGER;
+ }
+ }
+
+ // value1 is not neg, value2 is neg
+ return VALUE2BIGGER;
+ }
+
+ public static int ulong_cmp(long value1, long value2) {
+ final int VALUE2BIGGER = -1;
+ final int VALUE1BIGGER = 1;
+ final int EQUAL = 0;
+
+ if (value1 == value2)
+ return EQUAL;
+
+ if (value1 < 0) {
+ if (value2 < 0) {
+ // both are negative
+ if (value1 > value2)
+ // example: value1 == -1 (0xFFFF), value2 == -2 (0xFFFE)
+ return VALUE1BIGGER;
+ return VALUE2BIGGER;
+ }
+ else {
+ // value1 is neg, value 2 is not
+ return VALUE1BIGGER;
+ }
+ }
+ else if (value2 < 0) {
+ // value1 is not neg, value2 is neg
+ return VALUE2BIGGER;
+ }
+
+ if (value1 > value2)
+ return VALUE1BIGGER;
+ return VALUE2BIGGER;
+ }
+
+ public static final double BITS16 = (double)0xFFFF;
+
+ public static double uint_to_double(int value) {
+ if (value >= 0)
+ return value;
+ else {
+ int loword = value & 0xFFFF;
+ double result = loword;
+ int hiword = value >>> 16;
+ result += hiword * BITS16;
+ return result;
+ }
+ }
+
+ public static int double_to_uint(double value) {
+ if (value <= Integer.MAX_VALUE)
+ return (int)value;
+
+ int loword = (int)(value % BITS16);
+ int hiword = (int)(Math.floor(value / BITS16));
+ assert (loword & 0xFFFF0000) == 0;
+ assert (hiword & 0xFFFF0000) == 0;
+ return (hiword << 16) + loword;
+ }
+
+ public static long long_bitwise_negate(long value) {
+ return ~value;
+ }
+
+ public static List<?> array_to_list(Object[] array) {
+ List l = new ArrayList();
+ for (Object o : array) {
+ l.add(o);
+ }
+ return l;
+ }
+
+ public static int str_to_int(String s) {
+ try {
+ return Integer.parseInt(s);
+ } catch (NumberFormatException fe) {
+ throw new RuntimeException(fe);
+ }
+ }
+
+ public static int str_to_uint(String s) {
+ try {
+ long l = Long.parseLong(s);
+ if (l < Integer.MAX_VALUE)
+ return (int)l;
+ int lowerword = (int)(l & 0xFFFF);
+ int upperword = (int)(l >> 16);
+ return lowerword + (upperword << 16);
+ } catch (NumberFormatException fe) {
+ throw new RuntimeException(fe);
+ }
+ }
+
+ public static long str_to_long(String s) {
+ try {
+ return Long.parseLong(s);
+ } catch (NumberFormatException fe) {
+ throw new RuntimeException(fe);
+ }
+ }
+
+ public static long str_to_ulong(String s) {
+ // oh bother
+ throw new RuntimeException("TODO--- str to ulong");
+ }
+
+ public static boolean str_to_bool(String s) {
+ // not sure what are considered valid boolean values...
+ // let's be very accepting and take both strings and numbers
+ if (s.equalsIgnoreCase("true"))
+ return true;
+ if (s.equalsIgnoreCase("false"))
+ return false;
+
+ try {
+ int i = Integer.parseInt(s);
+ return i != 0;
+ } catch (NumberFormatException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static double str_to_double(String s) {
+ try {
+ return Double.parseDouble(s);
+ } catch (NumberFormatException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static char str_to_char(String s) {
+ if (s.length() != 1)
+ throw new RuntimeException("String not single character: '"+s+"'");
+ return s.charAt(0);
+ }
+
+ // Used in testing:
+
+ public static void dump(String text) {
+ System.out.println(text);
+ }
+
+ public static String serialize_void() {
+ return "None";
+ }
+
+ public static String serialize_uint(int i) {
+ if (i >= 0)
+ return Integer.toString(i);
+ else {
+ int loword = i & 0xFFFF;
+ int hiword = i >>> 16;
+ long res = loword + (hiword*0xFFFF);
+ return Long.toString(res);
+ }
+ }
+
+ public static String serialize_boolean(boolean l) {
+ if (l)
+ return "True";
+ else
+ return "False";
+ }
+
+ public static void _append_char(StringBuffer sb, char c) {
+ if (c == '"')
+ sb.append("\\\"");
+ else
+ sb.append(c);
+ }
+
+ public static String escaped_char(char c) {
+ StringBuffer sb = new StringBuffer();
+ sb.append('"');
+ _append_char(sb, c);
+ sb.append('"');
+ return sb.toString();
+ }
+
+ public static String escaped_string(String b) {
+ if (b == null)
+ return "None";
+ 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('"');
+ return sb.toString();
+ }
+
+ // used in running unit tests
+ // not really part of the dump_XXX set of objects, hence the lack
+ // of an indent parameter
+ public static void dump_exc_wrapper(Object o) {
+ String clnm = o.getClass().getName();
+ StringBuffer sb = new StringBuffer();
+ sb.append("ExceptionWrapper(");
+ sb.append(escaped_string(clnm));
+ sb.append(")");
+ dump(sb.toString());
+ }
+
+ public static String serializeObject(Object o) {
+ if (o == null)
+ return "None";
+ return o.toString();
+ }
+
+ // ----------------------------------------------------------------------
+ // String
+
+ public static String ll_strconcat(String str1, String str2) {
+ return str1 + str2;
+ }
+
+ // ----------------------------------------------------------------------
+ // StringBuffer
+
+ public static void ll_append_char(StringBuilder sb, byte c) {
+ // annoyingly, the actual return code is StringBuilder, so I have
+ // to make this wrapper to ignore the return value
+ sb.append((char)c);
+ }
+
+ 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) {
+ // all classes in our system have constructors w/ no arguments
+ try {
+ return c.getConstructor().newInstance();
+ } catch (Exception exc) {
+ throw new RuntimeException("Unexpected", exc);
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Helpers
+
+ public static byte[] string2bytes(String s) {
+ return s.getBytes();
+ }
+
+ public static void append(StringBuilder sb, String s) {
+ // avoid the annoying return value of StringBuilder.append
+ sb.append(s);
+ }
+
+ // ----------------------------------------------------------------------
+ // OOString support
+
+ 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 "-" + Integer.toString(-n, base_);
+ else
+ return Integer.toString(n, base_);
+ }
+
+ public static String oostring(double d, int base_) {
+ return new Double(d).toString();
+ }
+
+ public static String oostring(Object obj, int base_)
+ {
+ String clnm = obj.getClass().getName();
+ int underscore = clnm.lastIndexOf('_');
+ // strip "pypy." from the start, and _NN from the end
+ clnm = clnm.substring(5, underscore);
+ return String.format("<%s object>", new Object[] { clnm });
+ }
+
+ public static String oostring(char ch, int base_)
+ {
+ return new Character(ch).toString();
+ }
+
+ public static byte[] oostring(byte[] s, int base_)
+ {
+ return s;
+ }
+
+ public static String oostring(String s, int base_)
+ {
+ return s;
+ }
+
+ public static String oostring(boolean b, int base_)
+ {
+ if (b) return "True";
+ return "False";
+ }
+
+ // ----------------------------------------------------------------------
+ // Exceptions
+ //
+ // If we don't use true Java exceptions, then this
+
+/*
+ static private ThreadLocal<Object> excObject = new ThreadLocal();
+
+ public static int startTry() {
+ return excCounter.get();
+ }
+
+ public void throw(Object o) {
+ excObject.put(o);
+ }
+
+ public static Object catch(int ctr) {
+ return excObject.get();
+ }
+*/
+
+ // ----------------------------------------------------------------------
+ // Dicts
+
+ public static boolean ll_remove(HashMap map, Object key) {
+ return map.remove(key) != null;
+ }
+
+ public static DictItemsIterator ll_get_items_iterator(HashMap map) {
+ return new DictItemsIterator(map);
+ }
+
+ // ----------------------------------------------------------------------
+ // Lists
+
+ public static void ll_setitem_fast(ArrayList self, int index, Object val)
+ {
+ // need a wrapper because set returns the old value
+ self.set(index, val);
+ }
+
+ public static void _ll_resize_ge(ArrayList self, int length) {
+ while (self.size() < length) {
+ self.add(null);
+ }
+ }
+
+ public static void _ll_resize_le(ArrayList self, int length) {
+ while (self.size() > length) {
+ self.remove(self.size()-1);
+ }
+ }
+
+ public static void _ll_resize(ArrayList self, int length) {
+ if (length > self.size())
+ _ll_resize_ge(self, length);
+ else if (length < self.size())
+ _ll_resize_le(self, length);
+ }
+
+ // ----------------------------------------------------------------------
+ // Self Test
+
+ public static int __counter = 0, __failures = 0;
+ public static void ensure(boolean f) {
+ if (f) {
+ System.out.println("Test #"+__counter+": OK");
+ }
+ else {
+ System.out.println("Test #"+__counter+": FAILED");
+ __failures++;
+ }
+ __counter++;
+ }
+
+ public static void main(String args[]) {
+ // Small self test:
+
+ ensure(uint_cmp(0xFFFFFFFF, 0) > 0);
+ ensure(uint_cmp(0, 0xFFFFFFFF) < 0);
+ ensure(uint_cmp(0x80000000, 0) > 0);
+ ensure(uint_cmp(0, 0x80000000) < 0);
+ ensure(uint_cmp(0xFFFF, 0) > 0);
+ ensure(uint_cmp(0, 0xFFFF) < 0);
+ ensure(uint_cmp(0xFFFFFFFF, 0xFFFF) > 0);
+ ensure(uint_cmp(0xFFFF, 0xFFFFFFFF) < 0);
+
+ ensure(ulong_cmp(0xFFFFFFFFFFFFFFFFL, 0) > 0);
+ ensure(ulong_cmp(0, 0xFFFFFFFFFFFFFFFFL) < 0);
+ ensure(ulong_cmp(0xFFFFFFFFFFFFFFFFL, 0xFFFF) > 0);
+ ensure(ulong_cmp(0xFFFF, 0xFFFFFFFFFFFFFFFFL) < 0);
+ ensure(ulong_cmp(0x8000000000000000L, 0xFFFF) > 0);
+ ensure(ulong_cmp(0xFFFF, 0x8000000000000000L) < 0);
+
+ System.out.println("Total Failures: "+__failures);
+ }
+}
\ No newline at end of file
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 18:15:11 2007
@@ -138,4 +138,7 @@
return isinstance(val, InstanceWrapper)
def read_attr(self, obj, name):
- py.test.skip('read_attr not supported on genjvm tests')
+ py.test.skip("read_attr not supported on JVM")
+ # TODO --- this "almost works": I think the problem is that our
+ # dump methods don't dump fields of the super class??
+ #return obj.fields["o"+name]
Added: pypy/dist/pypy/translator/jvm/test/test_dict.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/test/test_dict.py Thu Jan 11 18:15:11 2007
@@ -0,0 +1,13 @@
+from pypy.translator.jvm.test.runtest import JvmTest
+import pypy.translator.oosupport.test_template.dict as oodict
+
+class TestJvmDict(JvmTest, oodict.BaseTestDict):
+ pass
+
+class TestJvmEmptyDict(JvmTest, oodict.BaseTestEmptyDict):
+ pass
+
+class TestJvmConstantDict(JvmTest, oodict.BaseTestConstantDict):
+ pass
+
+
Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py (original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py Thu Jan 11 18:15:11 2007
@@ -165,6 +165,7 @@
jPyPyExcWrap = JvmClassType('pypy.ExceptionWrapper')
jPyPyConst = JvmClassType('pypy.Constant')
jPyPyMain = JvmClassType('pypy.Main')
+jPyPyDictItemsIterator = JvmClassType('pypy.DictItemsIterator')
class JvmScalarType(JvmType):
"""
@@ -202,4 +203,60 @@
jObjectArray = JvmArrayType(jObject)
jStringArray = JvmArrayType(jString)
+class Generifier(object):
+ """
+
+ A utility class for working with generic methods in the OOTYPE
+ system. You instantiate it with a given type, and you can ask it
+ for the actual or erased types of any method of that type.
+
+ """
+
+ def __init__(self, OOTYPE):
+ self.OOTYPE = OOTYPE
+
+ # Make a hashtable mapping the generic parameter to a tuple:
+ # (actual type, erased type)
+
+ self.generics = {}
+
+ if hasattr(self.OOTYPE, 'SELFTYPE_T'):
+ self.generics[self.OOTYPE.SELFTYPE_T] = (self.OOTYPE,self.OOTYPE)
+
+ for pname,pval in (('ITEMTYPE_T', '_ITEMTYPE'),
+ ('KEYTYPE_T', '_KEYTYPE'),
+ ('VALUETYPE_T', '_VALUETYPE')):
+ if hasattr(self.OOTYPE, pname):
+ placeholder = getattr(self.OOTYPE, pname)
+ placeholder_val = getattr(self.OOTYPE, pval)
+ self.generics[placeholder] = (placeholder_val, ootype.ROOT)
+
+ def full_types(self, method_name):
+ """
+ Returns a tuple of argument and return types for the method
+ named 'method_name'. These are the actual generic types. The set method for
+ a list of strings, for example, might return:
+ ( [INT, STRING], VOID )
+ """
+ GENMETH = self.OOTYPE._GENERIC_METHODS[method_name]
+ ARGS, RESULT = (GENMETH.ARGS, GENMETH.RESULT)
+ ARGS = [self.generics.get(X,(X,))[0] for X in ARGS]
+ RESULT = self.generics.get(RESULT, (RESULT,))[0]
+ return (ARGS, RESULT)
+
+ def erased_types(self, method_name):
+ """
+ Returns a tuple of argument and return types for the method
+ named 'method_name'. These are the erased generic types. The set method for
+ a list of strings, for example, might return:
+ ( [INT, OBJECT], VOID )
+ """
+ GENMETH = self.OOTYPE._GENERIC_METHODS[method_name]
+ ARGS, RESULT = (GENMETH.ARGS, GENMETH.RESULT)
+ ARGS = [self.generics.get(X,(None,X))[1] for X in ARGS]
+ RESULT = self.generics.get(RESULT, (None,RESULT))[1]
+ return (ARGS, RESULT)
+
+
+
Modified: pypy/dist/pypy/translator/oosupport/constant.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/constant.py (original)
+++ pypy/dist/pypy/translator/oosupport/constant.py Thu Jan 11 18:15:11 2007
@@ -212,6 +212,11 @@
return genoo.DictConst(self.db, value, uniq)
elif isinstance(value, llmemory.fakeweakaddress):
return genoo.WeakRefConst(self.db, value, uniq)
+ elif value is ootype.null(value._TYPE):
+ # for NULL values, we can just use "NULL" const. This is
+ # a fallback since we sometimes have constants of
+ # unhandled types which are equal to NULL.
+ return genoo.NullConst(self.db, value, uniq)
else:
assert False, 'Unknown constant: %s' % value
@@ -407,6 +412,21 @@
# ______________________________________________________________________
+# Null Values
+#
+# NULL constants of types for which we have no better class use this
+# class. For example, dict item iterators and the like.
+
+class NullConst(AbstractConst):
+ def __init__(self, db, value, count):
+ AbstractConst.__init__(self, db, value, count)
+ self.name = 'NULL__%d' % count
+ assert self.is_null() and self.is_inline()
+
+ def record_dependencies(self):
+ return
+
+# ______________________________________________________________________
# Records
class RecordConst(AbstractConst):
@@ -627,11 +647,13 @@
gen.dup(SELFTYPE)
gen.add_comment(' key=%r value=%r' % (key,value))
push_constant(self.db, KEYTYPE, key, gen)
+ gen.prepare_generic_argument(KEYTYPE)
if VALUETYPE is ootype.Void:
# special case dict of Void; for now store the key as value?
gen.dup(KEYTYPE)
else:
push_constant(self.db, VALUETYPE, value, gen)
+ gen.prepare_generic_argument(VALUETYPE)
gen.call_method(SELFTYPE, 'll_set')
class CustomDictConst(DictConst):
Modified: pypy/dist/pypy/translator/oosupport/genoo.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/genoo.py (original)
+++ pypy/dist/pypy/translator/oosupport/genoo.py Thu Jan 11 18:15:11 2007
@@ -13,6 +13,7 @@
# _create_complex_const:
ConstantGenerator = None
+ NullConst = ooconst.NullConst
InstanceConst = ooconst.InstanceConst
RecordConst = ooconst.RecordConst
ClassConst = ooconst.ClassConst
Added: pypy/dist/pypy/translator/oosupport/test_template/dict.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/oosupport/test_template/dict.py Thu Jan 11 18:15:11 2007
@@ -0,0 +1,42 @@
+import py
+from pypy.rpython.test.test_rdict import TestOOtype as _TestOOtype
+from pypy.rpython.test.test_remptydict import BaseTestRemptydict
+from pypy.rpython.test.test_rconstantdict import BaseTestRconstantdict
+
+class BaseTestDict(_TestOOtype):
+ def test_dict_of_void(self):
+ class A: pass
+ def f():
+ d2 = {A(): None, A(): None}
+ return len(d2)
+ res = self.interpret(f, [])
+ assert res == 2
+
+ def test_dict_of_void_iter(self):
+ def f():
+ d = {1: None, 2: None, 3: None}
+ total = 0
+ for key, value in d.iteritems():
+ total += key
+ return total
+ assert self.interpret(f, []) == 6
+
+ def test_dict_of_dict(self):
+ py.test.skip("CLI doesn't support recursive dicts")
+
+ def test_recursive(self):
+ py.test.skip("CLI doesn't support recursive dicts")
+
+class BaseTestEmptyDict(BaseTestRemptydict):
+ def test_iterate_over_empty_dict(self):
+ py.test.skip("Iteration over empty dict is not supported, yet")
+
+class BaseTestConstantDict(BaseTestRconstantdict):
+ def test_constant_r_dict(self):
+ py.test.skip('r_dict is not supported, yet')
+
+ def test_tuple_as_key(self):
+ mydict = {('r',): 42}
+ def fn(ch):
+ return mydict[(ch,)]
+ assert self.interpret(fn, ['r']) == 42
More information about the Pypy-commit
mailing list