in runtime/check_jni.cc [2883:3065]
static JniValueType CallMethodA(const char* function_name, JNIEnv* env, jobject obj, jclass c,
jmethodID mid, jvalue* 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)->CallObjectMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.L = baseEnv(env)->CallNonvirtualObjectMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.L = baseEnv(env)->CallStaticObjectMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimBoolean:
result_check = "Z";
switch (invoke) {
case kVirtual:
result.Z = baseEnv(env)->CallBooleanMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.Z = baseEnv(env)->CallNonvirtualBooleanMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.Z = baseEnv(env)->CallStaticBooleanMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimByte:
result_check = "B";
switch (invoke) {
case kVirtual:
result.B = baseEnv(env)->CallByteMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.B = baseEnv(env)->CallNonvirtualByteMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.B = baseEnv(env)->CallStaticByteMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimChar:
result_check = "C";
switch (invoke) {
case kVirtual:
result.C = baseEnv(env)->CallCharMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.C = baseEnv(env)->CallNonvirtualCharMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.C = baseEnv(env)->CallStaticCharMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimShort:
result_check = "S";
switch (invoke) {
case kVirtual:
result.S = baseEnv(env)->CallShortMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.S = baseEnv(env)->CallNonvirtualShortMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.S = baseEnv(env)->CallStaticShortMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimInt:
result_check = "I";
switch (invoke) {
case kVirtual:
result.I = baseEnv(env)->CallIntMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.I = baseEnv(env)->CallNonvirtualIntMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.I = baseEnv(env)->CallStaticIntMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimLong:
result_check = "J";
switch (invoke) {
case kVirtual:
result.J = baseEnv(env)->CallLongMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.J = baseEnv(env)->CallNonvirtualLongMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.J = baseEnv(env)->CallStaticLongMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimFloat:
result_check = "F";
switch (invoke) {
case kVirtual:
result.F = baseEnv(env)->CallFloatMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.F = baseEnv(env)->CallNonvirtualFloatMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.F = baseEnv(env)->CallStaticFloatMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimDouble:
result_check = "D";
switch (invoke) {
case kVirtual:
result.D = baseEnv(env)->CallDoubleMethodA(env, obj, mid, vargs);
break;
case kDirect:
result.D = baseEnv(env)->CallNonvirtualDoubleMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
result.D = baseEnv(env)->CallStaticDoubleMethodA(env, c, mid, vargs);
break;
default:
break;
}
break;
case Primitive::kPrimVoid:
result_check = "V";
result.V = nullptr;
switch (invoke) {
case kVirtual:
baseEnv(env)->CallVoidMethodA(env, obj, mid, vargs);
break;
case kDirect:
baseEnv(env)->CallNonvirtualVoidMethodA(env, obj, c, mid, vargs);
break;
case kStatic:
baseEnv(env)->CallStaticVoidMethodA(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;
}