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;
}