From ee77e50c4a840f22cd41898584d3d7c1a8b9a492 Mon Sep 17 00:00:00 2001 From: Tobias Ritzau Date: Mon, 16 May 2016 22:45:05 -0700 Subject: [PATCH] Collapse native/{fb,jni,xplatinit} into one DSO Reviewed By: dcolascione Differential Revision: D3201488 fbshipit-source-id: 0cf965ee16e360329285d834a4c575d8f1061f15 --- .../java/com/facebook/jni/Prerequisites.java | 2 +- .../src/main/jni/first-party/fb/Android.mk | 24 ++- ReactAndroid/src/main/jni/first-party/fb/BUCK | 28 --- .../src/main/jni/first-party/fb/Doxyfile | 15 ++ .../first-party/{jni => fb/include/fb}/ALog.h | 0 .../fb/{ => include/fb}/Countable.h | 0 .../{jni => fb/include/fb}/Doxyfile | 0 .../{jni => fb/include/fb}/Environment.h | 57 +++--- .../fb/{ => include/fb}/ProgramLocation.h | 0 .../first-party/fb/{ => include/fb}/RefPtr.h | 0 .../fb/{ => include/fb}/StaticInitialized.h | 0 .../fb/{ => include/fb}/ThreadLocal.h | 0 .../jni/first-party/fb/include/fb/assert.h | 4 +- .../jni/first-party/fb/include/fb/fbjni.h | 24 +++ .../first-party/fb/include/fb/fbjni/Boxed.h | 66 +++++++ .../{jni => fb/include/fb}/fbjni/ByteBuffer.h | 4 +- .../{jni => fb/include/fb}/fbjni/Common.h | 5 +- .../{jni => fb/include/fb}/fbjni/Context.h | 0 .../include/fb}/fbjni/CoreClasses-inl.h | 0 .../include/fb}/fbjni/CoreClasses.h | 44 ++--- .../{jni => fb/include/fb}/fbjni/Exceptions.h | 14 +- .../{jni => fb/include/fb}/fbjni/File.h | 0 .../{jni => fb/include/fb}/fbjni/Hybrid.h | 9 +- .../include/fb}/fbjni/Iterator-inl.h | 0 .../{jni => fb/include/fb}/fbjni/Iterator.h | 0 .../include/fb}/fbjni/Meta-forward.h | 2 +- .../{jni => fb/include/fb}/fbjni/Meta-inl.h | 110 +++++++++--- .../{jni => fb/include/fb}/fbjni/Meta.h | 6 + .../include/fb}/fbjni/MetaConvert.h | 0 .../fb}/fbjni/ReferenceAllocators-inl.h | 0 .../include/fb}/fbjni/ReferenceAllocators.h | 10 +- .../include/fb}/fbjni/References-forward.h | 0 .../include/fb}/fbjni/References-inl.h | 4 +- .../{jni => fb/include/fb}/fbjni/References.h | 4 +- .../include/fb}/fbjni/Registration-inl.h | 8 +- .../include/fb}/fbjni/Registration.h | 0 .../{jni => fb/include/fb}/fbjni/TypeTraits.h | 0 .../main/jni/first-party/fb/include/fb/log.h | 127 ++++++------- .../main/jni/first-party/fb/include/fb/lyra.h | 168 ++++++++++++++++++ .../fb/{ => include/fb}/noncopyable.h | 0 .../fb/{ => include/fb}/nonmovable.h | 0 .../first-party/fb/include/fb/visibility.h | 12 ++ .../{ => fb/include}/jni/Countable.h | 7 +- .../{ => fb/include}/jni/GlobalReference.h | 2 +- .../{ => fb/include}/jni/LocalReference.h | 4 +- .../{ => fb/include}/jni/LocalString.h | 8 +- .../{ => fb/include}/jni/Registration.h | 0 .../{ => fb/include}/jni/WeakReference.h | 6 +- .../{ => fb/include}/jni/jni_helpers.h | 24 +-- .../{jni/fbjni => fb/jni}/ByteBuffer.cpp | 5 +- .../first-party/{ => fb}/jni/Countable.cpp | 4 +- .../first-party/{ => fb}/jni/Environment.cpp | 2 +- .../{jni/fbjni => fb/jni}/Exceptions.cpp | 14 +- .../{jni/fbjni => fb/jni}/Hybrid.cpp | 2 +- .../first-party/{ => fb}/jni/LocalString.cpp | 2 +- .../main/jni/first-party/fb/jni/OnLoad.cpp | 19 ++ .../{jni/fbjni => fb/jni}/References.cpp | 2 +- .../{ => fb}/jni/WeakReference.cpp | 2 +- .../jni/first-party/{ => fb}/jni/fbjni.cpp | 16 +- .../first-party/fb/jni/java/CppException.java | 20 +++ .../fb/jni/java/CppSystemErrorException.java | 27 +++ .../fb/jni/java/UnknownCppException.java | 25 +++ .../first-party/{ => fb}/jni/jni_helpers.cpp | 2 + .../src/main/jni/first-party/fb/lyra/lyra.cpp | 100 +++++++++++ .../{jni/OnLoad.cpp => fb/onload.cpp} | 16 +- .../src/main/jni/first-party/jni/Android.mk | 36 ---- .../src/main/jni/first-party/jni/BUCK | 51 ------ .../src/main/jni/first-party/jni/fbjni.h | 24 --- .../jni/fbjni/android/ReferenceChecking.cpp | 37 ---- ReactAndroid/src/main/jni/react/Android.mk | 3 +- .../src/main/jni/react/jni/Android.mk | 6 +- ReactAndroid/src/main/jni/react/jni/BUCK | 2 +- .../src/main/jni/react/jni/JExecutorToken.h | 2 +- .../jni/react/jni/JExecutorTokenFactory.h | 2 +- .../jni/react/jni/JMessageQueueThread.cpp | 2 +- .../main/jni/react/jni/JMessageQueueThread.h | 2 +- .../src/main/jni/react/jni/JSCPerfLogging.cpp | 2 +- .../src/main/jni/react/jni/JSLoader.cpp | 2 +- .../src/main/jni/react/jni/NativeArray.cpp | 2 +- .../src/main/jni/react/jni/NativeArray.h | 2 +- .../src/main/jni/react/jni/OnLoad.cpp | 6 +- .../src/main/jni/react/jni/ProxyExecutor.cpp | 2 +- .../src/main/jni/react/jni/ProxyExecutor.h | 2 +- .../src/main/jni/react/perftests/BUCK | 2 +- .../src/main/jni/react/perftests/OnLoad.cpp | 2 +- 85 files changed, 840 insertions(+), 405 deletions(-) delete mode 100644 ReactAndroid/src/main/jni/first-party/fb/BUCK create mode 100644 ReactAndroid/src/main/jni/first-party/fb/Doxyfile rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/ALog.h (100%) rename ReactAndroid/src/main/jni/first-party/fb/{ => include/fb}/Countable.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/Doxyfile (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/Environment.h (69%) rename ReactAndroid/src/main/jni/first-party/fb/{ => include/fb}/ProgramLocation.h (100%) rename ReactAndroid/src/main/jni/first-party/fb/{ => include/fb}/RefPtr.h (100%) rename ReactAndroid/src/main/jni/first-party/fb/{ => include/fb}/StaticInitialized.h (100%) rename ReactAndroid/src/main/jni/first-party/fb/{ => include/fb}/ThreadLocal.h (100%) create mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni.h create mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Boxed.h rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/ByteBuffer.h (89%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Common.h (94%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Context.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/CoreClasses-inl.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/CoreClasses.h (93%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Exceptions.h (91%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/File.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Hybrid.h (97%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Iterator-inl.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Iterator.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Meta-forward.h (97%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Meta-inl.h (81%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Meta.h (97%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/MetaConvert.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/ReferenceAllocators-inl.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/ReferenceAllocators.h (87%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/References-forward.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/References-inl.h (99%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/References.h (99%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Registration-inl.h (94%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/Registration.h (100%) rename ReactAndroid/src/main/jni/first-party/{jni => fb/include/fb}/fbjni/TypeTraits.h (100%) create mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/lyra.h rename ReactAndroid/src/main/jni/first-party/fb/{ => include/fb}/noncopyable.h (100%) rename ReactAndroid/src/main/jni/first-party/fb/{ => include/fb}/nonmovable.h (100%) create mode 100644 ReactAndroid/src/main/jni/first-party/fb/include/fb/visibility.h rename ReactAndroid/src/main/jni/first-party/{ => fb/include}/jni/Countable.h (78%) rename ReactAndroid/src/main/jni/first-party/{ => fb/include}/jni/GlobalReference.h (98%) rename ReactAndroid/src/main/jni/first-party/{ => fb/include}/jni/LocalReference.h (96%) rename ReactAndroid/src/main/jni/first-party/{ => fb/include}/jni/LocalString.h (96%) rename ReactAndroid/src/main/jni/first-party/{ => fb/include}/jni/Registration.h (100%) rename ReactAndroid/src/main/jni/first-party/{ => fb/include}/jni/WeakReference.h (89%) rename ReactAndroid/src/main/jni/first-party/{ => fb/include}/jni/jni_helpers.h (80%) rename ReactAndroid/src/main/jni/first-party/{jni/fbjni => fb/jni}/ByteBuffer.cpp (97%) rename ReactAndroid/src/main/jni/first-party/{ => fb}/jni/Countable.cpp (97%) rename ReactAndroid/src/main/jni/first-party/{ => fb}/jni/Environment.cpp (98%) rename ReactAndroid/src/main/jni/first-party/{jni/fbjni => fb/jni}/Exceptions.cpp (97%) rename ReactAndroid/src/main/jni/first-party/{jni/fbjni => fb/jni}/Hybrid.cpp (98%) rename ReactAndroid/src/main/jni/first-party/{ => fb}/jni/LocalString.cpp (99%) create mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/OnLoad.cpp rename ReactAndroid/src/main/jni/first-party/{jni/fbjni => fb/jni}/References.cpp (96%) rename ReactAndroid/src/main/jni/first-party/{ => fb}/jni/WeakReference.cpp (97%) rename ReactAndroid/src/main/jni/first-party/{ => fb}/jni/fbjni.cpp (90%) create mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/java/CppException.java create mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/java/CppSystemErrorException.java create mode 100644 ReactAndroid/src/main/jni/first-party/fb/jni/java/UnknownCppException.java rename ReactAndroid/src/main/jni/first-party/{ => fb}/jni/jni_helpers.cpp (99%) create mode 100644 ReactAndroid/src/main/jni/first-party/fb/lyra/lyra.cpp rename ReactAndroid/src/main/jni/first-party/{jni/OnLoad.cpp => fb/onload.cpp} (71%) delete mode 100644 ReactAndroid/src/main/jni/first-party/jni/Android.mk delete mode 100644 ReactAndroid/src/main/jni/first-party/jni/BUCK delete mode 100644 ReactAndroid/src/main/jni/first-party/jni/fbjni.h delete mode 100644 ReactAndroid/src/main/jni/first-party/jni/fbjni/android/ReferenceChecking.cpp diff --git a/ReactAndroid/src/main/java/com/facebook/jni/Prerequisites.java b/ReactAndroid/src/main/java/com/facebook/jni/Prerequisites.java index 74d137aa5..5f279d0b2 100644 --- a/ReactAndroid/src/main/java/com/facebook/jni/Prerequisites.java +++ b/ReactAndroid/src/main/java/com/facebook/jni/Prerequisites.java @@ -29,7 +29,7 @@ public class Prerequisites { private static final int EGL_OPENGL_ES2_BIT = 0x0004; public static void ensure() { - SoLoader.loadLibrary("fbjni"); + SoLoader.loadLibrary("fb"); } // Code is simplified version of getDetectedVersion() diff --git a/ReactAndroid/src/main/jni/first-party/fb/Android.mk b/ReactAndroid/src/main/jni/first-party/fb/Android.mk index 3361c433d..510d07018 100644 --- a/ReactAndroid/src/main/jni/first-party/fb/Android.mk +++ b/ReactAndroid/src/main/jni/first-party/fb/Android.mk @@ -3,12 +3,25 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ assert.cpp \ + jni/ByteBuffer.cpp \ + jni/Countable.cpp \ + jni/Environment.cpp \ + jni/Exceptions.cpp \ + jni/fbjni.cpp \ + jni/Hybrid.cpp \ + jni/jni_helpers.cpp \ + jni/LocalString.cpp \ + jni/OnLoad.cpp \ + jni/References.cpp \ + jni/WeakReference.cpp \ log.cpp \ + lyra/lyra.cpp \ + onload.cpp \ -LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. $(LOCAL_PATH)/include -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.. $(LOCAL_PATH)/include +LOCAL_C_INCLUDES := $(LOCAL_PATH)/include +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include -LOCAL_CFLAGS := -DLOG_TAG=\"libfb\" +LOCAL_CFLAGS := -DLOG_TAG=\"libfb\" -DDISABLE_XPLAT -fexceptions -frtti LOCAL_CFLAGS += -Wall -Werror # include/utils/threads.h has unused parameters LOCAL_CFLAGS += -Wno-unused-parameter @@ -17,7 +30,7 @@ ifeq ($(TOOLCHAIN_PERMISSIVE),true) endif LOCAL_CFLAGS += -DHAVE_POSIX_CLOCKS -CXX11_FLAGS := -std=c++11 +CXX11_FLAGS := -std=gnu++11 LOCAL_CFLAGS += $(CXX11_FLAGS) LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS) @@ -27,4 +40,5 @@ LOCAL_EXPORT_LDLIBS := -llog LOCAL_MODULE := libfb -include $(BUILD_SHARED_LIBRARY) \ No newline at end of file +include $(BUILD_SHARED_LIBRARY) + diff --git a/ReactAndroid/src/main/jni/first-party/fb/BUCK b/ReactAndroid/src/main/jni/first-party/fb/BUCK deleted file mode 100644 index 2890f37a1..000000000 --- a/ReactAndroid/src/main/jni/first-party/fb/BUCK +++ /dev/null @@ -1,28 +0,0 @@ -include_defs('//ReactAndroid/DEFS') - -cxx_library( - name = 'fb', - soname = 'libfb.so', - srcs = [ - 'assert.cpp', - 'log.cpp', - ], - header_namespace='fb', - exported_headers=subdir_glob([ - ('', '*.h'), - ('include/fb', '*.h'), - ]), - preprocessor_flags=[ - '-DLOG_TAG="libfb"', - ], - # We want to use this library during bootstrap - can_be_asset = False, - deps = [ - react_native_target('jni/third-party/android-ndk:android'), - react_native_target('jni/third-party/android-ndk:log'), - react_native_target('jni/third-party/glibc:dl'), - ], - visibility = [ - 'PUBLIC' - ], -) \ No newline at end of file diff --git a/ReactAndroid/src/main/jni/first-party/fb/Doxyfile b/ReactAndroid/src/main/jni/first-party/fb/Doxyfile new file mode 100644 index 000000000..b44118dd5 --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/Doxyfile @@ -0,0 +1,15 @@ +PROJECT_NAME = "Facebook Android Support" +JAVADOC_AUTOBRIEF = YES +EXTRACT_ALL = YES +RECURSIVE = YES +EXCLUDE = tests +EXCLUDE_PATTERNS = *.cpp +GENERATE_HTML = YES +GENERATE_LATEX = NO +ENABLE_PREPROCESSING = YES +HIDE_UNDOC_MEMBERS = YES +HIDE_SCOPE_NAMES = YES +HIDE_FRIEND_COMPOUNDS = YES +HIDE_UNDOC_CLASSES = YES +SHOW_INCLUDE_FILES = NO +#ENABLED_SECTIONS = INTERNAL diff --git a/ReactAndroid/src/main/jni/first-party/jni/ALog.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/ALog.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/ALog.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/ALog.h diff --git a/ReactAndroid/src/main/jni/first-party/fb/Countable.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/Countable.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/fb/Countable.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/Countable.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/Doxyfile b/ReactAndroid/src/main/jni/first-party/fb/include/fb/Doxyfile similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/Doxyfile rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/Doxyfile diff --git a/ReactAndroid/src/main/jni/first-party/jni/Environment.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/Environment.h similarity index 69% rename from ReactAndroid/src/main/jni/first-party/jni/Environment.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/Environment.h index 4dc6966a2..bf6c36162 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/Environment.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/Environment.h @@ -11,40 +11,56 @@ #include #include +#include + namespace facebook { namespace jni { // Keeps a thread-local reference to the current thread's JNIEnv. struct Environment { // May be null if this thread isn't attached to the JVM - static JNIEnv* current(); + FBEXPORT static JNIEnv* current(); static void initialize(JavaVM* vm); - static JNIEnv* ensureCurrentThreadIsAttached(); - static void detachCurrentThread(); + FBEXPORT static JNIEnv* ensureCurrentThreadIsAttached(); + FBEXPORT static void detachCurrentThread(); }; /** - * RAII Object that attaches a thread to the JVM. Failing to detach from a thread before it - * exits will cause a crash, as will calling Detach an extra time, and this guard class helps - * keep that straight. In addition, it remembers whether it performed the attach or not, so it - * is safe to nest it with itself or with non-fbjni code that manages the attachment correctly. + * RAII Object that attaches a thread to the JVM. Failing to detach from a + * thread before it + * exits will cause a crash, as will calling Detach an extra time, and this + * guard class helps + * keep that straight. In addition, it remembers whether it performed the attach + * or not, so it + * is safe to nest it with itself or with non-fbjni code that manages the + * attachment correctly. * * Potential concerns: - * - Attaching to the JVM is fast (~100us on MotoG), but ideally you would attach while the + * - Attaching to the JVM is fast (~100us on MotoG), but ideally you would + * attach while the * app is not busy. - * - Having a thread detach at arbitrary points is not safe in Dalvik; you need to be sure that - * there is no Java code on the current stack or you run the risk of a crash like: + * - Having a thread detach at arbitrary points is not safe in Dalvik; you need + * to be sure that + * there is no Java code on the current stack or you run the risk of a crash + * like: * ERROR: detaching thread with interp frames (count=18) - * (More detail at https://groups.google.com/forum/#!topic/android-ndk/2H8z5grNqjo) - * ThreadScope won't do a detach if the thread was already attached before the guard is + * (More detail at + * https://groups.google.com/forum/#!topic/android-ndk/2H8z5grNqjo) + * ThreadScope won't do a detach if the thread was already attached before + * the guard is * instantiated, but there's probably some usage that could trip this up. - * - Newly attached C++ threads only get the bootstrap class loader -- i.e. java language - * classes, not any of our application's classes. This will be different behavior than threads - * that were initiated on the Java side. A workaround is to pass a global reference for a - * class or instance to the new thread; this bypasses the need for the class loader. - * (See http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#attach_current_thread) + * - Newly attached C++ threads only get the bootstrap class loader -- i.e. + * java language + * classes, not any of our application's classes. This will be different + * behavior than threads + * that were initiated on the Java side. A workaround is to pass a global + * reference for a + * class or instance to the new thread; this bypasses the need for the class + * loader. + * (See + * http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#attach_current_thread) */ -class ThreadScope { +class FBEXPORT ThreadScope { public: ThreadScope(); ThreadScope(ThreadScope&) = delete; @@ -56,6 +72,5 @@ class ThreadScope { private: bool attachedWithThisScope_; }; - -} } - +} +} diff --git a/ReactAndroid/src/main/jni/first-party/fb/ProgramLocation.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/ProgramLocation.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/fb/ProgramLocation.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/ProgramLocation.h diff --git a/ReactAndroid/src/main/jni/first-party/fb/RefPtr.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/RefPtr.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/fb/RefPtr.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/RefPtr.h diff --git a/ReactAndroid/src/main/jni/first-party/fb/StaticInitialized.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/StaticInitialized.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/fb/StaticInitialized.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/StaticInitialized.h diff --git a/ReactAndroid/src/main/jni/first-party/fb/ThreadLocal.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/ThreadLocal.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/fb/ThreadLocal.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/ThreadLocal.h diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/assert.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/assert.h index 648ab2cdc..1ff0740ac 100644 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/assert.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/assert.h @@ -10,6 +10,8 @@ #ifndef FBASSERT_H #define FBASSERT_H +#include + namespace facebook { #define ENABLE_FBASSERT 1 @@ -24,7 +26,7 @@ namespace facebook { #define FBCRASH(msg, ...) facebook::assertInternal("Fatal error (%s:%d): " msg, __FILE__, __LINE__, ##__VA_ARGS__) #define FBUNREACHABLE() facebook::assertInternal("This code should be unreachable (%s:%d)", __FILE__, __LINE__) -void assertInternal(const char* formatstr, ...) __attribute__((noreturn)); +FBEXPORT void assertInternal(const char* formatstr, ...) __attribute__((noreturn)); // This allows storing the assert message before the current process terminates due to a crash typedef void (*AssertHandler)(const char* message); diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni.h new file mode 100644 index 000000000..66944c1ca --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Boxed.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Boxed.h new file mode 100644 index 000000000..5044d503d --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Boxed.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#pragma once + +#include "CoreClasses.h" + +namespace facebook { +namespace jni { + +namespace detail { +template +struct JPrimitive : JavaClass { + using typename JavaClass::javaobject; + using JavaClass::javaClassStatic; + static local_ref valueOf(jprim val) { + static auto cls = javaClassStatic(); + static auto method = + cls->template getStaticMethod("valueOf"); + return method(cls, val); + } + jprim value() const { + static auto method = + javaClassStatic()->template getMethod(T::kValueMethod); + return method(this->self()); + } +}; + +} // namespace detail + + +#define DEFINE_BOXED_PRIMITIVE(LITTLE, BIG) \ + struct J ## BIG : detail::JPrimitive { \ + static auto constexpr kJavaDescriptor = "Ljava/lang/" #BIG ";"; \ + static auto constexpr kValueMethod = #LITTLE "Value"; \ + j ## LITTLE LITTLE ## Value() const { \ + return value(); \ + } \ + }; \ + inline local_ref autobox(j ## LITTLE val) { \ + return J ## BIG::valueOf(val); \ + } + +DEFINE_BOXED_PRIMITIVE(boolean, Boolean) +DEFINE_BOXED_PRIMITIVE(byte, Byte) +DEFINE_BOXED_PRIMITIVE(char, Character) +DEFINE_BOXED_PRIMITIVE(short, Short) +DEFINE_BOXED_PRIMITIVE(int, Integer) +DEFINE_BOXED_PRIMITIVE(long, Long) +DEFINE_BOXED_PRIMITIVE(float, Float) +DEFINE_BOXED_PRIMITIVE(double, Double) + +#undef DEFINE_BOXED_PRIMITIVE + +inline local_ref autobox(alias_ref val) { + return make_local(val); +} + +}} + diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/ByteBuffer.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ByteBuffer.h similarity index 89% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/ByteBuffer.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ByteBuffer.h index b10573752..450f66a62 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/ByteBuffer.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ByteBuffer.h @@ -9,6 +9,8 @@ #pragma once +#include + #include "CoreClasses.h" #include "References-forward.h" @@ -17,7 +19,7 @@ namespace jni { // JNI's NIO support has some awkward preconditions and error reporting. This // class provides much more user-friendly access. -class JByteBuffer : public JavaClass { +class FBEXPORT JByteBuffer : public JavaClass { public: static constexpr const char* kJavaDescriptor = "Ljava/nio/ByteBuffer;"; diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Common.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Common.h similarity index 94% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Common.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Common.h index 9fa80c7a4..5db529304 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Common.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Common.h @@ -18,7 +18,8 @@ #include -#include +#include +#include #ifdef FBJNI_DEBUG_REFS # ifdef __ANDROID__ @@ -47,7 +48,7 @@ namespace jni { * unhelpful way (typically a segfault) while trying to handle an exception * which occurs later. */ -jint initialize(JavaVM*, std::function&&) noexcept; +FBEXPORT jint initialize(JavaVM*, std::function&&) noexcept; namespace internal { diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Context.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Context.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Context.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Context.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/CoreClasses-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses-inl.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/CoreClasses-inl.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses-inl.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/CoreClasses.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses.h similarity index 93% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/CoreClasses.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses.h index ed129af1b..62b8bb7fe 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/CoreClasses.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses.h @@ -23,6 +23,8 @@ #include +#include + namespace facebook { namespace jni { @@ -38,7 +40,7 @@ class JObject; /// in a "static auto" variable, or a static global. /// /// @return Returns a leaked global reference to the class -alias_ref findClassStatic(const char* name); +FBEXPORT alias_ref findClassStatic(const char* name); /// Lookup a class by name. Note this functions returns a local reference, /// which means that it must not be stored in a static variable. @@ -47,12 +49,12 @@ alias_ref findClassStatic(const char* name); /// (like caching method ids). /// /// @return Returns a global reference to the class -local_ref findClassLocal(const char* name); +FBEXPORT local_ref findClassLocal(const char* name); /// Check to see if two references refer to the same object. Comparison with nullptr /// returns true if and only if compared to another nullptr. A weak reference that /// refers to a reclaimed object count as nullptr. -bool isSameObject(alias_ref lhs, alias_ref rhs) noexcept; +FBEXPORT bool isSameObject(alias_ref lhs, alias_ref rhs) noexcept; // Together, these classes allow convenient use of any class with the fbjni // helpers. To use: @@ -95,7 +97,7 @@ static local_ref newInstance(Args... args); class MonitorLock; -class JObject : detail::JObjectBase { +class FBEXPORT JObject : detail::JObjectBase { public: static constexpr auto kJavaDescriptor = "Ljava/lang/Object;"; @@ -191,7 +193,7 @@ struct JTypeFor { // jthrowable) to be used as javaobject. This should only be necessary for // built-in jni types and not user-defined ones. template -class JavaClass : public Base { +class FBEXPORT JavaClass : public Base { using JObjType = typename detail::JTypeFor; public: using _javaobject = typename JObjType::_javaobject; @@ -219,7 +221,7 @@ protected: /// Wrapper to provide functionality to jclass references struct NativeMethod; -class JClass : public JavaClass { +class FBEXPORT JClass : public JavaClass { public: /// Java type descriptor static constexpr const char* kJavaDescriptor = "Ljava/lang/Class;"; @@ -324,7 +326,7 @@ private: void registerNatives(const char* name, std::initializer_list methods); /// Wrapper to provide functionality to jstring references -class JString : public JavaClass { +class FBEXPORT JString : public JavaClass { public: /// Java type descriptor static constexpr const char* kJavaDescriptor = "Ljava/lang/String;"; @@ -335,11 +337,11 @@ class JString : public JavaClass { /// Convenience functions to convert a std::string or const char* into a @ref local_ref to a /// jstring -local_ref make_jstring(const char* modifiedUtf8); -local_ref make_jstring(const std::string& modifiedUtf8); +FBEXPORT local_ref make_jstring(const char* modifiedUtf8); +FBEXPORT local_ref make_jstring(const std::string& modifiedUtf8); /// Wrapper to provide functionality to jthrowable references -class JThrowable : public JavaClass { +class FBEXPORT JThrowable : public JavaClass { public: static constexpr const char* kJavaDescriptor = "Ljava/lang/Throwable;"; }; @@ -370,7 +372,7 @@ class ElementProxy { } namespace detail { -class JArray : public JavaClass { +class FBEXPORT JArray : public JavaClass { public: // This cannot be used in a scope that derives a descriptor (like in a method // signature). Use a more derived type instead (like JArrayInt or @@ -382,7 +384,7 @@ class JArray : public JavaClass { // This is used so that the JArrayClass javaobject extends jni's // jobjectArray. This class should not be used directly. A general Object[] // should use JArrayClass. -class JTypeArray : public JavaClass { +class FBEXPORT JTypeArray : public JavaClass { // This cannot be used in a scope that derives a descriptor (like in a method // signature). static constexpr const char* kJavaDescriptor = nullptr; @@ -452,7 +454,7 @@ template class PinnedCriticalAlloc; /// This is an empty holder by itself. Construct a PinnedPrimitiveArray to actually interact with /// the elements of the array. template -class JPrimitiveArray : +class FBEXPORT JPrimitiveArray : public JavaClass, detail::JArray, JArrayType> { static_assert(is_jni_primitive_array(), ""); public: @@ -492,14 +494,14 @@ private: void releaseElements(T* elements, jint mode); }; -local_ref make_boolean_array(jsize size); -local_ref make_byte_array(jsize size); -local_ref make_char_array(jsize size); -local_ref make_short_array(jsize size); -local_ref make_int_array(jsize size); -local_ref make_long_array(jsize size); -local_ref make_float_array(jsize size); -local_ref make_double_array(jsize size); +FBEXPORT local_ref make_boolean_array(jsize size); +FBEXPORT local_ref make_byte_array(jsize size); +FBEXPORT local_ref make_char_array(jsize size); +FBEXPORT local_ref make_short_array(jsize size); +FBEXPORT local_ref make_int_array(jsize size); +FBEXPORT local_ref make_long_array(jsize size); +FBEXPORT local_ref make_float_array(jsize size); +FBEXPORT local_ref make_double_array(jsize size); using JArrayBoolean = JPrimitiveArray; using JArrayByte = JPrimitiveArray; diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Exceptions.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Exceptions.h similarity index 91% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Exceptions.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Exceptions.h index 1892fd49c..8edb871c2 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Exceptions.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Exceptions.h @@ -26,6 +26,8 @@ #include +#include + #include "Common.h" // If a pending JNI Java exception is found, wraps it in a JniException object and throws it as @@ -50,7 +52,7 @@ namespace internal { * Before using any of the state initialized above, call this. It * will assert if initialization has not yet occurred. */ -void assertIfExceptionsNotInitialized(); +FBEXPORT void assertIfExceptionsNotInitialized(); // JniException //////////////////////////////////////////////////////////////////////////////////// @@ -62,7 +64,7 @@ void assertIfExceptionsNotInitialized(); * * Note: the what() method of this class is not thread-safe (t6900503). */ -class JniException : public std::exception { +class FBEXPORT JniException : public std::exception { public: JniException(); @@ -93,15 +95,15 @@ class JniException : public std::exception { // Functions that throw C++ exceptions -void throwPendingJniExceptionAsCppException(); +FBEXPORT void throwPendingJniExceptionAsCppException(); -void throwCppExceptionIf(bool condition); +FBEXPORT void throwCppExceptionIf(bool condition); static const int kMaxExceptionMessageBufferSize = 512; -[[noreturn]] void throwNewJavaException(jthrowable); +[[noreturn]] FBEXPORT void throwNewJavaException(jthrowable); -[[noreturn]] void throwNewJavaException(const char* throwableName, const char* msg); +[[noreturn]] FBEXPORT void throwNewJavaException(const char* throwableName, const char* msg); // These methods are the preferred way to throw a Java exception from // a C++ function. They create and throw a C++ exception which wraps diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/File.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/File.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/File.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/File.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Hybrid.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Hybrid.h similarity index 97% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Hybrid.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Hybrid.h index 70fc670f5..e272c2dad 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Hybrid.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Hybrid.h @@ -11,7 +11,10 @@ #include #include + #include +#include + #include "CoreClasses.h" namespace facebook { @@ -24,7 +27,7 @@ public: virtual ~BaseHybridClass() {} }; -struct HybridData : public JavaClass { +struct FBEXPORT HybridData : public JavaClass { constexpr static auto kJavaDescriptor = "Lcom/facebook/jni/HybridData;"; void setNativePointer(std::unique_ptr new_value); BaseHybridClass* getNativePointer(); @@ -65,7 +68,7 @@ struct HybridTraits< // convert to HybridClass* from jhybridobject template -struct Convert< +struct FBEXPORT Convert< T, typename std::enable_if< std::is_base_of::type>::value>::type> { typedef typename std::remove_pointer::type::jhybridobject jniType; @@ -90,7 +93,7 @@ struct RefReprType -class HybridClass : public detail::HybridTraits::CxxBase { +class FBEXPORT HybridClass : public detail::HybridTraits::CxxBase { public: struct JavaPart : JavaClass::JavaBase> { // At this point, T is incomplete, and so we cannot access diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Iterator-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator-inl.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Iterator-inl.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator-inl.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Iterator.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Iterator.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Iterator.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta-forward.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-forward.h similarity index 97% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta-forward.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-forward.h index 2f524ad06..ff08aff46 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta-forward.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-forward.h @@ -19,7 +19,7 @@ class JStaticMethod; template class JNonvirtualMethod; template -class JConstructor; +struct JConstructor; template class JField; template diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-inl.h similarity index 81% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta-inl.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-inl.h index 38fabc500..dda35925d 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta-inl.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta-inl.h @@ -15,6 +15,11 @@ #include "Exceptions.h" #include "MetaConvert.h" #include "References.h" +#include "Boxed.h" + +#if defined(__ANDROID__) +#include +#endif namespace facebook { namespace jni { @@ -33,9 +38,72 @@ inline jmethodID JMethodBase::getId() const noexcept { return method_id_; } +namespace { + +template +struct ArgsArraySetter; + +template +struct ArgsArraySetter { + static void set(alias_ref::javaobject> array, Arg arg0, Args... args) { + // TODO(xxxxxxxx): Use Convert... to do conversions like the fast path. + (*array)[idx] = autobox(arg0); + ArgsArraySetter::set(array, args...); + } +}; + +template +struct ArgsArraySetter { + static void set(alias_ref::javaobject> array) { + } +}; + +template +local_ref::javaobject> makeArgsArray(Args... args) { + auto arr = JArrayClass::newArray(sizeof...(args)); + ArgsArraySetter<0, Args...>::set(arr, args...); + return arr; +} + + +bool needsSlowPath(alias_ref obj) { +#if defined(__ANDROID__) + // On Android 6.0, art crashes when attempting to call a function on a Proxy. + // So, when we detect that case we must use the safe, slow workaround. That is, + // we resolve the method id to the corresponding java.lang.reflect.Method object + // and make the call via it's invoke() method. + static auto android_sdk = ([] { + char sdk_version_str[PROP_VALUE_MAX]; + __system_property_get("ro.build.version.sdk", sdk_version_str); + return atoi(sdk_version_str); + })(); + static auto is_bad_android = android_sdk == 23; + if (!is_bad_android) return false; + static auto proxy_class = findClassStatic("java/lang/reflect/Proxy"); + return obj->isInstanceOf(proxy_class); +#else + return false; +#endif +} + +} + +template +local_ref slowCall(jmethodID method_id, alias_ref self, Args... args) { + static auto invoke = findClassStatic("java/lang/reflect/Method") + ->getMethod::javaobject)>("invoke"); + // TODO(xxxxxxx): Provide fbjni interface to ToReflectedMethod. + auto reflected = adopt_local(Environment::current()->ToReflectedMethod(self->getClass().get(), method_id, JNI_FALSE)); + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); + if (!reflected) throw JniException(); + auto argsArray = makeArgsArray(args...); + // No need to check for exceptions since invoke is itself a JMethod that will do that for us. + return invoke(reflected, self.get(), argsArray.get()); +} + template inline void JMethod::operator()(alias_ref self, Args... args) { - const auto env = internal::getEnv(); + const auto env = Environment::current(); env->CallVoidMethod( self.get(), getId(), @@ -45,7 +113,7 @@ inline void JMethod::operator()(alias_ref self, Args... #pragma push_macro("DEFINE_PRIMITIVE_CALL") #undef DEFINE_PRIMITIVE_CALL -#define DEFINE_PRIMITIVE_CALL(TYPE, METHOD) \ +#define DEFINE_PRIMITIVE_CALL(TYPE, METHOD, CLASS) \ template \ inline TYPE JMethod::operator()(alias_ref self, Args... args) { \ const auto env = internal::getEnv(); \ @@ -57,17 +125,16 @@ inline TYPE JMethod::operator()(alias_ref self, Args... return result; \ } -DEFINE_PRIMITIVE_CALL(jboolean, Boolean) -DEFINE_PRIMITIVE_CALL(jbyte, Byte) -DEFINE_PRIMITIVE_CALL(jchar, Char) -DEFINE_PRIMITIVE_CALL(jshort, Short) -DEFINE_PRIMITIVE_CALL(jint, Int) -DEFINE_PRIMITIVE_CALL(jlong, Long) -DEFINE_PRIMITIVE_CALL(jfloat, Float) -DEFINE_PRIMITIVE_CALL(jdouble, Double) +DEFINE_PRIMITIVE_CALL(jboolean, Boolean, JBoolean) +DEFINE_PRIMITIVE_CALL(jbyte, Byte, JByte) +DEFINE_PRIMITIVE_CALL(jchar, Char, JCharacter) +DEFINE_PRIMITIVE_CALL(jshort, Short, JShort) +DEFINE_PRIMITIVE_CALL(jint, Int, JInteger) +DEFINE_PRIMITIVE_CALL(jlong, Long, JLong) +DEFINE_PRIMITIVE_CALL(jfloat, Float, JFloat) +DEFINE_PRIMITIVE_CALL(jdouble, Double, JDouble) #pragma pop_macro("DEFINE_PRIMITIVE_CALL") - /// JMethod specialization for references that wraps the return value in a @ref local_ref template class JMethod : public JMethodBase { @@ -80,19 +147,22 @@ class JMethod : public JMethodBase { JMethod(const JMethod& other) noexcept = default; /// Invoke a method and return a local reference wrapping the result - local_ref operator()(alias_ref self, Args... args) { - const auto env = internal::getEnv(); - auto result = env->CallObjectMethod( - self.get(), - getId(), - detail::callToJni(detail::Convert::type>::toCall(args))...); - FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); - return adopt_local(static_cast(result)); - } + local_ref operator()(alias_ref self, Args... args); friend class JClass; }; +template +inline auto JMethod::operator()(alias_ref self, Args... args) -> local_ref { + const auto env = Environment::current(); + auto result = env->CallObjectMethod( + self.get(), + getId(), + detail::callToJni(detail::Convert::type>::toCall(args))...); + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); + return adopt_local(static_cast(result)); +} + template inline void JStaticMethod::operator()(alias_ref cls, Args... args) { const auto env = internal::getEnv(); diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta.h similarity index 97% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta.h index 23c745050..4aefb0ca1 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Meta.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Meta.h @@ -35,6 +35,12 @@ namespace facebook { namespace jni { +// This will get the reflected Java Method from the method_id, get it's invoke +// method, and call the method via that. This shouldn't ever be needed, but +// Android 6.0 crashes when calling a method on a java.lang.Proxy via jni. +template +local_ref slowCall(jmethodID method_id, alias_ref self, Args... args); + class JObject; diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/MetaConvert.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/MetaConvert.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/MetaConvert.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/MetaConvert.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/ReferenceAllocators-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators-inl.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/ReferenceAllocators-inl.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators-inl.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/ReferenceAllocators.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators.h similarity index 87% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/ReferenceAllocators.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators.h index ee328e071..024ba797f 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/ReferenceAllocators.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/ReferenceAllocators.h @@ -16,12 +16,14 @@ #pragma once +#include + #include "Common.h" namespace facebook { namespace jni { /// Allocator that handles local references -class LocalReferenceAllocator { +class FBEXPORT LocalReferenceAllocator { public: jobject newReference(jobject original) const; void deleteReference(jobject reference) const noexcept; @@ -29,7 +31,7 @@ class LocalReferenceAllocator { }; /// Allocator that handles global references -class GlobalReferenceAllocator { +class FBEXPORT GlobalReferenceAllocator { public: jobject newReference(jobject original) const; void deleteReference(jobject reference) const noexcept; @@ -37,7 +39,7 @@ class GlobalReferenceAllocator { }; /// Allocator that handles weak global references -class WeakGlobalReferenceAllocator { +class FBEXPORT WeakGlobalReferenceAllocator { public: jobject newReference(jobject original) const; void deleteReference(jobject reference) const noexcept; @@ -50,7 +52,7 @@ namespace internal { /** * @return true iff env->GetObjectRefType is expected to work properly. */ -bool doesGetObjectRefTypeWork(); +FBEXPORT bool doesGetObjectRefTypeWork(); } /// @endcond diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/References-forward.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-forward.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/References-forward.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-forward.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/References-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-inl.h similarity index 99% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/References-inl.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-inl.h index 2176d1e02..f81a84325 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/References-inl.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References-inl.h @@ -198,7 +198,9 @@ template template inline base_owned_ref::base_owned_ref(const base_owned_ref& other) : storage_{static_cast(Alloc{}.newReference(other.get()))} -{} +{ + static_assert(std::is_convertible, javaobject>::value, ""); +} template inline facebook::jni::base_owned_ref::base_owned_ref( diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/References.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References.h similarity index 99% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/References.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References.h index b578c5c91..8795216a7 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/References.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/References.h @@ -77,6 +77,8 @@ #include +#include + #include "ReferenceAllocators.h" #include "TypeTraits.h" #include "References-forward.h" @@ -555,7 +557,7 @@ class alias_ref { * This is useful when you have a call which is initiated from C++-land, and therefore * doesn't automatically get a local JNI frame managed for you by the JNI framework. */ -class JniLocalScope { +class FBEXPORT JniLocalScope { public: JniLocalScope(JNIEnv* p_env, jint capacity); ~JniLocalScope(); diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Registration-inl.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration-inl.h similarity index 94% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Registration-inl.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration-inl.h index 2ac6abaf4..9bcf21a26 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Registration-inl.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration-inl.h @@ -88,14 +88,14 @@ inline NativeMethodWrapper* exceptionWrapJNIMethod(void (*)(alias_ref, Args.. template inline NativeMethodWrapper* exceptionWrapJNIMethod(R (*)(alias_ref, Args... args)) { struct funcWrapper { - typedef typename Convert::type>::jniType jniRet; - JNI_ENTRY_POINT static jniRet call(JNIEnv*, jobject obj, + JNI_ENTRY_POINT static typename Convert::type>::jniType call(JNIEnv*, jobject obj, typename Convert::type>::jniType... args) { try { return Convert::type>::toJniRet( (*func)(static_cast>(obj), Convert::type>::fromJni(args)...)); } catch (...) { + using jniRet = typename Convert::type>::jniType; translatePendingCppExceptionToJavaException(); return jniRet{}; } @@ -138,9 +138,8 @@ inline NativeMethodWrapper* exceptionWrapJNIMethod(void (C::*method0)(Args... ar template inline NativeMethodWrapper* exceptionWrapJNIMethod(R (C::*method0)(Args... args)) { struct funcWrapper { - typedef typename Convert::type>::jniType jniRet; - JNI_ENTRY_POINT static jniRet call(JNIEnv* env, jobject obj, + JNI_ENTRY_POINT static typename Convert::type>::jniType call(JNIEnv* env, jobject obj, typename Convert::type>::jniType... args) { try { try { @@ -156,6 +155,7 @@ inline NativeMethodWrapper* exceptionWrapJNIMethod(R (C::*method0)(Args... args) throw; } } catch (...) { + using jniRet = typename Convert::type>::jniType; translatePendingCppExceptionToJavaException(); return jniRet{}; } diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Registration.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Registration.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/Registration.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/TypeTraits.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/TypeTraits.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/TypeTraits.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/TypeTraits.h diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/log.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/log.h index 5bac939dd..e26e716bf 100644 --- a/ReactAndroid/src/main/jni/first-party/fb/include/fb/log.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/log.h @@ -41,6 +41,8 @@ // #pragma once +#include + #ifdef __cplusplus extern "C" { #endif @@ -48,35 +50,36 @@ extern "C" { #ifdef ANDROID #include #else - // These declarations are needed for our internal use even on non-Android builds. - // (they are borrowed from ) +// These declarations are needed for our internal use even on non-Android +// builds. +// (they are borrowed from ) - /* - * Android log priority values, in ascending priority order. - */ - typedef enum android_LogPriority { - ANDROID_LOG_UNKNOWN = 0, - ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ - ANDROID_LOG_VERBOSE, - ANDROID_LOG_DEBUG, - ANDROID_LOG_INFO, - ANDROID_LOG_WARN, - ANDROID_LOG_ERROR, - ANDROID_LOG_FATAL, - ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ - } android_LogPriority; +/* + * Android log priority values, in ascending priority order. + */ +typedef enum android_LogPriority { + ANDROID_LOG_UNKNOWN = 0, + ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ + ANDROID_LOG_VERBOSE, + ANDROID_LOG_DEBUG, + ANDROID_LOG_INFO, + ANDROID_LOG_WARN, + ANDROID_LOG_ERROR, + ANDROID_LOG_FATAL, + ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ +} android_LogPriority; - /* - * Send a simple string to the log. - */ - int __android_log_write(int prio, const char *tag, const char *text); +/* + * Send a simple string to the log. + */ +int __android_log_write(int prio, const char *tag, const char *text); - /* - * Send a formatted string to the log, used like printf(fmt,...) - */ - int __android_log_print(int prio, const char *tag, const char *fmt, ...) +/* + * Send a formatted string to the log, used like printf(fmt,...) + */ +int __android_log_print(int prio, const char *tag, const char *fmt, ...) #if defined(__GNUC__) - __attribute__ ((format(printf, 3, 4))) + __attribute__((format(printf, 3, 4))) #endif ; @@ -113,22 +116,21 @@ extern "C" { */ #ifndef FBLOGV #if FBLOG_NDEBUG -#define FBLOGV(...) ((void)0) +#define FBLOGV(...) ((void)0) #else #define FBLOGV(...) ((void)FBLOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) #endif #endif -#define CONDITION(cond) (__builtin_expect((cond)!=0, 0)) +#define CONDITION(cond) (__builtin_expect((cond) != 0, 0)) #ifndef FBLOGV_IF #if FBLOG_NDEBUG -#define FBLOGV_IF(cond, ...) ((void)0) +#define FBLOGV_IF(cond, ...) ((void)0) #else -#define FBLOGV_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)FBLOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) +#define FBLOGV_IF(cond, ...) \ + ((CONDITION(cond)) ? ((void)FBLOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ + : (void)0) #endif #endif @@ -141,9 +143,7 @@ extern "C" { #ifndef FBLOGD_IF #define FBLOGD_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)FBLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) + ((CONDITION(cond)) ? ((void)FBLOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) : (void)0) #endif /* @@ -155,9 +155,7 @@ extern "C" { #ifndef FBLOGI_IF #define FBLOGI_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)FBLOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) + ((CONDITION(cond)) ? ((void)FBLOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) : (void)0) #endif /* @@ -169,9 +167,7 @@ extern "C" { #ifndef FBLOGW_IF #define FBLOGW_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)FBLOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) + ((CONDITION(cond)) ? ((void)FBLOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) : (void)0) #endif /* @@ -183,9 +179,7 @@ extern "C" { #ifndef FBLOGE_IF #define FBLOGE_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)FBLOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) + ((CONDITION(cond)) ? ((void)FBLOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) : (void)0) #endif // --------------------------------------------------------------------- @@ -234,7 +228,6 @@ extern "C" { #define IF_FBLOGE() IF_FBLOG(LOG_ERROR, LOG_TAG) #endif - // --------------------------------------------------------------------- /* @@ -243,13 +236,12 @@ extern "C" { * It is NOT stripped from release builds. Note that the condition test * is -inverted- from the normal assert() semantics. */ -#define FBLOG_ALWAYS_FATAL_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)fb_printAssert(#cond, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) +#define FBLOG_ALWAYS_FATAL_IF(cond, ...) \ + ((CONDITION(cond)) ? ((void)fb_printAssert(#cond, LOG_TAG, __VA_ARGS__)) \ + : (void)0) #define FBLOG_ALWAYS_FATAL(...) \ - ( ((void)fb_printAssert(NULL, LOG_TAG, __VA_ARGS__)) ) + (((void)fb_printAssert(NULL, LOG_TAG, __VA_ARGS__))) /* * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that @@ -286,20 +278,19 @@ extern "C" { */ #ifndef FBLOG #define FBLOG(priority, tag, ...) \ - FBLOG_PRI(ANDROID_##priority, tag, __VA_ARGS__) + FBLOG_PRI(ANDROID_##priority, tag, __VA_ARGS__) #endif #ifndef FBLOG_BY_DELIMS #define FBLOG_BY_DELIMS(priority, tag, delims, msg, ...) \ - logPrintByDelims(ANDROID_##priority, tag, delims, msg, ##__VA_ARGS__) + logPrintByDelims(ANDROID_##priority, tag, delims, msg, ##__VA_ARGS__) #endif /* * Log macro that allows you to specify a number for the priority. */ #ifndef FBLOG_PRI -#define FBLOG_PRI(priority, tag, ...) \ - fb_printLog(priority, tag, __VA_ARGS__) +#define FBLOG_PRI(priority, tag, ...) fb_printLog(priority, tag, __VA_ARGS__) #endif /* @@ -307,44 +298,40 @@ extern "C" { */ #ifndef FBLOG_PRI_VA #define FBLOG_PRI_VA(priority, tag, fmt, args) \ - fb_vprintLog(priority, NULL, tag, fmt, args) + fb_vprintLog(priority, NULL, tag, fmt, args) #endif /* * Conditional given a desired logging priority and tag. */ #ifndef IF_FBLOG -#define IF_FBLOG(priority, tag) \ - if (fb_testLog(ANDROID_##priority, tag)) +#define IF_FBLOG(priority, tag) if (fb_testLog(ANDROID_##priority, tag)) #endif typedef void (*LogHandler)(int priority, const char* tag, const char* message); -void setLogHandler(LogHandler logHandler); +FBEXPORT void setLogHandler(LogHandler logHandler); /* * =========================================================================== * * The stuff in the rest of this file should not be used directly. */ -int fb_printLog(int prio, const char *tag, const char *fmt, ...) +FBEXPORT int fb_printLog(int prio, const char* tag, const char* fmt, ...) #if defined(__GNUC__) - __attribute__ ((format(printf, 3, 4))) + __attribute__((format(printf, 3, 4))) #endif -; + ; #define fb_vprintLog(prio, cond, tag, fmt...) \ - __android_log_vprint(prio, tag, fmt) + __android_log_vprint(prio, tag, fmt) -#define fb_printAssert(cond, tag, fmt...) \ - __android_log_assert(cond, tag, fmt) +#define fb_printAssert(cond, tag, fmt...) __android_log_assert(cond, tag, fmt) -#define fb_writeLog(prio, tag, text) \ - __android_log_write(prio, tag, text) +#define fb_writeLog(prio, tag, text) __android_log_write(prio, tag, text) -#define fb_bWriteLog(tag, payload, len) \ - __android_log_bwrite(tag, payload, len) +#define fb_bWriteLog(tag, payload, len) __android_log_bwrite(tag, payload, len) #define fb_btWriteLog(tag, type, payload, len) \ - __android_log_btwrite(tag, type, payload, len) + __android_log_btwrite(tag, type, payload, len) #define fb_testLog(prio, tag) (1) @@ -354,8 +341,6 @@ int fb_printLog(int prio, const char *tag, const char *fmt, ...) void logPrintByDelims(int priority, const char* tag, const char* delims, const char* msg, ...); - #ifdef __cplusplus } #endif - diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/lyra.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/lyra.h new file mode 100644 index 000000000..c60ff27b6 --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/lyra.h @@ -0,0 +1,168 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#pragma once + +#include +#include +#include +#include + +#include + +namespace facebook { +namespace lyra { + +constexpr size_t kDefaultLimit = 64; + +using InstructionPointer = const void*; + +class FBEXPORT StackTraceElement { + public: + StackTraceElement(InstructionPointer absoluteProgramCounter, + InstructionPointer libraryBase, + InstructionPointer functionAddress, std::string libraryName, + std::string functionName) + : absoluteProgramCounter_{absoluteProgramCounter}, + libraryBase_{libraryBase}, + functionAddress_{functionAddress}, + libraryName_{std::move(libraryName)}, + functionName_{std::move(functionName)} {} + + InstructionPointer libraryBase() const noexcept { return libraryBase_; } + + InstructionPointer functionAddress() const noexcept { + return functionAddress_; + } + + InstructionPointer absoluteProgramCounter() const noexcept { + return absoluteProgramCounter_; + } + + const std::string& libraryName() const noexcept { return libraryName_; } + + const std::string& functionName() const noexcept { return functionName_; } + + /** + * The offset of the program counter to the base of the library (i.e. the + * address that addr2line takes as input> + */ + std::ptrdiff_t libraryOffset() const noexcept { + auto absoluteLibrary = static_cast(libraryBase_); + auto absoluteabsoluteProgramCounter = + static_cast(absoluteProgramCounter_); + return absoluteabsoluteProgramCounter - absoluteLibrary; + } + + /** + * The offset within the current function + */ + int functionOffset() const noexcept { + auto absoluteSymbol = static_cast(functionAddress_); + auto absoluteabsoluteProgramCounter = + static_cast(absoluteProgramCounter_); + return absoluteabsoluteProgramCounter - absoluteSymbol; + } + + private: + const InstructionPointer absoluteProgramCounter_; + const InstructionPointer libraryBase_; + const InstructionPointer functionAddress_; + const std::string libraryName_; + const std::string functionName_; +}; + +/** + * Populate the vector with the current stack trace + * + * Note that this trace needs to be symbolicated to get the library offset even + * if it is to be symbolicated off-line. + * + * Beware of a bug on some platforms, which makes the trace loop until the + * buffer is full when it reaches a noexpr function. It seems to be fixed in + * newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846 + * + * @param stackTrace The vector that will receive the stack trace. Before + * filling the vector it will be cleared. The vector will never grow so the + * number of frames captured is limited by the capacity of it. + * + * @param skip The number of frames to skip before capturing the trace + */ +FBEXPORT void getStackTrace(std::vector& stackTrace, + size_t skip = 0); + +/** + * Creates a vector and populates it with the current stack trace + * + * Note that this trace needs to be symbolicated to get the library offset even + * if it is to be symbolicated off-line. + * + * Beware of a bug on some platforms, which makes the trace loop until the + * buffer is full when it reaches a noexpr function. It seems to be fixed in + * newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846 + * + * @param skip The number of frames to skip before capturing the trace + * + * @limit The maximum number of frames captured + */ +FBEXPORT inline std::vector getStackTrace( + size_t skip = 0, + size_t limit = kDefaultLimit) { + auto stackTrace = std::vector{}; + stackTrace.reserve(limit); + getStackTrace(stackTrace, skip + 1); + return stackTrace; +} + +/** + * Symbolicates a stack trace into a given vector + * + * @param symbols The vector to receive the output. The vector is cleared and + * enough room to keep the frames are reserved. + * + * @param stackTrace The input stack trace + */ +FBEXPORT void getStackTraceSymbols(std::vector& symbols, + const std::vector& trace); + +/** + * Symbolicates a stack trace into a new vector + * + * @param stackTrace The input stack trace + */ +FBEXPORT inline std::vector getStackTraceSymbols( + const std::vector& trace) { + auto symbols = std::vector{}; + getStackTraceSymbols(symbols, trace); + return symbols; +} + + +/** + * Captures and symbolicates a stack trace + * + * Beware of a bug on some platforms, which makes the trace loop until the + * buffer is full when it reaches a noexpr function. It seems to be fixed in + * newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846 + * + * @param skip The number of frames before capturing the trace + * + * @param limit The maximum number of frames captured + */ +FBEXPORT inline std::vector getStackTraceSymbols( + size_t skip = 0, + size_t limit = kDefaultLimit) { + return getStackTraceSymbols(getStackTrace(skip + 1, limit)); +} + +/** + * Formatting a stack trace element + */ +FBEXPORT std::ostream& operator<<(std::ostream& out, const StackTraceElement& elm); + +/** + * Formatting a stack trace + */ +FBEXPORT std::ostream& operator<<(std::ostream& out, + const std::vector& trace); +} +} diff --git a/ReactAndroid/src/main/jni/first-party/fb/noncopyable.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/noncopyable.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/fb/noncopyable.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/noncopyable.h diff --git a/ReactAndroid/src/main/jni/first-party/fb/nonmovable.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/nonmovable.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/fb/nonmovable.h rename to ReactAndroid/src/main/jni/first-party/fb/include/fb/nonmovable.h diff --git a/ReactAndroid/src/main/jni/first-party/fb/include/fb/visibility.h b/ReactAndroid/src/main/jni/first-party/fb/include/fb/visibility.h new file mode 100644 index 000000000..7011a06bc --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/include/fb/visibility.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#pragma once + +#define FBEXPORT __attribute__((visibility("default"))) diff --git a/ReactAndroid/src/main/jni/first-party/jni/Countable.h b/ReactAndroid/src/main/jni/first-party/fb/include/jni/Countable.h similarity index 78% rename from ReactAndroid/src/main/jni/first-party/jni/Countable.h rename to ReactAndroid/src/main/jni/first-party/fb/include/jni/Countable.h index 69460d8a7..24f27c692 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/Countable.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/jni/Countable.h @@ -8,14 +8,17 @@ */ #pragma once + #include + #include #include +#include namespace facebook { namespace jni { -const RefPtr& countableFromJava(JNIEnv* env, jobject obj); +FBEXPORT const RefPtr& countableFromJava(JNIEnv* env, jobject obj); template RefPtr extractRefPtr(JNIEnv* env, jobject obj) { return static_cast>(countableFromJava(env, obj)); @@ -25,7 +28,7 @@ template RefPtr extractPossiblyNullRefPtr(JNIEnv* env, jobject o return obj ? extractRefPtr(env, obj) : nullptr; } -void setCountableForJava(JNIEnv* env, jobject obj, RefPtr&& countable); +FBEXPORT void setCountableForJava(JNIEnv* env, jobject obj, RefPtr&& countable); void CountableOnLoad(JNIEnv* env); diff --git a/ReactAndroid/src/main/jni/first-party/jni/GlobalReference.h b/ReactAndroid/src/main/jni/first-party/fb/include/jni/GlobalReference.h similarity index 98% rename from ReactAndroid/src/main/jni/first-party/jni/GlobalReference.h rename to ReactAndroid/src/main/jni/first-party/fb/include/jni/GlobalReference.h index 55f537ab5..f0faf5fb8 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/GlobalReference.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/jni/GlobalReference.h @@ -14,7 +14,7 @@ #include -#include +#include namespace facebook { namespace jni { diff --git a/ReactAndroid/src/main/jni/first-party/jni/LocalReference.h b/ReactAndroid/src/main/jni/first-party/fb/include/jni/LocalReference.h similarity index 96% rename from ReactAndroid/src/main/jni/first-party/jni/LocalReference.h rename to ReactAndroid/src/main/jni/first-party/fb/include/jni/LocalReference.h index b5d9c54a1..22a558dc7 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/LocalReference.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/jni/LocalReference.h @@ -14,7 +14,7 @@ #include -#include +#include namespace facebook { namespace jni { @@ -27,7 +27,7 @@ struct LocalReferenceDeleter { if (localReference != nullptr) { Environment::current()->DeleteLocalRef(localReference); } - } + } }; template diff --git a/ReactAndroid/src/main/jni/first-party/jni/LocalString.h b/ReactAndroid/src/main/jni/first-party/fb/include/jni/LocalString.h similarity index 96% rename from ReactAndroid/src/main/jni/first-party/jni/LocalString.h rename to ReactAndroid/src/main/jni/first-party/fb/include/jni/LocalString.h index 2290af10d..2763e62be 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/LocalString.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/jni/LocalString.h @@ -8,9 +8,13 @@ */ #pragma once + #include + #include +#include + namespace facebook { namespace jni { @@ -41,7 +45,7 @@ std::string utf16toUTF8(const uint16_t* utf16Bytes, size_t len); // - http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html // - https://docs.oracle.com/javase/6/docs/api/java/io/DataInput.html#modified-utf-8 -class LocalString { +class FBEXPORT LocalString { public: // Assumes UTF8 encoding and make a required convertion to modified UTF-8 when the string // contains unicode supplementary characters. @@ -85,6 +89,6 @@ private: // The string from JNI is converted to standard UTF-8 if the string contains supplementary // characters. -std::string fromJString(JNIEnv* env, jstring str); +FBEXPORT std::string fromJString(JNIEnv* env, jstring str); } } diff --git a/ReactAndroid/src/main/jni/first-party/jni/Registration.h b/ReactAndroid/src/main/jni/first-party/fb/include/jni/Registration.h similarity index 100% rename from ReactAndroid/src/main/jni/first-party/jni/Registration.h rename to ReactAndroid/src/main/jni/first-party/fb/include/jni/Registration.h diff --git a/ReactAndroid/src/main/jni/first-party/jni/WeakReference.h b/ReactAndroid/src/main/jni/first-party/fb/include/jni/WeakReference.h similarity index 89% rename from ReactAndroid/src/main/jni/first-party/jni/WeakReference.h rename to ReactAndroid/src/main/jni/first-party/fb/include/jni/WeakReference.h index 2723155fe..d8d59f9b7 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/WeakReference.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/jni/WeakReference.h @@ -12,11 +12,13 @@ #include #include #include +#include + namespace facebook { namespace jni { -class WeakReference : public Countable { +class FBEXPORT WeakReference : public Countable { public: typedef RefPtr Ptr; WeakReference(jobject strongRef); @@ -31,7 +33,7 @@ private: // This class is intended to take a weak reference and turn it into a strong // local reference. Consequently, it should only be allocated on the stack. -class ResolvedWeakReference : public noncopyable { +class FBEXPORT ResolvedWeakReference : public noncopyable { public: ResolvedWeakReference(jobject weakRef); ResolvedWeakReference(const RefPtr& weakRef); diff --git a/ReactAndroid/src/main/jni/first-party/jni/jni_helpers.h b/ReactAndroid/src/main/jni/first-party/fb/include/jni/jni_helpers.h similarity index 80% rename from ReactAndroid/src/main/jni/first-party/jni/jni_helpers.h rename to ReactAndroid/src/main/jni/first-party/fb/include/jni/jni_helpers.h index 01482a8b7..808593ab3 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/jni_helpers.h +++ b/ReactAndroid/src/main/jni/first-party/fb/include/jni/jni_helpers.h @@ -11,6 +11,8 @@ #include +#include + namespace facebook { /** @@ -22,7 +24,7 @@ namespace facebook { * @param ... sprintf-style args * @return 0 on success; a negative value on failure */ -jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va_list va_args); +FBEXPORT jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va_list va_args); /** * Instructs the JNI environment to throw a NoClassDefFoundError. @@ -32,7 +34,7 @@ jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va * @param ... sprintf-style args * @return 0 on success; a negative value on failure */ -jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...); +FBEXPORT jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...); /** * Instructs the JNI environment to throw a RuntimeException. @@ -42,7 +44,7 @@ jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...); * @param ... sprintf-style args * @return 0 on success; a negative value on failure */ -jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...); +FBEXPORT jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...); /** * Instructs the JNI environment to throw a IllegalArgumentException. @@ -52,7 +54,7 @@ jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...); * @param ... sprintf-style args * @return 0 on success; a negative value on failure */ -jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...); +FBEXPORT jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...); /** * Instructs the JNI environment to throw a IllegalStateException. @@ -62,7 +64,7 @@ jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...); * @param ... sprintf-style args * @return 0 on success; a negative value on failure */ -jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...); +FBEXPORT jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...); /** * Instructs the JNI environment to throw an IOException. @@ -72,7 +74,7 @@ jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...); * @param ... sprintf-style args * @return 0 on success; a negative value on failure */ -jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...); +FBEXPORT jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...); /** * Instructs the JNI environment to throw an AssertionError. @@ -82,7 +84,7 @@ jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...); * @param ... sprintf-style args * @return 0 on success; a negative value on failure */ -jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...); +FBEXPORT jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...); /** * Instructs the JNI environment to throw an OutOfMemoryError. @@ -92,7 +94,7 @@ jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...); * @param ... sprintf-style args * @return 0 on success; a negative value on failure */ -jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...); +FBEXPORT jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...); /** * Finds the specified class. If it's not found, instructs the JNI environment to throw an @@ -103,7 +105,7 @@ jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...); * @return the class or NULL if not found (in which case a pending exception will be queued). This * returns a global reference (JNIEnv::NewGlobalRef). */ -jclass findClassOrThrow(JNIEnv *pEnv, const char* szClassName); +FBEXPORT jclass findClassOrThrow(JNIEnv *pEnv, const char* szClassName); /** * Finds the specified field of the specified class. If it's not found, instructs the JNI @@ -115,7 +117,7 @@ jclass findClassOrThrow(JNIEnv *pEnv, const char* szClassName); * @param szSig the signature of the field * @return the field or NULL if not found (in which case a pending exception will be queued) */ -jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName, const char* szSig); +FBEXPORT jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName, const char* szSig); /** * Finds the specified method of the specified class. If it's not found, instructs the JNI @@ -127,7 +129,7 @@ jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName, * @param szSig the signature of the method * @return the method or NULL if not found (in which case a pending exception will be queued) */ -jmethodID getMethodIdOrThrow( +FBEXPORT jmethodID getMethodIdOrThrow( JNIEnv* pEnv, jclass clazz, const char* szMethodName, diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/ByteBuffer.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/ByteBuffer.cpp similarity index 97% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/ByteBuffer.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/ByteBuffer.cpp index a41f9106e..b95ae4a14 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/ByteBuffer.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/ByteBuffer.cpp @@ -7,11 +7,12 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#include "ByteBuffer.h" +#include -#include "References.h" #include +#include + namespace facebook { namespace jni { diff --git a/ReactAndroid/src/main/jni/first-party/jni/Countable.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/Countable.cpp similarity index 97% rename from ReactAndroid/src/main/jni/first-party/jni/Countable.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/Countable.cpp index 6ff7efe90..0d7c388f5 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/Countable.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/Countable.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include namespace facebook { @@ -41,7 +41,7 @@ void setCountableForJava(JNIEnv* env, jobject obj, RefPtr&& countable * * This method deletes the corresponding native object on whatever thread the method is called * on. In the common case when this is called by Countable#finalize(), this will be called on the - * system finalizer thread. If you manually call dispose on the Java object, the native object + * system finalizer thread. If you manually call dispose on the Java object, the native object * will be deleted synchronously on that thread. */ void dispose(JNIEnv* env, jobject obj) { diff --git a/ReactAndroid/src/main/jni/first-party/jni/Environment.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/Environment.cpp similarity index 98% rename from ReactAndroid/src/main/jni/first-party/jni/Environment.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/Environment.cpp index 02b88ce73..60f63ef6b 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/Environment.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/Environment.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace facebook { namespace jni { diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Exceptions.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/Exceptions.cpp similarity index 97% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Exceptions.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/Exceptions.cpp index 6a3516cd3..e7d38054c 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Exceptions.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/Exceptions.cpp @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#include "jni/fbjni.h" +#include "fb/fbjni.h" #include @@ -26,7 +26,7 @@ namespace jni { // CommonJniExceptions ///////////////////////////////////////////////////////////////////////////// -class CommonJniExceptions { +class FBEXPORT CommonJniExceptions { public: static void init(); @@ -226,7 +226,7 @@ void setNewJavaException(const char* className, const char* fmt, ARGS... args) { // Functions that throw C++ exceptions // TODO(T6618159) Take a stack dump here to save context if it results in a crash when propagated -void throwPendingJniExceptionAsCppException() { +FBEXPORT void throwPendingJniExceptionAsCppException() { assertIfExceptionsNotInitialized(); JNIEnv* env = internal::getEnv(); if (env->ExceptionCheck() == JNI_FALSE) { @@ -257,11 +257,13 @@ void throwCppExceptionIf(bool condition) { throw JniException(); } -void throwNewJavaException(jthrowable throwable) { +FBEXPORT void throwNewJavaException(jthrowable throwable) { throw JniException(throwable); } -void throwNewJavaException(const char* throwableName, const char* msg) { +FBEXPORT void throwNewJavaException( + const char* throwableName, + const char* msg) { // If anything of the fbjni calls fail, an exception of a suitable // form will be thrown, which is what we want. auto throwableClass = findClassLocal(throwableName); @@ -273,7 +275,7 @@ void throwNewJavaException(const char* throwableName, const char* msg) { // Translate C++ to Java Exception -void translatePendingCppExceptionToJavaException() noexcept { +FBEXPORT void translatePendingCppExceptionToJavaException() noexcept { assertIfExceptionsNotInitialized(); try { try { diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Hybrid.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/Hybrid.cpp similarity index 98% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/Hybrid.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/Hybrid.cpp index c779cde4e..1b95993dc 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/Hybrid.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/Hybrid.cpp @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#include "jni/fbjni.h" +#include "fb/fbjni.h" namespace facebook { diff --git a/ReactAndroid/src/main/jni/first-party/jni/LocalString.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/LocalString.cpp similarity index 99% rename from ReactAndroid/src/main/jni/first-party/jni/LocalString.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/LocalString.cpp index a26807267..1a0e8d703 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/LocalString.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/LocalString.cpp @@ -8,7 +8,7 @@ */ #include -#include +#include #include #include diff --git a/ReactAndroid/src/main/jni/first-party/fb/jni/OnLoad.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/OnLoad.cpp new file mode 100644 index 000000000..d50416133 --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/OnLoad.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include +#include + +using namespace facebook::jni; + +void initialize_fbjni() { + CountableOnLoad(Environment::current()); + HybridDataOnLoad(); +} diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/References.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/References.cpp similarity index 96% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni/References.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/References.cpp index 0ee4c9e8f..0ef4b0d6d 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/References.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/References.cpp @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#include "References.h" +#include namespace facebook { namespace jni { diff --git a/ReactAndroid/src/main/jni/first-party/jni/WeakReference.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/WeakReference.cpp similarity index 97% rename from ReactAndroid/src/main/jni/first-party/jni/WeakReference.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/WeakReference.cpp index d87ea33c0..1fd4e50ac 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/WeakReference.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/WeakReference.cpp @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#include +#include #include namespace facebook { diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/fbjni.cpp similarity index 90% rename from ReactAndroid/src/main/jni/first-party/jni/fbjni.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/fbjni.cpp index 22d4dc2a4..e2bd795fa 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/fbjni.cpp @@ -7,11 +7,12 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#include "fbjni.h" +#include #include #include #include +#include namespace facebook { namespace jni { @@ -44,6 +45,9 @@ jint initialize(JavaVM* vm, std::function&& init_fn) noexcept { } init_fn(); + } catch (const std::exception& e) { + FBLOGE("error %s", e.what()); + translatePendingCppExceptionToJavaException(); } catch (...) { translatePendingCppExceptionToJavaException(); // So Java will handle the translated exception, fall through and @@ -113,6 +117,7 @@ local_ref make_jstring(const char* utf8) { #define DEFINE_PRIMITIVE_METHODS(TYPE, NAME, SMALLNAME) \ \ template<> \ +FBEXPORT \ TYPE* JPrimitiveArray::getElements(jboolean* isCopy) { \ auto env = internal::getEnv(); \ TYPE* res = env->Get ## NAME ## ArrayElements(self(), isCopy); \ @@ -121,6 +126,7 @@ TYPE* JPrimitiveArray::getElements(jboolean* isCopy) { \ } \ \ template<> \ +FBEXPORT \ void JPrimitiveArray::releaseElements( \ TYPE* elements, jint mode) { \ auto env = internal::getEnv(); \ @@ -129,6 +135,7 @@ void JPrimitiveArray::releaseElements( \ } \ \ template<> \ +FBEXPORT \ void JPrimitiveArray::getRegion( \ jsize start, jsize length, TYPE* buf) { \ auto env = internal::getEnv(); \ @@ -137,6 +144,7 @@ void JPrimitiveArray::getRegion( \ } \ \ template<> \ +FBEXPORT \ void JPrimitiveArray::setRegion( \ jsize start, jsize length, const TYPE* elements) { \ auto env = internal::getEnv(); \ @@ -144,6 +152,7 @@ void JPrimitiveArray::setRegion( \ FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \ } \ \ +FBEXPORT \ local_ref make_ ## SMALLNAME ## _array(jsize size) { \ auto array = internal::getEnv()->New ## NAME ## Array(size); \ FACEBOOK_JNI_THROW_EXCEPTION_IF(!array); \ @@ -151,6 +160,7 @@ local_ref make_ ## SMALLNAME ## _array(jsize size) { \ } \ \ template<> \ +FBEXPORT \ local_ref JArray ## NAME::newArray(size_t count) { \ return make_ ## SMALLNAME ## _array(count); \ } \ @@ -170,9 +180,9 @@ DEFINE_PRIMITIVE_METHODS(jdouble, Double, double) namespace internal { -ReferenceStats g_reference_stats; +FBEXPORT ReferenceStats g_reference_stats; -void facebook::jni::internal::ReferenceStats::reset() noexcept { +FBEXPORT void facebook::jni::internal::ReferenceStats::reset() noexcept { locals_deleted = globals_deleted = weaks_deleted = 0; } diff --git a/ReactAndroid/src/main/jni/first-party/fb/jni/java/CppException.java b/ReactAndroid/src/main/jni/first-party/fb/jni/java/CppException.java new file mode 100644 index 000000000..a0c845dd6 --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/java/CppException.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public class CppException extends RuntimeException { + @DoNotStrip + public CppException(String message) { + super(message); + } +} diff --git a/ReactAndroid/src/main/jni/first-party/fb/jni/java/CppSystemErrorException.java b/ReactAndroid/src/main/jni/first-party/fb/jni/java/CppSystemErrorException.java new file mode 100644 index 000000000..13090a18c --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/java/CppSystemErrorException.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public class CppSystemErrorException extends CppException { + int errorCode; + + @DoNotStrip + public CppSystemErrorException(String message, int errorCode) { + super(message); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } +} diff --git a/ReactAndroid/src/main/jni/first-party/fb/jni/java/UnknownCppException.java b/ReactAndroid/src/main/jni/first-party/fb/jni/java/UnknownCppException.java new file mode 100644 index 000000000..45e9bfe0c --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/java/UnknownCppException.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public class UnknownCppException extends CppException { + @DoNotStrip + public UnknownCppException() { + super("Unknown"); + } + + @DoNotStrip + public UnknownCppException(String message) { + super(message); + } +} diff --git a/ReactAndroid/src/main/jni/first-party/jni/jni_helpers.cpp b/ReactAndroid/src/main/jni/first-party/fb/jni/jni_helpers.cpp similarity index 99% rename from ReactAndroid/src/main/jni/first-party/jni/jni_helpers.cpp rename to ReactAndroid/src/main/jni/first-party/fb/jni/jni_helpers.cpp index ae7f6974f..8bf7c3542 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/jni_helpers.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/jni/jni_helpers.cpp @@ -11,6 +11,8 @@ #include #include +#include + #define MSG_SIZE 1024 namespace facebook { diff --git a/ReactAndroid/src/main/jni/first-party/fb/lyra/lyra.cpp b/ReactAndroid/src/main/jni/first-party/fb/lyra/lyra.cpp new file mode 100644 index 000000000..c3d25df1a --- /dev/null +++ b/ReactAndroid/src/main/jni/first-party/fb/lyra/lyra.cpp @@ -0,0 +1,100 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#include + +#include +#include + +#include +#include + +using namespace std; + +namespace facebook { +namespace lyra { + +namespace { + +struct BacktraceState { + size_t skip; + vector& stackTrace; +}; + +_Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg) { + BacktraceState* state = reinterpret_cast(arg); + auto absoluteProgramCounter = + reinterpret_cast(_Unwind_GetIP(context)); + + if (state->skip > 0) { + --state->skip; + return _URC_NO_REASON; + } + + if (state->stackTrace.size() == state->stackTrace.capacity()) { + return _URC_END_OF_STACK; + } + + state->stackTrace.push_back(absoluteProgramCounter); + + return _URC_NO_REASON; +} + +void captureBacktrace(size_t skip, vector& stackTrace) { + // Beware of a bug on some platforms, which makes the trace loop until the + // buffer is full when it reaches a noexcept function. It seems to be fixed in + // newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846 + // TODO(t10738439): Investigate workaround for the stack trace bug + BacktraceState state = {skip, stackTrace}; + _Unwind_Backtrace(unwindCallback, &state); +} +} + +void getStackTrace(vector& stackTrace, size_t skip) { + stackTrace.clear(); + captureBacktrace(skip + 1, stackTrace); +} + +// TODO(t10737622): Improve on-device symbolification +void getStackTraceSymbols(vector& symbols, + const vector& trace) { + symbols.clear(); + symbols.reserve(trace.size()); + + for (size_t i = 0; i < trace.size(); ++i) { + Dl_info info; + if (dladdr(trace[i], &info)) { + symbols.emplace_back(trace[i], info.dli_fbase, info.dli_saddr, + info.dli_fname ? info.dli_fname : "", + info.dli_sname ? info.dli_sname : ""); + } + } +} + +ostream& operator<<(ostream& out, const StackTraceElement& elm) { + // TODO(t10748683): Add build id to the output + out << "{dso=" << elm.libraryName() << " offset=" << hex + << showbase << elm.libraryOffset(); + + if (!elm.functionName().empty()) { + out << " func=" << elm.functionName() << "()+" << elm.functionOffset(); + } + + out << " build-id=" << hex << setw(8) << 0 + << "}"; + + return out; +} + +// TODO(t10737667): The implement a tool that parse the stack trace and +// symbolicate it +ostream& operator<<(ostream& out, const vector& trace) { + auto i = 0; + out << "Backtrace:\n"; + for (auto& elm : trace) { + out << " #" << dec << setfill('0') << setw(2) << i++ << " " << elm << '\n'; + } + + return out; +} +} +} diff --git a/ReactAndroid/src/main/jni/first-party/jni/OnLoad.cpp b/ReactAndroid/src/main/jni/first-party/fb/onload.cpp similarity index 71% rename from ReactAndroid/src/main/jni/first-party/jni/OnLoad.cpp rename to ReactAndroid/src/main/jni/first-party/fb/onload.cpp index a4c404090..9357940a4 100644 --- a/ReactAndroid/src/main/jni/first-party/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/jni/first-party/fb/onload.cpp @@ -8,16 +8,18 @@ */ #include -#include -#include -#include -#include +#include using namespace facebook::jni; +void initialize_xplatinit(); +void initialize_fbjni(); + JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { return facebook::jni::initialize(vm, [] { - CountableOnLoad(Environment::current()); - HybridDataOnLoad(); - }); + initialize_fbjni(); +#ifndef DISABLE_XPLAT + initialize_xplatinit(); +#endif + }); } diff --git a/ReactAndroid/src/main/jni/first-party/jni/Android.mk b/ReactAndroid/src/main/jni/first-party/jni/Android.mk deleted file mode 100644 index 1ee4d0898..000000000 --- a/ReactAndroid/src/main/jni/first-party/jni/Android.mk +++ /dev/null @@ -1,36 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - Countable.cpp \ - Environment.cpp \ - fbjni.cpp \ - jni_helpers.cpp \ - LocalString.cpp \ - OnLoad.cpp \ - WeakReference.cpp \ - fbjni/ByteBuffer.cpp \ - fbjni/Exceptions.cpp \ - fbjni/Hybrid.cpp \ - fbjni/References.cpp - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.. - -LOCAL_CFLAGS := -DLOG_TAG=\"fbjni\" -fexceptions -frtti -LOCAL_CFLAGS += -Wall -Werror - -CXX11_FLAGS := -std=gnu++11 -LOCAL_CFLAGS += $(CXX11_FLAGS) - -LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS) - -LOCAL_LDLIBS := -landroid - -LOCAL_SHARED_LIBRARIES := libfb - -LOCAL_MODULE := libfbjni - -include $(BUILD_SHARED_LIBRARY) - -$(call import-module,fb) diff --git a/ReactAndroid/src/main/jni/first-party/jni/BUCK b/ReactAndroid/src/main/jni/first-party/jni/BUCK deleted file mode 100644 index 36574b0b3..000000000 --- a/ReactAndroid/src/main/jni/first-party/jni/BUCK +++ /dev/null @@ -1,51 +0,0 @@ -include_defs('//ReactAndroid/DEFS') - -cxx_library( - name = 'jni', - srcs = [ - 'Countable.cpp', - 'Environment.cpp', - 'fbjni.cpp', - 'jni_helpers.cpp', - 'LocalString.cpp', - 'OnLoad.cpp', - 'WeakReference.cpp', - 'fbjni/ByteBuffer.cpp', - 'fbjni/Exceptions.cpp', - 'fbjni/Hybrid.cpp', - 'fbjni/References.cpp', - ], - platform_srcs = [ - (r'.*\bandroid\b.*', [ - 'fbjni/android/ReferenceChecking.cpp', - ]), - ], - exported_headers = glob(['*.h', 'fbjni/*.h']), - header_namespace = 'jni', - soname = 'libfbjni.so', - preprocessor_flags = [ - '-fexceptions', - '-DLOG_TAG="fbjni"', - ], - compiler_flags = [ - '-fexceptions', - '-frtti', - ], - # We want to use this library during bootstrap - can_be_asset = False, - exported_deps = [ - react_native_target('jni/first-party/fb:fb'), - react_native_target('jni/third-party/android-ndk:log'), - ], - deps = [ - # TODO Is this needed? Not used in the Gradle build. - # '//native/jni-hack:jni-hack', - # TODO should be react_native_target('java/com/facebook/jni:jni') but might not be needed as the bridge already depends on it. - # '//native/jni/java:java', - ], - visibility = ['PUBLIC'], -) - -project_config( - src_target = ':jni', -) diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni.h b/ReactAndroid/src/main/jni/first-party/jni/fbjni.h deleted file mode 100644 index 7728153cd..000000000 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#pragma once - -#include - -#include "Environment.h" -#include "ALog.h" -#include "fbjni/Common.h" -#include "fbjni/Exceptions.h" -#include "fbjni/ReferenceAllocators.h" -#include "fbjni/References.h" -#include "fbjni/Meta.h" -#include "fbjni/CoreClasses.h" -#include "fbjni/Iterator.h" -#include "fbjni/Hybrid.h" -#include "fbjni/Registration.h" diff --git a/ReactAndroid/src/main/jni/first-party/jni/fbjni/android/ReferenceChecking.cpp b/ReactAndroid/src/main/jni/first-party/jni/fbjni/android/ReferenceChecking.cpp deleted file mode 100644 index e17eb2af5..000000000 --- a/ReactAndroid/src/main/jni/first-party/jni/fbjni/android/ReferenceChecking.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#ifndef __ANDROID__ -#error "This file should only be compiled for Android." -#endif - -#include -#include - -namespace facebook { -namespace jni { -namespace internal { - -static int32_t getApiLevel() { - auto cls = findClassLocal("android/os/Build$VERSION"); - auto fld = cls->getStaticField("SDK_INT"); - if (fld) { - return cls->getStaticFieldValue(fld); - } - return 0; -} - -bool doesGetObjectRefTypeWork() { - static auto level = getApiLevel(); - return level >= 14; -} - -} -} -} \ No newline at end of file diff --git a/ReactAndroid/src/main/jni/react/Android.mk b/ReactAndroid/src/main/jni/react/Android.mk index f72729bdc..9c5498da9 100644 --- a/ReactAndroid/src/main/jni/react/Android.mk +++ b/ReactAndroid/src/main/jni/react/Android.mk @@ -24,12 +24,11 @@ CXX11_FLAGS := -std=c++11 LOCAL_CFLAGS += $(CXX11_FLAGS) LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS) -LOCAL_SHARED_LIBRARIES := libfb libfbjni libfolly_json libjsc libglog +LOCAL_SHARED_LIBRARIES := libfb libfolly_json libjsc libglog include $(BUILD_STATIC_LIBRARY) $(call import-module,fb) -$(call import-module,jni) $(call import-module,folly) $(call import-module,jsc) $(call import-module,glog) diff --git a/ReactAndroid/src/main/jni/react/jni/Android.mk b/ReactAndroid/src/main/jni/react/jni/Android.mk index 46bf1d525..0fabec805 100644 --- a/ReactAndroid/src/main/jni/react/jni/Android.mk +++ b/ReactAndroid/src/main/jni/react/jni/Android.mk @@ -5,7 +5,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := reactnativejni LOCAL_SRC_FILES := \ - JExecutorToken.cpp \ + JExecutorToken.cpp \ JMessageQueueThread.cpp \ JSCPerfLogging.cpp \ JSLoader.cpp \ @@ -23,7 +23,7 @@ LOCAL_CFLAGS += $(CXX11_FLAGS) LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS) LOCAL_LDLIBS += -landroid -LOCAL_SHARED_LIBRARIES := libfolly_json libfbjni libjsc libglog_init +LOCAL_SHARED_LIBRARIES := libfolly_json libfb libjsc libglog_init LOCAL_STATIC_LIBRARIES := libreactnative include $(BUILD_SHARED_LIBRARY) @@ -32,5 +32,5 @@ $(call import-module,react) $(call import-module,jsc) $(call import-module,folly) $(call import-module,fbgloginit) -$(call import-module,jni) +$(call import-module,fb) $(call import-module,jsc) diff --git a/ReactAndroid/src/main/jni/react/jni/BUCK b/ReactAndroid/src/main/jni/react/jni/BUCK index e61637847..0941c5f7c 100644 --- a/ReactAndroid/src/main/jni/react/jni/BUCK +++ b/ReactAndroid/src/main/jni/react/jni/BUCK @@ -5,7 +5,7 @@ SUPPORTED_PLATFORMS = '^android-(armv7|x86)$' DEPS = [ FBGLOGINIT_TARGET, - '//native/jni:jni', + '//native/fb:fb', '//native/third-party/android-ndk:android', '//xplat/folly:molly', ] diff --git a/ReactAndroid/src/main/jni/react/jni/JExecutorToken.h b/ReactAndroid/src/main/jni/react/jni/JExecutorToken.h index ac348f0ec..0cd69ca06 100644 --- a/ReactAndroid/src/main/jni/react/jni/JExecutorToken.h +++ b/ReactAndroid/src/main/jni/react/jni/JExecutorToken.h @@ -4,7 +4,7 @@ #include -#include +#include #include diff --git a/ReactAndroid/src/main/jni/react/jni/JExecutorTokenFactory.h b/ReactAndroid/src/main/jni/react/jni/JExecutorTokenFactory.h index d7d923111..9e158eee7 100644 --- a/ReactAndroid/src/main/jni/react/jni/JExecutorTokenFactory.h +++ b/ReactAndroid/src/main/jni/react/jni/JExecutorTokenFactory.h @@ -2,7 +2,7 @@ #pragma once -#include +#include #include #include "JExecutorToken.h" diff --git a/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.cpp b/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.cpp index 0c068ab19..88e587e63 100644 --- a/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include "JNativeRunnable.h" diff --git a/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h b/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h index e81d5dead..a04bcb376 100644 --- a/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h +++ b/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h @@ -6,7 +6,7 @@ #include -#include +#include using namespace facebook::jni; diff --git a/ReactAndroid/src/main/jni/react/jni/JSCPerfLogging.cpp b/ReactAndroid/src/main/jni/react/jni/JSCPerfLogging.cpp index d480a8833..1b7b5e688 100644 --- a/ReactAndroid/src/main/jni/react/jni/JSCPerfLogging.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JSCPerfLogging.cpp @@ -3,7 +3,7 @@ #include "JSCPerfLogging.h" #include -#include +#include #include using namespace facebook::jni; diff --git a/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp b/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp index a96d0c3de..9423e578f 100644 --- a/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp +++ b/ReactAndroid/src/main/jni/react/jni/JSLoader.cpp @@ -3,7 +3,7 @@ #include "JSLoader.h" #include -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/jni/react/jni/NativeArray.cpp b/ReactAndroid/src/main/jni/react/jni/NativeArray.cpp index cc5e4a0b2..1bf903469 100644 --- a/ReactAndroid/src/main/jni/react/jni/NativeArray.cpp +++ b/ReactAndroid/src/main/jni/react/jni/NativeArray.cpp @@ -2,7 +2,7 @@ #include "NativeArray.h" -#include +#include #include namespace facebook { diff --git a/ReactAndroid/src/main/jni/react/jni/NativeArray.h b/ReactAndroid/src/main/jni/react/jni/NativeArray.h index f30ef107d..0fc69d5ac 100644 --- a/ReactAndroid/src/main/jni/react/jni/NativeArray.h +++ b/ReactAndroid/src/main/jni/react/jni/NativeArray.h @@ -2,7 +2,7 @@ #pragma once -#include +#include #include namespace facebook { diff --git a/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp b/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp index ee9aed7f4..76a24fbb1 100644 --- a/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp @@ -6,12 +6,12 @@ #include #include #include -#include -#include +#include +#include #include #include #include -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp index 4ad7a8eb0..999f139d1 100644 --- a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp +++ b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.cpp @@ -3,7 +3,7 @@ #include "ProxyExecutor.h" #include -#include +#include #include #include #include diff --git a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h index c06ee9287..36be74173 100644 --- a/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h +++ b/ReactAndroid/src/main/jni/react/jni/ProxyExecutor.h @@ -3,7 +3,7 @@ #pragma once #include -#include +#include #include #include #include "OnLoad.h" diff --git a/ReactAndroid/src/main/jni/react/perftests/BUCK b/ReactAndroid/src/main/jni/react/perftests/BUCK index 85de4ac64..6f2d1acfc 100644 --- a/ReactAndroid/src/main/jni/react/perftests/BUCK +++ b/ReactAndroid/src/main/jni/react/perftests/BUCK @@ -9,7 +9,7 @@ cxx_library( ], deps = [ '//native:base', - '//native/jni:jni', + '//native/fb:fb', ], visibility = [ '//instrumentation_tests/com/facebook/react/...', diff --git a/ReactAndroid/src/main/jni/react/perftests/OnLoad.cpp b/ReactAndroid/src/main/jni/react/perftests/OnLoad.cpp index cb62b126f..f2fac8d91 100644 --- a/ReactAndroid/src/main/jni/react/perftests/OnLoad.cpp +++ b/ReactAndroid/src/main/jni/react/perftests/OnLoad.cpp @@ -1,7 +1,7 @@ // Copyright 2004-present Facebook. All Rights Reserved. #include -#include +#include #include #include