move exception handling to method wrapper

This commit is contained in:
Ari Lazier 2016-03-30 11:55:13 -07:00
parent 58d50bb3c5
commit 0282e98232
3 changed files with 193 additions and 273 deletions

View File

@ -41,36 +41,29 @@ struct List {
using ObjectType = typename T::Object;
using ValueType = typename T::Value;
using ReturnType = typename T::Return;
using ExceptionType = typename T::Exception;
static void Push(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret, ExceptionType &exception);
static void Pop(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret, ExceptionType &exception);
static void Unshift(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret, ExceptionType &exception);
static void Shift(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret, ExceptionType &exception);
static void Splice(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret, ExceptionType &exception);
static void StaticResults(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret, ExceptionType &exception);
static void Filtered(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret, ExceptionType &exception);
static void Sorted(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret, ExceptionType &exception);
static void Push(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
static void Pop(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
static void Unshift(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
static void Shift(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
static void Splice(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
static void StaticResults(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
static void Filtered(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
static void Sorted(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
};
template<typename T>
void List<T>::Push(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void List<T>::Push(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
for (size_t i = 0; i < argumentCount; i++) {
list->add(ctx, arguments[i]);
}
RJSSetReturnNumber(ctx, returnObject, list->size());
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void List<T>::Pop(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void List<T>::Pop(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
RJSValidateArgumentCount(argumentCount, 0);
@ -84,31 +77,21 @@ void List<T>::Pop(ContextType ctx, ObjectType thisObject, size_t argumentCount,
returnObject = RJSObjectCreate(ctx, Object(list->get_realm(), list->get_object_schema(), list->get(index)));
list->remove(index);
}
}
catch (std::exception &exception) {
RJSSetException(ctx, exceptionObject, exception);
}
}
template<typename T>
void List<T>::Unshift(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void List<T>::Unshift(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
for (size_t i = 0; i < argumentCount; i++) {
list->insert(ctx, arguments[i], i);
}
RJSSetReturnNumber(ctx, returnObject, list->size());
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void List<T>::Shift(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void List<T>::Shift(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
RJSValidateArgumentCount(argumentCount, 0);
if (list->size() == 0) {
@ -119,15 +102,10 @@ void List<T>::Shift(ContextType ctx, ObjectType thisObject, size_t argumentCount
returnObject = RJSObjectCreate(ctx, Object(list->get_realm(), list->get_object_schema(), list->get(0)));
list->remove(0);
}
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void List<T>::Splice(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void List<T>::Splice(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
size_t size = list->size();
@ -155,51 +133,32 @@ void List<T>::Splice(ContextType ctx, ObjectType thisObject, size_t argumentCoun
list->insert(ctx, arguments[i], index + i - 2);
}
RJSSetReturnArray(ctx, remove, removedObjects.data(), returnObject);
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void List<T>::StaticResults(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void List<T>::StaticResults(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
RJSValidateArgumentCount(argumentCount, 0);
returnObject = RJSResultsCreate(ctx, list->get_realm(), list->get_object_schema(), std::move(list->get_query()), false);
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void List<T>::Filtered(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void List<T>::Filtered(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
SharedRealm sharedRealm = *RJSGetInternal<SharedRealm *>(thisObject);
returnObject = RJSResultsCreateFiltered(ctx, sharedRealm, list->get_object_schema(), std::move(list->get_query()), argumentCount, arguments);
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void List<T>::Sorted(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void List<T>::Sorted(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
RJSValidateArgumentRange(argumentCount, 1, 2);
SharedRealm sharedRealm = *RJSGetInternal<SharedRealm *>(thisObject);
returnObject = RJSResultsCreateSorted(ctx, sharedRealm, list->get_object_schema(), std::move(list->get_query()), argumentCount, arguments);
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
}

View File

@ -127,15 +127,15 @@ public:
using ReturnType = typename T::Return;
using ExceptionType = typename T::Exception;
static void Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void Create(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void Delete(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void DeleteAll(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void Write(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void AddListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void RemoveListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void RemoveAllListeners(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void Close(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject);
static void Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void Create(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void Delete(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void DeleteAll(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void Write(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void AddListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void RemoveListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void RemoveAllListeners(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void Close(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static std::string validated_notification_name(JSContextRef ctx, JSValueRef value) {
std::string name = RJSValidatedStringForValue(ctx, value);
@ -165,22 +165,16 @@ public:
};
template<typename T>
void Realm<T>::Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void Realm<T>::Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentCount(argumentCount, 1);
SharedRealm sharedRealm = *RJSGetInternal<SharedRealm *>(thisObject);
std::string className = validated_object_type_for_value(sharedRealm, ctx, arguments[0]);
returnObject = RJSResultsCreate(ctx, sharedRealm, className);
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void Realm<T>::Create(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void Realm<T>::Create(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentRange(argumentCount, 2, 3);
SharedRealm sharedRealm = *RJSGetInternal<SharedRealm *>(thisObject);
@ -203,15 +197,10 @@ void Realm<T>::Create(ContextType ctx, ObjectType thisObject, size_t argumentCou
}
returnObject = RJSObjectCreate(ctx, Object::create<ValueType>(ctx, sharedRealm, *object_schema, object, update));
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void Realm<T>::Delete(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void Realm<T>::Delete(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentCount(argumentCount, 1);
SharedRealm realm = *RJSGetInternal<SharedRealm *>(thisObject);
@ -249,15 +238,10 @@ void Realm<T>::Delete(ContextType ctx, ObjectType thisObject, size_t argumentCou
else {
throw std::runtime_error("Argument to 'delete' must be a Realm object or a collection of Realm objects.");
}
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void Realm<T>::DeleteAll(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void Realm<T>::DeleteAll(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentCount(argumentCount, 0);
SharedRealm realm = *RJSGetInternal<SharedRealm *>(thisObject);
@ -269,19 +253,15 @@ void Realm<T>::DeleteAll(ContextType ctx, ObjectType thisObject, size_t argument
for (auto objectSchema : *realm->config().schema) {
ObjectStore::table_for_object_type(realm->read_group(), objectSchema.name)->clear();
}
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void Realm<T>::Write(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
SharedRealm realm = *RJSGetInternal<SharedRealm *>(thisObject);
try {
void Realm<T>::Write(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentCount(argumentCount, 1);
SharedRealm realm = *RJSGetInternal<SharedRealm *>(thisObject);
auto object = RJSValidatedValueToFunction(ctx, arguments[0]);
try {
realm->begin_transaction();
RJSCallFunction(ctx, object, thisObject, 0, NULL);
realm->commit_transaction();
@ -290,43 +270,32 @@ void Realm<T>::Write(ContextType ctx, ObjectType thisObject, size_t argumentCoun
if (realm->is_in_transaction()) {
realm->cancel_transaction();
}
RJSSetException(ctx, exceptionObject, exp);
throw;
}
}
template<typename T>
void Realm<T>::AddListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void Realm<T>::AddListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentCount(argumentCount, 2);
__unused std::string name = validated_notification_name(ctx, arguments[0]);
auto callback = RJSValidatedValueToFunction(ctx, arguments[1]);
SharedRealm realm = *RJSGetInternal<SharedRealm *>(thisObject);
static_cast<js::RealmDelegate<jsc::Types> *>(realm->m_binding_context.get())->add_notification(callback);
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void Realm<T>::RemoveListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void Realm<T>::RemoveListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentCount(argumentCount, 2);
__unused std::string name = validated_notification_name(ctx, arguments[0]);
auto callback = RJSValidatedValueToFunction(ctx, arguments[1]);
SharedRealm realm = *RJSGetInternal<SharedRealm *>(thisObject);
static_cast<js::RealmDelegate<jsc::Types> *>(realm->m_binding_context.get())->remove_notification(callback);
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void Realm<T>::RemoveAllListeners(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void Realm<T>::RemoveAllListeners(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentRange(argumentCount, 0, 1);
if (argumentCount) {
validated_notification_name(ctx, arguments[0]);
@ -334,22 +303,13 @@ void Realm<T>::RemoveAllListeners(ContextType ctx, ObjectType thisObject, size_t
SharedRealm realm = *RJSGetInternal<SharedRealm *>(thisObject);
static_cast<js::RealmDelegate<jsc::Types> *>(realm->m_binding_context.get())->remove_all_notifications();
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
template<typename T>
void Realm<T>::Close(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
void Realm<T>::Close(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentCount(argumentCount, 0);
SharedRealm realm = *RJSGetInternal<SharedRealm *>(thisObject);
realm->close();
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
}

View File

@ -36,7 +36,8 @@
#define WRAP_CLASS_METHOD(CLASS_NAME, METHOD_NAME) \
JSValueRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { \
JSValueRef returnObject = NULL; \
CLASS_NAME::METHOD_NAME(ctx, thisObject, argumentCount, arguments, returnObject, *jsException); \
try { CLASS_NAME::METHOD_NAME(ctx, thisObject, argumentCount, arguments, returnObject); } \
catch(std::exception &ex) { RJSSetException(ctx, *jsException, ex); } \
return returnObject; \
}