Eval4j: catch IndexOutOfBounds exceptions

This commit is contained in:
Natalia Ukhorskaya
2014-06-20 13:43:53 +04:00
parent bdc60441c0
commit 0968ea6914
3 changed files with 91 additions and 32 deletions
+11 -4
View File
@@ -127,11 +127,21 @@ class JDIEval(
} }
override fun getArrayElement(array: Value, index: Value): Value { override fun getArrayElement(array: Value, index: Value): Value {
try {
return array.array().getValue(index.int).asValue() return array.array().getValue(index.int).asValue()
} }
catch (e: IndexOutOfBoundsException) {
throwEvalException(ArrayIndexOutOfBoundsException(e.getMessage()))
}
}
override fun setArrayElement(array: Value, index: Value, newValue: Value) { override fun setArrayElement(array: Value, index: Value, newValue: Value) {
array.array().setValue(index.int, newValue.asJdiValue(vm, array.asmType.arrayElementType)) try {
return array.array().setValue(index.int, newValue.asJdiValue(vm, array.asmType.arrayElementType))
}
catch (e: IndexOutOfBoundsException) {
throwEvalException(ArrayIndexOutOfBoundsException(e.getMessage()))
}
} }
private fun findField(fieldDesc: FieldDescription): jdi.Field { private fun findField(fieldDesc: FieldDescription): jdi.Field {
@@ -277,7 +287,4 @@ fun <T> mayThrow(f: () -> T): T {
catch (e: jdi.InvocationException) { catch (e: jdi.InvocationException) {
throw ThrownFromEvaluatedCodeException(e.exception().asValue()) throw ThrownFromEvaluatedCodeException(e.exception().asValue())
} }
catch (e: Throwable) {
throwBrokenCodeException(e)
}
} }
@@ -731,6 +731,54 @@ class TestData extends BaseTestData {
static class Derived extends Base {} static class Derived extends Base {}
} }
static boolean exceptionIndexOutOfBounds() {
int[] ints = new int[1];
try { int i = ints[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { ints[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
short[] shorts = new short[1];
try { short s = shorts[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { shorts[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
char[] chars = new char[1];
try { char c = chars[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { chars[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
byte[] bytes = new byte[1];
try { byte b = bytes[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { bytes[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
long[] longs = new long[1];
try { long l = longs[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { longs[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
double[] doubles = new double[1];
try { double d = doubles[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { doubles[2] = 1.0; return false; } catch (ArrayIndexOutOfBoundsException e) { }
float[] floats = new float[1];
try { float f = floats[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { floats[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
boolean[] booleans = new boolean[1];
try { boolean bool = booleans[2];return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { booleans[2] = true; return false; } catch (ArrayIndexOutOfBoundsException e) { }
Object[] objects = new Object[1];
try { Object o = objects[2]; return false; } catch (ArrayIndexOutOfBoundsException e) { }
try { objects[2] = 1; return false; } catch (ArrayIndexOutOfBoundsException e) { }
return true;
}
static boolean indexOutOfBoundsForString() {
String str = "";
try { str.charAt(10); return false; } catch (IndexOutOfBoundsException e) { }
try { str.substring(10); return false; } catch (IndexOutOfBoundsException e) { }
return true;
}
public TestData() { public TestData() {
} }
} }
@@ -150,7 +150,8 @@ object REFLECTION_EVAL : Eval {
val elementType = if (asmType.getDimensions() == 1) asmType.getElementType() else Type.getType(asmType.getDescriptor().substring(1)) val elementType = if (asmType.getDimensions() == 1) asmType.getElementType() else Type.getType(asmType.getDescriptor().substring(1))
val arr = array.obj().checkNull() val arr = array.obj().checkNull()
val ind = index.int val ind = index.int
return when (elementType.getSort()) { return mayThrow {
when (elementType.getSort()) {
Type.BOOLEAN -> boolean(JArray.getBoolean(arr, ind)) Type.BOOLEAN -> boolean(JArray.getBoolean(arr, ind))
Type.BYTE -> byte(JArray.getByte(arr, ind)) Type.BYTE -> byte(JArray.getByte(arr, ind))
Type.SHORT -> short(JArray.getShort(arr, ind)) Type.SHORT -> short(JArray.getShort(arr, ind))
@@ -167,6 +168,7 @@ object REFLECTION_EVAL : Eval {
else -> throw UnsupportedOperationException("Unsupported array element type: $elementType") else -> throw UnsupportedOperationException("Unsupported array element type: $elementType")
} }
} }
}
override fun setArrayElement(array: Value, index: Value, newValue: Value) { override fun setArrayElement(array: Value, index: Value, newValue: Value) {
val arr = array.obj().checkNull() val arr = array.obj().checkNull()
@@ -176,6 +178,7 @@ object REFLECTION_EVAL : Eval {
return return
} }
val elementType = array.asmType.getElementType() val elementType = array.asmType.getElementType()
mayThrow {
when (elementType.getSort()) { when (elementType.getSort()) {
Type.BOOLEAN -> JArray.setBoolean(arr, ind, newValue.boolean) Type.BOOLEAN -> JArray.setBoolean(arr, ind, newValue.boolean)
Type.BYTE -> JArray.setByte(arr, ind, newValue.int.toByte()) Type.BYTE -> JArray.setByte(arr, ind, newValue.int.toByte())
@@ -192,6 +195,7 @@ object REFLECTION_EVAL : Eval {
else -> throw UnsupportedOperationException("Unsupported array element type: $elementType") else -> throw UnsupportedOperationException("Unsupported array element type: $elementType")
} }
} }
}
fun <T> mayThrow(f: () -> T): T { fun <T> mayThrow(f: () -> T): T {
try { try {