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 23:40:23 UTC

[08/17] lucy-clownfish git commit: Given a Class, find its PyTypeObject.

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/master
Commit: 2b37cc17c94eabbb27efeb090fd5827eac74807a
Parents: d7133b8
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Feb 1 14:47:34 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
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*