From 67915b5905f0a23a76b283a543f83de5f279bbce Mon Sep 17 00:00:00 2001 From: Sidharth Guglani Date: Mon, 2 Dec 2019 05:21:56 -0800 Subject: [PATCH] Add YogaJniException class Summary: ## Changelog: [Internal][Yoga] Add YogaJniException class to be used later for jni exceptions Reviewed By: astreet Differential Revision: D18745609 fbshipit-source-id: 53503b54dbc59e9fe47f599dee6be9cb68134cb2 --- java/jni/YogaJniException.cpp | 49 +++++++++++++++++++++++++++++++++++ java/jni/YogaJniException.h | 38 +++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 java/jni/YogaJniException.cpp create mode 100644 java/jni/YogaJniException.h diff --git a/java/jni/YogaJniException.cpp b/java/jni/YogaJniException.cpp new file mode 100644 index 00000000..77aa3763 --- /dev/null +++ b/java/jni/YogaJniException.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include "YogaJniException.h" +#include "common.h" + +namespace facebook { +namespace yoga { +namespace vanillajni { + +YogaJniException::YogaJniException() { + jclass cl = getCurrentEnv()->FindClass("Ljava/lang/RuntimeException;"); + static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId( + getCurrentEnv(), cl, "", "()V"); + auto throwable = getCurrentEnv()->NewObject(cl, methodId); + throwable_ = make_global_ref(static_cast(throwable)); +} + +YogaJniException::YogaJniException(jthrowable throwable) { + throwable_ = make_global_ref(throwable); +} + +YogaJniException::YogaJniException(YogaJniException&& rhs) + : throwable_(std::move(rhs.throwable_)) {} + +YogaJniException::YogaJniException(const YogaJniException& rhs) { + throwable_ = make_global_ref(rhs.throwable_.get()); +} + +YogaJniException::~YogaJniException() { + try { + throwable_.reset(); + } catch (...) { + std::terminate(); + } +} + +ScopedLocalRef YogaJniException::getThrowable() const noexcept { + return make_local_ref(getCurrentEnv(), throwable_.get()); +} +} // namespace vanillajni +} // namespace yoga +} // namespace facebook diff --git a/java/jni/YogaJniException.h b/java/jni/YogaJniException.h new file mode 100644 index 00000000..d333adf5 --- /dev/null +++ b/java/jni/YogaJniException.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include "common.h" + +namespace facebook { +namespace yoga { +namespace vanillajni { +/** + * This class wraps a Java exception (jthrowable) into a C++ exception; A global + * reference to Java exception (jthrowable) is made so that the exception object + * does not gets cleared before jni call completion + */ +class YogaJniException : public std::exception { +public: + YogaJniException(); + ~YogaJniException() override; + + explicit YogaJniException(jthrowable throwable); + + YogaJniException(YogaJniException&& rhs); + + YogaJniException(const YogaJniException& other); + + ScopedLocalRef getThrowable() const noexcept; + +private: + ScopedGlobalRef throwable_; +}; +} // namespace vanillajni +} // namespace yoga +} // namespace facebook