diff options
author | Orion Hodson <oth@google.com> | 2019-11-12 18:44:47 +0000 |
---|---|---|
committer | Orion Hodson <oth@google.com> | 2019-12-09 10:23:58 +0000 |
commit | 2fdb0f3eecc1abf7e26ca5b410e07bf742f48457 (patch) | |
tree | 146500b51469de422301ab9bfcb1f6c4d7f01a55 /dalvik | |
parent | 06620d5308621889a296943c0a2029e6e5cb8d42 (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.java | 57 |
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++]; } |