Commit 473210a9 by Dalibor Topic Committed by Matthias Klose

re PR classpath/32844 (EnumSet causes code to be miscompiled)

2007-07-31  Dalibor Topic  <robilad@kaffe.org>

        PR 32844
        * java/util/EnumSet.java:
        Made class abstract per API spec.
        (size, iterator, add, addAll, clear, contains,
        containsAll, remove, removeAll, retainAll) Moved 
        into an anonymous inner class in of(T).
        (allOf, noneOf, copyOf, of, range) Made more 
        implementation independent.
        (of(T)) return an instance of an anonymous class
        implementing EmptySet.

From-SVN: r127291
parent 5b6693af
2007-07-31 Dalibor Topic <robilad@kaffe.org>
PR 32844
* java/util/EnumSet.java:
Made class abstract per API spec.
(size, iterator, add, addAll, clear, contains,
containsAll, remove, removeAll, retainAll) Moved
into an anonymous inner class in of(T).
(allOf, noneOf, copyOf, of, range) Made more
implementation independent.
(of(T)) return an instance of an anonymous class
implementing EmptySet.
2007-07-28 Matthias Klose <doko@ubuntu.com> 2007-07-28 Matthias Klose <doko@ubuntu.com>
* include/jvmti.h(jniNativeInterface): Rename type. * include/jvmti.h(jniNativeInterface): Rename type.
......
...@@ -43,16 +43,20 @@ import java.io.Serializable; ...@@ -43,16 +43,20 @@ import java.io.Serializable;
/** /**
* @author Tom Tromey (tromey@redhat.com) * @author Tom Tromey (tromey@redhat.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @author Dalibor Topic (robilad@kaffe.org)
* @since 1.5 * @since 1.5
*/ */
// FIXME: serialization is special. // FIXME: serialization is special, uses SerializationProxy.
public class EnumSet<T extends Enum<T>> // of(E e) is the 'bottom' method that creates a real EnumSet.
public abstract class EnumSet<T extends Enum<T>>
extends AbstractSet<T> extends AbstractSet<T>
implements Cloneable, Serializable implements Cloneable, Serializable
{ {
private static final long serialVersionUID = 4782406773684236311L; private static final long serialVersionUID = 4782406773684236311L;
// These fields could go into the anonymous inner class in of(E),
// complementOf would need to be refactored then, though.
BitSet store; BitSet store;
int cardinality; int cardinality;
Class<T> enumClass; Class<T> enumClass;
...@@ -78,276 +82,246 @@ public class EnumSet<T extends Enum<T>> ...@@ -78,276 +82,246 @@ public class EnumSet<T extends Enum<T>>
return r; return r;
} }
public int size() public static <T extends Enum<T>> EnumSet<T> allOf(Class<T> eltType)
{ {
return cardinality; // create an EnumSet from the list of values of the type
return copyOf(Arrays.asList(eltType.getEnumConstants()));
} }
public Iterator<T> iterator() public static <T extends Enum<T>> EnumSet<T> noneOf(Class<T> eltType)
{ {
return new Iterator<T>() return complementOf(allOf(eltType));
{ }
int next = -1;
int count = 0;
public boolean hasNext() public static <T extends Enum<T>> EnumSet<T> copyOf(EnumSet<T> other)
{ {
return count < cardinality; return other.clone();
} }
public T next() public static <T extends Enum<T>> EnumSet<T> copyOf(Collection<T> other)
{ {
next = store.nextSetBit(next + 1); if (other instanceof EnumSet)
++count; return copyOf((EnumSet<T>) other);
return enumClass.getEnumConstants()[next]; if (other.isEmpty())
} throw new IllegalArgumentException("Collection is empty");
public void remove() EnumSet<T> r = null;
for (T val : other)
{ {
if (! store.get(next)) if (r == null)
{ r = of(val);
store.clear(next); else
--cardinality; r.add(val);
}
} }
};
return r;
} }
public boolean add(T val) public static <T extends Enum<T>> EnumSet<T> complementOf(EnumSet<T> other)
{ {
if (store.get(val.ordinal())) EnumSet<T> r = other.clone();
return false; r.store.flip(0, r.store.size());
store.set(val.ordinal()); r.cardinality = r.store.size() - other.cardinality;
++cardinality; return r;
return true;
} }
public boolean addAll(Collection<? extends T> c) public static <T extends Enum<T>> EnumSet<T> of(T first)
{ {
boolean result = false; EnumSet<T> r = new EnumSet<T>()
if (c instanceof EnumSet) {
public boolean add(T val)
{
if (store.get(val.ordinal()))
return false;
store.set(val.ordinal());
++cardinality;
return true;
}
public boolean addAll(Collection<? extends T> c)
{ {
EnumSet<T> other = (EnumSet<T>) c; boolean result = false;
if (enumClass == other.enumClass) if (c instanceof EnumSet)
{
EnumSet<T> other = (EnumSet<T>) c;
if (enumClass == other.enumClass)
{ {
store.or(other.store); store.or(other.store);
int save = cardinality; int save = cardinality;
cardinality = store.cardinality(); cardinality = store.cardinality();
result = save != cardinality; result = save != cardinality;
} }
} }
else else
{ {
for (T val : c) for (T val : c)
{ {
if (add (val)) if (add (val))
result = true; result = true;
} }
}
return result;
} }
return result;
}
public void clear() public void clear()
{
store.clear();
cardinality = 0;
}
public boolean contains(Object o)
{
if (! (o instanceof Enum))
return false;
Enum<T> e = (Enum<T>) o;
if (e.getDeclaringClass() != enumClass)
return false;
return store.get(e.ordinal());
}
public boolean containsAll(Collection<?> c)
{
if (c instanceof EnumSet)
{ {
EnumSet<T> other = (EnumSet<T>) c; store.clear();
if (enumClass == other.enumClass) cardinality = 0;
return store.containsAll(other.store);
return false;
} }
return super.containsAll(c);
}
public boolean remove(Object o)
{
if (! (o instanceof Enum))
return false;
Enum<T> e = (Enum<T>) o;
if (e.getDeclaringClass() != enumClass)
return false;
store.clear(e.ordinal());
--cardinality;
return true;
}
public boolean removeAll(Collection<?> c) public boolean contains(Object o)
{
if (c instanceof EnumSet)
{ {
EnumSet<T> other = (EnumSet<T>) c; if (! (o instanceof Enum))
if (enumClass != other.enumClass) return false;
Enum<T> e = (Enum<T>) o;
if (e.getDeclaringClass() != enumClass)
return false; return false;
store.andNot(other.store);
int save = cardinality; return store.get(e.ordinal());
cardinality = store.cardinality();
return save != cardinality;
} }
return super.removeAll(c);
}
public boolean retainAll(Collection<?> c) public boolean containsAll(Collection<?> c)
{
if (c instanceof EnumSet)
{ {
EnumSet<T> other = (EnumSet<T>) c; if (c instanceof EnumSet)
if (enumClass != other.enumClass) {
EnumSet<T> other = (EnumSet<T>) c;
if (enumClass == other.enumClass)
return store.containsAll(other.store);
return false; return false;
store.and(other.store); }
int save = cardinality; return super.containsAll(c);
cardinality = store.cardinality();
return save != cardinality;
} }
return super.retainAll(c);
}
public static <T extends Enum<T>> EnumSet<T> allOf(Class<T> eltType) public Iterator<T> iterator()
{ {
EnumSet<T> r = new EnumSet<T>(); return new Iterator<T>()
r.store = new BitSet(eltType.getEnumConstants().length); {
r.store.set(0, r.store.size()); int next = -1;
r.cardinality = r.store.size(); int count = 0;
r.enumClass = eltType;
return r;
}
public static <T extends Enum<T>> EnumSet<T> noneOf(Class<T> eltType) public boolean hasNext()
{ {
EnumSet<T> r = new EnumSet<T>(); return count < cardinality;
r.store = new BitSet(eltType.getEnumConstants().length); }
r.enumClass = eltType;
return r;
}
public static <T extends Enum<T>> EnumSet<T> copyOf(EnumSet<T> other) public T next()
{ {
// We can't just use `other.clone' since we don't want to make a next = store.nextSetBit(next + 1);
// subclass. ++count;
EnumSet<T> r = new EnumSet<T>(); return enumClass.getEnumConstants()[next];
r.store = (BitSet) other.store.clone(); }
r.cardinality = other.cardinality;
r.enumClass = other.enumClass;
return r;
}
public static <T extends Enum<T>> EnumSet<T> copyOf(Collection<T> other) public void remove()
{
if (other instanceof EnumSet)
return copyOf((EnumSet<T>) other);
EnumSet<T> r = new EnumSet<T>();
for (T val : other)
{
if (r.store == null)
{ {
r.enumClass = val.getDeclaringClass(); if (! store.get(next))
r.store = new BitSet(r.enumClass.getEnumConstants().length); {
store.clear(next);
--cardinality;
}
} }
r.store.set(val.ordinal()); };
} }
// The collection must contain at least one element.
if (r.store == null)
throw new IllegalArgumentException();
r.cardinality = r.store.cardinality();
return r;
}
public static <T extends Enum<T>> EnumSet<T> complementOf(EnumSet<T> other) public boolean remove(Object o)
{ {
EnumSet<T> r = new EnumSet<T>(); if (! (o instanceof Enum))
r.store = (BitSet) other.store.clone(); return false;
r.store.flip(0, r.store.size());
r.cardinality = r.store.size() - other.cardinality;
r.enumClass = other.enumClass;
return r;
}
public static <T extends Enum<T>> EnumSet<T> of(T first) Enum<T> e = (Enum<T>) o;
{ if (e.getDeclaringClass() != enumClass)
EnumSet<T> r = new EnumSet<T>(); return false;
store.clear(e.ordinal());
--cardinality;
return true;
}
public boolean removeAll(Collection<?> c)
{
if (c instanceof EnumSet)
{
EnumSet<T> other = (EnumSet<T>) c;
if (enumClass != other.enumClass)
return false;
store.andNot(other.store);
int save = cardinality;
cardinality = store.cardinality();
return save != cardinality;
}
return super.removeAll(c);
}
public boolean retainAll(Collection<?> c)
{
if (c instanceof EnumSet)
{
EnumSet<T> other = (EnumSet<T>) c;
if (enumClass != other.enumClass)
return false;
store.and(other.store);
int save = cardinality;
cardinality = store.cardinality();
return save != cardinality;
}
return super.retainAll(c);
}
public int size()
{
return cardinality;
}
};
// initialize the class
r.enumClass = first.getDeclaringClass(); r.enumClass = first.getDeclaringClass();
r.store = new BitSet(r.enumClass.getEnumConstants().length); r.store = new BitSet(r.enumClass.getEnumConstants().length);
r.store.set(first.ordinal());
r.cardinality = 1; r.add(first);
return r; return r;
} }
public static <T extends Enum<T>> EnumSet<T> of(T first, T second) public static <T extends Enum<T>> EnumSet<T> of(T first, T second)
{ {
EnumSet<T> r = new EnumSet<T>(); EnumSet<T> r = of(first);
r.enumClass = first.getDeclaringClass(); r.add(second);
r.store = new BitSet(r.enumClass.getEnumConstants().length);
r.store.set(first.ordinal());
r.store.set(second.ordinal());
r.cardinality = r.store.cardinality();
return r; return r;
} }
public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third) public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third)
{ {
EnumSet<T> r = new EnumSet<T>(); EnumSet<T> r = of(first, second);
r.enumClass = first.getDeclaringClass(); r.add(third);
r.store = new BitSet(r.enumClass.getEnumConstants().length);
r.store.set(first.ordinal());
r.store.set(second.ordinal());
r.store.set(third.ordinal());
r.cardinality = r.store.cardinality();
return r; return r;
} }
public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third, public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third,
T fourth) T fourth)
{ {
EnumSet<T> r = new EnumSet<T>(); EnumSet<T> r = of(first, second, third);
r.enumClass = first.getDeclaringClass(); r.add(fourth);
r.store = new BitSet(r.enumClass.getEnumConstants().length);
r.store.set(first.ordinal());
r.store.set(second.ordinal());
r.store.set(third.ordinal());
r.store.set(fourth.ordinal());
r.cardinality = r.store.cardinality();
return r; return r;
} }
public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third, public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third,
T fourth, T fifth) T fourth, T fifth)
{ {
EnumSet<T> r = new EnumSet<T>(); EnumSet<T> r = of(first, second, third, fourth);
r.enumClass = first.getDeclaringClass(); r.add(fifth);
r.store = new BitSet(r.enumClass.getEnumConstants().length);
r.store.set(first.ordinal());
r.store.set(second.ordinal());
r.store.set(third.ordinal());
r.store.set(fourth.ordinal());
r.store.set(fifth.ordinal());
r.cardinality = r.store.cardinality();
return r; return r;
} }
public static <T extends Enum<T>> EnumSet<T> of(T first, T... rest) public static <T extends Enum<T>> EnumSet<T> of(T first, T... rest)
{ {
EnumSet<T> r = new EnumSet<T>(); EnumSet<T> r = noneOf(first.getDeclaringClass());
r.enumClass = first.getDeclaringClass(); r.add(first);
r.store = new BitSet(r.enumClass.getEnumConstants().length);
r.store.set(first.ordinal());
for (T val : rest) for (T val : rest)
r.store.set(val.ordinal()); r.add(val);
r.cardinality = r.store.cardinality();
return r; return r;
} }
...@@ -355,11 +329,24 @@ public class EnumSet<T extends Enum<T>> ...@@ -355,11 +329,24 @@ public class EnumSet<T extends Enum<T>>
{ {
if (from.compareTo(to) > 0) if (from.compareTo(to) > 0)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
EnumSet<T> r = new EnumSet<T>(); Class<T> type = from.getDeclaringClass();
r.store = new BitSet(from.getDeclaringClass().getEnumConstants().length); EnumSet<T> r = noneOf(type);
r.store.set(from.ordinal(), to.ordinal() + 1);
r.enumClass = from.getDeclaringClass(); T[] values = type.getEnumConstants();
r.cardinality = to.ordinal() - from.ordinal() + 1; // skip over values until start of range is found
int i = 0;
while (from != values[i])
i++;
// add values until end of range is found
while (to != values[i]) {
r.add(values[i]);
i++;
}
// add end of range
r.add(to);
return r; return r;
} }
} }
...@@ -6,23 +6,25 @@ ...@@ -6,23 +6,25 @@
#pragma interface #pragma interface
#include <java/lang/Object.h> #include <java/util/EnumSet.h>
class java::util::EnumSet$1 : public ::java::lang::Object class java::util::EnumSet$1 : public ::java::util::EnumSet
{ {
public: // actually package-private public: // actually package-private
EnumSet$1(::java::util::EnumSet *); EnumSet$1();
public:
jboolean hasNext();
::java::lang::Enum * EnumSet$1$next();
void remove();
::java::lang::Object * next();
public: // actually package-private
jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) next__;
jint count;
::java::util::EnumSet * this$0;
public: public:
jboolean EnumSet$1$add(::java::lang::Enum *);
jboolean addAll(::java::util::Collection *);
void clear();
jboolean contains(::java::lang::Object *);
jboolean containsAll(::java::util::Collection *);
::java::util::Iterator * iterator();
jboolean remove(::java::lang::Object *);
jboolean removeAll(::java::util::Collection *);
jboolean retainAll(::java::util::Collection *);
jint size();
jboolean add(::java::lang::Object *);
static ::java::lang::Class class$; static ::java::lang::Class class$;
}; };
......
// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-
#ifndef __java_util_EnumSet$2__
#define __java_util_EnumSet$2__
#pragma interface
#include <java/lang/Object.h>
class java::util::EnumSet$2 : public ::java::lang::Object
{
public: // actually package-private
EnumSet$2(::java::util::EnumSet$1 *);
public:
jboolean hasNext();
::java::lang::Enum * EnumSet$2$next();
void remove();
::java::lang::Object * next();
public: // actually package-private
jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) next__;
jint count;
::java::util::EnumSet$1 * this$1;
public:
static ::java::lang::Class class$;
};
#endif // __java_util_EnumSet$2__
...@@ -17,16 +17,6 @@ public: // actually package-private ...@@ -17,16 +17,6 @@ public: // actually package-private
EnumSet(); EnumSet();
public: public:
virtual ::java::util::EnumSet * EnumSet$clone(); virtual ::java::util::EnumSet * EnumSet$clone();
virtual jint size();
virtual ::java::util::Iterator * iterator();
virtual jboolean EnumSet$add(::java::lang::Enum *);
virtual jboolean addAll(::java::util::Collection *);
virtual void clear();
virtual jboolean contains(::java::lang::Object *);
virtual jboolean containsAll(::java::util::Collection *);
virtual jboolean remove(::java::lang::Object *);
virtual jboolean removeAll(::java::util::Collection *);
virtual jboolean retainAll(::java::util::Collection *);
static ::java::util::EnumSet * allOf(::java::lang::Class *); static ::java::util::EnumSet * allOf(::java::lang::Class *);
static ::java::util::EnumSet * noneOf(::java::lang::Class *); static ::java::util::EnumSet * noneOf(::java::lang::Class *);
static ::java::util::EnumSet * copyOf(::java::util::EnumSet *); static ::java::util::EnumSet * copyOf(::java::util::EnumSet *);
...@@ -40,7 +30,6 @@ public: ...@@ -40,7 +30,6 @@ public:
static ::java::util::EnumSet * of(::java::lang::Enum *, JArray< ::java::lang::Enum * > *); static ::java::util::EnumSet * of(::java::lang::Enum *, JArray< ::java::lang::Enum * > *);
static ::java::util::EnumSet * range(::java::lang::Enum *, ::java::lang::Enum *); static ::java::util::EnumSet * range(::java::lang::Enum *, ::java::lang::Enum *);
virtual ::java::lang::Object * clone(); virtual ::java::lang::Object * clone();
virtual jboolean add(::java::lang::Object *);
private: private:
static const jlong serialVersionUID = 4782406773684236311LL; static const jlong serialVersionUID = 4782406773684236311LL;
public: // actually package-private public: // actually package-private
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment