namespace { // Helper function to avoid `ASSERT_EQ` with floating point types.
int32_t ToIntegralType(float value) { return bit_cast<int32_t>(value); }
int64_t ToIntegralType(double value) { return bit_cast<int64_t>(value); } template <typename T> T ToIntegralType(T value) { return value; }
}
class ArtMethodTest : public CommonRuntimeTest { protected:
ArtMethodTest() {
use_boot_image_ = true; // Make the Runtime creation cheaper.
}
// Test primitive type boxing and unboxing. // // This provides basic checks that the translation of the compile-time shorty // to argument types and return type are correct and that values are passed // correctly for these single-argument calls (`ArtMethod::InvokeStatic()` with // primitive args and `ArtMethod::InvokeInstance()` with a reference arg). template <typename Type, char kPrimitive> void TestBoxUnbox(ArtMethod* value_of, constchar* unbox_name, Type value) {
Thread* self = Thread::Current();
ScopedObjectAccess soa(self);
ASSERT_STREQ(value_of->GetName(), "valueOf");
std::string unbox_signature = std::string("()") + kPrimitive;
ArtMethod* unbox_method = value_of->GetDeclaringClass()->FindClassMethod(
unbox_name, unbox_signature, kRuntimePointerSize);
ASSERT_TRUE(unbox_method != nullptr);
ASSERT_FALSE(unbox_method->IsStatic());
ASSERT_TRUE(value_of->GetDeclaringClass()->IsFinal());
static_assert(std::is_same_v<ObjPtr<mirror::Object> (ArtMethod::*)(Thread*, Type),
decltype(&ArtMethod::InvokeStatic<'L', kPrimitive>)>);
StackHandleScope<1u> hs(self);
Handle<mirror::Object> boxed =
hs.NewHandle(value_of->InvokeStatic<'L', kPrimitive>(self, value));
ASSERT_TRUE(boxed != nullptr);
ASSERT_OBJ_PTR_EQ(boxed->GetClass(), value_of->GetDeclaringClass());
static_assert(std::is_same_v<Type (ArtMethod::*)(Thread*, ObjPtr<mirror::Object>),
decltype(&ArtMethod::InvokeInstance<kPrimitive>)>); // Exercise both `InvokeInstance()` and `InvokeFinal()` (boxing classes are final).
Type unboxed1 = unbox_method->InvokeInstance<kPrimitive>(self, boxed.Get());
ASSERT_EQ(ToIntegralType(value), ToIntegralType(unboxed1));
Type unboxed2 = unbox_method->InvokeFinal<kPrimitive>(self, boxed.Get());
ASSERT_EQ(ToIntegralType(value), ToIntegralType(unboxed2));
}
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.