MethodHandles: Enable return value conversions.
Enables return values conversions and simplify the type conversion
logic. Ensures check for WrongMethodTypeExceptions before invoking a
method handle.
Test: m test-art-host-run-test-956-methodhandles
Bug: 30550796
Change-Id: I8add3ad0a19b43010946b4fb9f1c0f0949287860
diff --git a/runtime/primitive.h b/runtime/primitive.h
index 18f45ff..7cc47ad 100644
--- a/runtime/primitive.h
+++ b/runtime/primitive.h
@@ -138,6 +138,9 @@
static const char* PrettyDescriptor(Type type);
+ // Returns the descriptor corresponding to the boxed type of |type|.
+ static const char* BoxedDescriptor(Type type);
+
static bool IsFloatingPointType(Type type) {
return type == kPrimFloat || type == kPrimDouble;
}
@@ -158,6 +161,32 @@
}
}
+ // Return true if |type| is an numeric type.
+ static bool IsNumericType(Type type) {
+ switch (type) {
+ case Primitive::Type::kPrimNot: return false;
+ case Primitive::Type::kPrimBoolean: return false;
+ case Primitive::Type::kPrimByte: return true;
+ case Primitive::Type::kPrimChar: return false;
+ case Primitive::Type::kPrimShort: return true;
+ case Primitive::Type::kPrimInt: return true;
+ case Primitive::Type::kPrimLong: return true;
+ case Primitive::Type::kPrimFloat: return true;
+ case Primitive::Type::kPrimDouble: return true;
+ case Primitive::Type::kPrimVoid: return false;
+ }
+ }
+
+ // Returns true if |from| and |to| are the same or a widening conversion exists between them.
+ static bool IsWidenable(Type from, Type to) {
+ static_assert(Primitive::Type::kPrimByte < Primitive::Type::kPrimShort, "Bad ordering");
+ static_assert(Primitive::Type::kPrimShort < Primitive::Type::kPrimInt, "Bad ordering");
+ static_assert(Primitive::Type::kPrimInt < Primitive::Type::kPrimLong, "Bad ordering");
+ static_assert(Primitive::Type::kPrimLong < Primitive::Type::kPrimFloat, "Bad ordering");
+ static_assert(Primitive::Type::kPrimFloat < Primitive::Type::kPrimDouble, "Bad ordering");
+ return IsNumericType(from) && IsNumericType(to) && from <= to;
+ }
+
static bool IsIntOrLongType(Type type) {
return type == kPrimInt || type == kPrimLong;
}