diff options
| -rw-r--r-- | runtime/method_handles.cc | 26 | ||||
| -rw-r--r-- | test/959-invoke-polymorphic-accessors/src/Main.java | 12 |
2 files changed, 34 insertions, 4 deletions
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc index bd7c4ad53c..b6f8a173c0 100644 --- a/runtime/method_handles.cc +++ b/runtime/method_handles.cc @@ -925,8 +925,17 @@ bool DoInvokePolymorphicFieldAccess(Thread* self, case mirror::MethodHandle::kInstancePut: { size_t obj_reg = is_range ? first_arg : args[0]; size_t value_reg = is_range ? (first_arg + 1) : args[1]; - JValue value = GetValueFromShadowFrame(shadow_frame, field_type, value_reg); - if (do_conversions && !ConvertArgumentValue(callsite_type, handle_type, 1, &value)) { + const size_t kPTypeIndex = 1; + // Use ptypes instead of field type since we may be unboxing a reference for a primitive + // field. The field type is incorrect for this case. + JValue value = GetValueFromShadowFrame( + shadow_frame, + callsite_type->GetPTypes()->Get(kPTypeIndex)->GetPrimitiveType(), + value_reg); + if (do_conversions && !ConvertArgumentValue(callsite_type, + handle_type, + kPTypeIndex, + &value)) { DCHECK(self->IsExceptionPending()); return false; } @@ -940,8 +949,17 @@ bool DoInvokePolymorphicFieldAccess(Thread* self, return false; } size_t value_reg = is_range ? first_arg : args[0]; - JValue value = GetValueFromShadowFrame(shadow_frame, field_type, value_reg); - if (do_conversions && !ConvertArgumentValue(callsite_type, handle_type, 0, &value)) { + const size_t kPTypeIndex = 0; + // Use ptypes instead of field type since we may be unboxing a reference for a primitive + // field. The field type is incorrect for this case. + JValue value = GetValueFromShadowFrame( + shadow_frame, + callsite_type->GetPTypes()->Get(kPTypeIndex)->GetPrimitiveType(), + value_reg); + if (do_conversions && !ConvertArgumentValue(callsite_type, + handle_type, + kPTypeIndex, + &value)) { DCHECK(self->IsExceptionPending()); return false; } diff --git a/test/959-invoke-polymorphic-accessors/src/Main.java b/test/959-invoke-polymorphic-accessors/src/Main.java index b7ecf8e818..59db8076b2 100644 --- a/test/959-invoke-polymorphic-accessors/src/Main.java +++ b/test/959-invoke-polymorphic-accessors/src/Main.java @@ -794,6 +794,7 @@ public class Main { ValueHolder valueHolder = new ValueHolder(); MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandle h0 = lookup.findSetter(ValueHolder.class, "m_f", float.class); + MethodHandle s0 = lookup.findSetter(ValueHolder.class, "m_s", short.class); h0.invoke(valueHolder, 0.22f); h0.invoke(valueHolder, new Float(1.11f)); Number floatNumber = getFloatAsNumber(); @@ -807,6 +808,11 @@ public class Main { unreachable(); } catch (NullPointerException e) {} + // Test that type conversion checks work on small field types. + short temp = (short)s0.invoke(valueHolder, new Byte((byte)45)); + assertTrue(temp == 0); + assertTrue(valueHolder.m_s == 45); + h0.invoke(valueHolder, (byte)1); h0.invoke(valueHolder, (short)2); h0.invoke(valueHolder, 3); @@ -848,6 +854,7 @@ public class Main { private static void testStaticSetter() throws Throwable { MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodHandle s0 = lookup.findStaticSetter(ValueHolder.class, "s_s", short.class); MethodHandle h0 = lookup.findStaticSetter(ValueHolder.class, "s_f", float.class); h0.invoke(0.22f); h0.invoke(new Float(1.11f)); @@ -860,6 +867,11 @@ public class Main { unreachable(); } catch (NullPointerException e) {} + // Test that type conversion checks work on small field types. + short temp = (short)s0.invoke(new Byte((byte)45)); + assertTrue(temp == 0); + assertTrue(ValueHolder.s_s == 45); + h0.invoke((byte)1); h0.invoke((short)2); h0.invoke(3); |