summaryrefslogtreecommitdiff
path: root/dalvik
diff options
context:
space:
mode:
authorOrion Hodson <oth@google.com>2019-11-12 18:44:47 +0000
committerOrion Hodson <oth@google.com>2019-12-09 10:23:58 +0000
commit2fdb0f3eecc1abf7e26ca5b410e07bf742f48457 (patch)
tree146500b51469de422301ab9bfcb1f6c4d7f01a55 /dalvik
parent06620d5308621889a296943c0a2029e6e5cb8d42 (diff)
Fix MethodHandles.explicitCastArguments for transforms
Fixes incorrectly handled paths in ExplicitCastArguments transform. Update MethodHandles.explicitCaseArguments() to use an ExplicitCastArguments transform if the call requires asType() conversion. We could have introduced another transform, but that's more code and before inserting the transform the code checks the explicit cast is equivalent to asType(). The transformer path had issues because StackFrame{Reader,Writer} classes do not perform asType() conversions as they read and write stack frame locations. Bug: 113855305 Test: art/test/testrunner.py --host --64 Test: art/tools/run-libcore-tests.sh --host Change-Id: I712bcf5a55f1f7c091af5daddeb3f8a5b7b5b4d3
Diffstat (limited to 'dalvik')
-rw-r--r--dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java57
1 files changed, 33 insertions, 24 deletions
diff --git a/dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java b/dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java
index b479d6fd88..7a1c20b64b 100644
--- a/dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java
+++ b/dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java
@@ -346,20 +346,29 @@ public class EmulatedStackFrame {
return this;
}
- protected void checkType(Class<?> type) {
+ private Class<?> getCurrentArgumentType() {
if (argumentIdx >= numArgs || argumentIdx == (RETURN_VALUE_IDX + 1)) {
throw new IllegalArgumentException("Invalid argument index: " + argumentIdx);
}
-
- final Class<?> expectedType = (argumentIdx == RETURN_VALUE_IDX) ?
+ return (argumentIdx == RETURN_VALUE_IDX) ?
frame.type.rtype() : frame.type.ptypes()[argumentIdx];
+ }
- if (expectedType != type) {
- throw new IllegalArgumentException("Incorrect type: " + type +
- ", expected: " + expectedType);
+ private static void checkAssignable(Class<?> expectedType, Class<?> actualType) {
+ if (!expectedType.isAssignableFrom(actualType)) {
+ throw new IllegalArgumentException("Incorrect type: " + actualType
+ + ", expected: " + expectedType);
}
}
+ protected void checkWriteType(Class<?> type) {
+ checkAssignable(getCurrentArgumentType(), type);
+ }
+
+ protected void checkReadType(Class<?> expectedType) {
+ checkAssignable(expectedType, getCurrentArgumentType());
+ }
+
/**
* Positions the cursor at the return value location, either in the references array
* or in the stack frame array. The next put* or next* call will result in a read or
@@ -408,55 +417,55 @@ public class EmulatedStackFrame {
*/
public static class StackFrameWriter extends StackFrameAccessor {
public void putNextByte(byte value) {
- checkType(byte.class);
+ checkWriteType(byte.class);
argumentIdx++;
frameBuf.putInt(value);
}
public void putNextInt(int value) {
- checkType(int.class);
+ checkWriteType(int.class);
argumentIdx++;
frameBuf.putInt(value);
}
public void putNextLong(long value) {
- checkType(long.class);
+ checkWriteType(long.class);
argumentIdx++;
frameBuf.putLong(value);
}
public void putNextChar(char value) {
- checkType(char.class);
+ checkWriteType(char.class);
argumentIdx++;
frameBuf.putInt((int) value);
}
public void putNextBoolean(boolean value) {
- checkType(boolean.class);
+ checkWriteType(boolean.class);
argumentIdx++;
frameBuf.putInt(value ? 1 : 0);
}
public void putNextShort(short value) {
- checkType(short.class);
+ checkWriteType(short.class);
argumentIdx++;
frameBuf.putInt((int) value);
}
public void putNextFloat(float value) {
- checkType(float.class);
+ checkWriteType(float.class);
argumentIdx++;
frameBuf.putFloat(value);
}
public void putNextDouble(double value) {
- checkType(double.class);
+ checkWriteType(double.class);
argumentIdx++;
frameBuf.putDouble(value);
}
public void putNextReference(Object value, Class<?> expectedType) {
- checkType(expectedType);
+ checkWriteType(expectedType);
argumentIdx++;
frame.references[referencesOffset++] = value;
}
@@ -468,55 +477,55 @@ public class EmulatedStackFrame {
*/
public static class StackFrameReader extends StackFrameAccessor {
public byte nextByte() {
- checkType(byte.class);
+ checkReadType(byte.class);
argumentIdx++;
return (byte) frameBuf.getInt();
}
public int nextInt() {
- checkType(int.class);
+ checkReadType(int.class);
argumentIdx++;
return frameBuf.getInt();
}
public long nextLong() {
- checkType(long.class);
+ checkReadType(long.class);
argumentIdx++;
return frameBuf.getLong();
}
public char nextChar() {
- checkType(char.class);
+ checkReadType(char.class);
argumentIdx++;
return (char) frameBuf.getInt();
}
public boolean nextBoolean() {
- checkType(boolean.class);
+ checkReadType(boolean.class);
argumentIdx++;
return (frameBuf.getInt() != 0);
}
public short nextShort() {
- checkType(short.class);
+ checkReadType(short.class);
argumentIdx++;
return (short) frameBuf.getInt();
}
public float nextFloat() {
- checkType(float.class);
+ checkReadType(float.class);
argumentIdx++;
return frameBuf.getFloat();
}
public double nextDouble() {
- checkType(double.class);
+ checkReadType(double.class);
argumentIdx++;
return frameBuf.getDouble();
}
public <T> T nextReference(Class<T> expectedType) {
- checkType(expectedType);
+ checkReadType(expectedType);
argumentIdx++;
return (T) frame.references[referencesOffset++];
}