Use custom C code for fleshing out Go bindings. Instead of wrapping the C version of the Clownfish shared library, prepare to custom-code Go-specific behaviors for the host-specific portions of Clownfish.
Content copied from c/src/**.c Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/5ff4b913 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/5ff4b913 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/5ff4b913 Branch: refs/heads/go_bindings_2 Commit: 5ff4b913a56cf13d5738326802f812d2301425f5 Parents: 28c6365 Author: Marvin Humphrey <[email protected]> Authored: Fri Nov 14 18:46:27 2014 -0800 Committer: Marvin Humphrey <[email protected]> Committed: Sat Nov 29 21:07:53 2014 -0800 ---------------------------------------------------------------------- runtime/go/build.go | 2 +- runtime/go/ext/clownfish.c | 223 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5ff4b913/runtime/go/build.go ---------------------------------------------------------------------- diff --git a/runtime/go/build.go b/runtime/go/build.go index d05113d..8f19e4d 100644 --- a/runtime/go/build.go +++ b/runtime/go/build.go @@ -45,7 +45,7 @@ var installedLibPath string func init() { _, buildGO, _, _ = runtime.Caller(1) buildDir = path.Dir(buildGO) - hostSrcDir = path.Join(buildDir, "../c/src") + hostSrcDir = path.Join(buildDir, "ext") configGO = path.Join(buildDir, "clownfish", "config.go") var err error installedLibPath, err = cfc.InstalledLibPath(packageName) http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5ff4b913/runtime/go/ext/clownfish.c ---------------------------------------------------------------------- diff --git a/runtime/go/ext/clownfish.c b/runtime/go/ext/clownfish.c new file mode 100644 index 0000000..a66d0a6 --- /dev/null +++ b/runtime/go/ext/clownfish.c @@ -0,0 +1,223 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define CFISH_USE_SHORT_NAMES +#define C_CFISH_OBJ +#define C_CFISH_CLASS +#define C_CFISH_METHOD +#define C_CFISH_ERR +#define C_CFISH_LOCKFREEREGISTRY + +#include <setjmp.h> +#include <stdio.h> +#include <stdlib.h> + +#include "charmony.h" + +#include "Clownfish/Obj.h" +#include "Clownfish/Class.h" +#include "Clownfish/Method.h" +#include "Clownfish/Err.h" +#include "Clownfish/Util/Memory.h" +#include "Clownfish/String.h" +#include "Clownfish/VArray.h" +#include "Clownfish/LockFreeRegistry.h" + +/******************************** Obj **************************************/ + +uint32_t +Obj_Get_RefCount_IMP(Obj *self) { + return self->refcount; +} + +Obj* +Obj_Inc_RefCount_IMP(Obj *self) { + self->refcount++; + return self; +} + +uint32_t +Obj_Dec_RefCount_IMP(Obj *self) { + uint32_t modified_refcount = INT32_MAX; + switch (self->refcount) { + case 0: + THROW(ERR, "Illegal refcount of 0"); + break; // useless + case 1: + modified_refcount = 0; + Obj_Destroy(self); + break; + default: + modified_refcount = --self->refcount; + break; + } + return modified_refcount; +} + +void* +Obj_To_Host_IMP(Obj *self) { + UNUSED_VAR(self); + THROW(ERR, "TODO"); + UNREACHABLE_RETURN(void*); +} + +/******************************* Class *************************************/ + +Obj* +Class_Make_Obj_IMP(Class *self) { + Obj *obj = (Obj*)Memory_wrapped_calloc(self->obj_alloc_size, 1); + obj->klass = self; + obj->refcount = 1; + return obj; +} + +Obj* +Class_Init_Obj_IMP(Class *self, void *allocation) { + Obj *obj = (Obj*)allocation; + obj->klass = self; + obj->refcount = 1; + return obj; +} + +Obj* +Class_Foster_Obj_IMP(Class *self, void *host_obj) { + UNUSED_VAR(self); + UNUSED_VAR(host_obj); + THROW(ERR, "TODO"); + UNREACHABLE_RETURN(Obj*); +} + +void +Class_register_with_host(Class *singleton, Class *parent) { + UNUSED_VAR(singleton); + UNUSED_VAR(parent); +} + +VArray* +Class_fresh_host_methods(String *class_name) { + UNUSED_VAR(class_name); + return VA_new(0); +} + +String* +Class_find_parent_class(String *class_name) { + UNUSED_VAR(class_name); + THROW(ERR, "TODO"); + UNREACHABLE_RETURN(String*); +} + +void* +Class_To_Host_IMP(Class *self) { + UNUSED_VAR(self); + THROW(ERR, "TODO"); + UNREACHABLE_RETURN(void*); +} + +/******************************* Method ************************************/ + +String* +Method_Host_Name_IMP(Method *self) { + return (String*)INCREF(self->name); +} + +/******************************** Err **************************************/ + +/* TODO: Thread safety */ +static Err *current_error; +static Err *thrown_error; +static jmp_buf *current_env; + +void +Err_init_class(void) { +} + +Err* +Err_get_error() { + return current_error; +} + +void +Err_set_error(Err *error) { + if (current_error) { + DECREF(current_error); + } + current_error = error; +} + +void +Err_do_throw(Err *error) { + if (current_env) { + thrown_error = error; + longjmp(*current_env, 1); + } + else { + String *message = Err_Get_Mess(error); + char *utf8 = Str_To_Utf8(message); + fprintf(stderr, "%s", utf8); + FREEMEM(utf8); + exit(EXIT_FAILURE); + } +} + +void* +Err_To_Host_IMP(Err *self) { + UNUSED_VAR(self); + THROW(ERR, "TODO"); + UNREACHABLE_RETURN(void*); +} + +void +Err_throw_mess(Class *klass, String *message) { + UNUSED_VAR(klass); + Err *err = Err_new(message); + Err_do_throw(err); +} + +void +Err_warn_mess(String *message) { + char *utf8 = Str_To_Utf8(message); + fprintf(stderr, "%s", utf8); + FREEMEM(utf8); + DECREF(message); +} + +Err* +Err_trap(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; + + Err *error = thrown_error; + thrown_error = NULL; + return error; +} + +/************************** LockFreeRegistry *******************************/ + +void* +LFReg_To_Host_IMP(LockFreeRegistry *self) { + UNUSED_VAR(self); + THROW(ERR, "TODO"); + UNREACHABLE_RETURN(void*); +} + +
