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*);
+}
+
+

Reply via email to