Merge branch 'master' of oss.readytalk.com:/var/local/git/avian

This commit is contained in:
Joel Dice 2009-08-09 14:43:53 -06:00
commit 1a2deff97d
29 changed files with 2655 additions and 70 deletions

View File

@ -305,6 +305,21 @@ Java_java_io_File_isDirectory(JNIEnv* e, jclass, jstring path)
}
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_isFile(JNIEnv* e, jclass, jstring path)
{
const char* chars = e->GetStringUTFChars(path, 0);
if (chars) {
STRUCT_STAT s;
int r = STAT(chars, &s);
bool v = (r == 0 and S_ISREG(s.st_mode));
e->ReleaseStringUTFChars(path, chars);
return v;
} else {
return false;
}
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_exists(JNIEnv* e, jclass, jstring path)
{

View File

@ -27,6 +27,7 @@
# include <netdb.h>
# include <sys/select.h>
# include <netinet/tcp.h>
# include <sys/socket.h>
#endif
#define java_nio_channels_SelectionKey_OP_READ 1L

View File

@ -41,6 +41,12 @@ public class File {
return isDirectory(path);
}
private static native boolean isFile(String path);
public boolean isFile() {
return isFile(path);
}
public String getName() {
int index = path.lastIndexOf(FileSeparator);
if (index >= 0) {
@ -141,6 +147,19 @@ public class File {
return mkdir();
}
public File[] listFiles() {
return listFiles(null);
}
public File[] listFiles(FilenameFilter filter) {
String[] list = list(filter);
File[] result = new File[list.length];
for (int i = 0; i < list.length; ++i) {
result[i] = new File(this, list[i]);
}
return result;
}
public String[] list() {
return list(null);
}

View File

@ -29,7 +29,7 @@ import java.security.Permissions;
import java.security.AllPermission;
public final class Class <T> implements Type, GenericDeclaration {
private static final int PrimitiveFlag = 1 << 4;
private static final int PrimitiveFlag = 1 << 5;
private short flags;
private byte vmFlags;
@ -64,6 +64,34 @@ public final class Class <T> implements Type, GenericDeclaration {
}
public String getName() {
if (name == null) {
if ((vmFlags & PrimitiveFlag) != 0) {
if (this == primitiveClass('V')) {
name = "void".getBytes();
} else if (this == primitiveClass('Z')) {
name = "boolean".getBytes();
} else if (this == primitiveClass('B')) {
name = "byte".getBytes();
} else if (this == primitiveClass('C')) {
name = "char".getBytes();
} else if (this == primitiveClass('S')) {
name = "short".getBytes();
} else if (this == primitiveClass('I')) {
name = "int".getBytes();
} else if (this == primitiveClass('F')) {
name = "float".getBytes();
} else if (this == primitiveClass('J')) {
name = "long".getBytes();
} else if (this == primitiveClass('D')) {
name = "double".getBytes();
} else {
throw new AssertionError();
}
} else {
throw new AssertionError();
}
}
return new String
(replace('/', '.', name, 0, name.length - 1), 0, name.length - 1, false);
}

View File

@ -35,4 +35,5 @@ public final class Modifier {
public static boolean isSuper (int v) { return (v & SUPER) != 0; }
public static boolean isNative (int v) { return (v & NATIVE) != 0; }
public static boolean isAbstract (int v) { return (v & ABSTRACT) != 0; }
public static boolean isInterface(int v) { return (v & INTERFACE) != 0; }
}

View File

@ -62,6 +62,10 @@ public abstract class AbstractCollection<T> implements Collection<T> {
public abstract int size();
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <S> S[] toArray(S[] array) {
return Collections.toArray(this, array);
}

View File

@ -0,0 +1,15 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util;
public abstract class AbstractList<T> extends AbstractCollection<T>
implements List<T>
{ }

View File

@ -0,0 +1,15 @@
/* Copyright (c) 2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util;
public abstract class AbstractSequentialList<T> extends AbstractList<T>
implements List<T>
{ }

View File

@ -10,7 +10,7 @@
package java.util;
public class ArrayList<T> implements List<T> {
public class ArrayList<T> extends AbstractList<T> {
private static final int MinimumCapacity = 16;
private Object[] array;
@ -94,7 +94,7 @@ public class ArrayList<T> implements List<T> {
return true;
}
public int indexOf(T element) {
public int indexOf(Object element) {
for (int i = 0; i < size; ++i) {
if (equal(element, array[i])) {
return i;
@ -103,8 +103,8 @@ public class ArrayList<T> implements List<T> {
return -1;
}
public int lastIndexOf(T element) {
for (int i = size; i >= 0; --i) {
public int lastIndexOf(Object element) {
for (int i = size - 1; i >= 0; --i) {
if (equal(element, array[i])) {
return i;
}
@ -159,17 +159,13 @@ public class ArrayList<T> implements List<T> {
return size() == 0;
}
public <S> S[] toArray(S[] a) {
return Collections.toArray(this, a);
}
public void clear() {
array = null;
size = 0;
}
public Iterator<T> iterator() {
return new Collections.ArrayListIterator(this);
return listIterator();
}
public ListIterator<T> listIterator(int index) {

View File

@ -73,6 +73,24 @@ public class Arrays {
return false;
}
public int indexOf(Object element) {
for (int i = 0; i < array.length; ++i) {
if (equal(element, array[i])) {
return i;
}
}
return -1;
}
public int lastIndexOf(Object element) {
for (int i = array.length - 1; i >= 0; --i) {
if (equal(element, array[i])) {
return i;
}
}
return -1;
}
public T get(int index) {
return array[index];
}
@ -81,6 +99,10 @@ public class Arrays {
throw new UnsupportedOperationException();
}
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <S> S[] toArray(S[] a) {
return (S[])array;
}
@ -102,7 +124,15 @@ public class Arrays {
}
public Iterator<T> iterator() {
return new Collections.ArrayListIterator(this);
return listIterator();
}
public ListIterator<T> listIterator(int index) {
return new Collections.ArrayListIterator(this, index);
}
public ListIterator<T> listIterator() {
return listIterator(0);
}
};
}

View File

@ -23,6 +23,8 @@ public interface Collection<T> extends Iterable<T> {
public boolean remove(Object element);
public Object[] toArray();
public <S> S[] toArray(S[] array);
public void clear();

View File

@ -129,6 +129,10 @@ public class Collections {
synchronized (lock) { return collection.remove((T)e); }
}
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <T> T[] toArray(T[] array) {
synchronized (lock) { return collection.toArray(array); }
}
@ -198,7 +202,6 @@ public class Collections {
return new SynchronizedMap<K, V> (map);
}
static class SynchronizedSet<T>
extends SynchronizedCollection<T>
implements Set<T>
@ -232,7 +235,7 @@ public class Collections {
static class ArrayListIterator<T> implements ListIterator<T> {
private final List<T> list;
private boolean canRemove = false;
private int toRemove = -1;
private int index;
public ArrayListIterator(List<T> list) {
@ -250,7 +253,7 @@ public class Collections {
public T previous() {
if (hasPrevious()) {
canRemove = true;
toRemove = index;
return list.get(index--);
} else {
throw new NoSuchElementException();
@ -259,8 +262,8 @@ public class Collections {
public T next() {
if (hasNext()) {
canRemove = true;
return list.get(++index);
toRemove = ++index;
return list.get(index);
} else {
throw new NoSuchElementException();
}
@ -271,9 +274,10 @@ public class Collections {
}
public void remove() {
if (canRemove) {
canRemove = false;
list.remove(index--);
if (toRemove != -1) {
list.remove(toRemove);
index = toRemove - 1;
toRemove = -1;
} else {
throw new IllegalStateException();
}
@ -319,10 +323,13 @@ public class Collections {
return inner.size();
}
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <S> S[] toArray(S[] array) {
return inner.toArray(array);
}
}
}
public static <T> Set<T> unmodifiableSet(Set<T> hs) {

View File

@ -334,6 +334,10 @@ public class HashMap<K, V> implements Map<K, V> {
return removeCell(e.getKey()) != null;
}
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <T> T[] toArray(T[] array) {
return Collections.toArray(this, array);
}
@ -374,6 +378,10 @@ public class HashMap<K, V> implements Map<K, V> {
return removeCell(key) != null;
}
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <T> T[] toArray(T[] array) {
return Collections.toArray(this, array);
}
@ -412,6 +420,10 @@ public class HashMap<K, V> implements Map<K, V> {
throw new UnsupportedOperationException();
}
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <T> T[] toArray(T[] array) {
return Collections.toArray(this, array);
}

View File

@ -10,7 +10,7 @@
package java.util;
public class HashSet<T> implements Set<T> {
public class HashSet<T> extends AbstractSet<T> implements Set<T> {
private static final Object Value = new Object();
private final HashMap<T, Object> map;
@ -54,10 +54,6 @@ public class HashSet<T> implements Set<T> {
return map.remove(element) != Value;
}
public <T> T[] toArray(T[] array) {
return Collections.toArray(this, array);
}
public void clear() {
map.clear();
}

View File

@ -10,7 +10,7 @@
package java.util;
public class LinkedList<T> implements List<T> {
public class LinkedList<T> extends AbstractSequentialList<T> {
private Cell<T> front;
private Cell<T> rear;
private int size;
@ -85,10 +85,6 @@ public class LinkedList<T> implements List<T> {
}
}
public <S> S[] toArray(S[] a) {
return Collections.toArray(this, a);
}
public int size() {
return size;
}
@ -97,6 +93,28 @@ public class LinkedList<T> implements List<T> {
return find(element) != null;
}
public int indexOf(Object element) {
int i = 0;
for (Cell<T> c = front; c != null; c = c.next) {
if (equal(c.value, element)) {
return i;
}
++ i;
}
return -1;
}
public int lastIndexOf(Object element) {
int i = size;
for (Cell<T> c = rear; c != null; c = c.prev) {
-- i;
if (equal(c.value, element)) {
return i;
}
}
return -1;
}
public boolean add(T element) {
addLast(element);
return true;
@ -198,7 +216,19 @@ public class LinkedList<T> implements List<T> {
}
public Iterator<T> iterator() {
return new MyIterator(front);
return listIterator();
}
public ListIterator<T> listIterator(int index) {
MyIterator it = new MyIterator();
for (int i = 0; i < index; ++i) {
it.next();
}
return it;
}
public ListIterator<T> listIterator() {
return listIterator(0);
}
public String toString() {
@ -217,18 +247,29 @@ public class LinkedList<T> implements List<T> {
}
}
private class MyIterator implements Iterator<T> {
private class MyIterator implements ListIterator<T> {
private Cell<T> toRemove;
private Cell<T> current;
private Cell<T> next;
public MyIterator(Cell<T> start) {
next = start;
public T previous() {
if (hasPrevious()) {
T v = current.value;
toRemove = current;
current = current.prev;
return v;
} else {
throw new NoSuchElementException();
}
}
public T next() {
if (hasNext()) {
current = next;
next = next.next;
if (current == null) {
current = front;
} else {
current = current.next;
}
toRemove = current;
return current.value;
} else {
throw new NoSuchElementException();
@ -236,13 +277,22 @@ public class LinkedList<T> implements List<T> {
}
public boolean hasNext() {
return next != null;
if (current == null) {
return front != null;
} else {
return current.next != null;
}
}
public boolean hasPrevious() {
return current != null;
}
public void remove() {
if (current != null) {
LinkedList.this.remove(current);
current = null;
if (toRemove != null) {
current = toRemove.prev;
LinkedList.this.remove(toRemove);
toRemove = null;
} else {
throw new IllegalStateException();
}

View File

@ -21,5 +21,13 @@ public interface List<T> extends Collection<T> {
public void add(int index, T element);
public int indexOf(Object value);
public int lastIndexOf(Object value);
public boolean isEmpty();
public ListIterator<T> listIterator(int index);
public ListIterator<T> listIterator();
}

View File

@ -144,6 +144,10 @@ public class TreeMap<K,V> implements Map<K,V> {
return set.removeAndReturn(new MyEntry(key, null)) != null;
}
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <T> T[] toArray(T[] array) {
return Collections.toArray(this, array);
}
@ -182,6 +186,10 @@ public class TreeMap<K,V> implements Map<K,V> {
throw new UnsupportedOperationException();
}
public Object[] toArray() {
return toArray(new Object[size()]);
}
public <T> T[] toArray(T[] array) {
return Collections.toArray(this, array);
}

View File

@ -10,7 +10,7 @@
package java.util;
public class Vector<T> implements List<T> {
public class Vector<T> extends AbstractList<T> {
private final ArrayList<T> list;
public Vector(int capacity) {
@ -77,10 +77,6 @@ public class Vector<T> implements List<T> {
return list.isEmpty();
}
public synchronized <S> S[] toArray(S[] a) {
return list.toArray(a);
}
public void removeElementAt(int index) {
remove(index);
}
@ -97,11 +93,11 @@ public class Vector<T> implements List<T> {
list.clear();
}
public synchronized int indexOf(T element) {
public synchronized int indexOf(Object element) {
return list.indexOf(element);
}
public synchronized int lastIndexOf(T element) {
public synchronized int lastIndexOf(Object element) {
return list.lastIndexOf(element);
}
@ -112,7 +108,15 @@ public class Vector<T> implements List<T> {
}
public Iterator<T> iterator() {
return new Collections.ArrayListIterator(this);
return listIterator();
}
public ListIterator<T> listIterator(int index) {
return new Collections.ArrayListIterator(this, index);
}
public ListIterator<T> listIterator() {
return listIterator(0);
}
public Enumeration<T> elements() {

View File

@ -21,6 +21,8 @@ vmJump(void* address, void* base, void* stack, void* thread,
# include "x86.h"
#elif defined __POWERPC__
# include "powerpc.h"
#elif defined __arm__
# include "arm.h"
#else
# error unsupported architecture
#endif

56
src/arm.S Normal file
View File

@ -0,0 +1,56 @@
/* arm.S: JNI gluecode for ARM/Linux
Copyright (c) 2008-2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
.text
.globl vmNativeCall
vmNativeCall:
/*
arguments:
r0 -> r4 : function
r1 -> r5 : stackTotal
r2 : memoryTable
r3 : memoryCount
[sp, #0] -> r6 : gprTable
*/
mov ip, sp // save stack frame
stmfd sp!, {r4-r6, lr} // save clobbered non-volatile regs
// mv args into non-volatile regs
mov r4, r0
mov r5, r1
ldr r6, [ip]
// setup stack arguments if necessary
sub sp, sp, r5 // allocate stack
mov ip, sp
.Lloop:
tst r3, r3
ldrne r0, [r2], #4
strne r0, [ip], #4
subne r3, r3, #4
bne .Lloop
// setup argument registers if necessary
tst r6, r6
ldmneia r6, {r0-r3}
blx r4 // call function
add sp, sp, r5 // deallocate stack
ldmfd sp!, {r4-r6, pc} // restore non-volatile regs and return
.globl vmJump
vmJump:
mov sp, r2
mov r4, r3
ldmia sp, {r0,r1}
mov pc, lr

2043
src/arm.cpp Normal file

File diff suppressed because it is too large Load Diff

119
src/arm.h Normal file
View File

@ -0,0 +1,119 @@
/* Copyright (c) 2008-2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef ARM_H
#define ARM_H
#include "types.h"
#include "common.h"
#define IP_REGISTER(context) (context->uc_mcontext.gregs[15])
#define STACK_REGISTER(context) (context->uc_mcontext.gregs[13])
#define THREAD_REGISTER(context) (context->uc_mcontext.gregs[12])
extern "C" uint64_t
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
unsigned memoryCount, void* gprTable);
namespace vm {
inline void
trap()
{
asm("nop");
}
inline void
memoryBarrier()
{
asm("nop");
}
inline void
storeStoreMemoryBarrier()
{
memoryBarrier();
}
inline void
storeLoadMemoryBarrier()
{
memoryBarrier();
}
inline void
loadMemoryBarrier()
{
memoryBarrier();
}
inline void
syncInstructionCache(const void* start UNUSED, unsigned size UNUSED)
{
asm("nop");
}
inline uint64_t
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned argumentCount, unsigned argumentsSize,
unsigned returnType UNUSED)
{
const unsigned GprCount = 4;
uintptr_t gprTable[GprCount];
unsigned gprIndex = 0;
uintptr_t stack[argumentsSize / BytesPerWord];
unsigned stackIndex = 0;
unsigned ai = 0;
for (unsigned ati = 0; ati < argumentCount; ++ ati) {
switch (argumentTypes[ati]) {
case DOUBLE_TYPE:
case INT64_TYPE: {
if (gprIndex + (8 / BytesPerWord) <= GprCount) {
memcpy(gprTable + gprIndex, arguments + ai, 8);
gprIndex += 8 / BytesPerWord;
} else if (gprIndex == GprCount-1) { // split between last GPR and stack
memcpy(gprTable + gprIndex, arguments + ai, 4);
++gprIndex;
memcpy(stack + stackIndex, arguments + ai + 4, 4);
++stackIndex;
} else {
memcpy(stack + stackIndex, arguments + ai, 8);
stackIndex += 8 / BytesPerWord;
}
ai += 8 / BytesPerWord;
} break;
default: {
if (gprIndex < GprCount) {
gprTable[gprIndex++] = arguments[ai];
} else {
stack[stackIndex++] = arguments[ai];
}
++ ai;
} break;
}
}
if (gprIndex < GprCount) { // pad since assembly loads all GPRs
memset(gprTable + gprIndex, 0, (GprCount-gprIndex)*4);
gprIndex = GprCount;
}
unsigned stackSize = stackIndex*BytesPerWord + ((stackIndex & 1) << 2);
return vmNativeCall
(function, stackSize, stack, stackIndex * BytesPerWord,
(gprIndex ? gprTable : 0));
}
} // namespace vm
#endif // ARM_H

View File

@ -29,16 +29,20 @@
# define PATH_SEPARATOR ':'
#endif
#if (defined __i386__) || (defined __POWERPC__)
#if (defined __i386__) || (defined __POWERPC__) || (defined __arm__)
# define LD "ld"
# define LLD "lld"
#ifdef __APPLE__
# define ULD "lu"
# define LX "lx"
#else
# define LX "x"
# define ULD "u"
#endif
# ifdef __MINGW32__
# define LLD "I64d"
# else
# define LLD "lld"
# endif
# ifdef __APPLE__
# define ULD "lu"
# define LX "lx"
# else
# define LX "x"
# define ULD "u"
# endif
#elif defined __x86_64__
# ifdef __MINGW32__
# define LD "I64d"

View File

@ -189,8 +189,10 @@ compareIpToMethodBounds(Thread* t, intptr_t ip, object method)
intptr_t start = methodCompiled(t, method);
if (DebugMethodTree) {
fprintf(stderr, "find 0x%"LX" in (0x%"LX",0x%"LX")\n", ip, start,
start + compiledSize(start));
fprintf(stderr, "find %p in (%p,%p)\n",
reinterpret_cast<void*>(ip),
reinterpret_cast<void*>(start),
reinterpret_cast<void*>(start + compiledSize(start)));
}
if (ip < start) {

View File

@ -117,7 +117,11 @@ pushLong(Thread* t, uint64_t v)
inline void
pushDouble(Thread* t, double v)
{
pushLong(t, doubleToBits(v));
uint64_t w = doubleToBits(v);
#ifdef __arm__
w = w << 32 | w >> 32;
#endif
pushLong(t, w);
}
inline object
@ -167,10 +171,14 @@ popLong(Thread* t)
return (b << 32) | a;
}
inline float
inline double
popDouble(Thread* t)
{
return bitsToDouble(popLong(t));
uint64_t v = popLong(t);
#ifdef __arm__
v = v << 32 | v >> 32;
#endif
return bitsToDouble(v);
}
inline object
@ -560,8 +568,17 @@ pushResult(Thread* t, unsigned returnCode, uint64_t result, bool indirect)
pushInt(t, result);
break;
case LongField:
case DoubleField:
#ifdef __arm__
result = result << 32 | result >> 32;
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", result);
}
pushLong(t, result);
break;
#endif
case LongField:
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", result);
}
@ -611,8 +628,17 @@ marshalArguments(Thread* t, uintptr_t* args, unsigned i, unsigned count,
args[offset++] = peekInt(t, sp++);
break;
case INT64_TYPE:
case DOUBLE_TYPE: {
case DOUBLE_TYPE:
#ifdef __arm__
{
uint64_t v = peekLong(t, sp);
v = v << 32 | v >> 32;
memcpy(args + offset, &v, 8);
offset += (8 / BytesPerWord);
sp += 2;
} break;
#endif
case INT64_TYPE: {
uint64_t v = peekLong(t, sp);
memcpy(args + offset, &v, 8);
offset += (8 / BytesPerWord);

View File

@ -895,7 +895,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
case 4:
if (bSize == 8) {
if (BytesPerWord == 8) {
alwaysRex(c, aSize, b, a);
alwaysRex(c, bSize, b, a);
opcode(c, 0x63);
modrm(c, 0xc0, a, b);
} else {

View File

@ -1,4 +1,6 @@
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;
public class List {
private static void expect(boolean v) {
@ -21,6 +23,114 @@ public class List {
expect(s1.equals(s2));
}
private static void testIterators(java.util.List<Integer> l) {
l.add(1);
l.add(2);
l.add(3);
ListIterator<Integer> it = l.listIterator();
expect(it.next().equals(Integer.valueOf(1)));
expect(it.next().equals(Integer.valueOf(2)));
expect(it.next().equals(Integer.valueOf(3)));
expect(! it.hasNext());
it = l.listIterator(1);
expect(it.next().equals(Integer.valueOf(2)));
expect(it.next().equals(Integer.valueOf(3)));
expect(! it.hasNext());
it = l.listIterator(2);
expect(it.next().equals(Integer.valueOf(3)));
expect(! it.hasNext());
it = l.listIterator(3);
expect(it.previous().equals(Integer.valueOf(3)));
expect(it.previous().equals(Integer.valueOf(2)));
expect(it.previous().equals(Integer.valueOf(1)));
expect(! it.hasPrevious());
it = l.listIterator(2);
expect(it.previous().equals(Integer.valueOf(2)));
expect(it.previous().equals(Integer.valueOf(1)));
expect(! it.hasPrevious());
it = l.listIterator(1);
expect(it.previous().equals(Integer.valueOf(1)));
expect(! it.hasPrevious());
}
private static void testIterators2(java.util.List<Integer> l) {
l.add(1);
l.add(2);
l.add(3);
ListIterator<Integer> it = l.listIterator();
expect(it.next().equals(Integer.valueOf(1)));
it.remove();
expect(it.next().equals(Integer.valueOf(2)));
it.remove();
expect(it.next().equals(Integer.valueOf(3)));
it.remove();
expect(! it.hasNext());
expect(l.isEmpty());
l.add(1);
l.add(2);
l.add(3);
it = l.listIterator(1);
expect(it.next().equals(Integer.valueOf(2)));
it.remove();
expect(it.next().equals(Integer.valueOf(3)));
it.remove();
expect(! it.hasNext());
expect(l.size() == 1);
l.add(2);
l.add(3);
it = l.listIterator(2);
expect(it.next().equals(Integer.valueOf(3)));
it.remove();
expect(! it.hasNext());
expect(l.size() == 2);
l.add(3);
it = l.listIterator(3);
expect(it.previous().equals(Integer.valueOf(3)));
it.remove();
expect(it.previous().equals(Integer.valueOf(2)));
it.remove();
expect(it.previous().equals(Integer.valueOf(1)));
it.remove();
expect(! it.hasPrevious());
expect(l.isEmpty());
l.add(1);
l.add(2);
l.add(3);
it = l.listIterator(2);
expect(it.previous().equals(Integer.valueOf(2)));
it.remove();
expect(it.previous().equals(Integer.valueOf(1)));
it.remove();
expect(! it.hasPrevious());
expect(l.size() == 1);
l.clear();
l.add(1);
l.add(2);
l.add(3);
it = l.listIterator(1);
expect(it.previous().equals(Integer.valueOf(1)));
it.remove();
expect(! it.hasPrevious());
expect(l.size() == 2);
}
public static void main(String args[]) {
ArrayList<Integer> l = new ArrayList<Integer>();
l.add(1); l.add(2); l.add(3); l.add(4); l.add(5);
@ -39,5 +149,11 @@ public class List {
for (int i=0; i < z.length; i++) {
System.out.println(z[i]);
}
testIterators(new ArrayList());
testIterators(new LinkedList());
testIterators2(new ArrayList());
testIterators2(new LinkedList());
}
}

View File

@ -35,7 +35,13 @@ public class Longs {
return a - (a % b);
}
private static int negativeOne() {
return -1;
}
public static void main(String[] args) {
expect(((long) negativeOne()) == -1);
{ long foo = 25214903884L;
int radix = 10;
expect(foo > 0);

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
log=build/log.txt
vg="nice valgrind --leak-check=full --num-callers=32 \
@ -28,7 +28,7 @@ for test in ${tests}; do
exit 1;;
esac
if (( ${?} == 0 )); then
if [ "${?}" = "0" ]; then
echo "success"
else
echo "fail"