Start to implement Clownfish methods for C bindings
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/27a89bf2 Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/27a89bf2 Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/27a89bf2 Branch: refs/heads/c-bindings-wip1 Commit: 27a89bf243566731d642cae8b4109ad0624d1d37 Parents: fc223c2 Author: Nick Wellnhofer <[email protected]> Authored: Sun Nov 25 18:01:52 2012 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Wed Dec 5 00:00:32 2012 +0100 ---------------------------------------------------------------------- c/src/CFBind.h | 1 + c/src/Clownfish/Err.c | 54 ++++++++++++++++++++++++++++++++++------- c/src/Clownfish/Obj.c | 23 +++++++++++++---- c/src/Clownfish/VTable.c | 7 +++-- 4 files changed, 67 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy/blob/27a89bf2/c/src/CFBind.h ---------------------------------------------------------------------- diff --git a/c/src/CFBind.h b/c/src/CFBind.h index f8443cd..31e57b0 100644 --- a/c/src/CFBind.h +++ b/c/src/CFBind.h @@ -40,6 +40,7 @@ extern "C" { */ #define THROW CFISH_THROW #define WARN CFISH_WARN +#define UNUSED_VAR CHY_UNUSED_VAR #define UNREACHABLE_RETURN CHY_UNREACHABLE_RETURN #ifdef __cplusplus http://git-wip-us.apache.org/repos/asf/lucy/blob/27a89bf2/c/src/Clownfish/Err.c ---------------------------------------------------------------------- diff --git a/c/src/Clownfish/Err.c b/c/src/Clownfish/Err.c index b2de599..0744f67 100644 --- a/c/src/Clownfish/Err.c +++ b/c/src/Clownfish/Err.c @@ -16,24 +16,43 @@ #include "CFBind.h" +#include <setjmp.h> +#include <stdio.h> +#include <stdlib.h> + +/* TODO: Thread safety */ +lucy_Err *current_error; +lucy_Err *thrown_error; +jmp_buf *current_env; + void lucy_Err_init_class(void) { } lucy_Err* lucy_Err_get_error() { - THROW(LUCY_ERR, "TODO"); - UNREACHABLE_RETURN(lucy_Err*); + return current_error; } void lucy_Err_set_error(lucy_Err *error) { - THROW(LUCY_ERR, "TODO"); + if (current_error) { + CFISH_DECREF(current_error); + } + current_error = error; } void -lucy_Err_do_throw(lucy_Err *err) { - THROW(LUCY_ERR, "TODO"); +lucy_Err_do_throw(lucy_Err *error) { + if (current_env) { + thrown_error = error; + longjmp(*current_env, 1); + } + else { + lucy_CharBuf *message = lucy_Err_get_mess(error); + fprintf(stderr, "%s", Lucy_CB_Get_Ptr8(message)); + exit(EXIT_FAILURE); + } } void* @@ -44,17 +63,34 @@ lucy_Err_to_host(lucy_Err *self) { void lucy_Err_throw_mess(lucy_VTable *vtable, lucy_CharBuf *message) { - THROW(LUCY_ERR, "TODO"); + Lucy_Err_Make_t make + = CFISH_METHOD_PTR(CFISH_CERTIFY(vtable, LUCY_VTABLE), Lucy_Err_Make); + lucy_Err *err = (lucy_Err*)CFISH_CERTIFY(make(NULL), LUCY_ERR); + Lucy_Err_Cat_Mess(err, message); + CFISH_DECREF(message); + lucy_Err_do_throw(err); } void lucy_Err_warn_mess(lucy_CharBuf *message) { - THROW(LUCY_ERR, "TODO"); + fprintf(stderr, "%s", Lucy_CB_Get_Ptr8(message)); + CFISH_DECREF(message); } lucy_Err* lucy_Err_trap(Cfish_Err_Attempt_t routine, void *context) { - THROW(LUCY_ERR, "TODO"); - UNREACHABLE_RETURN(lucy_Err*); + jmp_buf env; + jmp_buf *prev_env = current_env; + current_env = &env; + + if (!setjmp(env)) { + routine(context); + } + + current_env = prev_env; + + lucy_Err *error = thrown_error; + thrown_error = NULL; + return error; } http://git-wip-us.apache.org/repos/asf/lucy/blob/27a89bf2/c/src/Clownfish/Obj.c ---------------------------------------------------------------------- diff --git a/c/src/Clownfish/Obj.c b/c/src/Clownfish/Obj.c index e529513..d8e781a 100644 --- a/c/src/Clownfish/Obj.c +++ b/c/src/Clownfish/Obj.c @@ -20,20 +20,31 @@ uint32_t lucy_Obj_get_refcount(lucy_Obj *self) { - THROW(LUCY_ERR, "TODO"); - UNREACHABLE_RETURN(uint32_t); + return self->ref.count; } lucy_Obj* lucy_Obj_inc_refcount(lucy_Obj *self) { - THROW(LUCY_ERR, "TODO"); - UNREACHABLE_RETURN(lucy_Obj*); + self->ref.count++; + return self; } uint32_t lucy_Obj_dec_refcount(lucy_Obj *self) { - THROW(LUCY_ERR, "TODO"); - UNREACHABLE_RETURN(uint32_t); + uint32_t modified_refcount = INT32_MAX; + switch (self->ref.count) { + case 0: + THROW(LUCY_ERR, "Illegal refcount of 0"); + break; // useless + case 1: + modified_refcount = 0; + Lucy_Obj_Destroy(self); + break; + default: + modified_refcount = --self->ref.count; + break; + } + return modified_refcount; } void* http://git-wip-us.apache.org/repos/asf/lucy/blob/27a89bf2/c/src/Clownfish/VTable.c ---------------------------------------------------------------------- diff --git a/c/src/Clownfish/VTable.c b/c/src/Clownfish/VTable.c index 00c9901..d444e77 100644 --- a/c/src/Clownfish/VTable.c +++ b/c/src/Clownfish/VTable.c @@ -27,13 +27,14 @@ lucy_VTable_foster_obj(lucy_VTable *self, void *host_obj) { void lucy_VTable_register_with_host(lucy_VTable *singleton, lucy_VTable *parent) { - THROW(LUCY_ERR, "TODO"); + UNUSED_VAR(singleton); + UNUSED_VAR(parent); } lucy_VArray* lucy_VTable_fresh_host_methods(const lucy_CharBuf *class_name) { - THROW(LUCY_ERR, "TODO"); - UNREACHABLE_RETURN(lucy_VArray*); + UNUSED_VAR(class_name); + return lucy_VA_new(0); } lucy_CharBuf*
