Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_RUNTIME_REFLECTION_INL_H_
     18 #define ART_RUNTIME_REFLECTION_INL_H_
     19 
     20 #include "reflection.h"
     21 
     22 #include "android-base/stringprintf.h"
     23 
     24 #include "base/utils.h"
     25 #include "common_throws.h"
     26 #include "dex/descriptors_names.h"
     27 #include "dex/primitive.h"
     28 #include "jvalue-inl.h"
     29 #include "mirror/object-inl.h"
     30 #include "obj_ptr-inl.h"
     31 
     32 namespace art {
     33 
     34 inline bool ConvertPrimitiveValueNoThrow(Primitive::Type srcType,
     35                                          Primitive::Type dstType,
     36                                          const JValue& src,
     37                                          JValue* dst) {
     38   DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
     39   if (LIKELY(srcType == dstType)) {
     40     dst->SetJ(src.GetJ());
     41     return true;
     42   }
     43   switch (dstType) {
     44   case Primitive::kPrimBoolean:  // Fall-through.
     45   case Primitive::kPrimChar:  // Fall-through.
     46   case Primitive::kPrimByte:
     47     // Only expect assignment with source and destination of identical type.
     48     break;
     49   case Primitive::kPrimShort:
     50     if (srcType == Primitive::kPrimByte) {
     51       dst->SetS(src.GetI());
     52       return true;
     53     }
     54     break;
     55   case Primitive::kPrimInt:
     56     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
     57         srcType == Primitive::kPrimShort) {
     58       dst->SetI(src.GetI());
     59       return true;
     60     }
     61     break;
     62   case Primitive::kPrimLong:
     63     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
     64         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
     65       dst->SetJ(src.GetI());
     66       return true;
     67     }
     68     break;
     69   case Primitive::kPrimFloat:
     70     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
     71         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
     72       dst->SetF(src.GetI());
     73       return true;
     74     } else if (srcType == Primitive::kPrimLong) {
     75       dst->SetF(src.GetJ());
     76       return true;
     77     }
     78     break;
     79   case Primitive::kPrimDouble:
     80     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
     81         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
     82       dst->SetD(src.GetI());
     83       return true;
     84     } else if (srcType == Primitive::kPrimLong) {
     85       dst->SetD(src.GetJ());
     86       return true;
     87     } else if (srcType == Primitive::kPrimFloat) {
     88       dst->SetD(src.GetF());
     89       return true;
     90     }
     91     break;
     92   default:
     93     break;
     94   }
     95   return false;
     96 }
     97 
     98 inline bool ConvertPrimitiveValue(bool unbox_for_result,
     99                                   Primitive::Type srcType,
    100                                   Primitive::Type dstType,
    101                                   const JValue& src,
    102                                   JValue* dst) {
    103   if (ConvertPrimitiveValueNoThrow(srcType, dstType, src, dst)) {
    104     return true;
    105   }
    106 
    107   if (!unbox_for_result) {
    108     ThrowIllegalArgumentException(
    109         android::base::StringPrintf("Invalid primitive conversion from %s to %s",
    110                                     PrettyDescriptor(srcType).c_str(),
    111                                     PrettyDescriptor(dstType).c_str()).c_str());
    112   } else {
    113     ThrowClassCastException(android::base::StringPrintf("Couldn't convert result of type %s to %s",
    114                                                         PrettyDescriptor(srcType).c_str(),
    115                                                         PrettyDescriptor(dstType).c_str()).c_str());
    116   }
    117   return false;
    118 }
    119 
    120 inline bool VerifyObjectIsClass(ObjPtr<mirror::Object> o, ObjPtr<mirror::Class> c) {
    121   if (UNLIKELY(o == nullptr)) {
    122     ThrowNullPointerException("null receiver");
    123     return false;
    124   } else if (UNLIKELY(!o->InstanceOf(c.Ptr()))) {
    125     InvalidReceiverError(o, c);
    126     return false;
    127   }
    128   return true;
    129 }
    130 
    131 }  // namespace art
    132 
    133 #endif  // ART_RUNTIME_REFLECTION_INL_H_
    134