--- a/src/hotspot/share/prims/jni.cpp Mon Jan 28 23:00:31 2019 +0100
+++ b/src/hotspot/share/prims/jni.cpp Tue Jan 29 08:43:33 2019 +0100
@@ -2591,9 +2591,10 @@
ret = JNIHandles::make_local(env, a->obj_at(index));
return ret;
} else {
- char buf[jintAsStringSize];
- sprintf(buf, "%d", index);
- THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
+ ResourceMark rm(THREAD);
+ stringStream ss;
+ ss.print("Index %d out of bounds for length %d", index, a->length());
+ THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
}
JNI_END
@@ -2624,9 +2625,10 @@
THROW_MSG(vmSymbols::java_lang_ArrayStoreException(), ss.as_string());
}
} else {
- char buf[jintAsStringSize];
- sprintf(buf, "%d", index);
- THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
+ ResourceMark rm(THREAD);
+ stringStream ss;
+ ss.print("Index %d out of bounds for length %d", index, a->length());
+ THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
}
JNI_END
@@ -2801,6 +2803,19 @@
, HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
+static void check_bounds(jsize start, jsize copy_len, jsize array_len, TRAPS) {
+ ResourceMark rm(THREAD);
+ if (copy_len < 0) {
+ stringStream ss;
+ ss.print("Length %d is negative", copy_len);
+ THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
+ } else if (start < 0 || (start > array_len - copy_len)) {
+ stringStream ss;
+ ss.print("Array region %d.." INT64_FORMAT " out of bounds for length %d",
+ start, (int64_t)start+(int64_t)copy_len, array_len);
+ THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string());
+ }
+}
#define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
, EntryProbe, ReturnProbe); \
@@ -2814,12 +2829,9 @@
EntryProbe; \
DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
- if (start < 0 || len < 0 || (start > src->length() - len)) { \
- THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
- } else { \
- if (len > 0) { \
- ArrayAccess<>::arraycopy_to_native(src, typeArrayOopDesc::element_offset<ElementType>(start), buf, len); \
- } \
+ check_bounds(start, len, src->length(), CHECK); \
+ if (len > 0) { \
+ ArrayAccess<>::arraycopy_to_native(src, typeArrayOopDesc::element_offset<ElementType>(start), buf, len); \
} \
JNI_END
@@ -2861,12 +2873,9 @@
EntryProbe; \
DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
- if (start < 0 || len < 0 || (start > dst->length() - len)) { \
- THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
- } else { \
- if (len > 0) { \
- ArrayAccess<>::arraycopy_from_native(buf, dst, typeArrayOopDesc::element_offset<ElementType>(start), len); \
- } \
+ check_bounds(start, len, dst->length(), CHECK); \
+ if (len > 0) { \
+ ArrayAccess<>::arraycopy_from_native(buf, dst, typeArrayOopDesc::element_offset<ElementType>(start), len); \
} \
JNI_END
--- a/test/hotspot/jtreg/runtime/exceptionMsgs/ArrayIndexOutOfBoundsException/ArrayIndexOutOfBoundsExceptionTest.java Mon Jan 28 23:00:31 2019 +0100
+++ b/test/hotspot/jtreg/runtime/exceptionMsgs/ArrayIndexOutOfBoundsException/ArrayIndexOutOfBoundsExceptionTest.java Tue Jan 29 08:43:33 2019 +0100
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2018 SAP SE. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,10 @@
*/
public class ArrayIndexOutOfBoundsExceptionTest {
+ static {
+ System.loadLibrary("ArrayIndexOutOfBoundsExceptionTest");
+ }
+
// Some fields used in the test.
static int[] staticArray = new int[0];
static long[][] staticLongArray = new long[0][0];
@@ -88,6 +92,26 @@
}
}
+ static native void doNativeArrayStore(Object[] dst, Object element, int index);
+ static native Object doNativeArrayLoad(Object[] src, int index);
+
+ static native void doNativeBooleanArrayRegionLoad (boolean[] source, int start, int len);
+ static native void doNativeBooleanArrayRegionStore(boolean[] source, int start, int len);
+ static native void doNativeByteArrayRegionLoad (byte[] source, int start, int len);
+ static native void doNativeByteArrayRegionStore (byte[] source, int start, int len);
+ static native void doNativeShortArrayRegionLoad (short[] source, int start, int len);
+ static native void doNativeShortArrayRegionStore (short[] source, int start, int len);
+ static native void doNativeCharArrayRegionLoad (char[] source, int start, int len);
+ static native void doNativeCharArrayRegionStore (char[] source, int start, int len);
+ static native void doNativeIntArrayRegionLoad (int[] source, int start, int len);
+ static native void doNativeIntArrayRegionStore (int[] source, int start, int len);
+ static native void doNativeLongArrayRegionLoad (long[] source, int start, int len);
+ static native void doNativeLongArrayRegionStore (long[] source, int start, int len);
+ static native void doNativeFloatArrayRegionLoad (float[] source, int start, int len);
+ static native void doNativeFloatArrayRegionStore (float[] source, int start, int len);
+ static native void doNativeDoubleArrayRegionLoad (double[] source, int start, int len);
+ static native void doNativeDoubleArrayRegionStore (double[] source, int start, int len);
+
/**
*
*/
@@ -439,5 +463,463 @@
assertEquals(e.getMessage(),
"arraycopy: last destination index 7 out of bounds for float[5]");
}
+
+
+ // Test native array access.
+
+
+ try {
+ System.out.println(doNativeArrayLoad(oa2, 77));
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Index 77 out of bounds for length 5");
+ }
+ try {
+ System.out.println(doNativeArrayLoad(oa1, -1));
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Index -1 out of bounds for length 10");
+ }
+
+ try {
+ doNativeArrayStore(oa1, "Some String", Integer.MIN_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Index -2147483648 out of bounds for length 10");
+ }
+ try {
+ doNativeArrayStore(oa1, "Some String", 13);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Index 13 out of bounds for length 10");
+ }
+
+ // Boolean
+
+ // Native array region loads.
+ // Boolean, len negative.
+ try {
+ doNativeBooleanArrayRegionLoad(za2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Boolean, index negative.
+ try {
+ doNativeBooleanArrayRegionLoad(za2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Boolean, index+len too big.
+ try {
+ doNativeBooleanArrayRegionLoad(za2, 3, Integer.MAX_VALUE-1);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483649 out of bounds for length 10");
+ }
+ // Native array region stores
+ // Boolean, len negative.
+ try {
+ doNativeBooleanArrayRegionStore(za2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Boolean, index negative.
+ try {
+ doNativeBooleanArrayRegionStore(za2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Boolean, index+len too big.
+ try {
+ doNativeBooleanArrayRegionStore(za2, 3, Integer.MAX_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483650 out of bounds for length 10");
+ }
+
+ // Byte
+
+ // Native array region loads.
+ // Byte, len negative.
+ try {
+ doNativeByteArrayRegionLoad(ba1, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Byte, index negative.
+ try {
+ doNativeByteArrayRegionLoad(ba1, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 0");
+ }
+ // Byte, index+len too big.
+ try {
+ doNativeByteArrayRegionLoad(ba2, 3, Integer.MAX_VALUE-1);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483649 out of bounds for length 10");
+ }
+ // Native array region stores
+ // Byte, len negative.
+ try {
+ doNativeByteArrayRegionStore(ba2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Byte, index negative.
+ try {
+ doNativeByteArrayRegionStore(ba2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Byte, index+len too big.
+ try {
+ doNativeByteArrayRegionStore(ba2, 3, Integer.MAX_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483650 out of bounds for length 10");
+ }
+
+ // Short
+
+ // Native array region loads.
+ // Short, len negative.
+ try {
+ doNativeShortArrayRegionLoad(sa2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Short, index negative.
+ try {
+ doNativeShortArrayRegionLoad(sa2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Short, index+len too big.
+ try {
+ doNativeShortArrayRegionLoad(sa2, 3, Integer.MAX_VALUE-1);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483649 out of bounds for length 10");
+ }
+ // Native array region stores
+ // Short, len negative.
+ try {
+ doNativeShortArrayRegionStore(sa2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Short, index negative.
+ try {
+ doNativeShortArrayRegionStore(sa2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Short, index+len too big.
+ try {
+ doNativeShortArrayRegionStore(sa2, 3, Integer.MAX_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483650 out of bounds for length 10");
+ }
+
+ // Char
+
+ // Native array region loads.
+ // Char, len negative.
+ try {
+ doNativeCharArrayRegionLoad(ca2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Char, index negative.
+ try {
+ doNativeCharArrayRegionLoad(ca2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Char, index+len too big.
+ try {
+ doNativeCharArrayRegionLoad(ca2, 3, Integer.MAX_VALUE-1);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483649 out of bounds for length 10");
+ }
+ // Native array region stores
+ // Char, len negative.
+ try {
+ doNativeCharArrayRegionStore(ca2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Char, index negative.
+ try {
+ doNativeCharArrayRegionStore(ca2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Char, index+len too big.
+ try {
+ doNativeCharArrayRegionStore(ca2, 3, Integer.MAX_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483650 out of bounds for length 10");
+ }
+
+ // Int
+
+ // Native array region loads.
+ // Int, len negative.
+ try {
+ doNativeIntArrayRegionLoad(ia2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Int, index negative.
+ try {
+ doNativeIntArrayRegionLoad(ia2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Int, index+len too big.
+ try {
+ doNativeIntArrayRegionLoad(ia2, 3, Integer.MAX_VALUE-1);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483649 out of bounds for length 10");
+ }
+ // Native array region stores
+ // Int, len negative.
+ try {
+ doNativeIntArrayRegionStore(ia2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Int, index negative.
+ try {
+ doNativeIntArrayRegionStore(ia2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Int, index+len too big.
+ try {
+ doNativeIntArrayRegionStore(ia2, 3, Integer.MAX_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483650 out of bounds for length 10");
+ }
+
+ // Long
+
+ // Native array region loads.
+ // Long, len negative.
+ try {
+ doNativeLongArrayRegionLoad(la2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Long, index negative.
+ try {
+ doNativeLongArrayRegionLoad(la2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Long, index+len too big.
+ try {
+ doNativeLongArrayRegionLoad(la2, 3, Integer.MAX_VALUE-1);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483649 out of bounds for length 10");
+ }
+ // Native array region stores
+ // Long, len negative.
+ try {
+ doNativeLongArrayRegionStore(la2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Long, index negative.
+ try {
+ doNativeLongArrayRegionStore(la2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Long, index+len too big.
+ try {
+ doNativeLongArrayRegionStore(la2, 3, Integer.MAX_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483650 out of bounds for length 10");
+ }
+
+ // Float
+
+ // Native array region loads.
+ // Float, len negative.
+ try {
+ doNativeFloatArrayRegionLoad(fa2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Float, index negative.
+ try {
+ doNativeFloatArrayRegionLoad(fa2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Float, index+len too big.
+ try {
+ doNativeFloatArrayRegionLoad(fa2, 3, Integer.MAX_VALUE-1);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483649 out of bounds for length 10");
+ }
+ // Native array region stores
+ // Float, len negative.
+ try {
+ doNativeFloatArrayRegionStore(fa2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Float, index negative.
+ try {
+ doNativeFloatArrayRegionStore(fa2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Float, index+len too big.
+ try {
+ doNativeFloatArrayRegionStore(fa2, 3, Integer.MAX_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483650 out of bounds for length 10");
+ }
+
+ // Double
+
+ // Native array region loads.
+ // Double, len negative.
+ try {
+ doNativeDoubleArrayRegionLoad(da2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Double, index negative.
+ try {
+ doNativeDoubleArrayRegionLoad(da2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Double, index+len too big.
+ try {
+ doNativeDoubleArrayRegionLoad(da2, 3, Integer.MAX_VALUE-1);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483649 out of bounds for length 10");
+ }
+ // Native array region stores
+ // Double, len negative.
+ try {
+ doNativeDoubleArrayRegionStore(da2, 3, -77);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Length -77 is negative");
+ }
+ // Double, index negative.
+ try {
+ doNativeDoubleArrayRegionStore(da2, -3, 3);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region -3..0 out of bounds for length 10");
+ }
+ // Double, index+len too big.
+ try {
+ doNativeDoubleArrayRegionStore(da2, 3, Integer.MAX_VALUE);
+ fail();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ assertEquals(e.getMessage(),
+ "Array region 3..2147483650 out of bounds for length 10");
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/exceptionMsgs/ArrayIndexOutOfBoundsException/libArrayIndexOutOfBoundsExceptionTest.c Tue Jan 29 08:43:33 2019 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+
+JNIEXPORT void JNICALL
+ Java_ArrayIndexOutOfBoundsExceptionTest_doNativeArrayStore(JNIEnv *env, jclass klass,
+ jobjectArray array, jobject element, jint index) {
+ (*env)->SetObjectArrayElement(env, array, index, element);
+}
+
+JNIEXPORT jobject JNICALL
+ Java_ArrayIndexOutOfBoundsExceptionTest_doNativeArrayLoad(JNIEnv *env, jclass klass,
+ jobjectArray array, jint index) {
+ return (*env)->GetObjectArrayElement(env, array, index);
+}
+
+
+#define REGIONACCESS(ElementType,NameType) \
+JNIEXPORT void JNICALL \
+ Java_ArrayIndexOutOfBoundsExceptionTest_doNative##NameType##ArrayRegionLoad(JNIEnv *env, jclass klass, \
+ ElementType##Array array, jint start, jint len) { \
+ ElementType clone[100]; \
+ (*env)->Get##NameType##ArrayRegion(env, array, start, len, clone); \
+} \
+JNIEXPORT void JNICALL \
+ Java_ArrayIndexOutOfBoundsExceptionTest_doNative##NameType##ArrayRegionStore(JNIEnv *env, jclass klass, \
+ ElementType##Array array, jint start, jint len) { \
+ ElementType content[100]; \
+ (*env)->Set##NameType##ArrayRegion(env, array, start, len, content); \
+}
+
+REGIONACCESS(jboolean, Boolean)
+REGIONACCESS(jbyte, Byte)
+REGIONACCESS(jshort, Short)
+REGIONACCESS(jchar, Char)
+REGIONACCESS(jint, Int)
+REGIONACCESS(jlong, Long)
+REGIONACCESS(jfloat, Float)
+REGIONACCESS(jdouble, Double)