/*
|
* Copyright (C) 2014 The Android Open Source Project
|
*
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
* you may not use this file except in compliance with the License.
|
* You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
* limitations under the License.
|
*/
|
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
|
// Note that $opt$ is a marker for the optimizing compiler to test
|
// it does compile the method.
|
|
public class Main extends TestCase {
|
public static void main(String[] args) throws Exception {
|
$opt$TestAllocations();
|
$opt$TestWithInitializations();
|
$opt$TestNegativeValueNewByteArray();
|
$opt$TestNegativeValueNewCharArray();
|
testNegativeArraySize();
|
testSmaliFilledNewArray();
|
testSmaliFillArrayData();
|
testSmaliVerifyError();
|
}
|
|
static void $opt$TestAllocations() {
|
float[] a = new float[1];
|
assertEquals(1, a.length);
|
|
double[] b = new double[2];
|
assertEquals(2, b.length);
|
|
long[] c = new long[3];
|
assertEquals(3, c.length);
|
|
int[] d = new int[4];
|
assertEquals(4, d.length);
|
|
short[] e = new short[5];
|
assertEquals(5, e.length);
|
|
char[] f = new char[6];
|
assertEquals(6, f.length);
|
|
byte[] g = new byte[7];
|
assertEquals(7, g.length);
|
|
boolean[] h = new boolean[8];
|
assertEquals(8, h.length);
|
|
Object[] i = new Object[9];
|
assertEquals(9, i.length);
|
}
|
|
static void $opt$TestWithInitializations() {
|
float[] a = { 1.2f };
|
assertEquals(1, a.length);
|
assertEquals(1.2f, a[0]);
|
|
double[] b = { 4.3, 1.2 };
|
assertEquals(2, b.length);
|
assertEquals(4.3, b[0]);
|
assertEquals(1.2, b[1]);
|
|
long[] c = { 4L, 5L };
|
assertEquals(2, c.length);
|
assertEquals(4L, c[0]);
|
assertEquals(5L, c[1]);
|
|
int[] d = {1, 2, 3};
|
assertEquals(3, d.length);
|
assertEquals(1, d[0]);
|
assertEquals(2, d[1]);
|
assertEquals(3, d[2]);
|
|
short[] e = {4, 5, 6};
|
assertEquals(3, e.length);
|
assertEquals(4, e[0]);
|
assertEquals(5, e[1]);
|
assertEquals(6, e[2]);
|
|
char[] f = {'a', 'b'};
|
assertEquals(2, f.length);
|
assertEquals('a', f[0]);
|
assertEquals('b', f[1]);
|
|
byte[] g = {7, 8, 9};
|
assertEquals(3, g.length);
|
assertEquals(7, g[0]);
|
assertEquals(8, g[1]);
|
assertEquals(9, g[2]);
|
|
boolean[] h = {true, false};
|
assertEquals(2, h.length);
|
assertEquals(true, h[0]);
|
assertEquals(false, h[1]);
|
|
Object obj1 = new Object();
|
Object obj2 = new Object();
|
Object[] i = {obj1, obj2};
|
assertEquals(2, i.length);
|
assertEquals(obj1, i[0]);
|
assertEquals(obj2, i[1]);
|
}
|
|
static void $opt$TestNegativeValueNewByteArray() {
|
// Use an array initializer to hint the use of filled-new-array.
|
byte[] a = { (byte)0xa0, (byte)0xa1, (byte)0xa2, (byte)0xa3,
|
(byte)0xa4, (byte)0xa5, (byte)0xa6, (byte)0xa7 };
|
for (int i = 0; i < a.length; i++) {
|
assertEquals((byte)0xa0 + i, a[i]);
|
}
|
}
|
|
static void $opt$TestNegativeValueNewCharArray() {
|
// Use an array initializer to hint the use of filled-new-array.
|
char[] a = { (char)0xa000, (char)0xa001, (char)0xa002, (char)0xa003,
|
(char)0xa004, (char)0xa005, (char)0xa006, (char)0xa007 };
|
for (int i = 0; i < a.length; i++) {
|
assertEquals((char)0xa000 + i, a[i]);
|
}
|
}
|
|
static void testNegativeArraySize() {
|
int i = 0;
|
try {
|
$opt$TestNegativeArraySize();
|
} catch (NegativeArraySizeException e) {
|
i = 1;
|
}
|
assertEquals(i, 1);
|
}
|
|
static int[] $opt$TestNegativeArraySize() {
|
int[] array = new int[-1];
|
return null;
|
}
|
|
public static void testSmaliFilledNewArray() throws Exception {
|
Class<?> c = Class.forName("FilledNewArray");
|
|
{
|
Method m = c.getMethod("newInt", Integer.TYPE, Integer.TYPE, Integer.TYPE);
|
Object[] args = {new Integer(1), new Integer(2), new Integer(3)};
|
int[] result = (int[])m.invoke(null, args);
|
assertEquals(3, result.length);
|
assertEquals(1, result[0]);
|
assertEquals(2, result[1]);
|
assertEquals(3, result[2]);
|
}
|
|
{
|
Method m = c.getMethod("newRef", Object.class, Object.class);
|
Object[] args = {new Integer(1), new Integer(2)};
|
Object[] result = (Object[])m.invoke(null, args);
|
assertEquals(2, result.length);
|
assertEquals(args[0], result[0]);
|
assertEquals(args[1], result[1]);
|
}
|
|
{
|
Method m = c.getMethod("newArray", int[].class, int[].class);
|
Object[] args = {new int[0], new int[1]};
|
Object[] result = (Object[])m.invoke(null, args);
|
assertEquals(2, result.length);
|
assertEquals(args[0], result[0]);
|
assertEquals(args[1], result[1]);
|
}
|
|
{
|
Method m = c.getMethod("newIntRange", Integer.TYPE, Integer.TYPE, Integer.TYPE);
|
Object[] args = {new Integer(1), new Integer(2), new Integer(3)};
|
int[] result = (int[])m.invoke(null, args);
|
assertEquals(3, result.length);
|
assertEquals(1, result[0]);
|
assertEquals(2, result[1]);
|
assertEquals(3, result[2]);
|
}
|
|
{
|
Method m = c.getMethod("newRefRange", Object.class, Object.class);
|
Object[] args = {new Integer(1), new Integer(2)};
|
Object[] result = (Object[])m.invoke(null, args);
|
assertEquals(2, result.length);
|
assertEquals(args[0], result[0]);
|
assertEquals(args[1], result[1]);
|
}
|
|
{
|
Method m = c.getMethod("newArrayRange", int[].class, int[].class);
|
Object[] args = {new int[0], new int[1]};
|
Object[] result = (Object[])m.invoke(null, args);
|
assertEquals(2, result.length);
|
assertEquals(args[0], result[0]);
|
assertEquals(args[1], result[1]);
|
}
|
}
|
|
public static void testSmaliVerifyError() throws Exception {
|
Error error = null;
|
// Ensure the elements in filled-new-array must be assignable
|
// to the array component type.
|
try {
|
Class.forName("FilledNewArrayVerifyError");
|
} catch (VerifyError e) {
|
error = e;
|
}
|
assertNotNull(error);
|
}
|
|
public static void testSmaliFillArrayData() throws Exception {
|
Class<?> c = Class.forName("FillArrayData");
|
{
|
Method m = c.getMethod("emptyIntArray", int[].class);
|
int[] array = new int[0];
|
Object[] args = { array };
|
m.invoke(null, args);
|
assertEquals(0, array.length);
|
|
array = new int[2];
|
args[0] = array;
|
m.invoke(null, args);
|
// Test that nothing has been written to the array.
|
assertEquals(0, array[0]);
|
assertEquals(0, array[1]);
|
|
array = new int[] { 42, -42 };
|
args[0] = array;
|
m.invoke(null, args);
|
// Test that nothing has been written to the array.
|
assertEquals(42, array[0]);
|
assertEquals(-42, array[1]);
|
|
Throwable exception = null;
|
args[0] = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof NullPointerException);
|
}
|
assertNotNull(exception);
|
}
|
|
{
|
Method m = c.getMethod("intArray", int[].class);
|
int[] array = new int[7];
|
Object[] args = { array };
|
m.invoke(null, args);
|
assertEquals(7, array.length);
|
assertEquals(1, array[0]);
|
assertEquals(2, array[1]);
|
assertEquals(3, array[2]);
|
assertEquals(4, array[3]);
|
assertEquals(5, array[4]);
|
assertEquals(0, array[5]);
|
assertEquals(0, array[6]);
|
|
array = new int[2];
|
args[0] = array;
|
Throwable exception = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof IndexOutOfBoundsException);
|
}
|
assertNotNull(exception);
|
exception = null;
|
// Test that nothing has been written to the array.
|
assertEquals(0, array[0]);
|
assertEquals(0, array[1]);
|
|
args[0] = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof NullPointerException);
|
}
|
assertNotNull(exception);
|
}
|
|
{
|
Method m = c.getMethod("intArrayFillInstructionAfterData", int[].class);
|
int[] array = new int[7];
|
Object[] args = { array };
|
m.invoke(null, args);
|
assertEquals(7, array.length);
|
assertEquals(1, array[0]);
|
assertEquals(2, array[1]);
|
assertEquals(3, array[2]);
|
assertEquals(4, array[3]);
|
assertEquals(5, array[4]);
|
assertEquals(0, array[5]);
|
assertEquals(0, array[6]);
|
|
array = new int[2];
|
args[0] = array;
|
Throwable exception = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof IndexOutOfBoundsException);
|
}
|
assertNotNull(exception);
|
exception = null;
|
// Test that nothing has been written to the array.
|
assertEquals(0, array[0]);
|
assertEquals(0, array[1]);
|
|
args[0] = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof NullPointerException);
|
}
|
assertNotNull(exception);
|
}
|
|
{
|
Method m = c.getMethod("shortArray", short[].class);
|
short[] array = new short[7];
|
Object[] args = { array };
|
m.invoke(null, args);
|
assertEquals(7, array.length);
|
assertEquals(1, array[0]);
|
assertEquals(2, array[1]);
|
assertEquals(3, array[2]);
|
assertEquals(4, array[3]);
|
assertEquals(5, array[4]);
|
assertEquals(0, array[5]);
|
assertEquals(0, array[6]);
|
|
array = new short[2];
|
args[0] = array;
|
Throwable exception = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof IndexOutOfBoundsException);
|
}
|
assertNotNull(exception);
|
exception = null;
|
// Test that nothing has been written to the array.
|
assertEquals(0, array[0]);
|
assertEquals(0, array[1]);
|
|
args[0] = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof NullPointerException);
|
}
|
assertNotNull(exception);
|
}
|
|
{
|
Method m = c.getMethod("longArray", long[].class);
|
long[] array = new long[7];
|
Object[] args = { array };
|
m.invoke(null, args);
|
assertEquals(7, array.length);
|
assertEquals(1L, array[0]);
|
assertEquals(2L, array[1]);
|
assertEquals(3L, array[2]);
|
assertEquals(4L, array[3]);
|
assertEquals(5L, array[4]);
|
assertEquals(0L, array[5]);
|
assertEquals(0L, array[6]);
|
|
array = new long[2];
|
args[0] = array;
|
Throwable exception = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof IndexOutOfBoundsException);
|
}
|
assertNotNull(exception);
|
exception = null;
|
// Test that nothing has been written to the array.
|
assertEquals(0, array[0]);
|
assertEquals(0, array[1]);
|
|
args[0] = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof NullPointerException);
|
}
|
assertNotNull(exception);
|
}
|
|
{
|
Method m = c.getMethod("charArray", char[].class);
|
char[] array = new char[7];
|
Object[] args = { array };
|
m.invoke(null, args);
|
assertEquals(7, array.length);
|
assertEquals(1, array[0]);
|
assertEquals(2, array[1]);
|
assertEquals(3, array[2]);
|
assertEquals(4, array[3]);
|
assertEquals(5, array[4]);
|
assertEquals(0, array[5]);
|
assertEquals(0, array[6]);
|
|
array = new char[2];
|
args[0] = array;
|
Throwable exception = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof IndexOutOfBoundsException);
|
}
|
assertNotNull(exception);
|
exception = null;
|
// Test that nothing has been written to the array.
|
assertEquals(0, array[0]);
|
assertEquals(0, array[1]);
|
|
args[0] = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof NullPointerException);
|
}
|
assertNotNull(exception);
|
}
|
|
{
|
Method m = c.getMethod("byteArray", byte[].class);
|
byte[] array = new byte[7];
|
Object[] args = { array };
|
m.invoke(null, args);
|
assertEquals(7, array.length);
|
assertEquals(1, array[0]);
|
assertEquals(2, array[1]);
|
assertEquals(3, array[2]);
|
assertEquals(4, array[3]);
|
assertEquals(5, array[4]);
|
assertEquals(0, array[5]);
|
assertEquals(0, array[6]);
|
|
array = new byte[2];
|
args[0] = array;
|
Throwable exception = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof IndexOutOfBoundsException);
|
}
|
assertNotNull(exception);
|
exception = null;
|
// Test that nothing has been written to the array.
|
assertEquals(0, array[0]);
|
assertEquals(0, array[1]);
|
|
args[0] = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof NullPointerException);
|
}
|
assertNotNull(exception);
|
}
|
|
{
|
Method m = c.getMethod("booleanArray", boolean[].class);
|
boolean[] array = new boolean[5];
|
Object[] args = { array };
|
m.invoke(null, args);
|
assertEquals(5, array.length);
|
assertEquals(false, array[0]);
|
assertEquals(true, array[1]);
|
assertEquals(true, array[2]);
|
assertEquals(false, array[3]);
|
assertEquals(false, array[4]);
|
|
array = new boolean[2];
|
args[0] = array;
|
Throwable exception = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof IndexOutOfBoundsException);
|
}
|
assertNotNull(exception);
|
exception = null;
|
// Test that nothing has been written to the array.
|
assertEquals(false, array[0]);
|
assertEquals(false, array[1]);
|
|
args[0] = null;
|
try {
|
m.invoke(null, args);
|
} catch (InvocationTargetException e) {
|
exception = e.getCause();
|
assertTrue(exception instanceof NullPointerException);
|
}
|
assertNotNull(exception);
|
}
|
}
|
}
|