Given a Class, find its PyTypeObject. Cache the PyTypeObject inside the Clownfish Class object, in a `host_type` member.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/2b37cc17 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/2b37cc17 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/2b37cc17 Branch: refs/heads/py_exp13 Commit: 2b37cc17c94eabbb27efeb090fd5827eac74807a Parents: d7133b8 Author: Marvin Humphrey <[email protected]> Authored: Mon Feb 1 14:47:34 2016 -0800 Committer: Marvin Humphrey <[email protected]> Committed: Wed Feb 24 15:20:37 2016 -0800 ---------------------------------------------------------------------- runtime/core/Clownfish/Class.cfh | 1 + runtime/python/cfext/CFBind.c | 43 +++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2b37cc17/runtime/core/Clownfish/Class.cfh ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh index dbb31cb..c87964f 100644 --- a/runtime/core/Clownfish/Class.cfh +++ b/runtime/core/Clownfish/Class.cfh @@ -32,6 +32,7 @@ public final class Clownfish::Class inherits Clownfish::Obj { int32_t parcel_id; uint32_t obj_alloc_size; uint32_t class_alloc_size; + void *host_type; Method **methods; cfish_method_t[1] vtable; /* flexible array */ http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2b37cc17/runtime/python/cfext/CFBind.c ---------------------------------------------------------------------- diff --git a/runtime/python/cfext/CFBind.c b/runtime/python/cfext/CFBind.c index 2f8d657..f73b76a 100644 --- a/runtime/python/cfext/CFBind.c +++ b/runtime/python/cfext/CFBind.c @@ -50,10 +50,8 @@ S_get_cached_py_type(cfish_Class *klass); static bool S_py_obj_is_a(PyObject *py_obj, cfish_Class *klass) { - CFISH_UNUSED_VAR(py_obj); - CFISH_UNUSED_VAR(klass); - CFISH_THROW(CFISH_ERR, "TODO"); - CFISH_UNREACHABLE_RETURN(bool); + PyTypeObject *py_type = S_get_cached_py_type(klass); + return !!PyObject_TypeCheck(py_obj, py_type); } void @@ -859,11 +857,42 @@ CFISH_Obj_To_Host_IMP(cfish_Obj *self) { /**** Class ****************************************************************/ +/* Check the Class object for its associated PyTypeObject, which is stored in + * `klass->host_type`. If it is not there yet, search the class mapping and + * cache it in the object. Return the PyTypeObject. + */ static PyTypeObject* S_get_cached_py_type(cfish_Class *self) { - // FIXME: dummy implementation - CFISH_UNUSED_VAR(self); - return NULL; + PyTypeObject *py_type = (PyTypeObject*)self->host_type; + if (py_type == NULL) { + ClassMap *current = klass_map; + for (int32_t i = 0; i < current->size; i++) { + cfish_Class **handle = current->elems[i].klass_handle; + if (handle == NULL || *handle != self) { + continue; + } + py_type = current->elems[i].py_type; + Py_INCREF(py_type); + if (!cfish_Atomic_cas_ptr((void*volatile*)&self->host_type, py_type, NULL)) { + // Lost the race to another thread, so get rid of the refcount. + Py_DECREF(py_type); + } + break; + } + } + if (py_type == NULL) { + if (Err_initialized) { + CFISH_THROW(CFISH_ERR, + "Can't find a Python type object corresponding to %o", + CFISH_Class_Get_Name(self)); + } + else { + fprintf(stderr, "Can't find a Python type corresponding to a " + "Clownfish class\n"); + exit(1); + } + } + return py_type; } cfish_Obj*
