Backed out 5 changesets (bug 1178850) for android build bustage CLOSED TREE

Backed out changeset 79085d3894e8 (bug 1178850)
Backed out changeset c02b603104ea (bug 1178850)
Backed out changeset d6dab7810669 (bug 1178850)
Backed out changeset 8ee5809f349b (bug 1178850)
Backed out changeset 821b22ce79e1 (bug 1178850)
This commit is contained in:
Wes Kocher 2015-07-10 14:17:53 -07:00
parent 5c3fddb97e
commit 5c2976c995
13 changed files with 265 additions and 1116 deletions

View File

@ -15,15 +15,14 @@ import java.util.Arrays;
import java.util.Iterator;
public class AnnotationProcessor {
public static final String SOURCE_FILE = "GeneratedJNIWrappers.cpp";
public static final String HEADER_FILE = "GeneratedJNIWrappers.h";
public static final String NATIVES_FILE = "GeneratedJNINatives.h";
public static final String OUTFILE = "GeneratedJNIWrappers.cpp";
public static final String HEADERFILE = "GeneratedJNIWrappers.h";
public static final String GENERATED_COMMENT =
"// GENERATED CODE\n" +
"// Generated by the Java program at /build/annotationProcessors at compile time\n" +
"// from annotations on Java methods. To update, change the annotations on the\n" +
"// corresponding Java methods and rerun the build. Manually updating this file\n" +
"// corresponding Javamethods and rerun the build. Manually updating this file\n" +
"// will cause your build to fail.\n" +
"\n";
@ -48,8 +47,8 @@ public class AnnotationProcessor {
StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT);
headerFile.append(
"#ifndef " + getHeaderGuardName(HEADER_FILE) + "\n" +
"#define " + getHeaderGuardName(HEADER_FILE) + "\n" +
"#ifndef GeneratedJNIWrappers_h__\n" +
"#define GeneratedJNIWrappers_h__\n" +
"\n" +
"#include \"mozilla/jni/Refs.h\"\n" +
"\n" +
@ -66,18 +65,6 @@ public class AnnotationProcessor {
"namespace widget {\n" +
"\n");
StringBuilder nativesFile = new StringBuilder(GENERATED_COMMENT);
nativesFile.append(
"#ifndef " + getHeaderGuardName(NATIVES_FILE) + "\n" +
"#define " + getHeaderGuardName(NATIVES_FILE) + "\n" +
"\n" +
"#include \"GeneratedJNIWrappers.h\"\n" +
"#include \"mozilla/jni/Natives.h\"\n" +
"\n" +
"namespace mozilla {\n" +
"namespace widget {\n" +
"\n");
while (jarClassIterator.hasNext()) {
ClassWithOptions aClassTuple = jarClassIterator.next();
@ -98,9 +85,6 @@ public class AnnotationProcessor {
case METHOD:
generatorInstance.generateMethod(aElementTuple);
break;
case NATIVE:
generatorInstance.generateNative(aElementTuple);
break;
case FIELD:
generatorInstance.generateField(aElementTuple);
break;
@ -112,7 +96,6 @@ public class AnnotationProcessor {
headerFile.append(generatorInstance.getHeaderFileContents());
implementationFile.append(generatorInstance.getWrapperFileContents());
nativesFile.append(generatorInstance.getNativesFileContents());
}
implementationFile.append(
@ -124,33 +107,38 @@ public class AnnotationProcessor {
"\n" +
"} /* widget */\n" +
"} /* mozilla */\n" +
"#endif // " + getHeaderGuardName(HEADER_FILE) + "\n");
"#endif // GeneratedJNIWrappers_h__\n");
nativesFile.append(
"\n" +
"} /* widget */\n" +
"} /* mozilla */\n" +
"#endif // " + getHeaderGuardName(NATIVES_FILE) + "\n");
writeOutputFile(SOURCE_FILE, implementationFile);
writeOutputFile(HEADER_FILE, headerFile);
writeOutputFile(NATIVES_FILE, nativesFile);
writeOutputFiles(headerFile, implementationFile);
long e = System.currentTimeMillis();
System.out.println("Annotation processing complete in " + (e - s) + "ms");
}
private static String getHeaderGuardName(final String name) {
return name.replaceAll("\\W", "_");
}
private static void writeOutputFiles(StringBuilder aHeaderFile, StringBuilder aImplementationFile) {
FileOutputStream headerStream = null;
try {
headerStream = new FileOutputStream(OUTFILE);
headerStream.write(aImplementationFile.toString().getBytes());
} catch (IOException e) {
System.err.println("Unable to write " + OUTFILE + ". Perhaps a permissions issue?");
e.printStackTrace(System.err);
} finally {
if (headerStream != null) {
try {
headerStream.close();
} catch (IOException e) {
System.err.println("Unable to close headerStream due to "+e);
e.printStackTrace(System.err);
}
}
}
private static void writeOutputFile(final String name,
final StringBuilder content) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(name);
outStream.write(content.toString().getBytes());
outStream = new FileOutputStream(HEADERFILE);
outStream.write(aHeaderFile.toString().getBytes());
} catch (IOException e) {
System.err.println("Unable to write " + name + ". Perhaps a permissions issue?");
System.err.println("Unable to write " + HEADERFILE + ". Perhaps a permissions issue?");
e.printStackTrace(System.err);
} finally {
if (outStream != null) {

View File

@ -22,8 +22,6 @@ public class CodeGenerator {
// Buffers holding the strings to ultimately be written to the output files.
private final StringBuilder cpp = new StringBuilder();
private final StringBuilder header = new StringBuilder();
private final StringBuilder natives = new StringBuilder();
private final StringBuilder nativesInits = new StringBuilder();
private final Class<?> cls;
private final String clsName;
@ -35,13 +33,13 @@ public class CodeGenerator {
this.clsName = annotatedClass.generatedName;
header.append(
"class " + clsName + " : public mozilla::jni::Class<" + clsName + ">\n" +
"{\n" +
"class " + clsName + " : public mozilla::jni::Class<" + clsName + "> {\n" +
"\n" +
"public:\n" +
" typedef mozilla::jni::Ref<" + clsName + "> Ref;\n" +
" typedef mozilla::jni::LocalRef<" + clsName + "> LocalRef;\n" +
" typedef mozilla::jni::GlobalRef<" + clsName + "> GlobalRef;\n" +
" typedef const mozilla::jni::Param<" + clsName + ">& Param;\n" +
" typedef const typename mozilla::jni::Param<" + clsName + ">::Type& Param;\n" +
"\n" +
" static constexpr char name[] =\n" +
" \"" + cls.getName().replace('.', '/') + "\";\n" +
@ -53,12 +51,6 @@ public class CodeGenerator {
cpp.append(
"constexpr char " + clsName + "::name[];\n" +
"\n");
natives.append(
"template<class Impl>\n" +
"class " + clsName + "::Natives : " +
"public mozilla::jni::NativeImpl<" + clsName + ", Impl>\n" +
"{\n");
}
private String getTraitsName(String uniqueName, boolean includeScope) {
@ -80,30 +72,20 @@ public class CodeGenerator {
}
private void generateMember(AnnotationInfo info, Member member,
String uniqueName, Class<?> type, Class<?>[] argTypes) {
final StringBuilder args = new StringBuilder();
for (Class<?> argType : argTypes) {
args.append("\n " + getNativeParameterType(argType, info) + ",");
}
if (args.length() > 0) {
args.setLength(args.length() - 1);
}
String uniqueName, Class<?> type) {
header.append(
"public:\n" +
" struct " + getTraitsName(uniqueName, /* includeScope */ false) + " {\n" +
" typedef " + clsName + " Owner;\n" +
" typedef " + getNativeReturnType(type, info) + " ReturnType;\n" +
" typedef " + getNativeParameterType(type, info) + " SetterType;\n" +
" typedef mozilla::jni::Args<" + args + "> Args;\n" +
" static constexpr char name[] = \"" +
Utils.getMemberName(member) + "\";\n" +
" static constexpr char signature[] =\n" +
" \"" + Utils.getSignature(member) + "\";\n" +
" static const bool isStatic = " + Utils.isStatic(member) + ";\n" +
" static const bool isMultithreaded = " + info.isMultithreaded + ";\n" +
" static const mozilla::jni::ExceptionMode exceptionMode =\n" +
" " + (
" static const mozilla::jni::ExceptionMode exceptionMode = " + (
info.catchException ? "mozilla::jni::ExceptionMode::NSRESULT" :
info.noThrow ? "mozilla::jni::ExceptionMode::IGNORE" :
"mozilla::jni::ExceptionMode::ABORT") + ";\n" +
@ -266,15 +248,15 @@ public class CodeGenerator {
final Method method = annotatedMethod.getMethod();
final AnnotationInfo info = annotatedMethod.mAnnotationInfo;
final String uniqueName = getUniqueMethodName(info.wrapperName);
final Class<?>[] argTypes = method.getParameterTypes();
final Class<?> returnType = method.getReturnType();
if (method.isSynthetic()) {
return;
}
generateMember(info, method, uniqueName, returnType, argTypes);
generateMember(info, method, uniqueName, returnType);
final Class<?>[] argTypes = method.getParameterTypes();
final boolean isStatic = Utils.isStatic(method);
header.append(
@ -290,35 +272,6 @@ public class CodeGenerator {
"\n");
}
/**
* Append the appropriate generated code to the buffers for the native method provided.
*
* @param annotatedMethod The Java native method, plus annotation data.
*/
public void generateNative(AnnotatableEntity annotatedMethod) {
// Unpack the tuple and extract some useful fields from the Method..
final Method method = annotatedMethod.getMethod();
final AnnotationInfo info = annotatedMethod.mAnnotationInfo;
final String uniqueName = getUniqueMethodName(info.wrapperName);
final Class<?>[] argTypes = method.getParameterTypes();
final Class<?> returnType = method.getReturnType();
generateMember(info, method, uniqueName, returnType, argTypes);
final String traits = getTraitsName(uniqueName, /* includeScope */ true);
if (nativesInits.length() > 0) {
nativesInits.append(',');
}
nativesInits.append(
"\n" +
"\n" +
" mozilla::jni::MakeNativeMethod<" + traits + ">(\n" +
" mozilla::jni::NativeStub<" + traits + ", Impl>\n" +
" ::template Wrap<&Impl::" + info.wrapperName + ">)");
}
private String getLiteral(Object val, AnnotationInfo info) {
final Class<?> type = val.getClass();
@ -395,7 +348,7 @@ public class CodeGenerator {
// Fall back to using accessors if we encounter an exception.
}
generateMember(info, field, uniqueName, type, EMPTY_CLASS_ARRAY);
generateMember(info, field, uniqueName, type);
final Class<?>[] getterArgs = EMPTY_CLASS_ARRAY;
@ -436,14 +389,15 @@ public class CodeGenerator {
final AnnotationInfo info = annotatedConstructor.mAnnotationInfo;
final String wrapperName = "New";
final String uniqueName = getUniqueMethodName(wrapperName);
final Class<?>[] argTypes = method.getParameterTypes();
final Class<?> returnType = cls;
if (method.isSynthetic()) {
return;
}
generateMember(info, method, uniqueName, returnType, argTypes);
generateMember(info, method, uniqueName, returnType);
final Class<?>[] argTypes = method.getParameterTypes();
header.append(
" " + generateDeclaration(wrapperName, argTypes,
@ -500,34 +454,9 @@ public class CodeGenerator {
* @return The bytes to be written to the header file.
*/
public String getHeaderFileContents() {
if (nativesInits.length() > 0) {
header.append(
"public:\n" +
" template<class Impl> class Natives;\n");
}
header.append(
"};\n" +
"\n");
return header.toString();
}
/**
* Get the finalised bytes to go into the generated natives header file.
*
* @return The bytes to be written to the header file.
*/
public String getNativesFileContents() {
if (nativesInits.length() == 0) {
return "";
}
natives.append(
"public:\n" +
" static constexpr JNINativeMethod methods[] = {" + nativesInits + '\n' +
" };\n" +
"};\n" +
"\n" +
"template<class Impl>\n" +
"constexpr JNINativeMethod " + clsName + "::Natives<Impl>::methods[];\n");
return natives.toString();
}
}

View File

@ -10,14 +10,13 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* Union type to hold either a method, field, or ctor. Allows us to iterate "The generatable stuff", despite
* the fact that such things can be of either flavour.
*/
public class AnnotatableEntity {
public enum ENTITY_TYPE {METHOD, NATIVE, FIELD, CONSTRUCTOR}
public enum ENTITY_TYPE {METHOD, FIELD, CONSTRUCTOR}
private final Member mMember;
public final ENTITY_TYPE mEntityType;
@ -29,11 +28,7 @@ public class AnnotatableEntity {
mAnnotationInfo = aAnnotationInfo;
if (aObject instanceof Method) {
if (Modifier.isNative(aObject.getModifiers())) {
mEntityType = ENTITY_TYPE.NATIVE;
} else {
mEntityType = ENTITY_TYPE.METHOD;
}
mEntityType = ENTITY_TYPE.METHOD;
} else if (aObject instanceof Field) {
mEntityType = ENTITY_TYPE.FIELD;
} else {
@ -42,7 +37,7 @@ public class AnnotatableEntity {
}
public Method getMethod() {
if (mEntityType != ENTITY_TYPE.METHOD && mEntityType != ENTITY_TYPE.NATIVE) {
if (mEntityType != ENTITY_TYPE.METHOD) {
throw new UnsupportedOperationException("Attempt to cast to unsupported member type.");
}
return (Method) mMember;

View File

@ -46,7 +46,6 @@ GARBAGE += \
.aapt.deps \
javah.out \
jni-stubs.inc \
GeneratedJNINatives.h \
GeneratedJNIWrappers.cpp \
GeneratedJNIWrappers.h \
$(NULL)
@ -233,8 +232,6 @@ jni-stubs.inc: gecko-browser.jar gecko-mozglue.jar gecko-util.jar sync-thirdpart
ANNOTATION_PROCESSOR_JAR_FILES := $(DEPTH)/build/annotationProcessors/annotationProcessors.jar
# This annotation processing step also generates
# GeneratedJNIWrappers.h and GeneratedJNINatives.h
GeneratedJNIWrappers.cpp: $(ANNOTATION_PROCESSOR_JAR_FILES)
GeneratedJNIWrappers.cpp: $(ALL_JARS)
$(JAVA) -classpath gecko-mozglue.jar:$(JAVA_BOOTCLASSPATH):$(JAVA_CLASSPATH):$(ANNOTATION_PROCESSOR_JAR_FILES) org.mozilla.gecko.annotationProcessors.AnnotationProcessor $(ALL_JARS)
@ -466,9 +463,12 @@ $(eval $(call aapt_command,.aapt.nodeps,$(CURDIR)/AndroidManifest.xml FORCE,geck
include $(topsrcdir)/config/android-common.mk
update-generated-wrappers:
@mv $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp.old
@mv $(topsrcdir)/widget/android/GeneratedJNIWrappers.h $(topsrcdir)/widget/android/GeneratedJNIWrappers.h.old
@echo old GeneratedJNIWrappers.cpp/h moved to GeneratedJNIWrappers.cpp/h.old
@cp $(CURDIR)/jni-stubs.inc $(topsrcdir)/mozglue/android
@cp $(CURDIR)/GeneratedJNIWrappers.cpp $(CURDIR)/GeneratedJNIWrappers.h $(CURDIR)/GeneratedJNINatives.h $(topsrcdir)/widget/android
@echo Updated generated JNI code
@cp $(CURDIR)/GeneratedJNIWrappers.* $(topsrcdir)/widget/android
@echo Updated GeneratedJNIWrappers
.PHONY: update-generated-wrappers
@ -500,14 +500,9 @@ libs:: geckoview_resources.zip
$(INSTALL) geckoview_resources.zip $(FINAL_TARGET)
endif
# GeneratedJNIWrappers.cpp target also generates
# GeneratedJNIWrappers.h and GeneratedJNINatives.h
libs:: classes.dex jni-stubs.inc GeneratedJNIWrappers.cpp $(CURDIR)/fennec_ids.txt
$(INSTALL) classes.dex $(FINAL_TARGET)
@(diff jni-stubs.inc $(topsrcdir)/mozglue/android/jni-stubs.inc >/dev/null && \
diff GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp >/dev/null && \
diff GeneratedJNIWrappers.h $(topsrcdir)/widget/android/GeneratedJNIWrappers.h >/dev/null && \
diff GeneratedJNINatives.h $(topsrcdir)/widget/android/GeneratedJNINatives.h >/dev/null) || \
@(diff jni-stubs.inc $(topsrcdir)/mozglue/android/jni-stubs.inc >/dev/null && diff GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp >/dev/null) || \
(echo '*****************************************************' && \
echo '*** Error: The generated JNI code has changed ***' && \
echo '* To update generated code in the tree, please run *' && \

View File

@ -79,7 +79,7 @@ jclass AndroidBridge::GetClassGlobalRef(JNIEnv* env, const char* className)
classRef = ClassObject::LocalRef::Adopt(env,
env->CallObjectMethod(sBridge->mClassLoader.Get(),
sBridge->mClassLoaderLoadClass,
Param<String>(className, env).Get()));
Param<String>::Type(className, env).Get()));
}
if (!classRef) {

View File

@ -1,19 +0,0 @@
// GENERATED CODE
// Generated by the Java program at /build/annotationProcessors at compile time
// from annotations on Java methods. To update, change the annotations on the
// corresponding Java methods and rerun the build. Manually updating this file
// will cause your build to fail.
#ifndef GeneratedJNINatives_h
#define GeneratedJNINatives_h
#include "GeneratedJNIWrappers.h"
#include "mozilla/jni/Natives.h"
namespace mozilla {
namespace widget {
} /* widget */
} /* mozilla */
#endif // GeneratedJNINatives_h

View File

@ -1,7 +1,7 @@
// GENERATED CODE
// Generated by the Java program at /build/annotationProcessors at compile time
// from annotations on Java methods. To update, change the annotations on the
// corresponding Java methods and rerun the build. Manually updating this file
// corresponding Javamethods and rerun the build. Manually updating this file
// will cause your build to fail.
#include "GeneratedJNIWrappers.h"

File diff suppressed because it is too large Load Diff

View File

@ -33,18 +33,16 @@ struct Value
// Base class for Method<>, Field<>, and Constructor<>.
class Accessor {
public:
private:
template<class Cls>
static jclass EnsureClassRef(JNIEnv* env)
static void EnsureClassRef(JNIEnv* env)
{
if (!Cls::sClassRef) {
MOZ_ALWAYS_TRUE(Cls::sClassRef =
AndroidBridge::GetClassGlobalRef(env, Cls::name));
}
return Cls::sClassRef;
}
private:
static void GetNsresult(JNIEnv* env, nsresult* rv)
{
if (env->ExceptionCheck()) {

View File

@ -1,212 +0,0 @@
#ifndef mozilla_jni_Natives_h__
#define mozilla_jni_Natives_h__
#include <jni.h>
#include "mozilla/jni/Accessors.h"
#include "mozilla/jni/Refs.h"
#include "mozilla/jni/Types.h"
#include "mozilla/jni/Utils.h"
namespace mozilla {
namespace jni{
// Get the native pointer stored in a Java instance.
template<class Impl>
Impl* GetInstancePtr(JNIEnv* env, jobject instance)
{
// TODO: implement instance native pointers.
return nullptr;
}
namespace detail {
// Wrapper methods that convert arguments from the JNI types to the native
// types, e.g. from jobject to jni::Object::Ref. For instance methods, the
// wrapper methods also convert calls to calls on objects.
//
// We need specialization for static/non-static because the two have different
// signatures (jobject vs jclass and Impl::*Method vs *Method).
// We need specialization for return type, because void return type requires
// us to not deal with the return value.
template<bool IsStatic, typename ReturnType,
class Traits, class Impl, class Args>
class NativeStubImpl;
// Specialization for instance methods with non-void return type
template<typename ReturnType, class Traits, class Impl, typename... Args>
class NativeStubImpl<false, ReturnType, Traits, Impl, jni::Args<Args...>>
{
typedef typename Traits::Owner Owner;
typedef typename TypeAdapter<ReturnType>::JNIType ReturnJNIType;
public:
// Instance method
template<ReturnType (Impl::*Method) (Args...)>
static ReturnJNIType Wrap(JNIEnv* env, jobject instance,
typename TypeAdapter<Args>::JNIType... args)
{
Impl* const impl = GetInstancePtr<Impl>(env, instance);
if (!impl) {
return ReturnJNIType();
}
return TypeAdapter<ReturnType>::FromNative(env,
(impl->*Method)(TypeAdapter<Args>::ToNative(env, args)...));
}
// Instance method with instance reference
template<ReturnType (Impl::*Method) (typename Owner::Param, Args...)>
static ReturnJNIType Wrap(JNIEnv* env, jobject instance,
typename TypeAdapter<Args>::JNIType... args)
{
Impl* const impl = GetInstancePtr<Impl>(env, instance);
if (!impl) {
return ReturnJNIType();
}
return TypeAdapter<ReturnType>::FromNative(env,
(impl->*Method)(Owner::Ref::From(instance),
TypeAdapter<Args>::ToNative(env, args)...));
}
};
// Specialization for instance methods with void return type
template<class Traits, class Impl, typename... Args>
class NativeStubImpl<false, void, Traits, Impl, jni::Args<Args...>>
{
typedef typename Traits::Owner Owner;
public:
// Instance method
template<void (Impl::*Method) (Args...)>
static void Wrap(JNIEnv* env, jobject instance,
typename TypeAdapter<Args>::JNIType... args)
{
Impl* const impl = GetInstancePtr<Impl>(env, instance);
if (!impl) {
return;
}
(impl->*Method)(TypeAdapter<Args>::ToNative(env, args)...);
}
// Instance method with instance reference
template<void (Impl::*Method) (typename Owner::Param, Args...)>
static void Wrap(JNIEnv* env, jobject instance,
typename TypeAdapter<Args>::JNIType... args)
{
Impl* const impl = GetInstancePtr<Impl>(env, instance);
if (!impl) {
return;
}
(impl->*Method)(Owner::Ref::From(instance),
TypeAdapter<Args>::ToNative(env, args)...);
}
};
// Specialization for static methods with non-void return type
template<typename ReturnType, class Traits, class Impl, typename... Args>
class NativeStubImpl<true, ReturnType, Traits, Impl, jni::Args<Args...>>
{
typedef typename TypeAdapter<ReturnType>::JNIType ReturnJNIType;
public:
// Static method
template<ReturnType (*Method) (Args...)>
static ReturnJNIType Wrap(JNIEnv* env, jclass,
typename TypeAdapter<Args>::JNIType... args)
{
return TypeAdapter<ReturnType>::FromNative(env,
(*Method)(TypeAdapter<Args>::ToNative(env, args)...));
}
// Static method with class reference
template<ReturnType (*Method) (ClassObject::Param, Args...)>
static ReturnJNIType Wrap(JNIEnv* env, jclass cls,
typename TypeAdapter<Args>::JNIType... args)
{
return TypeAdapter<ReturnType>::FromNative(env,
(*Method)(ClassObject::Ref::From(cls),
TypeAdapter<Args>::ToNative(env, args)...));
}
};
// Specialization for static methods with void return type
template<class Traits, class Impl, typename... Args>
class NativeStubImpl<true, void, Traits, Impl, jni::Args<Args...>>
{
public:
// Static method
template<void (*Method) (Args...)>
static void Wrap(JNIEnv* env, jclass,
typename TypeAdapter<Args>::JNIType... args)
{
(*Method)(TypeAdapter<Args>::ToNative(env, args)...);
}
// Static method with class reference
template<void (*Method) (ClassObject::Param, Args...)>
static void Wrap(JNIEnv* env, jclass cls,
typename TypeAdapter<Args>::JNIType... args)
{
(*Method)(ClassObject::Ref::From(cls),
TypeAdapter<Args>::ToNative(env, args)...);
}
};
} // namespace detail
// Form a stub wrapper from a native method's traits class and an implementing
// class. The stub wrapper has a Wrap function that will form a wrapped stub.
template<class Traits, class Impl>
struct NativeStub : detail::NativeStubImpl<Traits::isStatic,
typename Traits::ReturnType,
Traits, Impl, typename Traits::Args>
{
};
// Generate a JNINativeMethod from a native
// method's traits class and a wrapped stub.
template<class Traits, typename Ret, typename... Args>
constexpr JNINativeMethod MakeNativeMethod(Ret (*stub)(JNIEnv*, Args...))
{
return {
Traits::name,
Traits::signature,
reinterpret_cast<void*>(stub)
};
}
// Class inherited by implementing class.
template<class Cls, class Impl>
class NativeImpl
{
typedef typename Cls::template Natives<Impl> Natives;
static bool sInited;
public:
static void Init() {
if (sInited) {
return;
}
JNIEnv* const env = GetJNIForThread();
env->RegisterNatives(Accessor::EnsureClassRef<Cls>(env),
Natives::methods,
sizeof(Natives::methods) / sizeof(JNINativeMethod));
sInited = true;
}
NativeImpl() {
// Initialize on creation if not already initialized.
Init();
}
};
// Define static member.
template<class C, class I>
bool NativeImpl<C, I>::sInited;
} // namespace jni
} // namespace mozilla
#endif // mozilla_jni_Natives_h__

View File

@ -25,11 +25,10 @@ template<class Cls> class LocalRef;
template<class Cls> class GlobalRef;
// Type used for a reference parameter. Default is a wrapped object
// reference, but ParamImpl can be specialized to define custom behavior,
// reference, but Param can be specialized to define custom behavior,
// e.g. a StringParam class that automatically converts nsAString& and
// nsACString& to a jstring.
template<class Cls> struct ParamImpl { typedef Ref<Cls> Type; };
template<class Cls> using Param = typename ParamImpl<Cls>::Type;
template<class Cls> struct Param { typedef Ref<Cls> Type; };
// How exception during a JNI call should be treated.
@ -44,13 +43,6 @@ enum class ExceptionMode
};
// Class to hold the native types of a method's arguments.
// For example, if a method has signature (ILjava/lang/String;)V,
// its arguments class would be jni::Args<int32_t, jni::String::Param>
template<typename...>
struct Args {};
// Base class for all JNI binding classes.
// Templated so that we have one sClassRef for each class.
template<class Cls>
@ -81,7 +73,7 @@ public:
typedef jni::Ref<Object> Ref;
typedef jni::LocalRef<Object> LocalRef;
typedef jni::GlobalRef<Object> GlobalRef;
typedef const jni::Param<Object>& Param;
typedef const typename jni::Param<Object>::Type& Param;
};
@ -98,7 +90,7 @@ public:
typedef jni::Ref<Self> Ref;
typedef jni::LocalRef<Self> LocalRef;
typedef jni::GlobalRef<Self> GlobalRef;
typedef const jni::Param<Self>& Param;
typedef const typename jni::Param<Self>::Type& Param;
};
// Define bindings for built-in types.
@ -116,7 +108,7 @@ typedef TypedObject<jfloatArray> FloatArray;
typedef TypedObject<jdoubleArray> DoubleArray;
typedef TypedObject<jobjectArray> ObjectArray;
template<> struct ParamImpl<String> { class Type; };
template<> struct Param<String> { class Type; };
// Base class for Ref and its specializations.
@ -533,7 +525,7 @@ public:
// Define a custom parameter type for String,
// which accepts both String::Ref and nsAString/nsACString
class ParamImpl<String>::Type : public Ref<String>
class Param<String>::Type : public Ref<String>
{
private:
// Not null if we should delete ref on destruction.

View File

@ -28,8 +28,6 @@ template<typename T> struct TypeAdapter;
// TypeAdapter<LocalRef<Cls>> applies when jobject is a return value.
template<class Cls> struct TypeAdapter<LocalRef<Cls>> {
typedef decltype(Ref<Cls>(nullptr).Get()) JNIType;
static constexpr auto Call = &JNIEnv::CallObjectMethodA;
static constexpr auto StaticCall = &JNIEnv::CallStaticObjectMethodA;
static constexpr auto Get = &JNIEnv::GetObjectField;
@ -38,10 +36,6 @@ template<class Cls> struct TypeAdapter<LocalRef<Cls>> {
static LocalRef<Cls> ToNative(JNIEnv* env, jobject instance) {
return LocalRef<Cls>::Adopt(env, instance);
}
static JNIType FromNative(JNIEnv*, LocalRef<Cls>&& instance) {
return instance.Forget();
}
};
template<class Cls> constexpr jobject
@ -56,16 +50,10 @@ template<class Cls> constexpr jobject
// TypeAdapter<Ref<Cls>> applies when jobject is a parameter value.
template<class Cls> struct TypeAdapter<Ref<Cls>> {
typedef decltype(Ref<Cls>(nullptr).Get()) JNIType;
static constexpr auto Set = &JNIEnv::SetObjectField;
static constexpr auto StaticSet = &JNIEnv::SetStaticObjectField;
static Ref<Cls> ToNative(JNIEnv* env, jobject instance) {
return Ref<Cls>::From(instance);
}
static JNIType FromNative(JNIEnv*, const Ref<Cls>& instance) {
static jobject FromNative(JNIEnv*, const Ref<Cls>& instance) {
return instance.Get();
}
};
@ -77,7 +65,7 @@ template<class Cls> constexpr void
// jstring has its own Param type.
template<> struct TypeAdapter<Param<String>>
template<> struct TypeAdapter<class Param<String>::Type>
: public TypeAdapter<String::Ref>
{};
@ -85,8 +73,6 @@ template<> struct TypeAdapter<Param<String>>
#define DEFINE_PRIMITIVE_TYPE_ADAPTER(NativeType, JNIType, JNIName) \
\
template<> struct TypeAdapter<NativeType> { \
typedef JNIType JNI##Type; \
\
static constexpr auto Call = &JNIEnv::Call ## JNIName ## MethodA; \
static constexpr auto StaticCall = &JNIEnv::CallStatic ## JNIName ## MethodA; \
static constexpr auto Get = &JNIEnv::Get ## JNIName ## Field; \

View File

@ -6,7 +6,6 @@
EXPORTS.mozilla.jni += [
'Accessors.h',
'Natives.h',
'Refs.h',
'Types.h',
'Utils.h',