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:56:05 UTC

[04/36] lucy-clownfish git commit: Create mapping from Py type to CF Class.

Create mapping from Py type to CF Class.

Before initializing Clownfish Class objects, create a mapping which
mates the addresses of Clownfish Class objects to their corresponding
PyTypeObjects.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d7133b8d
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d7133b8d
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d7133b8d

Branch: refs/heads/py_exp13
Commit: d7133b8d149e2090331b767c1f54d5bf118d1a43
Parents: def4923
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Feb 1 14:37:58 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:20:37 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPython.c      |  2 +-
 runtime/python/cfext/CFBind.c | 63 ++++++++++++++++++++++++++++++++++++++
 runtime/python/cfext/CFBind.h |  7 +++++
 3 files changed, 71 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d7133b8d/compiler/src/CFCPython.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPython.c b/compiler/src/CFCPython.c
index de19a9c..15f835f 100644
--- a/compiler/src/CFCPython.c
+++ b/compiler/src/CFCPython.c
@@ -398,7 +398,7 @@ S_gen_type_linkups(CFCPython *self, CFCParcel *parcel, CFCClass **ordered) {
         "    PyTypeObject **py_types = (PyTypeObject**)CFISH_MALLOCATE(py_types_size);\n"
         "%s\n"
         "%s\n"
-        "    //CFBind_assoc_py_types(handles, py_types, num_items);\n"
+        "    CFBind_assoc_py_types(handles, py_types, num_items);\n"
         "    CFISH_FREEMEM(handles);\n"
         "    CFISH_FREEMEM(py_types);\n"
         "}\n"

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d7133b8d/runtime/python/cfext/CFBind.c
----------------------------------------------------------------------
diff --git a/runtime/python/cfext/CFBind.c b/runtime/python/cfext/CFBind.c
index 48743a7..2f8d657 100644
--- a/runtime/python/cfext/CFBind.c
+++ b/runtime/python/cfext/CFBind.c
@@ -36,6 +36,7 @@
 #include "Clownfish/Num.h"
 #include "Clownfish/String.h"
 #include "Clownfish/TestHarness/TestUtils.h"
+#include "Clownfish/Util/Atomic.h"
 #include "Clownfish/Util/Memory.h"
 #include "Clownfish/Util/StringHelper.h"
 #include "Clownfish/Vector.h"
@@ -767,6 +768,68 @@ CFBind_maybe_convert_bool(PyObject *py_obj, bool *ptr) {
     return S_convert_bool(py_obj, ptr, true);
 }
 
+typedef struct ClassMapElem {
+    cfish_Class **klass_handle;
+    PyTypeObject *py_type;
+} ClassMapElem;
+
+typedef struct ClassMap {
+    int32_t size;
+    ClassMapElem *elems;
+} ClassMap;
+
+/* Before we can invoke methods on any Clownfish object safely, we must know
+ * about its corresponding Python type object.  This association must be made
+ * early in the bootstrapping process, which is tricky.  We can't use any
+ * of Clownfish's convenient data structures yet!
+ */
+static ClassMap *klass_map = NULL;
+
+static ClassMap*
+S_revise_class_map(ClassMap *current, cfish_Class ***klass_handles,
+                   PyTypeObject **py_types, int32_t num_items) {
+    int32_t num_current = current ? current->size : 0;
+    int32_t total = num_current + num_items;
+    ClassMap *revised = (ClassMap*)malloc(sizeof(ClassMap));
+    revised->elems = (ClassMapElem*)malloc(total * sizeof(ClassMapElem));
+    if (current) {
+        size_t size = num_current * sizeof(ClassMapElem);
+        memcpy(revised->elems, current->elems, size);
+    }
+    for (int32_t i = 0; i < num_items; i++) {
+        revised->elems[i + num_current].klass_handle = klass_handles[i];
+        revised->elems[i + num_current].py_type      = py_types[i];
+    }
+    revised->size = total;
+    return revised;
+}
+
+void
+CFBind_assoc_py_types(cfish_Class ***klass_handles, PyTypeObject **py_types,
+                      int32_t num_items) {
+    while (1) {
+        ClassMap *current = klass_map;
+        ClassMap *revised = S_revise_class_map(current, klass_handles,
+                                               py_types, num_items);
+        if (cfish_Atomic_cas_ptr((void*volatile*)&klass_map, current, revised)) {
+            if (current) {
+                // TODO: Use read locking.  For now we have to leak this
+                // memory to avoid memory errors in case another thread isn't
+                // done reading it yet.
+
+                //free(current->elems);
+                //free(current);
+            }
+            break;
+        }
+        else {
+            // Another thread beat us to it.  Try again.
+            free(revised->elems);
+            free(revised);
+        }
+    }
+}
+
 /**** refcounting **********************************************************/
 
 uint32_t

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d7133b8d/runtime/python/cfext/CFBind.h
----------------------------------------------------------------------
diff --git a/runtime/python/cfext/CFBind.h b/runtime/python/cfext/CFBind.h
index 9279510..0064985 100644
--- a/runtime/python/cfext/CFBind.h
+++ b/runtime/python/cfext/CFBind.h
@@ -112,6 +112,13 @@ cfish_Obj*
 CFBind_py_to_cfish_noinc(PyObject *py_obj, cfish_Class *klass,
                          void *allocation);
 
+/** Associate Clownfish classes with Python type objects.  (Internal-only,
+  * used during bootstrapping.)
+  */
+void
+CFBind_assoc_py_types(struct cfish_Class ***klass_handles,
+                      PyTypeObject **py_types, int32_t num_items);
+
 typedef struct CFBindArg {
     cfish_Class *klass;
     void        *ptr;