static JniValueType CallMethodV()

in runtime/check_jni.cc [3067:3249]


  static JniValueType CallMethodV(const char* function_name, JNIEnv* env, jobject obj, jclass c,
                                  jmethodID mid, va_list vargs, Primitive::Type type,
                                  InvokeType invoke) {
    ScopedObjectAccess soa(env);
    ScopedCheck sc(kFlag_Default, function_name);
    JniValueType result;
    VarArgs rest(mid, vargs);
    if (CheckCallArgs(soa, sc, env, obj, c, mid, invoke, &rest) &&
        sc.CheckMethodAndSig(soa, obj, c, mid, type, invoke)) {
      const char* result_check;
      switch (type) {
        case Primitive::kPrimNot:
          result_check = "L";
          switch (invoke) {
            case kVirtual:
              result.L = baseEnv(env)->CallObjectMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.L = baseEnv(env)->CallNonvirtualObjectMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.L = baseEnv(env)->CallStaticObjectMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimBoolean:
          result_check = "Z";
          switch (invoke) {
            case kVirtual:
              result.Z = baseEnv(env)->CallBooleanMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.Z = baseEnv(env)->CallNonvirtualBooleanMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.Z = baseEnv(env)->CallStaticBooleanMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimByte:
          result_check = "B";
          switch (invoke) {
            case kVirtual:
              result.B = baseEnv(env)->CallByteMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.B = baseEnv(env)->CallNonvirtualByteMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.B = baseEnv(env)->CallStaticByteMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimChar:
          result_check = "C";
          switch (invoke) {
            case kVirtual:
              result.C = baseEnv(env)->CallCharMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.C = baseEnv(env)->CallNonvirtualCharMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.C = baseEnv(env)->CallStaticCharMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimShort:
          result_check = "S";
          switch (invoke) {
            case kVirtual:
              result.S = baseEnv(env)->CallShortMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.S = baseEnv(env)->CallNonvirtualShortMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.S = baseEnv(env)->CallStaticShortMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimInt:
          result_check = "I";
          switch (invoke) {
            case kVirtual:
              result.I = baseEnv(env)->CallIntMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.I = baseEnv(env)->CallNonvirtualIntMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.I = baseEnv(env)->CallStaticIntMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimLong:
          result_check = "J";
          switch (invoke) {
            case kVirtual:
              result.J = baseEnv(env)->CallLongMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.J = baseEnv(env)->CallNonvirtualLongMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.J = baseEnv(env)->CallStaticLongMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimFloat:
          result_check = "F";
          switch (invoke) {
            case kVirtual:
              result.F = baseEnv(env)->CallFloatMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.F = baseEnv(env)->CallNonvirtualFloatMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.F = baseEnv(env)->CallStaticFloatMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimDouble:
          result_check = "D";
          switch (invoke) {
            case kVirtual:
              result.D = baseEnv(env)->CallDoubleMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              result.D = baseEnv(env)->CallNonvirtualDoubleMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              result.D = baseEnv(env)->CallStaticDoubleMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        case Primitive::kPrimVoid:
          result_check = "V";
          result.V = nullptr;
          switch (invoke) {
            case kVirtual:
              baseEnv(env)->CallVoidMethodV(env, obj, mid, vargs);
              break;
            case kDirect:
              baseEnv(env)->CallNonvirtualVoidMethodV(env, obj, c, mid, vargs);
              break;
            case kStatic:
              baseEnv(env)->CallStaticVoidMethodV(env, c, mid, vargs);
              break;
            default:
              LOG(FATAL) << "Unexpected invoke: " << invoke;
          }
          break;
        default:
          LOG(FATAL) << "Unexpected return type: " << type;
          result_check = nullptr;
      }
      if (sc.Check(soa, false, result_check, &result)) {
        return result;
      }
    }
    result.J = 0;
    return result;
  }