eo2: add cur_klass in call Stack and eo2_do_super

in eo2_do_start(), reuse previous stack fetched pointers when possible
This commit is contained in:
Jérémy Zurcher 2013-07-24 22:10:26 +00:00 committed by Tom Hacohen
parent 68fb3d4c03
commit c17a30dfb9
2 changed files with 99 additions and 39 deletions

View File

@ -673,20 +673,29 @@ EAPI Eo_Op eo2_get_op_id(void *api_func, const Eo_Class *klass);
EAPI Eina_Bool eo2_call_resolve_internal(const Eo_Class *klass, Eo_Op op, Eo2_Op_Call_Data *call);
// start of eo2_do barrier, gets the object pointer and ref it, put it on the stask
EAPI Eina_Bool eo2_do_start(Eo *obj_id);
EAPI Eina_Bool eo2_do_start(Eo *obj_id, Eina_Bool do_super);
// end of the eo2_do barrier, unref the obj, move the stack pointer
EAPI void eo2_do_end();
// eo object method calls batch,
// DO NOT use return statement in it, use break if necessary
#define eo2_do(objid, ...) \
do \
{ \
Eo *_objid_ = objid; \
if (!eo2_do_start(_objid_)) break; \
do { __VA_ARGS__ ; } while (0); \
eo2_do_end(); \
#define eo2_do(objid, ...) \
do \
{ \
Eo *_objid_ = objid; \
if (!eo2_do_start(_objid_, EINA_FALSE)) break; \
do { __VA_ARGS__ ; } while (0); \
eo2_do_end(); \
} while (0)
#define eo2_do_super(objid, ...) \
do \
{ \
Eo *_objid_ = objid; \
if (!eo2_do_start(_objid_, EINA_TRUE)) break; \
do { __VA_ARGS__ ; } while (0); \
eo2_do_end(); \
} while (0)
// FIXME

View File

@ -257,14 +257,31 @@ _eo_kls_itr_func_get(const _Eo_Class *cur_klass, Eo_Op op)
/************************************ EO2 ************************************/
static inline const _Eo_Class *
_eo2_kls_itr_next(const _Eo_Class *orig_kls, const _Eo_Class *cur_klass)
{
const _Eo_Class **kls_itr = NULL;
/* Find the kls itr. */
kls_itr = orig_kls->mro;
while (*kls_itr && (*kls_itr != cur_klass))
kls_itr++;
if (*kls_itr)
return *(++kls_itr);
return NULL;
}
// FIXME: per thread stack, grow/shrink
#define EO2_INVALID_DATA (void *) -1
#define EO2_CALL_STACK_SIZE 5
typedef struct _Eo2_Stack_Frame
{
Eo *obj_id;
_Eo *obj;
void *obj_data;
Eo *obj_id;
_Eo *obj;
const _Eo_Class *cur_klass;
void *obj_data;
} Eo2_Stack_Frame;
@ -275,34 +292,59 @@ typedef struct _Eo2_Call_Stack {
static Eo2_Call_Stack eo2_call_stack = {
{
{ NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, NULL, EO2_INVALID_DATA },
{ NULL, NULL, NULL, EO2_INVALID_DATA },
},
NULL };
EAPI Eina_Bool
eo2_do_start(Eo *obj_id)
eo2_do_start(Eo *obj_id, Eina_Bool do_super)
{
EO_OBJ_POINTER_RETURN_VAL(obj_id, obj, EINA_FALSE);
_eo_ref(obj);
_Eo * obj;
const _Eo_Class *cur_klass;
Eo2_Stack_Frame *fptr;
if (eo2_call_stack.frame_ptr == NULL)
eo2_call_stack.frame_ptr = &eo2_call_stack.stack[0];
fptr = eo2_call_stack.frame_ptr;
if ((fptr != NULL) && (fptr->obj_id == obj_id))
{
obj = fptr->obj;
if (do_super)
cur_klass = _eo2_kls_itr_next(obj->klass, fptr->cur_klass);
else
cur_klass = fptr->cur_klass;
eo2_call_stack.frame_ptr++;
}
else
eo2_call_stack.frame_ptr++;
{
obj = _eo_obj_pointer_get((Eo_Id)obj_id);
if (!obj) return EINA_FALSE;
if (do_super)
cur_klass = _eo2_kls_itr_next(obj->klass, obj->klass);
else
cur_klass = obj->klass;
if (fptr == NULL)
eo2_call_stack.frame_ptr = &eo2_call_stack.stack[0];
else
eo2_call_stack.frame_ptr++;
}
if (eo2_call_stack.frame_ptr->obj_id != NULL)
ERR("eo2 call stack is not clear, you must have used a return statement in a eo2_do macro");
fptr = eo2_call_stack.frame_ptr;
if ((eo2_call_stack.frame_ptr - eo2_call_stack.stack) >= EO2_CALL_STACK_SIZE)
if ((fptr - eo2_call_stack.stack) >= EO2_CALL_STACK_SIZE)
ERR("eo2 call stack overflow !!!");
eo2_call_stack.frame_ptr->obj = obj;
eo2_call_stack.frame_ptr->obj_id = obj_id;
eo2_call_stack.frame_ptr->obj_data = EO2_INVALID_DATA;
if (fptr->obj_id != NULL)
ERR("eo2 call stack is not clear, you must have used a return statement in a eo2_do macro");
_eo_ref(obj);
fptr->obj = obj;
fptr->obj_id = obj_id;
fptr->cur_klass = cur_klass;
fptr->obj_data = EO2_INVALID_DATA;
return EINA_TRUE;
}
@ -310,13 +352,18 @@ eo2_do_start(Eo *obj_id)
EAPI void
eo2_do_end()
{
_eo_unref(eo2_call_stack.frame_ptr->obj);
Eo2_Stack_Frame *fptr;
eo2_call_stack.frame_ptr->obj = NULL;
eo2_call_stack.frame_ptr->obj_id = NULL;
eo2_call_stack.frame_ptr->obj_data = EO2_INVALID_DATA;
fptr = eo2_call_stack.frame_ptr;
if (eo2_call_stack.frame_ptr == &eo2_call_stack.stack[0])
_eo_unref(fptr->obj);
fptr->obj = NULL;
fptr->obj_id = NULL;
fptr->cur_klass = NULL;
fptr->obj_data = EO2_INVALID_DATA;
if (fptr == &eo2_call_stack.stack[0])
eo2_call_stack.frame_ptr = NULL;
else
eo2_call_stack.frame_ptr--;
@ -325,27 +372,31 @@ eo2_do_end()
EAPI Eina_Bool
eo2_call_resolve_internal(const Eo_Class *klass_id, Eo_Op op, Eo2_Op_Call_Data *call)
{
Eo2_Stack_Frame *fptr;
const _Eo * obj;
const _Eo_Class *klass;
const op_type_funcs *func;
const _Eo * obj = eo2_call_stack.frame_ptr->obj;
fptr = eo2_call_stack.frame_ptr;
obj = fptr->obj;
if (klass_id)
klass = _eo_class_pointer_get(klass_id);
else
klass = obj->klass;
klass = fptr->cur_klass;
func = _eo_kls_itr_func_get(klass, op);
if (EINA_LIKELY(func != NULL))
{
call->obj_id = eo2_call_stack.frame_ptr->obj_id;
call->obj_id = fptr->obj_id;
call->func = func->func;
if (func->src == obj->klass)
{
if (eo2_call_stack.frame_ptr->obj_data == EO2_INVALID_DATA)
eo2_call_stack.frame_ptr->obj_data = _eo_data_scope_get(obj, func->src);
if (fptr->obj_data == EO2_INVALID_DATA)
fptr->obj_data = _eo_data_scope_get(obj, func->src);
call->data = eo2_call_stack.frame_ptr->obj_data;
call->data = fptr->obj_data;
}
else
call->data = _eo_data_scope_get(obj, func->src);