You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2016/02/25 00:07:33 UTC
[06/20] lucy-clownfish git commit: Implement Clownfish exceptions
using `longjmp`.
Implement Clownfish exceptions using `longjmp`.
Though Python uses exceptions, executing exceptions from the Python C
API requires setting thread-local error information and indicating an
error condition to the Python interpreter by returning NULL from the
glue function. So Clownfish has to have its own independent exception
handling.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/eccf1b64
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/eccf1b64
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/eccf1b64
Branch: refs/heads/master
Commit: eccf1b645bb9042825d84bbe4db4041ad63e2fc1
Parents: 7910ca9
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jan 22 15:40:08 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Feb 23 18:22:02 2016 -0800
----------------------------------------------------------------------
runtime/python/cfext/CFBind.c | 66 +++++++++++++++++++++++++++-----------
1 file changed, 48 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/eccf1b64/runtime/python/cfext/CFBind.c
----------------------------------------------------------------------
diff --git a/runtime/python/cfext/CFBind.c b/runtime/python/cfext/CFBind.c
index 6b13120..3c4bb4b 100644
--- a/runtime/python/cfext/CFBind.c
+++ b/runtime/python/cfext/CFBind.c
@@ -19,6 +19,8 @@
#define C_CFISH_METHOD
#define C_CFISH_ERR
+#include <setjmp.h>
+
#include "charmony.h"
#include "CFBind.h"
@@ -36,6 +38,8 @@
#include "Clownfish/Util/Memory.h"
#include "Clownfish/Vector.h"
+static bool Err_initialized;
+
/**** refcounting **********************************************************/
uint32_t
@@ -114,48 +118,74 @@ CFISH_Method_Host_Name_IMP(cfish_Method *self) {
/**** Err ******************************************************************/
+/* TODO: Thread safety? */
+static cfish_Err *current_error;
+static cfish_Err *thrown_error;
+static jmp_buf *current_env;
+
void
-cfish_Err_init_class() {
- CFISH_THROW(CFISH_ERR, "TODO");
+cfish_Err_init_class(void) {
+ Err_initialized = true;
}
cfish_Err*
cfish_Err_get_error() {
- CFISH_THROW(CFISH_ERR, "TODO");
- CFISH_UNREACHABLE_RETURN(cfish_Err*);
+ return current_error;
}
void
cfish_Err_set_error(cfish_Err *error) {
- CFISH_UNUSED_VAR(error);
- CFISH_THROW(CFISH_ERR, "TODO");
+ if (current_error) {
+ CFISH_DECREF(current_error);
+ }
+ current_error = error;
}
void
cfish_Err_do_throw(cfish_Err *error) {
- CFISH_UNUSED_VAR(error);
- CFISH_THROW(CFISH_ERR, "TODO");
+ if (current_env) {
+ thrown_error = error;
+ longjmp(*current_env, 1);
+ }
+ else {
+ cfish_String *message = CFISH_Err_Get_Mess(error);
+ char *utf8 = CFISH_Str_To_Utf8(message);
+ fprintf(stderr, "%s", utf8);
+ CFISH_FREEMEM(utf8);
+ exit(EXIT_FAILURE);
+ }
}
void
cfish_Err_throw_mess(cfish_Class *klass, cfish_String *message) {
- CFISH_UNUSED_VAR(klass);
- CFISH_UNUSED_VAR(message);
- CFISH_THROW(CFISH_ERR, "TODO");
+ CFISH_UNUSED_VAR(klass); // TODO use klass
+ cfish_Err *err = cfish_Err_new(message);
+ cfish_Err_do_throw(err);
}
void
cfish_Err_warn_mess(cfish_String *message) {
- CFISH_UNUSED_VAR(message);
- CFISH_THROW(CFISH_ERR, "TODO");
+ char *utf8 = CFISH_Str_To_Utf8(message);
+ fprintf(stderr, "%s", utf8);
+ CFISH_FREEMEM(utf8);
+ CFISH_DECREF(message);
}
cfish_Err*
-cfish_Err_trap(CFISH_Err_Attempt_t routine, void *routine_context) {
- CFISH_UNUSED_VAR(routine);
- CFISH_UNUSED_VAR(routine_context);
- CFISH_THROW(CFISH_ERR, "TODO");
- CFISH_UNREACHABLE_RETURN(cfish_Err*);
+cfish_Err_trap(CFISH_Err_Attempt_t routine, void *context) {
+ jmp_buf env;
+ jmp_buf *prev_env = current_env;
+ current_env = &env;
+
+ if (!setjmp(env)) {
+ routine(context);
+ }
+
+ current_env = prev_env;
+
+ cfish_Err *error = thrown_error;
+ thrown_error = NULL;
+ return error;
}
/**** TestUtils ************************************************************/