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 2015/03/19 01:09:35 UTC
[15/19] lucy-clownfish git commit: Use custom C code for fleshing out
Go bindings.
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/56d26bc1
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/56d26bc1
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/56d26bc1
Branch: refs/heads/master
Commit: 56d26bc159fb97d8efb1f67f67f1d7b61a186aab
Parents: a255977
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Nov 14 18:46:27 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Sun Mar 15 19:01:11 2015 -0700
----------------------------------------------------------------------
runtime/go/ext/clownfish.c | 285 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 285 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/56d26bc1/runtime/go/ext/clownfish.c
----------------------------------------------------------------------
diff --git a/runtime/go/ext/clownfish.c b/runtime/go/ext/clownfish.c
index e69de29..196f90c 100644
--- a/runtime/go/ext/clownfish.c
+++ b/runtime/go/ext/clownfish.c
@@ -0,0 +1,285 @@
+/* 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 **************************************/
+
+static CFISH_INLINE bool
+SI_immortal(cfish_Class *klass) {
+ if (klass == CFISH_CLASS
+ || klass == CFISH_METHOD
+ || klass == CFISH_BOOLNUM
+ || klass == CFISH_HASHTOMBSTONE
+ ){
+ return true;
+ }
+ return false;
+}
+
+static CFISH_INLINE bool
+SI_is_string_type(cfish_Class *klass) {
+ if (klass == CFISH_STRING || klass == CFISH_STACKSTRING) {
+ return true;
+ }
+ return false;
+}
+
+static CFISH_INLINE bool
+SI_threadsafe_but_not_immortal(cfish_Class *klass) {
+ if (klass == CFISH_LOCKFREEREGISTRY) {
+ return true;
+ }
+ return false;
+}
+
+uint32_t
+cfish_get_refcount(void *vself) {
+ cfish_Obj *self = (cfish_Obj*)vself;
+ return self->refcount;
+}
+
+Obj*
+cfish_inc_refcount(void *vself) {
+ Obj *self = (Obj*)vself;
+
+ // Handle special cases.
+ cfish_Class *const klass = self->klass;
+ if (klass->flags & CFISH_fREFCOUNTSPECIAL) {
+ if (SI_is_string_type(klass)) {
+ // Only copy-on-incref Strings get special-cased. Ordinary
+ // strings fall through to the general case.
+ if (CFISH_Str_Is_Copy_On_IncRef((cfish_String*)self)) {
+ const char *utf8 = CFISH_Str_Get_Ptr8((cfish_String*)self);
+ size_t size = CFISH_Str_Get_Size((cfish_String*)self);
+ return (cfish_Obj*)cfish_Str_new_from_trusted_utf8(utf8, size);
+ }
+ }
+ else if (SI_immortal(klass)) {
+ return self;
+ }
+ else if (SI_threadsafe_but_not_immortal(klass)) {
+ // TODO: use atomic operation
+ }
+ }
+
+ self->refcount++;
+ return self;
+}
+
+uint32_t
+cfish_dec_refcount(void *vself) {
+ cfish_Obj *self = (Obj*)vself;
+ cfish_Class *klass = self->klass;
+ if (klass->flags & CFISH_fREFCOUNTSPECIAL) {
+ if (SI_immortal(klass)) {
+ return self->refcount;
+ }
+ else if (SI_threadsafe_but_not_immortal(klass)) {
+ // TODO: use atomic operation
+ }
+ }
+
+ 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*);
+}
+
+