eo2: rewrite eo2_do_start(...)

we need Eo_Class *cur_klass for eo2_do_super
 be sure not to update stack pointer before we can't fail anymore
This commit is contained in:
Jérémy Zurcher 2013-10-02 10:44:33 +02:00 committed by Tom Hacohen
parent 2be91e465a
commit 93f85f095e
2 changed files with 55 additions and 45 deletions

View File

@ -764,7 +764,7 @@ EAPI Eo_Op eo2_api_op_id_get(const void *api_func, const Eo_Op_Type);
EAPI Eina_Bool eo2_call_resolve_internal(const Eo_Class *klass, const Eo_Op op, Eo2_Op_Call_Data *call); EAPI Eina_Bool eo2_call_resolve_internal(const Eo_Class *klass, const 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 // 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, const Eina_Bool do_super, const char *file, const char *func, int line); EAPI Eina_Bool eo2_do_start(Eo *obj, const Eo_Class *cur_klass, const char *file, const char *func, int line);
EAPI Eina_Bool eo2_class_do_start(const Eo_Class *klass_id, const Eina_Bool do_super, const char *file, const char *func, int line); EAPI Eina_Bool eo2_class_do_start(const Eo_Class *klass_id, const Eina_Bool do_super, const char *file, const char *func, int line);
// end of the eo2_do barrier, unref the obj, move the stack pointer // end of the eo2_do barrier, unref the obj, move the stack pointer
@ -781,7 +781,7 @@ EAPI int eo2_call_stack_depth();
do \ do \
{ \ { \
Eo *_objid_ = objid; \ Eo *_objid_ = objid; \
if (eo2_do_start(_objid_, EINA_FALSE, __FILE__, __FUNCTION__, __LINE__)) \ if (eo2_do_start(_objid_, NULL, __FILE__, __FUNCTION__, __LINE__)) \
{ \ { \
Eo *_id_clean_ EO2_DO_CLEANUP = _objid_; \ Eo *_id_clean_ EO2_DO_CLEANUP = _objid_; \
__VA_ARGS__; \ __VA_ARGS__; \
@ -789,11 +789,11 @@ EAPI int eo2_call_stack_depth();
} \ } \
} while (0) } while (0)
#define eo2_do_super(objid, ...) \ #define eo2_do_super(objid, clsid, ...) \
do \ do \
{ \ { \
Eo *_objid_ = objid; \ Eo *_objid_ = objid; \
if (eo2_do_start(_objid_, EINA_TRUE, __FILE__, __FUNCTION__, __LINE__)) \ if (eo2_do_start(_objid_, clsid, __FILE__, __FUNCTION__, __LINE__)) \
{ \ { \
Eo *_id_clean_ EO2_DO_CLEANUP = _objid_; \ Eo *_id_clean_ EO2_DO_CLEANUP = _objid_; \
__VA_ARGS__; \ __VA_ARGS__; \

View File

@ -282,8 +282,8 @@ _eo2_kls_itr_next(const _Eo_Class *orig_kls, const _Eo_Class *cur_klass)
typedef struct _Eo2_Stack_Frame typedef struct _Eo2_Stack_Frame
{ {
Eo *eo_id; Eo *eo_id;
_Eo_Object *obj; Eo_Base *base;
const _Eo_Class *klass; const _Eo_Class *cur_klass;
void *obj_data; void *obj_data;
} Eo2_Stack_Frame; } Eo2_Stack_Frame;
@ -313,48 +313,58 @@ eo2_call_stack_depth()
} }
EAPI Eina_Bool EAPI Eina_Bool
eo2_do_start(Eo *eo_id, const Eina_Bool do_super, const char *file EINA_UNUSED, const char *func EINA_UNUSED, int line EINA_UNUSED) eo2_do_start(Eo *eo_id, const Eo_Class *cur_klass_id, const char *file EINA_UNUSED, const char *func EINA_UNUSED, int line EINA_UNUSED)
{ {
_Eo_Object * obj; _Eo_Object *obj;
const _Eo_Class *klass; const _Eo_Class *klass;
Eo2_Stack_Frame *fptr; Eo2_Stack_Frame *fptr, *nfptr;
Eina_Bool empty_stack = (eo2_call_stack.frame_ptr == NULL);
fptr = eo2_call_stack.frame_ptr; fptr = eo2_call_stack.frame_ptr;
if ((fptr != NULL) && (fptr->eo_id == eo_id)) if (((fptr - eo2_call_stack.stack) + 1) >= EO2_CALL_STACK_DEPTH)
{ {
obj = fptr->obj; ERR("eo2 call stack overflow !!!");
if (do_super) return EINA_FALSE;
klass = _eo2_kls_itr_next(obj->klass, fptr->klass); }
else
klass = fptr->klass; if (empty_stack)
eo2_call_stack.frame_ptr++; nfptr = &eo2_call_stack.stack[0];
else
nfptr = fptr + 1;
if ((!empty_stack) && (fptr->eo_id == eo_id))
{
obj = (_Eo_Object *)fptr->base;
memcpy(nfptr, fptr, sizeof(Eo2_Stack_Frame));
} }
else else
{ {
EO_OBJ_POINTER_RETURN_VAL(eo_id, _obj, EINA_FALSE); EO_OBJ_POINTER_RETURN_VAL(eo_id, _obj, EINA_FALSE);
obj = _obj; obj = _obj;
if (!obj) return EINA_FALSE; nfptr->base = (Eo_Base *)_obj;
if (do_super) nfptr->eo_id = eo_id;
klass = _eo2_kls_itr_next(obj->klass, obj->klass);
else
klass = obj->klass;
if (fptr == NULL)
eo2_call_stack.frame_ptr = &eo2_call_stack.stack[0];
else
eo2_call_stack.frame_ptr++;
} }
fptr = eo2_call_stack.frame_ptr; if (cur_klass_id)
{
EO_CLASS_POINTER_RETURN_VAL(cur_klass_id, cur_klass, EINA_FALSE);
klass = _eo2_kls_itr_next(obj->klass, cur_klass);
}
else
klass = obj->klass;
if ((fptr - eo2_call_stack.stack) >= EO2_CALL_STACK_DEPTH) if (klass != nfptr->cur_klass)
ERR("eo2 call stack overflow !!!"); {
nfptr->cur_klass = klass;
nfptr->obj_data = EO2_INVALID_DATA;
}
_eo_ref(obj); _eo_ref(obj);
fptr->obj = obj; if (empty_stack)
fptr->eo_id = eo_id; eo2_call_stack.frame_ptr = &eo2_call_stack.stack[0];
fptr->klass = klass; else
fptr->obj_data = EO2_INVALID_DATA; eo2_call_stack.frame_ptr++;
return EINA_TRUE; return EINA_TRUE;
} }
@ -368,12 +378,12 @@ eo2_class_do_start(const Eo_Class *klass_id, const Eina_Bool do_super, const cha
klass = NULL; klass = NULL;
fptr = eo2_call_stack.frame_ptr; fptr = eo2_call_stack.frame_ptr;
if ((fptr != NULL) && (_eo_class_id_get(fptr->klass) == (Eo *)klass_id)) if ((fptr != NULL) && (_eo_class_id_get(fptr->cur_klass) == (Eo *)klass_id))
{ {
if (do_super) if (do_super)
klass = _eo2_kls_itr_next(fptr->klass, fptr->klass); klass = _eo2_kls_itr_next(fptr->cur_klass, fptr->cur_klass);
else else
klass = fptr->klass; klass = fptr->cur_klass;
eo2_call_stack.frame_ptr++; eo2_call_stack.frame_ptr++;
} }
else else
@ -394,9 +404,9 @@ eo2_class_do_start(const Eo_Class *klass_id, const Eina_Bool do_super, const cha
if ((fptr - eo2_call_stack.stack) >= EO2_CALL_STACK_DEPTH) if ((fptr - eo2_call_stack.stack) >= EO2_CALL_STACK_DEPTH)
ERR("eo2 call stack overflow !!!"); ERR("eo2 call stack overflow !!!");
fptr->obj = NULL; fptr->base = NULL;
fptr->eo_id = NULL; fptr->eo_id = NULL;
fptr->klass = klass; fptr->cur_klass = klass;
fptr->obj_data = EO2_INVALID_DATA; fptr->obj_data = EO2_INVALID_DATA;
return EINA_TRUE; return EINA_TRUE;
@ -410,7 +420,7 @@ _eo2_do_end(const Eina_Bool obj_do)
fptr = eo2_call_stack.frame_ptr; fptr = eo2_call_stack.frame_ptr;
if(obj_do) if(obj_do)
_eo_unref(fptr->obj); _eo_unref((_Eo_Object *)fptr->base);
memset(fptr, 0, sizeof (Eo2_Stack_Frame)); memset(fptr, 0, sizeof (Eo2_Stack_Frame));
fptr->obj_data = EO2_INVALID_DATA; fptr->obj_data = EO2_INVALID_DATA;
@ -442,7 +452,7 @@ eo2_call_resolve_internal(const Eo_Class *klass_id, const Eo_Op op, Eo2_Op_Call_
const op_type_funcs *func; const op_type_funcs *func;
fptr = eo2_call_stack.frame_ptr; fptr = eo2_call_stack.frame_ptr;
obj = fptr->obj; obj = (_Eo_Object *)fptr->base;
klass = NULL; klass = NULL;
if (klass_id) if (klass_id)
@ -452,7 +462,7 @@ eo2_call_resolve_internal(const Eo_Class *klass_id, const Eo_Op op, Eo2_Op_Call_
} }
else else
{ {
klass = fptr->klass; klass = fptr->cur_klass;
if (!klass) if (!klass)
return EINA_FALSE; return EINA_FALSE;
} }
@ -536,9 +546,9 @@ eo2_api_op_id_get(const void *api_func, const Eo_Op_Type op_type)
const _Eo_Class *klass; const _Eo_Class *klass;
if (op_type == EO_OP_TYPE_REGULAR) if (op_type == EO_OP_TYPE_REGULAR)
klass = eo2_call_stack.frame_ptr->obj->klass; klass = ((_Eo_Object *)eo2_call_stack.frame_ptr->base)->klass;
else if (op_type == EO_OP_TYPE_CLASS) else if (op_type == EO_OP_TYPE_CLASS)
klass = eo2_call_stack.frame_ptr->klass; klass = eo2_call_stack.frame_ptr->cur_klass;
else else
{ {
ERR("api func %p, unknown op type %d", api_func, op_type); ERR("api func %p, unknown op type %d", api_func, op_type);
@ -671,12 +681,12 @@ eo2_add_internal_end(const char *file, int line, const Eo *eo_id)
return NULL; return NULL;
} }
if (!fptr->obj->condtor_done) if (!((_Eo_Object *)fptr->base)->condtor_done)
{ {
ERR("in %s:%d: Object of class '%s' - Not all of the object constructors have been executed.", ERR("in %s:%d: Object of class '%s' - Not all of the object constructors have been executed.",
file, line, fptr->klass->desc->name); file, line, fptr->cur_klass->desc->name);
/* for the for the basic object ref. */ /* for the for the basic object ref. */
_eo_unref(fptr->obj); _eo_unref((_Eo_Object *)fptr->base);
return NULL; return NULL;
} }