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 <[email protected]> Authored: Mon Feb 1 14:37:58 2016 -0800 Committer: Marvin Humphrey <[email protected]> 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;
