summaryrefslogtreecommitdiff
path: root/src/lib/eo/eo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/eo/eo.c')
-rw-r--r--src/lib/eo/eo.c780
1 files changed, 435 insertions, 345 deletions
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index 55479009c8..b7f10faad8 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -38,8 +38,8 @@ static Eina_Bool _eo_trash_bypass = EINA_FALSE;
#define EFL_OBJECT_OP_IDS_FIRST 1
/* Used inside the class_get functions of classes, see #EFL_DEFINE_CLASS */
-EAPI Eina_Lock _efl_class_creation_lock;
-EAPI unsigned int _efl_object_init_generation = 1;
+EO_API Eina_Lock _efl_class_creation_lock;
+EO_API unsigned int _efl_object_init_generation = 1;
int _eo_log_dom = -1;
Eina_Thread _efl_object_main_thread;
static unsigned int efl_del_api_generation = 0;
@@ -90,7 +90,6 @@ static _Efl_Class **_eo_classes = NULL;
static Eo_Id _eo_classes_last_id = 0;
static Eo_Id _eo_classes_alloc = 0;
static int _efl_object_init_count = 0;
-static Efl_Object_Op _eo_ops_last_id = 0;
static Eina_Hash *_ops_storage = NULL;
static Eina_Spinlock _ops_storage_lock;
@@ -104,7 +103,6 @@ static void _eo_condtor_reset(_Eo_Object *obj);
static inline void *_efl_data_scope_get(const _Eo_Object *obj, const _Efl_Class *klass);
static inline void *_efl_data_xref_internal(const char *file, int line, _Eo_Object *obj, const _Efl_Class *klass, const _Eo_Object *ref_obj);
static inline void _efl_data_xunref_internal(_Eo_Object *obj, void *data, const _Eo_Object *ref_obj);
-static void _vtable_init(Eo_Vtable *vtable, size_t size);
static inline Efl_Object_Op _efl_object_api_op_id_get_internal(const void *api_func);
@@ -120,96 +118,210 @@ static inline Efl_Object_Op _efl_object_api_op_id_get_internal(const void *api_f
(_eo_classes[_UNMASK_ID(id) - 1]) : NULL); \
})
-static inline void
-_vtable_chain2_unref(Dich_Chain2 *chain)
+#define EFL_OBJECT_OP_CLASS_PART(op) op >> 16
+#define EFL_OBJECT_OP_FUNC_PART(op) op & 0xffff
+#define EFL_OBJECT_OP_CREATE_OP_ID(class_id, func_id) ((unsigned short)class_id)<<16|((unsigned short)func_id&0xffff)
+
+static const _Efl_Class *
+_eo_op_class_get(Efl_Object_Op op)
{
- if (--(chain->refcount) == 0)
- {
- free(chain);
- }
+ short class_id = EFL_OBJECT_OP_CLASS_PART(op);
+ return _eo_classes[class_id];
}
+#if defined(DEBUG_VTABLE_ALLOCATION)
+static int _allocated_memory = 0;
-static inline void
-_vtable_chain_alloc(Dich_Chain1 *chain1)
+static inline void*
+_vtable_alloc(unsigned long n, size_t elem)
{
- chain1->chain2 = calloc(1, sizeof(*(chain1->chain2)));
- chain1->chain2->refcount = 1;
+ _allocated_memory += n*elem;
+ return calloc(n, elem);
}
+#else
+static inline void*
+_vtable_alloc(unsigned long n, size_t elem)
+{
+ return calloc(n, elem);
+}
+#endif
-static inline void _vtable_chain_write_prepare(Dich_Chain1 *dst);
-static inline void
-_vtable_chain_merge(Dich_Chain1 *dst, const Dich_Chain1 *src)
+/**
+ * This inits the vtable with a given size
+ */
+static void
+_vtable_init_size(Eo_Vtable *vtable, unsigned int size)
{
- size_t j;
- const op_type_funcs *sf = src->chain2->funcs;
- op_type_funcs *df = dst->chain2->funcs;
+ //we assume here that _eo_classes_last_id was called before
+ vtable->size = size;
+ vtable->chain = _vtable_alloc(vtable->size, sizeof(Eo_Vtable_Node));
+}
- if (df == sf)
- {
- /* Skip if the chain is the same. */
- return;
- }
+/**
+ * This inits the vtable wit hthe current size of allocated tables
+ */
+static void
+_vtable_init(Eo_Vtable *vtable)
+{
+ //we assume here that _eo_classes_last_id was called before
+ _vtable_init_size(vtable, _eo_classes_last_id);
+}
- for (j = 0 ; j < DICH_CHAIN_LAST_SIZE ; j++, df++, sf++)
+/**
+ * This removes all nodes from the klass that are copied from mro
+ */
+static void
+_vtable_mro_free(const _Efl_Class *klass)
+{
+ const _Efl_Class **mro_itr = klass->mro;
+ const Eo_Vtable *vtable = &klass->vtable;
+ for ( ; *mro_itr ; mro_itr++)
{
- if (sf->func && memcmp(df, sf, sizeof(*df)))
+ const Eo_Vtable *mro_vtable = &(*mro_itr)->vtable;
+ if ((*mro_itr) == klass)
+ continue;
+ for (unsigned int i = 0; i < mro_vtable->size; ++i)
{
- _vtable_chain_write_prepare(dst);
- df = dst->chain2->funcs + j;
- memcpy(df, sf, sizeof(*df));
+ if (i == klass->class_id)
+ continue;
+ if (vtable->chain[i].funcs && mro_vtable->chain[i].funcs == vtable->chain[i].funcs)
+ {
+ vtable->chain[i].funcs = NULL;
+ }
}
}
}
-static inline void
-_vtable_chain_write_prepare(Dich_Chain1 *dst)
+static void
+_vtable_free(Eo_Vtable *vtable, const Eo_Vtable *root)
{
- if (!dst->chain2)
+ if (root)
{
- _vtable_chain_alloc(dst);
- return;
+ EINA_SAFETY_ON_FALSE_RETURN(vtable->size == root->size);
}
- else if (dst->chain2->refcount == 1)
+
+ for (int i = 0; i < vtable->size; ++i)
{
- /* We own it, no need to duplicate */
- return;
+ if (root && root->chain[i].funcs == vtable->chain[i].funcs)
+ vtable->chain[i].count = 0;
+
+ if (vtable->chain[i].count)
+ {
+ free(vtable->chain[i].funcs);
+ }
}
+ free(vtable->chain);
+}
- Dich_Chain1 old;
- old.chain2 = dst->chain2;
+/**
+ * This takes over all set chains of the src to dest.
+ * This should only be called on Eo_Vtables, which are initialized with this value.
+ * Previous setted values are going to be overwritten.
+ */
+static void
+_vtable_take_over(Eo_Vtable *dest, const Eo_Vtable *src)
+{
+ for (int i = 0; i < src->size; ++i)
+ {
+ if (src->chain[i].funcs)
+ {
+ dest->chain[i] = src->chain[i];
+ }
+ }
+}
- _vtable_chain_alloc(dst);
- _vtable_chain_merge(dst, &old);
+/**
+ * Fills the node of the passed class id with a empty none NULL pointer.
+ * This is used to indicate that a specific node has a normal 0 size, but is set.
+ */
+static void
+_vtable_insert_empty_funcs(Eo_Vtable *vtable, unsigned short class_id)
+{
+ vtable->chain[class_id].funcs = (void*)0x1010101;
+ vtable->chain[class_id].count = 0;
+}
- _vtable_chain2_unref(old.chain2);
+/**
+ * duplicate the source node, and write the duplicated values to the destination
+ * No logical changes are applied to src.
+ */
+static void
+_vtable_copy_node(Eo_Vtable_Node *dest, const Eo_Vtable_Node *src)
+{
+ dest->count = src->count;
+ dest->funcs = _vtable_alloc(sizeof(op_type_funcs), src->count);
+ memcpy(dest->funcs, src->funcs, sizeof(op_type_funcs) * src->count);
}
-static inline void
-_vtable_chain_copy_ref(Dich_Chain1 *dst, const Dich_Chain1 *src)
+/**
+ * Initialize a node with a empty funcs array of the passed length
+ */
+static void
+_vtable_prepare_empty_node(Eo_Vtable *dest, unsigned int length, unsigned int class_id)
{
- if (dst->chain2)
- {
- _vtable_chain_merge(dst, src);
- }
- else
+ dest->chain[class_id].count = length;
+ dest->chain[class_id].funcs = _vtable_alloc(sizeof(op_type_funcs), dest->chain[class_id].count);
+}
+
+/**
+ * Copy all setted APIs from src to dest.
+ * Already set function slots are going to be replaced.
+ */
+static void
+_vtable_merge_defined_api(Eo_Vtable *dest, const Eo_Vtable *src, Eina_Bool *hitmap)
+{
+ for (unsigned int i = 0; i < src->size; ++i)
{
- dst->chain2 = src->chain2;
- dst->chain2->refcount++;
+ //if there is a source node evalulate if we need to copy it
+ if (src->chain[i].funcs)
+ {
+ if (!dest->chain[i].funcs)
+ {
+ dest->chain[i] = src->chain[i];
+ EINA_SAFETY_ON_FALSE_RETURN(hitmap[i] == EINA_FALSE);
+ }
+ else
+ {
+ if (!hitmap[i])
+ {
+ const Eo_Vtable_Node node = dest->chain[i];
+ if (!node.count)
+ _vtable_insert_empty_funcs(dest, i);
+ else
+ _vtable_copy_node(&dest->chain[i], &node); //we copy what we have, and overwrite in the later for loop
+ hitmap[i] = EINA_TRUE;
+ }
+ for (int j = 0; j < src->chain[i].count; ++j)
+ {
+ if (src->chain[i].funcs[j].func)
+ dest->chain[i].funcs[j] = src->chain[i].funcs[j];
+ }
+ }
+ }
}
}
-static inline void
-_vtable_copy_all(Eo_Vtable *dst, const Eo_Vtable *src)
+/**
+ * Ensure that all set nodes from src are also set on dest.
+ * No real values are copied, the newly taken or allocated slots will be empty.
+ */
+static void
+_vtable_merge_empty(Eo_Vtable *dest, const Eo_Vtable *src, Eina_Bool *hitmap)
{
- Efl_Object_Op i;
- const Dich_Chain1 *sc1 = src->chain;
- Dich_Chain1 *dc1 = dst->chain;
- for (i = 0 ; i < src->size ; i++, sc1++, dc1++)
+ for (unsigned int i = 0; i < src->size; ++i)
{
- if (sc1->chain2)
+ if (src->chain[i].funcs && !dest->chain[i].funcs)
{
- _vtable_chain_copy_ref(dc1, sc1);
+ if (!src->chain[i].count)
+ {
+ dest->chain[i].funcs = src->chain[i].funcs;
+ dest->chain[i].count = src->chain[i].count;
+ }
+ else
+ {
+ _vtable_prepare_empty_node(dest, src->chain[i].count, i);
+ hitmap[i] = EINA_TRUE;
+ }
}
}
}
@@ -217,37 +329,15 @@ _vtable_copy_all(Eo_Vtable *dst, const Eo_Vtable *src)
static inline const op_type_funcs *
_vtable_func_get(const Eo_Vtable *vtable, Efl_Object_Op op)
{
- size_t idx1 = DICH_CHAIN1(op);
- if (EINA_UNLIKELY(idx1 >= vtable->size))
- return NULL;
- Dich_Chain1 *chain1 = &vtable->chain[idx1];
- if (EINA_UNLIKELY(!chain1->chain2))
- return NULL;
- return &chain1->chain2->funcs[DICH_CHAIN_LAST(op)];
-}
-
-/* XXX: Only used for a debug message below. Doesn't matter that it's slow. */
-static const _Efl_Class *
-_eo_op_class_get(Efl_Object_Op op)
-{
- _Efl_Class **itr = _eo_classes;
- int mid, max, min;
+ unsigned short class_id = EFL_OBJECT_OP_CLASS_PART(op);
+ unsigned short func_id = EFL_OBJECT_OP_FUNC_PART(op);
- min = 0;
- max = _eo_classes_last_id - 1;
- while (min <= max)
- {
- mid = (min + max) / 2;
+ if (EINA_UNLIKELY(vtable->size <= class_id))
+ return NULL;
+ if (EINA_UNLIKELY(vtable->chain[class_id].count <= func_id))
+ return NULL;
- if (itr[mid]->base_id + itr[mid]->ops_count < op)
- min = mid + 1;
- else if (itr[mid]->base_id > op)
- max = mid - 1;
- else
- return itr[mid];
- }
-
- return NULL;
+ return &vtable->chain[class_id].funcs[func_id];
}
static inline Eina_Bool
@@ -256,24 +346,30 @@ _vtable_func_set(Eo_Vtable *vtable, const _Efl_Class *klass,
Eo_Op_Func_Type func, Eina_Bool allow_same_override)
{
op_type_funcs *fsrc;
- size_t idx1 = DICH_CHAIN1(op);
- Dich_Chain1 *chain1;
+ unsigned short class_id = EFL_OBJECT_OP_CLASS_PART(op);
+ unsigned short func_id = EFL_OBJECT_OP_FUNC_PART(op);
+ Eo_Vtable_Node *hirachy_node = NULL;
+ Eo_Vtable_Node *node = NULL;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(vtable->size >= class_id, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(idx1 < vtable->size, EINA_FALSE);
- chain1 = &vtable->chain[idx1];
- _vtable_chain_write_prepare(chain1);
- fsrc = &chain1->chain2->funcs[DICH_CHAIN_LAST(op)];
+ if (klass->parent && klass->parent->vtable.size > class_id)
+ hirachy_node = &klass->parent->vtable.chain[class_id];
if (hierarchy_klass)
+ hirachy_node = &hierarchy_klass->vtable.chain[class_id];
+ node = &vtable->chain[class_id];
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(node->funcs, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(node->count >= func_id, EINA_FALSE);
+ fsrc = &node->funcs[func_id];
+
+ if (hierarchy_klass && !func)
{
if (!func)
{
- op_type_funcs *fsrc_orig;
- Dich_Chain1 *chain1_orig;
-
- chain1_orig = &hierarchy_klass->vtable.chain[idx1];
- fsrc_orig = &chain1_orig->chain2->funcs[DICH_CHAIN_LAST(op)];
- func = fsrc_orig->func;
- klass = fsrc_orig->src;
+ op_type_funcs funcs = hirachy_node->funcs[func_id];
+ klass = funcs.src;
+ func = funcs.func;
}
}
else
@@ -287,27 +383,12 @@ _vtable_func_set(Eo_Vtable *vtable, const _Efl_Class *klass,
}
}
- fsrc->func = func;
fsrc->src = klass;
+ fsrc->func = func;
return EINA_TRUE;
}
-void
-_vtable_func_clean_all(Eo_Vtable *vtable)
-{
- size_t i;
- Dich_Chain1 *chain1 = vtable->chain;
-
- for (i = 0 ; i < vtable->size ; i++, chain1++)
- {
- if (chain1->chain2)
- _vtable_chain2_unref(chain1->chain2);
- }
- free(vtable->chain);
- vtable->chain = NULL;
-}
-
/* END OF DICH */
#define _EO_ID_GET(Id) ((Eo_Id) (Id))
@@ -443,19 +524,19 @@ err_obj_hierarchy:
return NULL;
}
-EAPI Eo *
+EO_API Eo *
efl_super(const Eo *eo_id, const Efl_Class *cur_klass)
{
return _efl_super_cast(eo_id, cur_klass, EINA_TRUE);
}
-EAPI Eo *
+EO_API Eo *
efl_cast(const Eo *eo_id, const Efl_Class *cur_klass)
{
return _efl_super_cast(eo_id, cur_klass, EINA_FALSE);
}
-EAPI Eina_Bool
+EO_API Eina_Bool
_efl_object_call_resolve(Eo *eo_id, const char *func_name, Efl_Object_Op_Call_Data *call, Efl_Object_Op op, const char *file, int line)
{
const _Efl_Class *klass, *main_klass;
@@ -463,42 +544,25 @@ _efl_object_call_resolve(Eo *eo_id, const char *func_name, Efl_Object_Op_Call_Da
_Eo_Object *obj = NULL;
const Eo_Vtable *vtable = NULL;
const op_type_funcs *func;
- Eina_Bool is_obj;
Eina_Bool super = EINA_TRUE;
if (EINA_UNLIKELY(!eo_id)) goto on_null;
- call->eo_id = eo_id;
- is_obj = _eo_is_a_obj(eo_id);
+ EO_OBJ_POINTER_RETURN_VAL_PROXY(eo_id, _obj, EINA_FALSE);
- if (EINA_LIKELY(is_obj == EINA_TRUE))
- {
- EO_OBJ_POINTER_RETURN_VAL_PROXY(eo_id, _obj, EINA_FALSE);
-
- obj = _obj;
- klass = _obj->klass;
- vtable = EO_VTABLE(obj);
- if (EINA_UNLIKELY(_obj->cur_klass != NULL))
- {
- // YES this is a goto with a label to return. this is a
- // micro-optimization to move infrequent code out of the
- // hot path of the function
- goto obj_super;
- }
-
-obj_super_back:
- call->obj = obj;
- _efl_ref(_obj);
- }
- else
+ obj = _obj;
+ klass = _obj->klass;
+ vtable = EO_VTABLE2(obj);
+ if (EINA_UNLIKELY(_obj->cur_klass != NULL))
{
// YES this is a goto with a label to return. this is a
// micro-optimization to move infrequent code out of the
// hot path of the function
- goto ok_klass;
+ goto obj_super;
}
-ok_klass_back:
+obj_super_back:
+ _efl_ref(_obj);
main_klass = klass;
@@ -513,6 +577,7 @@ ok_klass_back:
else
{
func = _vtable_func_get(vtable, op);
+ EINA_PREFETCH_NOCACHE(func);
// this is not very likely to happen - but may if its an invalid
// call or a composite object, but either way, it's not very likely
// so make it a goto to save on instruction cache
@@ -522,9 +587,10 @@ ok_cur_klass_back:
if (EINA_LIKELY(func->func && func->src))
{
+ call->eo_id = eo_id;
+ call->obj = obj;
call->func = func->func;
-
- if (is_obj) call->data = _efl_data_scope_get(obj, func->src);
+ call->data = _efl_data_scope_get(obj, func->src);
return EINA_TRUE;
}
@@ -535,7 +601,6 @@ ok_cur_klass_back:
end:
/* Try composite objects */
- if (is_obj)
{
Eina_List *itr;
Eo *emb_obj_id;
@@ -544,7 +609,7 @@ end:
EO_OBJ_POINTER_PROXY(emb_obj_id, emb_obj);
if (EINA_UNLIKELY(!emb_obj)) continue;
- func = _vtable_func_get(EO_VTABLE(emb_obj), op);
+ func = _vtable_func_get(&emb_obj->klass->vtable, op);
if (func == NULL) goto composite_continue;
if (EINA_LIKELY(func->func && func->src))
@@ -567,16 +632,16 @@ composite_continue:
// If it's a do_super call.
if (cur_klass)
{
- ERR("in %s:%d: func '%s' (%d) could not be resolved for class '%s' for super of '%s'.",
- file, line, func_name, op, main_klass->desc->name,
+ ERR("in %s:%d: func '%s' (%d) could not be resolved on %s for class '%s' for super of '%s'.",
+ file, line, func_name, op, efl_debug_name_get(eo_id), main_klass->desc->name,
cur_klass->desc->name);
goto err;
}
else
{
/* we should not be able to take this branch */
- ERR("in %s:%d: func '%s' (%d) could not be resolved for class '%s'.",
- file, line, func_name, op, main_klass->desc->name);
+ ERR("in %s:%d: func '%s' (%d) could not be resolved on %s for class '%s'.",
+ file, line, func_name, op, efl_debug_name_get(eo_id), main_klass->desc->name);
goto err;
}
@@ -584,12 +649,10 @@ err_func_src:
ERR("in %s:%d: you called a pure virtual func '%s' (%d) of class '%s'.",
file, line, func_name, op, klass->desc->name);
err:
- if (is_obj)
- {
- _apply_auto_unref(obj, eo_id);
- _efl_unref(obj);
- _eo_obj_pointer_done((Eo_Id)eo_id);
- }
+ _apply_auto_unref(obj, eo_id);
+ _efl_unref(obj);
+ _eo_obj_pointer_done((Eo_Id)eo_id);
+
return EINA_FALSE;
// yes - special "move out of hot path" code blobs with goto's for
@@ -600,18 +663,6 @@ ok_cur_klass:
klass = func->src;
goto ok_cur_klass_back;
-ok_klass:
- {
- EO_CLASS_POINTER_GOTO_PROXY(eo_id, _klass, err_klass);
- klass = _klass;
- vtable = &klass->vtable;
- cur_klass = _super_klass;
- if (cur_klass) _super_klass = NULL;
- call->obj = NULL;
- call->data = NULL;
- }
- goto ok_klass_back;
-
obj_super:
{
cur_klass = obj->cur_klass;
@@ -630,10 +681,6 @@ obj_super:
}
goto obj_super_back;
-err_klass:
- _EO_POINTER_ERR(eo_id, "in %s:%d: func '%s': obj_id=%p is an invalid ref.", file, line, func_name, eo_id);
- return EINA_FALSE;
-
on_null:
if (EINA_UNLIKELY(efl_del_api_generation != _efl_object_init_generation))
{
@@ -645,7 +692,7 @@ on_null:
return EINA_FALSE;
}
-EAPI void
+EO_API void
_efl_object_call_end(Efl_Object_Op_Call_Data *call)
{
if (EINA_LIKELY(!!call->obj))
@@ -688,7 +735,7 @@ _efl_object_api_op_id_get_internal(const void *api_func)
}
/* LEGACY, should be removed before next release */
-EAPI Efl_Object_Op
+EO_API Efl_Object_Op
_efl_object_api_op_id_get(const void *api_func)
{
Efl_Object_Op op = _efl_object_api_op_id_get_internal(api_func);
@@ -701,7 +748,7 @@ _efl_object_api_op_id_get(const void *api_func)
return op;
}
-EAPI Efl_Object_Op
+EO_API Efl_Object_Op
_efl_object_op_api_id_get(const void *api_func, const Eo *eo_obj, const char *api_func_name, const char *file, int line)
{
Efl_Object_Op op;
@@ -727,23 +774,25 @@ _efl_object_op_api_id_get(const void *api_func, const Eo *eo_obj, const char *ap
/* klass is the klass we are working on. hierarchy_klass is the class whe should
* use when validating. */
static Eina_Bool
-_eo_class_funcs_set(Eo_Vtable *vtable, const Efl_Object_Ops *ops, const _Efl_Class *hierarchy_klass, const _Efl_Class *klass, Efl_Object_Op id_offset, Eina_Bool override_only)
+_eo_class_funcs_set(Eo_Vtable *vtable, const Efl_Object_Ops *ops, const _Efl_Class *hierarchy_klass, const _Efl_Class *klass, Eina_Bool override_only, unsigned int class_id, Eina_Bool *hitmap)
{
unsigned int i, j;
- Efl_Object_Op op_id;
+ unsigned int number_of_new_functions = 0;
const Efl_Op_Description *op_desc;
const Efl_Op_Description *op_descs;
const _Efl_Class *override_class;
const void **api_funcs;
Eina_Bool check_equal;
- op_id = hierarchy_klass->base_id + id_offset;
op_descs = ops->descs;
override_class = override_only ? hierarchy_klass : NULL;
DBG("Set functions for class '%s':%p", klass->desc->name, klass);
- if (!op_descs || !ops->count) return EINA_TRUE;
+ if (!override_only)
+ _vtable_insert_empty_funcs(vtable, class_id);
+ if (!op_descs || !ops->count)
+ return EINA_TRUE;
#ifdef EO_DEBUG
check_equal = EINA_TRUE;
@@ -776,51 +825,73 @@ _eo_class_funcs_set(Eo_Vtable *vtable, const Efl_Object_Ops *ops, const _Efl_Cla
api_funcs[i] = op_desc->api_func;
}
+ if (_efl_object_api_op_id_get_internal(op_desc->api_func) == EFL_NOOP)
+ {
+ number_of_new_functions ++;
+ }
}
- for (i = 0, op_desc = op_descs; i < ops->count; i++, op_desc++)
+ if (!override_only)
+ {
+ if (number_of_new_functions)
+ {
+ //Before setting any real functions, allocate the node that will contain all the functions
+ _vtable_prepare_empty_node(vtable, number_of_new_functions, class_id);
+ }
+ hitmap[class_id] = EINA_TRUE;
+ }
+
+ for (i = 0, j = 0, op_desc = op_descs; i < ops->count; i++, op_desc++)
{
- Efl_Object_Op op = EFL_NOOP;
+ Efl_Object_Op op2 = EFL_NOOP;
+ short op2_class_id;
/* Get the opid for the function. */
- op = _efl_object_api_op_id_get_internal(op_desc->api_func);
+ op2 = _efl_object_api_op_id_get_internal(op_desc->api_func);
- if (op == EFL_NOOP)
+ if (op2 == EFL_NOOP)
{
+ //functions that do not have a op yet, are considered to be belonging to this class
if (override_only)
{
ERR("Class '%s': Tried overriding a previously undefined function.", klass->desc->name);
return EINA_FALSE;
}
- op = op_id;
+ op2 = EFL_OBJECT_OP_CREATE_OP_ID(class_id, j);
eina_spinlock_take(&_ops_storage_lock);
#ifndef _WIN32
- eina_hash_add(_ops_storage, &op_desc->api_func, (void *) (uintptr_t) op);
+ eina_hash_add(_ops_storage, &op_desc->api_func, (void *) (uintptr_t) op2);
#else
- eina_hash_add(_ops_storage, op_desc->api_func, (void *) (uintptr_t) op);
+ eina_hash_add(_ops_storage, op_desc->api_func, (void *) (uintptr_t) op2);
#endif
eina_spinlock_release(&_ops_storage_lock);
-
- op_id++;
+ j ++;
}
#ifdef EO_DEBUG
DBG("%p->%p '%s'", op_desc->api_func, op_desc->func, _eo_op_desc_name_get(op_desc));
#endif
-
- if (!_vtable_func_set(vtable, klass, override_class, op, op_desc->func, EINA_TRUE))
+ op2_class_id = EFL_OBJECT_OP_CLASS_PART(op2);
+ //in case we are having a function overwrite for a specific type, copy the relevant vtable
+ if (!hitmap[op2_class_id])
+ {
+ const Eo_Vtable_Node node = vtable->chain[op2_class_id];
+ _vtable_copy_node(&vtable->chain[op2_class_id], &node);
+ hitmap[op2_class_id] = EINA_TRUE;
+ }
+ if (!_vtable_func_set(vtable, klass, override_class, op2, op_desc->func, EINA_TRUE))
return EINA_FALSE;
}
-
return EINA_TRUE;
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_class_functions_set(const Efl_Class *klass_id, const Efl_Object_Ops *object_ops, const Efl_Object_Property_Reflection_Ops *reflection_table)
{
EO_CLASS_POINTER_GOTO(klass_id, klass, err_klass);
Efl_Object_Ops empty_ops = { 0 };
+ Eina_Bool *hitmap;
// not likely so use goto to alleviate l1 instruction cache of rare code
if (klass->functions_set) goto err_funcs;
@@ -832,35 +903,93 @@ efl_class_functions_set(const Efl_Class *klass_id, const Efl_Object_Ops *object_
klass->ops_count = object_ops->count;
- klass->base_id = _eo_ops_last_id;
- _eo_ops_last_id += klass->ops_count + 1;
+ klass->class_id = _UNMASK_ID(klass->header.id) - 1;
- _vtable_init(&klass->vtable, DICH_CHAIN1(_eo_ops_last_id) + 1);
+ _vtable_init(&klass->vtable);
+ if (!klass->vtable.chain) goto err_vtable;
- /* Flatten the function array */
+ hitmap = alloca(klass->vtable.size);
+ memset(hitmap, 0, klass->vtable.size);
+ /* Merge in all required vtable entries */
{
const _Efl_Class **mro_itr = klass->mro;
- for ( ; *mro_itr ; mro_itr++) ;
-
- /* Skip ourselves. */
+ /* take over everything from the parent */
+ if (klass->parent)
+ {
+ _vtable_take_over(&klass->vtable, &klass->parent->vtable);
+ }
+ /*
+ * - jump to the mro entry containing the parent
+ * - everything further from the parent to the next elements is already
+ * represented in the vtable of the parent.
+ */
+ for ( ; *mro_itr ; mro_itr++)
+ {
+ if (*mro_itr == klass->parent)
+ break;
+ }
+ /**
+ * merge in all the APIs that are extended in the current klass for this first time.
+ * That means, they are not extended anywhere from the parent further up.
+ */
for ( mro_itr-- ; mro_itr > klass->mro ; mro_itr--)
- _vtable_copy_all(&klass->vtable, &(*mro_itr)->vtable);
+ {
+ _vtable_merge_defined_api(&klass->vtable, &(*mro_itr)->vtable, hitmap);
+ }
+ /*
+ * add slots for the interfaces and mixins we are inheriting from
+ */
+ for (int i = 0; klass->extensions[i]; i++)
+ {
+ const _Efl_Class *ext = klass->extensions[i];
+ /*for all extensions of the class, ensure that *at least* empty vtables are available, so the efl_isa calls do succeed*/
+ _vtable_merge_empty(&klass->vtable, &ext->vtable, hitmap);
+ }
}
+ {
+ unsigned int i;
- return _eo_class_funcs_set(&klass->vtable, object_ops, klass, klass, 0, EINA_FALSE);
+ for (i = 0; i < object_ops->count; i++)
+ {
+ Efl_Object_Op op = _efl_object_api_op_id_get_internal(object_ops->descs[i].api_func);
+ if (op == EFL_NOOP) continue; //EFL_NOOP means that this function is not yet defined, this will be handled later
+ short class_id = EFL_OBJECT_OP_CLASS_PART(op);
+ if (klass->vtable.chain[class_id].count == 0)
+ {
+ const _Efl_Class *required_klass = _eo_classes[class_id];
+ /* in case this type is not already inherited, error on everything that is not a mixin */
+ if (klass->desc->type == EFL_CLASS_TYPE_MIXIN)
+ {
+ /* this is when a mixin implemets a regular api, we just prepare a empty node, the rest will be implemented later */
+ _vtable_prepare_empty_node(&klass->vtable, required_klass->vtable.chain[class_id].count, class_id);
+ hitmap[class_id] = EINA_TRUE;
+ }
+ else
+ {
+ ERR("There is an API implemented, whoms type is not part of this class. %s vs. %s", klass->desc->name, required_klass->desc->name);
+ _vtable_prepare_empty_node(&klass->vtable, required_klass->vtable.chain[class_id].count, class_id);
+ hitmap[class_id] = EINA_TRUE;
+ }
+ }
+ }
+ }
+ return _eo_class_funcs_set(&klass->vtable, object_ops, klass, klass, EINA_FALSE, klass->class_id, hitmap);
err_funcs:
ERR("Class %s already had its functions set..", klass->desc->name);
return EINA_FALSE;
err_klass:
_EO_POINTER_ERR(klass_id, "Class (%p) is an invalid ref.", klass_id);
return EINA_FALSE;
+err_vtable:
+ ERR("failed to allocate vtable for class '%s'", klass->desc->name);
+ return EINA_FALSE;
}
static Eo *
_efl_add_internal_start_do(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data)
{
- const char *func_name = __FUNCTION__;
+ const char *func_name = __func__;
_Eo_Object *obj;
Eo_Stack_Frame *fptr = NULL;
@@ -963,13 +1092,13 @@ err_parent:
return NULL;
}
-EAPI Eo *
+EO_API Eo *
_efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback)
{
return _efl_add_internal_start_do(file, line, klass_id, parent_id, ref, is_fallback, NULL, NULL);
}
-EAPI Eo * _efl_add_internal_start_bindings(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data)
+EO_API Eo * _efl_add_internal_start_bindings(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data)
{
return _efl_add_internal_start_do(file, line, klass_id, parent_id, ref, is_fallback, substitute_ctor, sub_ctor_data);
}
@@ -1016,7 +1145,7 @@ cleanup:
return NULL;
}
-EAPI Eo *
+EO_API Eo *
_efl_add_end(Eo *eo_id, Eina_Bool is_ref, Eina_Bool is_fallback)
{
if (!eo_id) return NULL;
@@ -1036,7 +1165,7 @@ _efl_add_end(Eo *eo_id, Eina_Bool is_ref, Eina_Bool is_fallback)
return ret;
}
-EAPI void
+EO_API void
efl_reuse(const Eo *eo_id)
{
Eo *obj = (Eo *) eo_id;
@@ -1096,10 +1225,9 @@ _eo_free(_Eo_Object *obj, Eina_Bool manual_free EINA_UNUSED)
}
}
#endif
- if (_obj_is_override(obj))
+ if (obj->opt && _obj_is_override(obj))
{
- _vtable_func_clean_all(obj->opt->vtable);
- eina_freeq_ptr_main_add(obj->opt->vtable, free, 0);
+ _vtable_free(obj->opt->vtable, &obj->klass->vtable);
EO_OPTIONAL_COW_SET(obj, vtable, NULL);
}
@@ -1120,7 +1248,7 @@ _eo_free(_Eo_Object *obj, Eina_Bool manual_free EINA_UNUSED)
}
/*****************************************************************************/
-EAPI const Efl_Class *
+EO_API const Efl_Class *
efl_class_get(const Eo *eo_id)
{
const Efl_Class *klass;
@@ -1142,7 +1270,7 @@ err_obj:
return NULL;
}
-EAPI const char *
+EO_API const char *
efl_class_name_get(const Efl_Class *eo_id)
{
const _Efl_Class *klass;
@@ -1166,7 +1294,7 @@ err_obj:
return NULL;
}
-EAPI size_t
+EO_API size_t
efl_class_memory_size_get(const Efl_Class *eo_id)
{
const _Efl_Class *klass;
@@ -1190,22 +1318,6 @@ err_obj:
return 0;
}
-
-static void
-_vtable_init(Eo_Vtable *vtable, size_t size)
-{
- vtable->size = size;
- vtable->chain = calloc(vtable->size, sizeof(*vtable->chain));
-}
-
-static void
-_vtable_free(Eo_Vtable *vtable)
-{
- if (!vtable) return;
- _vtable_func_clean_all(vtable);
- eina_freeq_ptr_main_add(vtable, free, sizeof(*vtable));
-}
-
static Eina_Bool
_eo_class_mro_has(const _Efl_Class *klass, const _Efl_Class *find)
{
@@ -1360,8 +1472,8 @@ eo_class_free(_Efl_Class *klass)
{
if (klass->desc->class_destructor)
klass->desc->class_destructor(_eo_class_id_get(klass));
-
- _vtable_func_clean_all(&klass->vtable);
+ _vtable_mro_free(klass);
+ _vtable_free(&klass->vtable, NULL);
}
EINA_TRASH_CLEAN(&klass->objects.trash, data)
@@ -1376,32 +1488,6 @@ eo_class_free(_Efl_Class *klass)
eina_freeq_ptr_main_add(klass, free, 0);
}
-/* Not really called, just used for the ptr... */
-static void
-_eo_class_isa_func(Eo *eo_id EINA_UNUSED, void *class_data EINA_UNUSED)
-{
- /* Do nonthing. */
-}
-
-static void
-_eo_class_isa_recursive_set(_Efl_Class *klass, const _Efl_Class *cur)
-{
- const _Efl_Class **extn_itr;
-
- _vtable_func_set(&klass->vtable, klass, NULL, cur->base_id + cur->ops_count,
- _eo_class_isa_func, EINA_TRUE);
-
- for (extn_itr = cur->extensions ; *extn_itr ; extn_itr++)
- {
- _eo_class_isa_recursive_set(klass, *extn_itr);
- }
-
- if (cur->parent)
- {
- _eo_class_isa_recursive_set(klass, cur->parent);
- }
-}
-
static inline void
_eo_classes_release(void)
{
@@ -1475,7 +1561,7 @@ _eo_classes_expand(void)
_eo_classes = (_Efl_Class **)ptr;
}
-EAPI const Efl_Class *
+EO_API const Efl_Class *
efl_class_new(const Efl_Class_Description *desc, const Efl_Class *parent_id, ...)
{
_Efl_Class *klass;
@@ -1635,7 +1721,9 @@ efl_class_new(const Efl_Class_Description *desc, const Efl_Class *parent_id, ...
mro = eina_list_remove(mro, NULL);
mro = eina_list_prepend(mro, klass);
if ((desc->type == EFL_CLASS_TYPE_MIXIN) && (desc->data_size > 0))
- mixins = eina_list_prepend(mixins, klass);
+ {
+ mixins = eina_list_prepend(mixins, klass);
+ }
/* Copy the extensions and free the list */
{
@@ -1665,7 +1753,9 @@ efl_class_new(const Efl_Class_Description *desc, const Efl_Class *parent_id, ...
size_t extn_data_off = klass->data_offset;
if (klass->desc->type != EFL_CLASS_TYPE_MIXIN)
+ {
extn_data_off += EO_ALIGN_SIZE(klass->desc->data_size);
+ }
/* Feed the mixins data offsets and free the mixins list. */
{
@@ -1710,12 +1800,6 @@ efl_class_new(const Efl_Class_Description *desc, const Efl_Class *parent_id, ...
efl_class_functions_set(_eo_class_id_get(klass), NULL, NULL);
}
- /* Mark which classes we implement */
- if (klass->vtable.size)
- {
- _eo_class_isa_recursive_set(klass, klass);
- }
-
_eo_class_constructor(klass);
DBG("Finished building class '%s'", klass->desc->name);
@@ -1723,7 +1807,7 @@ efl_class_new(const Efl_Class_Description *desc, const Efl_Class *parent_id, ...
return _eo_class_id_get(klass);
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
{
EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE);
@@ -1732,32 +1816,42 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
if (ops)
{
Eo_Vtable *vtable = obj->opt->vtable;
+ //copy all the vtable nodes that we are going to change later on
+ Eina_Bool *hitmap;
if (!vtable)
{
vtable = calloc(1, sizeof(*vtable));
- _vtable_init(vtable, obj->klass->vtable.size);
- _vtable_copy_all(vtable, &obj->klass->vtable);
+ _vtable_init_size(vtable, obj->klass->vtable.size);
+ _vtable_take_over(vtable, &obj->klass->vtable);
}
- if (!_eo_class_funcs_set(vtable, ops, obj->klass, klass, 0, EINA_TRUE))
+ hitmap = alloca(vtable->size * sizeof(Eina_Bool));
+ memset(hitmap, 0, vtable->size);
+
+ if (!_eo_class_funcs_set(vtable, ops, obj->klass, klass, EINA_TRUE, obj->klass->class_id, hitmap))
{
ERR("Failed to override functions for %s@%p. All previous "
"overrides have been reset.", obj->klass->desc->name, eo_id);
if (obj->opt->vtable == vtable)
- EO_OPTIONAL_COW_SET(obj, vtable, NULL);
+ {
+ EO_OPTIONAL_COW_SET(obj, vtable, NULL);
+ }
else
- _vtable_free(vtable);
+ {
+ _vtable_free(vtable, &obj->klass->vtable);
+ free(vtable);
+ }
+
goto err;
}
-
EO_OPTIONAL_COW_SET(obj, vtable, vtable);
}
else
{
if (obj->opt->vtable)
{
- _vtable_free(obj->opt->vtable);
+ _vtable_free(obj->opt->vtable, &obj->klass->vtable);
EO_OPTIONAL_COW_SET(obj, vtable, NULL);
}
}
@@ -1770,7 +1864,7 @@ err:
return EINA_FALSE;
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_isa(const Eo *eo_id, const Efl_Class *klass_id)
{
Efl_Id_Domain domain;
@@ -1791,10 +1885,10 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id)
EO_CLASS_POINTER_GOTO(klass_id, klass, err_class);
EO_CLASS_POINTER_GOTO(eo_id, lookinto, err_class0);
- const op_type_funcs *func = _vtable_func_get
- (&lookinto->vtable, klass->base_id + klass->ops_count);
+ if (EINA_UNLIKELY(lookinto->vtable.size <= klass->class_id))
+ return EINA_FALSE;
- return (func && (func->func == _eo_class_isa_func));;
+ return !!lookinto->vtable.chain[klass->class_id].funcs;
}
domain = ((Eo_Id)eo_id >> SHIFT_DOMAIN) & MASK_DOMAIN;
@@ -1813,15 +1907,17 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id)
EO_OBJ_POINTER_GOTO(eo_id, obj, err_obj);
EO_CLASS_POINTER_GOTO(klass_id, klass, err_class);
- const op_type_funcs *func = _vtable_func_get
- (EO_VTABLE(obj), klass->base_id + klass->ops_count);
+
+ const Eo_Vtable vtable = obj->klass->vtable;
+ if (EINA_UNLIKELY(vtable.size <= klass->class_id))
+ return EINA_FALSE;
+
+ isa = !!vtable.chain[klass->class_id].funcs;
// Caching the result as we do a lot of serial efl_isa due to evas_object_image using it.
tdata->cache.isa_id = eo_id;
tdata->cache.klass = klass_id;
- // Currently implemented by reusing the LAST op id. Just marking it with
- // _eo_class_isa_func.
- isa = tdata->cache.isa = (func && (func->func == _eo_class_isa_func));
+ tdata->cache.isa = isa;
}
else
{
@@ -1841,15 +1937,16 @@ efl_isa(const Eo *eo_id, const Efl_Class *klass_id)
EO_OBJ_POINTER_GOTO(eo_id, obj, err_shared_obj);
EO_CLASS_POINTER_GOTO(klass_id, klass, err_shared_class);
- const op_type_funcs *func = _vtable_func_get
- (EO_VTABLE(obj), klass->base_id + klass->ops_count);
+ if (EINA_UNLIKELY(obj->klass->vtable.size <= klass->class_id))
+ goto err_vtable;
+
+ isa = !!obj->klass->vtable.chain[klass->class_id].funcs;
// Caching the result as we do a lot of serial efl_isa due to evas_object_image using it.
tdata->cache.isa_id = eo_id;
tdata->cache.klass = klass_id;
- // Currently implemented by reusing the LAST op id. Just marking it with
- // _eo_class_isa_func.
- isa = tdata->cache.isa = (func && (func->func == _eo_class_isa_func));
+ tdata->cache.isa = isa;
+err_vtable:
EO_OBJ_DONE(eo_id);
eina_lock_release(&(_eo_table_data_shared_data->obj_lock));
}
@@ -1882,13 +1979,13 @@ err: EINA_COLD
return EINA_FALSE;
}
-EAPI Eo *
+EO_API Eo *
efl_xref_internal(const char *file, int line, Eo *obj_id, const Eo *ref_obj_id)
{
efl_ref(obj_id);
#ifdef EO_DEBUG
- const char *func_name = __FUNCTION__;
+ const char *func_name = __func__;
EO_OBJ_POINTER_RETURN_VAL_PROXY(obj_id, obj, obj_id);
Eo_Xref_Node *xref = calloc(1, sizeof(*xref));
@@ -1907,7 +2004,7 @@ efl_xref_internal(const char *file, int line, Eo *obj_id, const Eo *ref_obj_id)
return obj_id;
}
-EAPI void
+EO_API void
efl_xunref(Eo *obj_id, const Eo *ref_obj_id)
{
EO_OBJ_POINTER_RETURN(obj_id, obj);
@@ -1937,7 +2034,7 @@ efl_xunref(Eo *obj_id, const Eo *ref_obj_id)
efl_unref(obj_id);
}
-EAPI Eo *
+EO_API Eo *
efl_ref(const Eo *obj_id)
{
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, (Eo *)obj_id);
@@ -1955,7 +2052,7 @@ efl_ref(const Eo *obj_id)
return (Eo *)obj_id;
}
-EAPI void
+EO_API void
efl_unref(const Eo *obj_id)
{
EO_OBJ_POINTER_RETURN(obj_id, obj);
@@ -1999,7 +2096,7 @@ efl_unref(const Eo *obj_id)
{
ERR("Obj:%s@%p. User refcount (%d) < 0. Too many unrefs.",
obj->klass->desc->name, obj_id, obj->user_refcount);
- _eo_log_obj_report((Eo_Id)obj_id, EINA_LOG_LEVEL_ERR, __FUNCTION__, __FILE__, __LINE__);
+ _eo_log_obj_report((Eo_Id)obj_id, EINA_LOG_LEVEL_ERR, __func__, __FILE__, __LINE__);
EO_OBJ_DONE(obj_id);
_efl_unref(obj);
return;
@@ -2017,7 +2114,7 @@ efl_unref(const Eo *obj_id)
EO_OBJ_DONE(obj_id);
}
-EAPI int
+EO_API int
efl_ref_count(const Eo *obj_id)
{
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, 0);
@@ -2027,7 +2124,7 @@ efl_ref_count(const Eo *obj_id)
return ref;
}
-EAPI int
+EO_API int
___efl_ref2_count(const Eo *obj_id)
{
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, 0);
@@ -2037,7 +2134,7 @@ ___efl_ref2_count(const Eo *obj_id)
return ref;
}
-EAPI void
+EO_API void
___efl_ref2_reset(const Eo *obj_id)
{
EO_OBJ_POINTER_RETURN(obj_id, obj);
@@ -2046,7 +2143,7 @@ ___efl_ref2_reset(const Eo *obj_id)
}
-EAPI void
+EO_API void
efl_del_intercept_set(Eo *obj_id, Efl_Del_Intercept del_intercept_func)
{
EO_OBJ_POINTER_RETURN(obj_id, obj);
@@ -2054,7 +2151,7 @@ efl_del_intercept_set(Eo *obj_id, Efl_Del_Intercept del_intercept_func)
EO_OBJ_DONE(obj_id);
}
-EAPI Efl_Del_Intercept
+EO_API Efl_Del_Intercept
efl_del_intercept_get(const Eo *obj_id)
{
Efl_Del_Intercept func;
@@ -2185,7 +2282,7 @@ _efl_data_xunref_internal(_Eo_Object *obj EINA_UNUSED, void *data EINA_UNUSED, c
#endif
}
-EAPI void *
+EO_API void *
efl_data_scope_get(const Eo *obj_id, const Efl_Class *klass_id)
{
void *ret = NULL;
@@ -2213,7 +2310,7 @@ err_klass:
return ret;
}
-EAPI void *
+EO_API void *
efl_data_scope_safe_get(const Eo *obj_id, const Efl_Class *klass_id)
{
void *ret = NULL;
@@ -2238,12 +2335,12 @@ err_klass:
return ret;
}
-EAPI void *
+EO_API void *
efl_data_xref_internal(const char *file, int line, const Eo *obj_id, const Efl_Class *klass_id, const Eo *ref_obj_id)
{
void *ret = NULL;
_Efl_Class *klass = NULL;
- const char *func_name = __FUNCTION__;
+ const char *func_name = __func__;
EO_OBJ_POINTER_RETURN_VAL_PROXY(obj_id, obj, NULL);
EO_OBJ_POINTER_PROXY(ref_obj_id, ref_obj);
if (ref_obj)
@@ -2281,7 +2378,7 @@ err:
#endif
}
-EAPI void
+EO_API void
efl_data_xunref_internal(const Eo *obj_id, void *data, const Eo *ref_obj_id)
{
EO_OBJ_POINTER_RETURN(obj_id, obj);
@@ -2306,7 +2403,7 @@ _eo_table_del_cb(void *in)
* This is used by the gdb debug helper script */
Eo_Id_Data *_eo_gdb_main_domain = NULL;
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_object_init(void)
{
const char *log_dom = "eo";
@@ -2326,7 +2423,6 @@ efl_object_init(void)
_eo_classes = NULL;
_eo_classes_last_id = EO_CLASS_IDS_FIRST - 1;
- _eo_ops_last_id = EFL_OBJECT_OP_IDS_FIRST;
_eo_log_dom = eina_log_domain_register(log_dom, EINA_COLOR_LIGHTBLUE);
if (_eo_log_dom < 0)
{
@@ -2384,12 +2480,6 @@ efl_object_init(void)
eina_tls_set(_eo_table_data, data);
_efl_object_main_thread = eina_thread_self();
-#ifdef EO_DEBUG
- /* Call it just for coverage purposes. Ugly I know, but I like it better than
- * casting everywhere else. */
- _eo_class_isa_func(NULL, NULL);
-#endif
-
efl_object_optional_cow =
eina_cow_add("Efl Object Optional Data", sizeof(Efl_Object_Optional),
64, &efl_object_optional_cow_default, EINA_TRUE);
@@ -2401,14 +2491,14 @@ efl_object_init(void)
EINA_LOG_STATE_INIT);
/* bootstrap EFL_CLASS_CLASS */
- (void) EFL_CLASS_CLASS;
+ const Eo *efl_klass = EFL_CLASS_CLASS;
/* bootstrap EFL_OBJECT_CLASS */
- (void) EFL_OBJECT_CLASS;
+ const Eo *efl_object = EFL_OBJECT_CLASS;
- return EINA_TRUE;
+ return efl_klass && efl_object;
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_object_shutdown(void)
{
size_t i;
@@ -2479,21 +2569,21 @@ efl_object_shutdown(void)
}
-EAPI Efl_Id_Domain
+EO_API Efl_Id_Domain
efl_domain_get(void)
{
Eo_Id_Data *data = _eo_table_data_get();
return data->local_domain;
}
-EAPI Efl_Id_Domain
+EO_API Efl_Id_Domain
efl_domain_current_get(void)
{
Eo_Id_Data *data = _eo_table_data_get();
return data->domain_stack[data->stack_top];
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_domain_switch(Efl_Id_Domain domain)
{
Eo_Id_Data *data = _eo_table_data_get();
@@ -2540,21 +2630,21 @@ _efl_domain_pop(Eo_Id_Data *data)
if (data->stack_top > 0) data->stack_top--;
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_domain_current_push(Efl_Id_Domain domain)
{
Eo_Id_Data *data = _eo_table_data_get();
return _efl_domain_push(data, domain);
}
-EAPI void
+EO_API void
efl_domain_current_pop(void)
{
Eo_Id_Data *data = _eo_table_data_get();
_efl_domain_pop(data);
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_domain_current_set(Efl_Id_Domain domain)
{
Eo_Id_Data *data = _eo_table_data_get();
@@ -2567,14 +2657,14 @@ efl_domain_current_set(Efl_Id_Domain domain)
return EINA_TRUE;
}
-EAPI Efl_Domain_Data *
+EO_API Efl_Domain_Data *
efl_domain_data_get(void)
{
Eo_Id_Data *data = _eo_table_data_get();
return (Efl_Domain_Data *)data;
}
-EAPI Efl_Id_Domain
+EO_API Efl_Id_Domain
efl_domain_data_adopt(Efl_Domain_Data *data_in)
{
Eo_Id_Data *data = _eo_table_data_get();
@@ -2602,7 +2692,7 @@ efl_domain_data_adopt(Efl_Domain_Data *data_in)
return data->domain_stack[data->stack_top];
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_domain_data_return(Efl_Id_Domain domain)
{
Eo_Id_Data *data = _eo_table_data_get();
@@ -2622,7 +2712,7 @@ efl_domain_data_return(Efl_Id_Domain domain)
return EINA_TRUE;
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_compatible(const Eo *obj, const Eo *obj_target)
{
Efl_Id_Domain domain1 = ((Eo_Id)obj >> SHIFT_DOMAIN) & MASK_DOMAIN;
@@ -2633,7 +2723,7 @@ efl_compatible(const Eo *obj, const Eo *obj_target)
return EINA_FALSE;
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_class_override_register(const Efl_Class *klass, const Efl_Class *override)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(klass, EINA_FALSE);
@@ -2647,7 +2737,7 @@ efl_class_override_register(const Efl_Class *klass, const Efl_Class *override)
return EINA_TRUE;
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_class_override_unregister(const Efl_Class *klass, const Efl_Class *override)
{
const Efl_Class *set;
@@ -2660,7 +2750,7 @@ efl_class_override_unregister(const Efl_Class *klass, const Efl_Class *override)
return eina_hash_del_by_key(class_overrides, &klass);
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_destructed_is(const Eo *obj_id)
{
Eina_Bool is;
@@ -2670,7 +2760,7 @@ efl_destructed_is(const Eo *obj_id)
return is;
}
-EAPI void
+EO_API void
efl_manual_free_set(Eo *obj_id, Eina_Bool manual_free)
{
EO_OBJ_POINTER_RETURN(obj_id, obj);
@@ -2678,7 +2768,7 @@ efl_manual_free_set(Eo *obj_id, Eina_Bool manual_free)
EO_OBJ_DONE(obj_id);
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_manual_free(Eo *obj_id)
{
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE);
@@ -2702,7 +2792,7 @@ err:
return EINA_FALSE;
}
-EAPI const char *
+EO_API const char *
efl_debug_name_get(const Eo *obj_id)
{
const char *override = "";
@@ -2762,7 +2852,7 @@ efl_debug_name_get(const Eo *obj_id)
return eina_slstr_strbuf_new(sb);
}
-EAPI int
+EO_API int
efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_Array_Item *b)
{
if (a->desc == b->desc) return 0;
@@ -2892,7 +2982,7 @@ _eo_log_obj_entry_show(const Eo_Log_Obj_Entry *entry, int log_level, const char
entry->timestamp - _eo_log_time_start, now - entry->timestamp,
entry->bt_hits);
- // Skip EAPI and _eo_log_obj_ref_op()
+ // Skip EO_API and _eo_log_obj_ref_op()
for (i = 2; i < entry->bt_size; i++)
{
#ifdef HAVE_DLADDR
@@ -3390,7 +3480,7 @@ _eo_log_obj_shutdown(void)
entry->klass,
entry->klass->desc->name,
entry->timestamp - _eo_log_time_start, now - entry->timestamp);
- _eo_log_obj_entry_show(entry, EINA_LOG_LEVEL_DBG, __FUNCTION__, __FILE__, __LINE__, now);
+ _eo_log_obj_entry_show(entry, EINA_LOG_LEVEL_DBG, __func__, __FILE__, __LINE__, now);
leaks++;
}
}
@@ -3435,7 +3525,7 @@ _eo_classes_iterator_free(Eina_Iterator *it)
free(it);
}
-EAPI Eina_Iterator *
+EO_API Eina_Iterator *
eo_classes_iterator_new(void)
{
_Eo_Classes_Iterator *it;
@@ -3512,7 +3602,7 @@ _eo_objects_iterator_free(Eina_Iterator *it)
free(it);
}
-EAPI Eina_Iterator *
+EO_API Eina_Iterator *
eo_objects_iterator_new(void)
{
_Eo_Objects_Iterator *it;
@@ -3627,7 +3717,7 @@ static const Eina_Value_Type _EINA_VALUE_TYPE_OBJECT = {
.pget = _eo_value_pget
};
-EOAPI const Eina_Value_Type *EINA_VALUE_TYPE_OBJECT = &_EINA_VALUE_TYPE_OBJECT;
+EO_API const Eina_Value_Type *EINA_VALUE_TYPE_OBJECT = &_EINA_VALUE_TYPE_OBJECT;
static const Efl_Object_Property_Reflection*
_efl_class_reflection_find(const _Efl_Class *klass, const char *property_name)
@@ -3661,7 +3751,7 @@ _efl_class_reflection_find(const _Efl_Class *klass, const char *property_name)
return NULL;
}
-EAPI Eina_Error
+EO_API Eina_Error
efl_property_reflection_set(Eo *obj_id, const char *property_name, Eina_Value value)
{
Eina_Error r = EINA_ERROR_NOT_IMPLEMENTED;
@@ -3682,7 +3772,7 @@ efl_property_reflection_set(Eo *obj_id, const char *property_name, Eina_Value va
return r;
}
-EAPI Eina_Value
+EO_API Eina_Value
efl_property_reflection_get(const Eo *obj_id, const char *property_name)
{
Eina_Value r = eina_value_error_init(EINA_ERROR_NOT_IMPLEMENTED);
@@ -3699,7 +3789,7 @@ efl_property_reflection_get(const Eo *obj_id, const char *property_name)
return r;
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_property_reflection_exist(Eo *obj_id, const char *property_name)
{
Eina_Bool r = EINA_FALSE;
@@ -3712,7 +3802,7 @@ efl_property_reflection_exist(Eo *obj_id, const char *property_name)
return r;
}
-EAPI Efl_Class_Type
+EO_API Efl_Class_Type
efl_class_type_get(const Efl_Class *klass_id)
{
EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, EFL_CLASS_TYPE_INVALID);
@@ -3721,7 +3811,7 @@ efl_class_type_get(const Efl_Class *klass_id)
}
-EAPI Eina_Bool
+EO_API Eina_Bool
efl_ownable_get(const Eo *obj)
{
int ref = efl_ref_count(obj);