diff options
Diffstat (limited to 'src/lib/eo/eo.c')
-rw-r--r-- | src/lib/eo/eo.c | 780 |
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); |