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 "base/stringprintf.h"
     23 #include "common_throws.h"
     24 #include "jvalue.h"
     25 #include "mirror/object-inl.h"
     26 #include "primitive.h"
     27 #include "utils.h"
     28 
     29 namespace art {
     30 
     31 inline bool ConvertPrimitiveValue(bool unbox_for_result,
     32                                   Primitive::Type srcType, Primitive::Type dstType,
     33                                   const JValue& src, JValue* dst) {
     34   DCHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
     35   if (LIKELY(srcType == dstType)) {
     36     dst->SetJ(src.GetJ());
     37     return true;
     38   }
     39   switch (dstType) {
     40   case Primitive::kPrimBoolean:  // Fall-through.
     41   case Primitive::kPrimChar:  // Fall-through.
     42   case Primitive::kPrimByte:
     43     // Only expect assignment with source and destination of identical type.
     44     break;
     45   case Primitive::kPrimShort:
     46     if (srcType == Primitive::kPrimByte) {
     47       dst->SetS(src.GetI());
     48       return true;
     49     }
     50     break;
     51   case Primitive::kPrimInt:
     52     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
     53         srcType == Primitive::kPrimShort) {
     54       dst->SetI(src.GetI());
     55       return true;
     56     }
     57     break;
     58   case Primitive::kPrimLong:
     59     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
     60         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
     61       dst->SetJ(src.GetI());
     62       return true;
     63     }
     64     break;
     65   case Primitive::kPrimFloat:
     66     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
     67         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
     68       dst->SetF(src.GetI());
     69       return true;
     70     } else if (srcType == Primitive::kPrimLong) {
     71       dst->SetF(src.GetJ());
     72       return true;
     73     }
     74     break;
     75   case Primitive::kPrimDouble:
     76     if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
     77         srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
     78       dst->SetD(src.GetI());
     79       return true;
     80     } else if (srcType == Primitive::kPrimLong) {
     81       dst->SetD(src.GetJ());
     82       return true;
     83     } else if (srcType == Primitive::kPrimFloat) {
     84       dst->SetD(src.GetF());
     85       return true;
     86     }
     87     break;
     88   default:
     89     break;
     90   }
     91   if (!unbox_for_result) {
     92     ThrowIllegalArgumentException(StringPrintf("Invalid primitive conversion from %s to %s",
     93                                                PrettyDescriptor(srcType).c_str(),
     94                                                PrettyDescriptor(dstType).c_str()).c_str());
     95   } else {
     96     ThrowClassCastException(StringPrintf("Couldn't convert result of type %s to %s",
     97                                          PrettyDescriptor(srcType).c_str(),
     98                                          PrettyDescriptor(dstType).c_str()).c_str());
     99   }
    100   return false;
    101 }
    102 
    103 inline bool VerifyObjectIsClass(mirror::Object* o, mirror::Class* c) {
    104   if (UNLIKELY(o == nullptr)) {
    105     ThrowNullPointerException("null receiver");
    106     return false;
    107   } else if (UNLIKELY(!o->InstanceOf(c))) {
    108     InvalidReceiverError(o, c);
    109     return false;
    110   }
    111   return true;
    112 }
    113 
    114 }  // namespace art
    115 
    116 #endif  // ART_RUNTIME_REFLECTION_INL_H_
    117