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