Reviewed By: javache

Differential Revision: D4762575

fbshipit-source-id: fc3be786640b8c42664d7b357ab0fe197006b28b
This commit is contained in:
Kathy Gray 2017-03-29 02:32:35 -07:00 коммит произвёл Facebook Github Bot
Родитель a85a86bd8d
Коммит f804af27c2
3 изменённых файлов: 44 добавлений и 21 удалений

Просмотреть файл

@ -168,31 +168,45 @@ public abstract class BaseJavaModule implements NativeModule {
public class JavaMethod implements NativeMethod {
private Method mMethod;
private final ArgumentExtractor[] mArgumentExtractors;
private final String mSignature;
private final Object[] mArguments;
private final Method mMethod;
private final Class[] mParameterTypes;
private final int mParamLength;
private boolean mArgumentsProcessed = false;
private @Nullable ArgumentExtractor[] mArgumentExtractors;
private @Nullable String mSignature;
private @Nullable Object[] mArguments;
private String mType = METHOD_TYPE_ASYNC;
private final int mJSArgumentsNeeded;
private final String mTraceName;
private @Nullable int mJSArgumentsNeeded;
private String mTraceName;
public JavaMethod(Method method, boolean isSync) {
mMethod = method;
mMethod.setAccessible(true);
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "callGetParameterTypes");
mParameterTypes = mMethod.getParameterTypes();
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
mParamLength = mParameterTypes.length;
if (isSync) {
mType = METHOD_TYPE_SYNC;
} else if (mParamLength > 0 && (mParameterTypes[mParamLength - 1] == Promise.class)) {
mType = METHOD_TYPE_PROMISE;
}
// TODO: create these lazily
Class[] parameterTypes = method.getParameterTypes();
mArgumentExtractors = buildArgumentExtractors(parameterTypes);
mSignature = buildSignature(mMethod, parameterTypes, isSync);
// Since native methods are invoked from a message queue executed on a single thread, it is
// save to allocate only one arguments object per method that can be reused across calls
mArguments = new Object[parameterTypes.length];
mJSArgumentsNeeded = calculateJSArgumentsNeeded();
mTraceName = BaseJavaModule.this.getName() + "." + mMethod.getName();
}
private void processArguments() {
if (mArgumentsProcessed) {
return;
}
mArgumentsProcessed = true;
mArgumentExtractors = buildArgumentExtractors(mParameterTypes);
mSignature = buildSignature(mMethod, mParameterTypes, (mType.equals(METHOD_TYPE_SYNC)));
// Since native methods are invoked from a message queue executed on a single thread, it is
// safe to allocate only one arguments object per method that can be reused across calls
mArguments = new Object[mParameterTypes.length];
mJSArgumentsNeeded = calculateJSArgumentsNeeded();
}
public Method getMethod() {
@ -200,7 +214,10 @@ public abstract class BaseJavaModule implements NativeModule {
}
public String getSignature() {
return mSignature;
if (!mArgumentsProcessed) {
processArguments();
}
return assertNotNull(mSignature);
}
private String buildSignature(Method method, Class[] paramTypes, boolean isSync) {
@ -312,6 +329,12 @@ public abstract class BaseJavaModule implements NativeModule {
.arg("method", mTraceName)
.flush();
try {
if (!mArgumentsProcessed) {
processArguments();
}
if (mArguments == null || mArgumentExtractors == null) {
throw new Error("processArguments failed");
}
if (mJSArgumentsNeeded != parameters.size()) {
throw new NativeArgumentsParseException(
BaseJavaModule.this.getName() + "." + mMethod.getName() + " got " +

Просмотреть файл

@ -155,12 +155,12 @@ std::size_t countJsArgs(const std::string& signature) {
MethodInvoker::MethodInvoker(jni::alias_ref<JReflectMethod::javaobject> method, std::string signature, std::string traceName, bool isSync)
: method_(method->getMethodID()),
jsArgCount_(countJsArgs(signature) - 2),
signature_(std::move(signature)),
signature_(signature),
jsArgCount_(countJsArgs(signature) -2),
traceName_(std::move(traceName)),
isSync_(isSync) {
CHECK(signature_.at(1) == '.') << "Improper module method signature";
CHECK(isSync || signature_.at(0) == 'v') << "Non-sync hooks cannot have a non-void return type";
CHECK(signature_.at(1) == '.') << "Improper module method signature";
CHECK(isSync_ || signature_.at(0) == 'v') << "Non-sync hooks cannot have a non-void return type";
}
MethodCallResult MethodInvoker::invoke(std::weak_ptr<Instance>& instance, jni::alias_ref<JBaseJavaModule::javaobject> module, ExecutorToken token, const folly::dynamic& params) {

Просмотреть файл

@ -38,8 +38,8 @@ public:
}
private:
jmethodID method_;
std::size_t jsArgCount_;
std::string signature_;
std::size_t jsArgCount_;
std::string traceName_;
bool isSync_;
};