Use correct type for GetValueFromShadowFrame
The field type is not necessarily the input type for boxed
primitives. If the field type is < 32 bits, it means there will be
partial object pointer in the JValue. If a conversion check is
later needed in GetUnboxedTypeAndValue, it will crash. The fix is
to use the PTypes.
Bug: 37446461
Test: test-art-host
Change-Id: I0c4b405f0c13910523b98a87ef12b9f302a5e241
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc
index bd7c4ad..b6f8a17 100644
--- a/runtime/method_handles.cc
+++ b/runtime/method_handles.cc
@@ -925,8 +925,17 @@
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 @@
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;
}