Eo: Reorganise the vtable in classes and add pointer from objects.
authorTom Hacohen <tom@stosb.com>
Wed, 18 May 2016 17:12:39 +0000 (18:12 +0100)
committerTom Hacohen <tom@stosb.com>
Fri, 20 May 2016 09:25:00 +0000 (10:25 +0100)
This is the first step towards supporting eo_override().
More details about eo_override() to follow.

src/lib/eo/eo.c
src/lib/eo/eo_private.h
src/tests/eo/suite/eo_test_class_errors.c

index e11ef13..48669a7 100644 (file)
@@ -58,7 +58,7 @@ static inline void _eo_data_xunref_internal(_Eo_Object *obj, void *data, const _
       })
 
 static inline void
-_dich_chain_alloc(Dich_Chain1 *chain1)
+_vtable_chain_alloc(Dich_Chain1 *chain1)
 {
    if (!chain1->funcs)
      {
@@ -67,18 +67,18 @@ _dich_chain_alloc(Dich_Chain1 *chain1)
 }
 
 static inline void
-_dich_copy_all(_Eo_Class *dst, const _Eo_Class *src)
+_vtable_copy_all(Eo_Vtable *dst, const Eo_Vtable *src)
 {
    Eo_Op i;
    const Dich_Chain1 *sc1 = src->chain;
    Dich_Chain1 *dc1 = dst->chain;
-   for (i = 0 ; i < src->chain_size ; i++, sc1++, dc1++)
+   for (i = 0 ; i < src->size ; i++, sc1++, dc1++)
      {
         if (sc1->funcs)
           {
              size_t j;
 
-             _dich_chain_alloc(dc1);
+             _vtable_chain_alloc(dc1);
 
              const op_type_funcs *sf = sc1->funcs;
              op_type_funcs *df = dc1->funcs;
@@ -94,12 +94,12 @@ _dich_copy_all(_Eo_Class *dst, const _Eo_Class *src)
 }
 
 static inline const op_type_funcs *
-_dich_func_get(const _Eo_Class *klass, Eo_Op op)
+_vtable_func_get(const Eo_Vtable *vtable, Eo_Op op)
 {
    size_t idx1 = DICH_CHAIN1(op);
-   if (EINA_UNLIKELY(idx1 >= klass->chain_size))
+   if (EINA_UNLIKELY(idx1 >= vtable->size))
       return NULL;
-   Dich_Chain1 *chain1 = &klass->chain[idx1];
+   Dich_Chain1 *chain1 = &vtable->chain[idx1];
    if (EINA_UNLIKELY(!chain1->funcs))
       return NULL;
    return &chain1->funcs[DICH_CHAIN_LAST(op)];
@@ -130,12 +130,12 @@ _eo_op_class_get(Eo_Op op)
 }
 
 static inline Eina_Bool
-_dich_func_set(_Eo_Class *klass, Eo_Op op, eo_op_func_type func)
+_vtable_func_set(_Eo_Class *klass, Eo_Op op, eo_op_func_type func)
 {
    op_type_funcs *fsrc;
    size_t idx1 = DICH_CHAIN1(op);
-   Dich_Chain1 *chain1 = &klass->chain[idx1];
-   _dich_chain_alloc(chain1);
+   Dich_Chain1 *chain1 = &klass->vtable.chain[idx1];
+   _vtable_chain_alloc(chain1);
    fsrc = &chain1->funcs[DICH_CHAIN_LAST(op)];
    if (fsrc->src == klass)
      {
@@ -152,18 +152,18 @@ _dich_func_set(_Eo_Class *klass, Eo_Op op, eo_op_func_type func)
 }
 
 static inline void
-_dich_func_clean_all(_Eo_Class *klass)
+_vtable_func_clean_all(_Eo_Class *klass)
 {
    size_t i;
-   Dich_Chain1 *chain1 = klass->chain;
+   Dich_Chain1 *chain1 = klass->vtable.chain;
 
-   for (i = 0 ; i < klass->chain_size ; i++, chain1++)
+   for (i = 0 ; i < klass->vtable.size ; i++, chain1++)
      {
         if (chain1->funcs)
            free(chain1->funcs);
      }
-   free(klass->chain);
-   klass->chain = NULL;
+   free(klass->vtable.chain);
+   klass->vtable.chain = NULL;
 }
 
 /* END OF DICH */
@@ -236,7 +236,7 @@ _eo_kls_itr_next(const _Eo_Class *orig_kls, const _Eo_Class *cur_klass, Eo_Op op
         kls_itr++;
         while (*kls_itr)
           {
-             const op_type_funcs *fsrc = _dich_func_get(*kls_itr, op);
+             const op_type_funcs *fsrc = _vtable_func_get(&(*kls_itr)->vtable, op);
              if (!fsrc || !fsrc->func)
                {
                   kls_itr++;
@@ -358,7 +358,7 @@ _eo_call_resolve(Eo *eo_id, const char *func_name, Eo_Op_Call_Data *call, Eo_Cal
           }
 #endif
 
-        func = _dich_func_get(klass, cache->op);
+        func = _vtable_func_get(&klass->vtable, cache->op);
 
         if (!func)
           goto end;
@@ -414,7 +414,7 @@ end:
              if (!emb_obj)
                continue;
 
-             func = _dich_func_get(emb_obj->klass, cache->op);
+             func = _vtable_func_get(emb_obj->vtable, cache->op);
              if (func == NULL)
                continue;
 
@@ -607,7 +607,7 @@ _eo_class_funcs_set(_Eo_Class *klass)
 
         DBG("%p->%p '%s'", op_desc->api_func, op_desc->func, _eo_op_desc_name_get(op_desc));
 
-        if (!_dich_func_set(klass, op, op_desc->func))
+        if (!_vtable_func_set(klass, op, op_desc->func))
           return EINA_FALSE;
 
         last_api_func = op_desc->api_func;
@@ -655,6 +655,7 @@ _eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo
 
    obj->refcount++;
    obj->klass = klass;
+   obj->vtable = &klass->vtable;
 
 #ifndef HAVE_EO_ID
    EINA_MAGIC_SET((Eo_Header *) obj, EO_EINA_MAGIC);
@@ -806,8 +807,8 @@ _eo_class_base_op_init(_Eo_Class *klass)
 
    _eo_ops_last_id += desc->ops.count + 1;
 
-   klass->chain_size = DICH_CHAIN1(_eo_ops_last_id) + 1;
-   klass->chain = calloc(klass->chain_size, sizeof(*klass->chain));
+   klass->vtable.size = DICH_CHAIN1(_eo_ops_last_id) + 1;
+   klass->vtable.chain = calloc(klass->vtable.size, sizeof(*klass->vtable.chain));
 }
 
 #ifdef EO_DEBUG
@@ -950,7 +951,7 @@ eo_class_free(_Eo_Class *klass)
         if (klass->desc->class_destructor)
            klass->desc->class_destructor(_eo_class_id_get(klass));
 
-        _dich_func_clean_all(klass);
+        _vtable_func_clean_all(klass);
      }
 
    EINA_TRASH_CLEAN(&klass->objects.trash, data)
@@ -1245,7 +1246,7 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
         /* Skip ourselves. */
         for ( mro_itr-- ; mro_itr > klass->mro ; mro_itr--)
           {
-             _dich_copy_all(klass, *mro_itr);
+             _vtable_copy_all(&klass->vtable, &(*mro_itr)->vtable);
           }
      }
 
@@ -1257,16 +1258,16 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
           {
              const _Eo_Class *extn = *extn_itr;
              /* Set it in the dich. */
-             _dich_func_set(klass, extn->base_id +
+             _vtable_func_set(klass, extn->base_id +
                    extn->desc->ops.count, _eo_class_isa_func);
           }
 
-        _dich_func_set(klass, klass->base_id + klass->desc->ops.count,
+        _vtable_func_set(klass, klass->base_id + klass->desc->ops.count,
               _eo_class_isa_func);
 
         if (klass->parent)
           {
-             _dich_func_set(klass,
+             _vtable_func_set(klass,
                    klass->parent->base_id + klass->parent->desc->ops.count,
                    _eo_class_isa_func);
           }
@@ -1276,7 +1277,7 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
      {
         eina_spinlock_free(&klass->objects.trash_lock);
         eina_spinlock_free(&klass->iterators.trash_lock);
-        _dich_func_clean_all(klass);
+        _vtable_func_clean_all(klass);
         free(klass);
         return NULL;
      }
@@ -1305,7 +1306,7 @@ eo_isa(const Eo *eo_id, const Eo_Class *klass_id)
 {
    EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE);
    EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, EINA_FALSE);
-   const op_type_funcs *func = _dich_func_get(obj->klass,
+   const op_type_funcs *func = _vtable_func_get(obj->vtable,
          klass->base_id + klass->desc->ops.count);
 
    /* Currently implemented by reusing the LAST op id. Just marking it with
index a05bdf6..62f9b73 100644 (file)
@@ -77,6 +77,14 @@ static inline void _eo_free_ids_tables(void);
 
 void _eo_condtor_done(Eo *obj);
 
+typedef struct _Dich_Chain1 Dich_Chain1;
+
+typedef struct _Eo_Vtable
+{
+   Dich_Chain1 *chain;
+   unsigned int size;
+} Eo_Vtable;
+
 struct _Eo_Header
 {
 #ifndef HAVE_EO_ID
@@ -95,6 +103,8 @@ struct _Eo_Object
      Eina_Inlist *data_xrefs;
 #endif
 
+     Eo_Vtable *vtable;
+
      Eina_List *composite_objects;
      Eo_Del_Intercept del_intercept;
 
@@ -114,8 +124,6 @@ struct _Eo_Object
 /* FIXME: Change the type to something generic that makes sense for eo */
 typedef void (*eo_op_func_type)(Eo *, void *class_data, va_list *list);
 
-typedef struct _Dich_Chain1 Dich_Chain1;
-
 typedef struct
 {
    eo_op_func_type func;
@@ -139,7 +147,7 @@ struct _Eo_Class
 
    const _Eo_Class *parent;
    const Eo_Class_Description *desc;
-   Dich_Chain1 *chain; /**< The size is chain size */
+   Eo_Vtable vtable;
 
    const _Eo_Class **extensions;
 
@@ -162,7 +170,6 @@ struct _Eo_Class
    } iterators;
 
    unsigned int obj_size; /**< size of an object of this class */
-   unsigned int chain_size;
    unsigned int base_id;
    unsigned int data_offset; /* < Offset of the data within object data. */
 
index 6fc6e3b..8155c5d 100644 (file)
@@ -329,7 +329,7 @@ START_TEST(eo_dich_func_override)
         NULL
    };
 
-   TEST_EO_ERROR("_dich_func_set", "Class '%s': Overriding func %p for op %d (%s) with %p.");
+   TEST_EO_ERROR("_vtable_func_set", "Class '%s': Overriding func %p for op %d (%s) with %p.");
    klass = eo_class_new(&class_desc, SIMPLE_CLASS, NULL);
    fail_if(klass);
    fail_unless(ctx.did);