tasn pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=fc88037977dcc39dfd6d817c522cce01f5bfa024

commit fc88037977dcc39dfd6d817c522cce01f5bfa024
Author: Tom Hacohen <t...@stosb.com>
Date:   Mon Nov 9 11:45:04 2015 +0000

    Eo: Migrate to the new syntax (Eo 4).
    
    The syntax is described in: https://phab.enlightenment.org/w/eo/
    
    Summary:
    eo_do(obj, a_set(1)) -> a_set(obj, 1)
    eo_do_super(obj, CLASS, a_set(1)) -> a_set(eo_super(obj, CLASS), 1)
    
    eo_do_*_ret() set of functions are no longer needed.
    
    This is the first step, the next step would be to also fix up eo_add()
    which currently still uses the old syntax and is not 100% portable.
    
    @feature
---
 src/lib/eo/Eo.h                 | 136 +++++--------
 src/lib/eo/eo.c                 | 422 ++++++++--------------------------------
 src/lib/eo/eo_private.h         |   7 +-
 src/lib/eo/eo_ptr_indirection.x |  21 +-
 4 files changed, 154 insertions(+), 432 deletions(-)

diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index cfabd74..a0b817c 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -99,6 +99,8 @@ extern "C" {
  * @{
  */
 
+typedef struct _Eo_Object _Eo_Object;
+
 /**
  * @typedef Eo
  * The basic Object type.
@@ -452,7 +454,8 @@ EAPI Eina_Bool eo_shutdown(void);
 // to fetch internal function and object data at once
 typedef struct _Eo_Op_Call_Data
 {
-   Eo       *obj;
+   Eo *eo_id;
+   _Eo_Object *obj;
    void     *func;
    void     *data;
 } Eo_Op_Call_Data;
@@ -497,7 +500,7 @@ typedef struct _Eo_Call_Cache
 #endif
 
 // cache OP id, get real fct and object data then do the call
-#define EO_FUNC_COMMON_OP(Name, DefRet)                                 \
+#define EO_FUNC_COMMON_OP(Obj, Name, DefRet)                                 \
      static Eo_Call_Cache ___cache; /* static 0 by default */           \
      Eo_Op_Call_Data ___call;                                           \
      if (EINA_UNLIKELY(___cache.op == EO_NOOP))                         \
@@ -505,51 +508,65 @@ typedef struct _Eo_Call_Cache
           ___cache.op = _eo_api_op_id_get(EO_FUNC_COMMON_OP_FUNC(Name)); \
           if (___cache.op == EO_NOOP) return DefRet;                    \
        }                                                                \
-     if (!_eo_call_resolve(#Name, &___call, &___cache,                  \
+     if (!_eo_call_resolve((Eo *) Obj, #Name, &___call, &___cache,             
     \
                            __FILE__, __LINE__)) return DefRet;          \
      _Eo_##Name##_func _func_ = (_Eo_##Name##_func) ___call.func;       \
 
 // to define an EAPI function
-#define EO_FUNC_BODY(Name, Ret, DefRet)                                 \
+#define _EO_FUNC_BODY(Name, ObjType, Ret, DefRet)                              
   \
   Ret                                                                   \
-  Name(void)                                                            \
+  Name(ObjType obj)                                                            
\
   {                                                                     \
      typedef Ret (*_Eo_##Name##_func)(Eo *, void *obj_data);            \
      Ret _r;                                                            \
-     EO_FUNC_COMMON_OP(Name, DefRet);                                   \
-     _r = _func_(___call.obj, ___call.data);                            \
+     EO_FUNC_COMMON_OP(obj, Name, DefRet);                                   \
+     _r = _func_(___call.eo_id, ___call.data);                            \
+     _eo_call_end(&___call); \
      return _r;                                                         \
   }
 
-#define EO_VOID_FUNC_BODY(Name)                                        \
+#define _EO_VOID_FUNC_BODY(Name, ObjType)                                      
\
   void                                                                 \
-  Name(void)                                                            \
+  Name(ObjType obj)                                                            
\
   {                                                                     \
      typedef void (*_Eo_##Name##_func)(Eo *, void *obj_data);           \
-     EO_FUNC_COMMON_OP(Name, );                                         \
-     _func_(___call.obj, ___call.data);                                 \
+     EO_FUNC_COMMON_OP(obj, Name, );                                         \
+     _func_(___call.eo_id, ___call.data);                                 \
+     _eo_call_end(&___call); \
   }
 
-#define EO_FUNC_BODYV(Name, Ret, DefRet, Arguments, ...)                \
+#define _EO_FUNC_BODYV(Name, ObjType, Ret, DefRet, Arguments, ...)             
   \
   Ret                                                                   \
-  Name(__VA_ARGS__)                                                     \
+  Name(ObjType obj, __VA_ARGS__)                                               
      \
   {                                                                     \
      typedef Ret (*_Eo_##Name##_func)(Eo *, void *obj_data, __VA_ARGS__); \
      Ret _r;                                                            \
-     EO_FUNC_COMMON_OP(Name, DefRet);                                   \
-     _r = _func_(___call.obj, ___call.data, Arguments);                 \
+     EO_FUNC_COMMON_OP(obj, Name, DefRet);                                   \
+     _r = _func_(___call.eo_id, ___call.data, Arguments);                 \
+     _eo_call_end(&___call); \
      return _r;                                                         \
   }
 
-#define EO_VOID_FUNC_BODYV(Name, Arguments, ...)                        \
+#define _EO_VOID_FUNC_BODYV(Name, ObjType, Arguments, ...)                     
   \
   void                                                                  \
-  Name(__VA_ARGS__)                                                     \
+  Name(ObjType obj, __VA_ARGS__)                                               
      \
   {                                                                     \
      typedef void (*_Eo_##Name##_func)(Eo *, void *obj_data, __VA_ARGS__); \
-     EO_FUNC_COMMON_OP(Name, );                                         \
-     _func_(___call.obj, ___call.data, Arguments);                      \
+     EO_FUNC_COMMON_OP(obj, Name, );                                         \
+     _func_(___call.eo_id, ___call.data, Arguments);                      \
+     _eo_call_end(&___call); \
   }
 
+#define EO_FUNC_BODY(Name, Ret, DefRet) _EO_FUNC_BODY(Name, Eo *, Ret, DefRet)
+#define EO_VOID_FUNC_BODY(Name) _EO_VOID_FUNC_BODY(Name, Eo *)
+#define EO_FUNC_BODYV(Name, Ret, DefRet, Arguments, ...) _EO_FUNC_BODYV(Name, 
Eo *, Ret, DefRet, EO_FUNC_CALL(Arguments), __VA_ARGS__)
+#define EO_VOID_FUNC_BODYV(Name, Arguments, ...) _EO_VOID_FUNC_BODYV(Name, Eo 
*, EO_FUNC_CALL(Arguments), __VA_ARGS__)
+
+#define EO_FUNC_BODY_CONST(Name, Ret, DefRet) _EO_FUNC_BODY(Name, const Eo *, 
Ret, DefRet)
+#define EO_VOID_FUNC_BODY_CONST(Name) _EO_VOID_FUNC_BODY(Name, const Eo *)
+#define EO_FUNC_BODYV_CONST(Name, Ret, DefRet, Arguments, ...) 
_EO_FUNC_BODYV(Name, const Eo *, Ret, DefRet, EO_FUNC_CALL(Arguments), 
__VA_ARGS__)
+#define EO_VOID_FUNC_BODYV_CONST(Name, Arguments, ...) 
_EO_VOID_FUNC_BODYV(Name, const Eo *, EO_FUNC_CALL(Arguments), __VA_ARGS__)
+
 #ifndef _WIN32
 # define _EO_OP_API_ENTRY(a) (void*)a
 #else
@@ -565,52 +582,15 @@ typedef struct _Eo_Call_Cache
 EAPI Eo_Op _eo_api_op_id_get(const void *api_func);
 
 // gets the real function pointer and the object data
-EAPI Eina_Bool _eo_call_resolve(const char *func_name, Eo_Op_Call_Data *call, 
Eo_Call_Cache *callcache, const char *file, int line);
+EAPI Eina_Bool _eo_call_resolve(Eo *obj, const char *func_name, 
Eo_Op_Call_Data *call, Eo_Call_Cache *callcache, const char *file, int line);
 
-// start of eo_do barrier, gets the object pointer and ref it, put it on the 
stask
-EAPI Eina_Bool _eo_do_start(const Eo *obj, const Eo_Class *cur_klass, 
Eina_Bool is_super, void *eo_stack);
-
-// end of the eo_do barrier, unref the obj, move the stack pointer
-EAPI void _eo_do_end(void *eo_stack);
+// end of the eo call barrier, unref the obj
+EAPI void _eo_call_end(Eo_Op_Call_Data *call);
 
 // end of the eo_add. Calls finalize among others
-EAPI Eo * _eo_add_end(void *eo_stack);
-
-// XXX: We cheat and make it const to indicate to the compiler that the value 
never changes
-EAPI EINA_CONST void *_eo_stack_get(void);
-
-// eo object method calls batch,
-
-#define _eo_do_common(eoid, clsid, is_super, ...)                       \
-  do {                                                                  \
-       _eo_do_start(eoid, clsid, is_super, _eo_stack_get()); \
-       __VA_ARGS__;                                                     \
-       _eo_do_end(_eo_stack_get());                                            
        \
-  } while (0)
+EAPI Eo * _eo_add_end(Eo *obj);
 
-#define _eo_do_common_ret(eoid, clsid, is_super, ret_tmp, func)      \
-  (                                                                     \
-       _eo_do_start(eoid, clsid, is_super, _eo_stack_get()), \
-       ret_tmp = func,                                                  \
-       _eo_do_end(_eo_stack_get()),                                            
        \
-       ret_tmp                                                          \
-  )
-
-
-#define eo_do(eoid, ...) _eo_do_common(eoid, NULL, EINA_FALSE, __VA_ARGS__)
-
-#define eo_do_super(eoid, clsid, func) _eo_do_common(eoid, clsid, EINA_TRUE, 
func)
-
-#define eo_do_ret(eoid, ret_tmp, func) _eo_do_common_ret(eoid, NULL, 
EINA_FALSE, ret_tmp, func)
-
-#define eo_do_super_ret(eoid, clsid, ret_tmp, func) _eo_do_common_ret(eoid, 
clsid, EINA_TRUE, ret_tmp, func)
-
-#define eo_do_part(eoid, part_func, ...) \
-  do { \
-       Eo *__eo_part = eoid; \
-       eo_do(eoid, __eo_part = part_func); \
-       eo_do(__eo_part, __VA_ARGS__); \
-  } while (0)
+EAPI Eo *eo_super(const Eo *obj, const Eo_Class *cur_klass);
 
 /*****************************************************************************/
 
@@ -624,12 +604,11 @@ EAPI EINA_CONST void *_eo_stack_get(void);
 EAPI const Eo_Class *eo_class_get(const Eo *obj);
 
 #define _eo_add_common(klass, parent, is_ref, ...) \
-   ( \
-     _eo_do_start(_eo_add_internal_start(__FILE__, __LINE__, klass, parent, 
is_ref), \
-        klass, EINA_FALSE, _eo_stack_get()) \
-     , ##__VA_ARGS__, \
-     (Eo *) _eo_add_end(_eo_stack_get()) \
-   )
+   ({ \
+     Eo * const eoid = _eo_add_internal_start(__FILE__, __LINE__, klass, 
parent, is_ref); \
+     __VA_ARGS__; \
+     (Eo *) _eo_add_end(eoid); \
+    })
 
 /**
  * @def eo_add
@@ -900,16 +879,12 @@ typedef void (*eo_key_data_free_func)(void *);
  * @brief Reference a pointer to an Eo object
  * @param wref the pointer to use for the weak ref
  *
- * Same as eo_wref_add() with the difference that it call eo_do() itself. 
Checking
- * for *wref NULL and making sure that you pass the right pointer to both side 
of
- * eo_do().
- *
  * @see eo_weak_unref
  * @see eo_wref_add
  */
 #define eo_weak_ref(wref)                         \
   do {                                            \
-    if (*wref) eo_do(*wref, eo_wref_add(wref));  \
+    if (*wref) eo_wref_add(*wref, wref);  \
   } while (0)
 
 /**
@@ -917,17 +892,13 @@ typedef void (*eo_key_data_free_func)(void *);
  * @brief Unreference a pointer to an Eo object
  * @param wref the pointer to use for the weak unref
  *
- * Same as eo_wref_del() with the difference that it call eo_do() itself. 
Checking
- * for *wref NULL and making sure that you pass the right pointer to both side 
of
- * eo_do().
- *
  * @see eo_weak_ref
  * @see eo_wref_del
  * @see eo_wref_del_safe
  */
 #define eo_weak_unref(wref)                       \
   do {                                            \
-    if (*wref) eo_do(*wref, eo_wref_del(wref));  \
+    if (*wref) eo_wref_del(*wref, wref);  \
   } while (0)
 
 /**
@@ -935,9 +906,6 @@ typedef void (*eo_key_data_free_func)(void *);
  * @brief Delete the weak reference passed.
  * @param wref the weak reference to free.
  *
- * Same as eo_wref_del(), with the different that it's not called from eo_do()
- * so you don't need to check if *wref is not NULL.
- *
  * @see #eo_wref_del
  */
 #define eo_wref_del_safe(wref) eo_weak_unref(wref)
@@ -1018,8 +986,8 @@ EAPI const Eo_Event_Description 
*eo_base_legacy_only_event_description_get(const
  *
  * @see eo_event_callback_priority_add()
  */
-#define eo_event_callback_add(desc, cb, data) \
-   eo_event_callback_priority_add(desc, \
+#define eo_event_callback_add(obj, desc, cb, data) \
+   eo_event_callback_priority_add(obj, desc, \
          EO_CALLBACK_PRIORITY_DEFAULT, cb, data)
 
 /**
@@ -1032,8 +1000,8 @@ EAPI const Eo_Event_Description 
*eo_base_legacy_only_event_description_get(const
  *
  * @see eo_event_callback_array_priority_add()
  */
-#define eo_event_callback_array_add(array, data) \
-   eo_event_callback_array_priority_add(array, \
+#define eo_event_callback_array_add(obj, array, data) \
+   eo_event_callback_array_priority_add(obj, array, \
          EO_CALLBACK_PRIORITY_DEFAULT, data)
 
 /**
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index 6baa7e9..7408f41 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -249,288 +249,69 @@ _eo_kls_itr_next(const _Eo_Class *orig_kls, const 
_Eo_Class *cur_klass, Eo_Op op
 
 /************************************ EO ************************************/
 
-// 1024 entries == 16k or 32k (32 or 64bit) for eo call stack. that's 1023
-// imbricated/recursive calls it can handle before barfing. i'd say that's ok
-#define EO_CALL_STACK_DEPTH_MIN 1024
-#define EO_CALL_STACK_SHRINK_DROP (EO_CALL_STACK_DEPTH_MIN >> 1)
+static const Eo_Class *_super_class = NULL;
+static Eina_Spinlock _super_class_lock;
 
-typedef struct _Eo_Stack_Frame
+EAPI Eo *
+eo_super(const Eo *obj, const Eo_Class *cur_klass)
 {
-   union {
-        _Eo_Object        *obj;
-        const _Eo_Class   *kls;
-   } o;
-   const _Eo_Class   *cur_klass;
-   Eina_Bool is_obj : 1;
-} Eo_Stack_Frame;
-
-#define EO_CALL_STACK_SIZE (EO_CALL_STACK_DEPTH_MIN * sizeof(Eo_Stack_Frame))
-
-static Eina_TLS _eo_call_stack_key = 0;
+   /* FIXME: Switch to atomic operations intead of lock. */
+   eina_spinlock_take(&_super_class_lock);
+   _super_class = cur_klass;
 
-typedef struct _Eo_Call_Stack {
-   Eo_Stack_Frame *frames;
-   Eo_Stack_Frame *frame_ptr;
-   Eo_Stack_Frame *last_frame;
-   Eo_Stack_Frame *shrink_frame;
-} Eo_Call_Stack;
-
-#define MEM_PAGE_SIZE 4096
-
-static void *
-_eo_call_stack_mem_alloc(size_t size)
-{
-#ifdef HAVE_MMAP
-   // allocate eo call stack via mmped anon segment if on linux - more
-   // secure and safe. also gives page aligned memory allowing madvise
-   void *ptr;
-   size_t newsize;
-   newsize = MEM_PAGE_SIZE * ((size + MEM_PAGE_SIZE - 1) /
-                              MEM_PAGE_SIZE);
-   ptr = mmap(NULL, newsize, PROT_READ | PROT_WRITE,
-              MAP_PRIVATE | MAP_ANON, -1, 0);
-   if (ptr == MAP_FAILED)
-     {
-        ERR("eo call stack mmap failed.");
-        return NULL;
-     }
-   return ptr;
-#else
-   //in regular cases just use malloc
-   return calloc(1, size);
-#endif
+   return (Eo *) ((Eo_Id) obj | MASK_SUPER_TAG);
 }
 
-#ifdef HAVE_MMAP
-static void
-_eo_call_stack_mem_resize(void **ptr EINA_UNUSED, size_t newsize, size_t size)
-{
-   if (newsize > size)
-     {
-        CRI("eo call stack overflow, abort.");
-        abort();
-     }
-   return; // Do nothing, code for actual implementation in history. See 
commit message for details.
-#else
-static void
-_eo_call_stack_mem_resize(void **ptr, size_t newsize, size_t size EINA_UNUSED)
-{
-   *ptr = realloc(*ptr, newsize);
-   if (!*ptr)
-     {
-        CRI("eo call stack resize failed, abort.");
-        abort();
-     }
-#endif
-}
-
-#ifdef HAVE_MMAP
-static void
-_eo_call_stack_mem_free(void *ptr, size_t size)
-{
-   // free mmaped memory
-   munmap(ptr, size);
-#else
-static void
-_eo_call_stack_mem_free(void *ptr, size_t size EINA_UNUSED)
-{
-   // free regular memory
-   free(ptr);
-#endif
-}
-
-static Eo_Call_Stack *
-_eo_call_stack_create()
+EAPI Eina_Bool
+_eo_call_resolve(Eo *eo_id, const char *func_name, Eo_Op_Call_Data *call, 
Eo_Call_Cache *cache, const char *file, int line)
 {
-   Eo_Call_Stack *stack;
-
-   stack = calloc(1, sizeof(Eo_Call_Stack));
-   if (!stack)
-     return NULL;
+   const _Eo_Class *klass, *inputklass, *main_klass;
+   const _Eo_Class *cur_klass = NULL;
+   _Eo_Object *obj = NULL;
+   const op_type_funcs *func;
+   Eina_Bool is_obj;
 
-   stack->frames = _eo_call_stack_mem_alloc(EO_CALL_STACK_SIZE);
-   if (!stack->frames)
+   if (((Eo_Id) eo_id) & MASK_SUPER_TAG)
      {
-        free(stack);
-        return NULL;
-     }
+        const Eo_Class *tmp = _super_class;
+        _super_class = NULL;
+        eina_spinlock_release(&_super_class_lock);
 
-   // first frame is never used
-   stack->frame_ptr = stack->frames;
-   stack->last_frame = &stack->frames[EO_CALL_STACK_DEPTH_MIN - 1];
-   stack->shrink_frame = stack->frames;
-
-   return stack;
-}
-
-static void
-_eo_call_stack_free(void *ptr)
-{
-   Eo_Call_Stack *stack = (Eo_Call_Stack *) ptr;
+        eo_id = (Eo *) ((Eo_Id) eo_id & ~MASK_SUPER_TAG);
 
-   if (!stack) return;
-
-   if (stack->frames)
-     _eo_call_stack_mem_free(stack->frames, EO_CALL_STACK_SIZE);
-
-   free(stack);
-}
-
-#ifdef HAVE_THREAD_SPECIFIER
-static __thread Eo_Call_Stack *_eo_thread_stack = NULL;
-
-#define _EO_CALL_STACK_GET() ((_eo_thread_stack) ? _eo_thread_stack : 
(_eo_thread_stack = _eo_call_stack_create()))
-
-#else
-
-static Eo_Call_Stack *main_loop_stack = NULL;
-
-#define _EO_CALL_STACK_GET() ((EINA_LIKELY(eina_main_loop_is())) ? 
main_loop_stack : _eo_call_stack_get_thread())
-
-static inline Eo_Call_Stack *
-_eo_call_stack_get_thread(void)
-{
-   Eo_Call_Stack *stack = eina_tls_get(_eo_call_stack_key);
-
-   if (stack) return stack;
-
-   stack = _eo_call_stack_create();
-   eina_tls_set(_eo_call_stack_key, stack);
-
-   return stack;
-}
-#endif
-
-EAPI EINA_CONST void *
-_eo_stack_get(void)
-{
-   return _EO_CALL_STACK_GET();
-}
-
-static inline void
-_eo_call_stack_resize(Eo_Call_Stack *stack, Eina_Bool grow)
-{
-   size_t sz, next_sz;
-   int frame_offset;
-
-   sz = stack->last_frame - stack->frames + 1;
-   if (grow)
-     next_sz = sz * 2;
-   else
-     next_sz = sz / 2;
-   frame_offset = stack->frame_ptr - stack->frames;
-
-   _eo_call_stack_mem_resize((void **)&(stack->frames),
-                             next_sz * sizeof(Eo_Stack_Frame),
-                             sz * sizeof(Eo_Stack_Frame));
+        cur_klass = _eo_class_pointer_get(tmp);
+        if (!cur_klass)
+          {
+             ERR("Invalid super class found. Aborting.");
+             return EINA_FALSE;
+          }
+     }
 
-   stack->frame_ptr = &stack->frames[frame_offset];
-   stack->last_frame = &stack->frames[next_sz - 1];
+   if (EINA_UNLIKELY(!eo_id))
+      return EINA_FALSE;
 
-   if (next_sz == EO_CALL_STACK_DEPTH_MIN)
-     frame_offset = 0;
-   else
-     {
-        if (grow)
-          frame_offset = sz - EO_CALL_STACK_SHRINK_DROP;
-        else
-          frame_offset = (next_sz / 2) - EO_CALL_STACK_SHRINK_DROP;
-     }
-   stack->shrink_frame = &stack->frames[frame_offset];
-}
+   call->eo_id = eo_id;
 
-static inline Eina_Bool
-_eo_do_internal(const Eo *eo_id, const Eo_Class *cur_klass_id,
-                Eina_Bool is_super, Eo_Stack_Frame *fptr)
-{
-   fptr->is_obj = _eo_is_a_obj(eo_id);
+   is_obj = _eo_is_a_obj(eo_id);
 
-   /* If we are already in the same object context, we inherit info from it. */
-   if (fptr->is_obj)
+   if (is_obj)
      {
         EO_OBJ_POINTER_RETURN_VAL(eo_id, _obj, EINA_FALSE);
-        fptr->o.obj = _obj;
+        obj = _obj;
+        klass = _obj->klass;
+        call->obj = obj;
         _eo_ref(_obj);
      }
    else
      {
         EO_CLASS_POINTER_RETURN_VAL(eo_id, _klass, EINA_FALSE);
-        fptr->o.kls = _klass;
-     }
-
-   if (is_super)
-     {
-        EO_CLASS_POINTER_RETURN_VAL(cur_klass_id, cur_klass, EINA_FALSE);
-        fptr->cur_klass = cur_klass;
-     }
-   else
-     {
-        fptr->cur_klass = NULL;
-     }
-
-   return EINA_TRUE;
-}
-
-EAPI Eina_Bool
-_eo_do_start(const Eo *eo_id, const Eo_Class *cur_klass_id, Eina_Bool 
is_super, void *eo_stack)
-{
-   Eina_Bool ret = EINA_TRUE;
-   Eo_Stack_Frame *fptr;
-   Eo_Call_Stack *stack = eo_stack;
-
-   if (stack->frame_ptr == stack->last_frame)
-     _eo_call_stack_resize(stack, EINA_TRUE);
-
-   fptr = stack->frame_ptr;
-
-   fptr++;
-
-   if (!_eo_do_internal(eo_id, cur_klass_id, is_super, fptr))
-     {
-        fptr->o.obj = NULL;
-        fptr->cur_klass = NULL;
-
-        ret = EINA_FALSE;
+        klass = _klass;
+        call->obj = NULL;
+        call->data = NULL;
      }
 
-   stack->frame_ptr++;
+   inputklass = main_klass =  klass;
 
-   return ret;
-}
-
-EAPI void
-_eo_do_end(void *eo_stack)
-{
-   Eo_Stack_Frame *fptr;
-   Eo_Call_Stack *stack = eo_stack;
-
-   fptr = stack->frame_ptr;
-
-   if (fptr->is_obj && fptr->o.obj)
-     _eo_unref(fptr->o.obj);
-
-   stack->frame_ptr--;
-
-   if (fptr == stack->shrink_frame)
-     _eo_call_stack_resize(stack, EINA_FALSE);
-}
-
-EAPI Eina_Bool
-_eo_call_resolve(const char *func_name, Eo_Op_Call_Data *call, Eo_Call_Cache 
*cache, const char *file, int line)
-{
-   Eo_Stack_Frame *fptr;
-   const _Eo_Class *klass, *inputklass;
-   const op_type_funcs *func;
-   Eina_Bool is_obj;
-
-   fptr = _EO_CALL_STACK_GET()->frame_ptr;
-
-   if (EINA_UNLIKELY(!fptr->o.obj))
-      return EINA_FALSE;
-
-   is_obj = fptr->is_obj;
-
-   inputklass = klass = (is_obj) ? fptr->o.obj->klass : fptr->o.kls;
 
    if (!cache->op)
      {
@@ -542,9 +323,9 @@ _eo_call_resolve(const char *func_name, Eo_Op_Call_Data 
*call, Eo_Call_Cache *ca
      }
 
    /* If we have a current class, we need to itr to the next. */
-   if (fptr->cur_klass)
+   if (cur_klass)
      {
-        func = _eo_kls_itr_next(klass, fptr->cur_klass, cache->op);
+        func = _eo_kls_itr_next(klass, cur_klass, cache->op);
 
         if (!func)
           goto end;
@@ -568,13 +349,7 @@ _eo_call_resolve(const char *func_name, Eo_Op_Call_Data 
*call, Eo_Call_Cache *ca
                   call->func = func->func;
                   if (is_obj)
                     {
-                       call->obj = (Eo *) fptr->o.obj->header.id;
-                       call->data = (char *)fptr->o.obj + cache->off[i].off;
-                    }
-                  else
-                    {
-                       call->obj = _eo_class_id_get(inputklass);
-                       call->data = NULL;
+                       call->data = (char *) obj + cache->off[i].off;
                     }
                   return EINA_TRUE;
                }
@@ -593,17 +368,11 @@ _eo_call_resolve(const char *func_name, Eo_Op_Call_Data 
*call, Eo_Call_Cache *ca
 
         if (is_obj)
           {
-             call->obj = (Eo *) fptr->o.obj->header.id;
-             call->data = _eo_data_scope_get(fptr->o.obj, func->src);
-          }
-        else
-          {
-             call->obj = _eo_class_id_get(klass);
-             call->data = NULL;
+             call->data = _eo_data_scope_get(obj, func->src);
           }
 
 # if EO_CALL_CACHE_SIZE > 0
-        if (!fptr->cur_klass)
+        if (!cur_klass)
           {
 # if EO_CALL_CACHE_SIZE > 1
              const int slot = cache->next_slot;
@@ -612,7 +381,7 @@ _eo_call_resolve(const char *func_name, Eo_Op_Call_Data 
*call, Eo_Call_Cache *ca
 # endif
              cache->index[slot].klass = (const void *)inputklass;
              cache->entry[slot].func = (const void *)func;
-             cache->off[slot].off = (int)((long)((char *)call->data - (char 
*)fptr->o.obj));
+             cache->off[slot].off = (int)((long)((char *)call->data - (char 
*)obj));
 # if EO_CALL_CACHE_SIZE > 1
              cache->next_slot = (slot + 1) % EO_CALL_CACHE_SIZE;
 # endif
@@ -636,7 +405,7 @@ end:
      {
         Eina_List *itr;
         Eo *emb_obj_id;
-        EINA_LIST_FOREACH(((_Eo_Object *) fptr->o.obj)->composite_objects, 
itr, emb_obj_id)
+        EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj_id)
           {
              _Eo_Object *emb_obj = _eo_obj_pointer_get((Eo_Id)emb_obj_id);
 
@@ -649,7 +418,8 @@ end:
 
              if (EINA_LIKELY(func->func && func->src))
                {
-                  call->obj = _eo_id_get(emb_obj);
+                  call->eo_id = _eo_id_get(emb_obj);
+                  call->obj = obj; /* FIXME-eo4: Hack, we retain the previous 
object so we unref it... */
                   call->func = func->func;
                   call->data = _eo_data_scope_get(emb_obj, func->src);
 
@@ -659,15 +429,12 @@ end:
      }
 
      {
-        const _Eo_Class *main_klass;
-        main_klass = (is_obj) ? fptr->o.obj->klass : fptr->o.kls;
-
         /* If it's a do_super call. */
-        if (fptr->cur_klass)
+        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, cache->op, main_klass->desc->name,
-                 fptr->cur_klass->desc->name);
+                 cur_klass->desc->name);
           }
         else
           {
@@ -679,6 +446,15 @@ end:
    return EINA_FALSE;
 }
 
+EAPI void
+_eo_call_end(Eo_Op_Call_Data *call)
+{
+   if (EINA_LIKELY(!!call->obj))
+     {
+        _eo_unref(call->obj);
+     }
+}
+
 static inline Eina_Bool
 _eo_api_func_equal(const void *api_func1, const void *api_func2)
 {
@@ -882,20 +658,19 @@ _eo_add_internal_start(const char *file, int line, const 
Eo_Class *klass_id, Eo
 
    _eo_ref(obj);
 
-   eo_do(eo_id, eo_parent_set(parent_id));
+   eo_parent_set(eo_id, parent_id);
 
    /* If there's a parent. Ref. Eo_add should return an object with either a
     * parent ref, or with the lack of, just a ref. */
      {
-        Eo *parent_tmp;
-        if (ref && eo_do_ret(eo_id, parent_tmp, eo_parent_get()))
+        if (ref && eo_parent_get(eo_id))
           {
              _eo_ref(obj);
           }
      }
 
    /* eo_id can change here. Freeing is done on the resolved object. */
-   eo_do(eo_id, eo_id = eo_constructor());
+   eo_id = eo_constructor(eo_id);
    if (!eo_id)
      {
         ERR("Object of class '%s' - Error while constructing object",
@@ -909,28 +684,20 @@ _eo_add_internal_start(const char *file, int line, const 
Eo_Class *klass_id, Eo
 }
 
 static Eo *
-_eo_add_internal_end(Eo *eo_id, Eo_Call_Stack *stack)
+_eo_add_internal_end(Eo *eo_id, Eo *finalized_id)
 {
-   Eo_Stack_Frame *fptr;
-
-   fptr = stack->frame_ptr;
-
-   if (EINA_UNLIKELY(!fptr->o.obj))
-     {
-        ERR("Corrupt call stack, shouldn't happen, please report!");
-        return NULL;
-     }
+   EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, NULL);
 
-   if (!fptr->o.obj->condtor_done)
+   if (!obj->condtor_done)
      {
-        const _Eo_Class *klass = fptr->o.obj->klass;
+        const _Eo_Class *klass = obj->klass;
 
         ERR("Object of class '%s' - Not all of the object constructors have 
been executed.",
               klass->desc->name);
         goto cleanup;
      }
 
-   if (!eo_id)
+   if (!finalized_id)
      {
         // XXX: Given EFL usage of objects, construction is a perfectly valid 
thing
         // to do. we shouldn't complain about it as handling a NULL obj 
creation is
@@ -946,24 +713,24 @@ _eo_add_internal_end(Eo *eo_id, Eo_Call_Stack *stack)
         goto cleanup;
      }
 
-   fptr->o.obj->finalized = EINA_TRUE;
+   obj->finalized = EINA_TRUE;
 
-   _eo_unref(fptr->o.obj);
+   _eo_unref(obj);
 
    return (Eo *)eo_id;
 
 cleanup:
-   _eo_unref(fptr->o.obj);
-   eo_del((Eo *) fptr->o.obj->header.id);
+   _eo_unref(obj);
+   eo_del((Eo *) obj->header.id);
    return NULL;
 }
 
 EAPI Eo *
-_eo_add_end(void *eo_stack)
+_eo_add_end(Eo *eo_id)
 {
-   Eo *ret = eo_finalize();
-   ret = _eo_add_internal_end(ret, eo_stack);
-   _eo_do_end(eo_stack);
+   Eo *ret = eo_finalize(eo_id);
+   ret = _eo_add_internal_end(eo_id, ret);
+
    return ret;
 }
 
@@ -1552,10 +1319,9 @@ eo_unref(const Eo *obj_id)
 EAPI void
 eo_del(const Eo *obj)
 {
-   Eo *parent_tmp;
-   if (eo_do_ret(obj, parent_tmp, eo_parent_get()))
+   if (eo_parent_get((Eo *) obj))
      {
-        eo_do(obj, eo_parent_set(NULL));
+        eo_parent_set((Eo *) obj, NULL);
      }
    else
      {
@@ -1800,6 +1566,12 @@ eo_init(void)
         return EINA_FALSE;
      }
 
+   if (!eina_spinlock_new(&_super_class_lock))
+     {
+        EINA_LOG_ERR("Could not init lock.");
+        return EINA_FALSE;
+     }
+
    eina_magic_string_static_set(EO_EINA_MAGIC, EO_EINA_MAGIC_STR);
    eina_magic_string_static_set(EO_FREED_EINA_MAGIC,
                                 EO_FREED_EINA_MAGIC_STR);
@@ -1825,27 +1597,6 @@ eo_init(void)
    /* bootstrap EO_CLASS_CLASS */
    (void) EO_ABSTRACT_CLASS_CLASS;
 
-   if (_eo_call_stack_key != 0)
-     WRN("_eo_call_stack_key already set, this should not happen.");
-   else
-     {
-        if (!eina_tls_cb_new(&_eo_call_stack_key, _eo_call_stack_free))
-          {
-             EINA_LOG_ERR("Could not create TLS key for call stack.");
-             return EINA_FALSE;
-
-          }
-     }
-
-#ifndef HAVE_THREAD_SPECIFIER
-   main_loop_stack = _eo_call_stack_create();
-   if (!main_loop_stack)
-     {
-        EINA_LOG_ERR("Could not alloc eo call stack.");
-        return EINA_FALSE;
-     }
-#endif
-
    return EINA_TRUE;
 }
 
@@ -1873,15 +1624,10 @@ eo_shutdown(void)
 
    eina_hash_free(_ops_storage);
 
+   eina_spinlock_free(&_super_class_lock);
    eina_spinlock_free(&_ops_storage_lock);
    eina_spinlock_free(&_eo_class_creation_lock);
 
-   if (_eo_call_stack_key != 0)
-     {
-        eina_tls_free(_eo_call_stack_key);
-        _eo_call_stack_key = 0;
-     }
-
    _eo_free_ids_tables();
 
    eina_log_domain_unregister(_eo_log_dom);
diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h
index 869745c..3ee4134 100644
--- a/src/lib/eo/eo_private.h
+++ b/src/lib/eo/eo_private.h
@@ -61,7 +61,6 @@ extern int _eo_log_dom;
 
 typedef uintptr_t Eo_Id;
 typedef struct _Eo_Class _Eo_Class;
-typedef struct _Eo_Object _Eo_Object;
 typedef struct _Eo_Header Eo_Header;
 
 /* Retrieves the pointer to the object from the id */
@@ -214,11 +213,11 @@ _eo_del_internal(const char *file, int line, _Eo_Object 
*obj)
 
    const _Eo_Class *klass = obj->klass;
 
-   eo_do(_eo_id_get(obj), eo_event_callback_call(EO_BASE_EVENT_DEL, NULL));
+   eo_event_callback_call(_eo_id_get(obj), EO_BASE_EVENT_DEL, NULL);
 
    _eo_condtor_reset(obj);
 
-   eo_do(_eo_id_get(obj), eo_destructor());
+   eo_destructor(_eo_id_get(obj));
 
    if (!obj->condtor_done)
      {
@@ -232,7 +231,7 @@ _eo_del_internal(const char *file, int line, _Eo_Object 
*obj)
         Eo *emb_obj;
         EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj)
           {
-             eo_do(_eo_id_get(obj), eo_composite_detach(emb_obj));
+             eo_composite_detach(_eo_id_get(obj), emb_obj);
           }
      }
 
diff --git a/src/lib/eo/eo_ptr_indirection.x b/src/lib/eo/eo_ptr_indirection.x
index 2faae75..0e6ef34 100644
--- a/src/lib/eo/eo_ptr_indirection.x
+++ b/src/lib/eo/eo_ptr_indirection.x
@@ -57,14 +57,14 @@
  * it to the fifo.
  */
 
-/* most significant bit is kept to tag Eo_Id with 1 */
 #if SIZEOF_UINTPTR_T == 4
 /* 32 bits */
 # define BITS_MID_TABLE_ID        5
 # define BITS_TABLE_ID            5
 # define BITS_ENTRY_ID           12
-# define BITS_GENERATION_COUNTER  9
-# define REF_TAG_SHIFT           31
+# define BITS_GENERATION_COUNTER  8
+# define REF_TAG_SHIFT           30
+# define SUPER_TAG_SHIF          31
 # define DROPPED_TABLES           0
 # define DROPPED_ENTRIES          4
 typedef int16_t Table_Index;
@@ -74,8 +74,9 @@ typedef uint16_t Generation_Counter;
 # define BITS_MID_TABLE_ID       11
 # define BITS_TABLE_ID           11
 # define BITS_ENTRY_ID           12
-# define BITS_GENERATION_COUNTER 29
-# define REF_TAG_SHIFT           63
+# define BITS_GENERATION_COUNTER 28
+# define REF_TAG_SHIFT           62
+# define SUPER_TAG_SHIFT         63
 # define DROPPED_TABLES           2
 # define DROPPED_ENTRIES          3
 typedef int16_t Table_Index;
@@ -101,6 +102,15 @@ typedef uint32_t Generation_Counter;
 #define MASK_ENTRY_ID         ((1 << BITS_ENTRY_ID) - 1)
 #define MASK_GENERATIONS      (MAX_GENERATIONS - 1)
 #define MASK_OBJ_TAG          (((Eo_Id) 1) << (REF_TAG_SHIFT))
+/* When we have EO_ID use the highest bit.
+   When we don't have EO_ID, we can repurpose the lowest bit, because 
allocation
+   is at least 8 byte aligned.
+   XXX: If this is ever not the case, we need to allocate from a mempool and 
ensure it, or find another trick. */
+#ifdef HAVE_EO_ID
+# define MASK_SUPER_TAG       (((Eo_Id) 1) << (SUPER_TAG_SHIFT))
+#else
+# define MASK_SUPER_TAG       ((Eo_Id) 1)
+#endif
 
 /* This only applies to classes. Used to artificially enlarge the class ids
  * to reduce the likelihood of a clash with normal integers. */
@@ -417,7 +427,6 @@ _eo_id_allocate(const _Eo_Object *obj)
                               (entry - _current_table->entries),
                               entry->generation);
 #else
-   Eo_Id ret = 0x1;
    (void) obj;
    return MASK_OBJ_TAG;
 #endif

-- 


Reply via email to