eolian: precompute all enum field values (faster runtime, constness)
authorDaniel Kolesa <d.kolesa@osg.samsung.com>
Wed, 13 May 2015 17:10:02 +0000 (18:10 +0100)
committerDaniel Kolesa <d.kolesa@osg.samsung.com>
Wed, 13 May 2015 17:10:02 +0000 (18:10 +0100)
src/bin/eolian/types_generator.c
src/bindings/luajit/eolian.lua
src/lib/eolian/Eolian.h
src/lib/eolian/database_expr.c
src/lib/eolian/database_type_api.c
src/lib/eolian/eo_parser.c

index 90b62bd..7e6e483 100644 (file)
@@ -94,7 +94,7 @@ _type_generate(const Eolian_Type *tp, Eina_Bool full)
            }
       case EOLIAN_TYPE_ENUM:
            {
-              Eolian_Enum_Type_Field *member;
+              const Eolian_Enum_Type_Field *member;
               char *name;
               if (!full)
                 break;
index 334d141..f9f6168 100644 (file)
@@ -270,10 +270,10 @@ ffi.cdef [[
     const char *eolian_type_struct_field_description_get(const Eolian_Struct_Type_Field *fl);
     const Eolian_Type *eolian_type_struct_field_type_get(const Eolian_Struct_Type_Field *fl);
     Eina_Iterator *eolian_type_enum_fields_get(const Eolian_Type *tp);
-    Eolian_Enum_Type_Field *eolian_type_enum_field_get(const Eolian_Type *tp, const char *field);
+    const Eolian_Enum_Type_Field *eolian_type_enum_field_get(const Eolian_Type *tp, const char *field);
     const char *eolian_type_enum_field_name_get(const Eolian_Enum_Type_Field *fl);
     const char *eolian_type_enum_field_description_get(const Eolian_Enum_Type_Field *fl);
-    const Eolian_Expression *eolian_type_enum_field_value_get(Eolian_Enum_Type_Field *fl, Eina_Bool force);
+    const Eolian_Expression *eolian_type_enum_field_value_get(const Eolian_Enum_Type_Field *fl, Eina_Bool force);
     const char *eolian_type_enum_legacy_prefix_get(const Eolian_Type *tp);
     const char *eolian_type_description_get(const Eolian_Type *tp);
     const char *eolian_type_file_get(const Eolian_Type *tp);
@@ -510,7 +510,7 @@ M.Type = ffi.metatype("Eolian_Type", {
         end,
 
         enum_fields_get = function(self)
-            return Ptr_Iterator("Eolian_Enum_Type_Field*",
+            return Ptr_Iterator("const Eolian_Enum_Type_Field*",
                 eolian.eolian_type_enum_fields_get(self))
         end,
 
index 317d657..7ee0237 100644 (file)
@@ -1551,7 +1551,7 @@ EAPI Eina_Iterator *eolian_type_enum_fields_get(const Eolian_Type *tp);
  *
  * @ingroup Eolian
  */
-EAPI Eolian_Enum_Type_Field *eolian_type_enum_field_get(const Eolian_Type *tp, const char *field);
+EAPI const Eolian_Enum_Type_Field *eolian_type_enum_field_get(const Eolian_Type *tp, const char *field);
 
 /*
  * @brief Get the name of a field of an enum type.
@@ -1589,10 +1589,8 @@ EAPI Eina_Stringshare *eolian_type_enum_field_description_get(const Eolian_Enum_
  * @brief Get the value of a field of an enum type.
  *
  * When the @c force parameter is EINA_FALSE, this will only return values for
- * fields which are explicitly specified in the eo file. Otherwise, it will
- * create the field (if not already there) and return it. Keep in mind that
- * no matter if the field is already cached or not, you always have to force
- * retrieval if you want to be sure that a valid expr is returned.
+ * fields which are explicitly specified in the eo file, otherwise it will
+ * return a valid expression for any field.
  *
  * @param[in] fl the field.
  * @param[in] force force the value retrieval.
@@ -1600,7 +1598,7 @@ EAPI Eina_Stringshare *eolian_type_enum_field_description_get(const Eolian_Enum_
  *
  * @ingroup Eolian
  */
-EAPI const Eolian_Expression *eolian_type_enum_field_value_get(Eolian_Enum_Type_Field *fl, Eina_Bool force);
+EAPI const Eolian_Expression *eolian_type_enum_field_value_get(const Eolian_Enum_Type_Field *fl, Eina_Bool force);
 
 /*
  * @brief Get the legacy prefix of enum field names. When not specified,
index 7fe8108..d954506 100644 (file)
@@ -499,7 +499,7 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask,
            if (!var)
              {
                 const Eolian_Type *etp;
-                Eolian_Enum_Type_Field *fl;
+                const Eolian_Enum_Type_Field *fl;
 
                 /* try aliases, hoping it'll be enum */
                 char *fulln = NULL, *memb = NULL;
index 709f541..81a769c 100644 (file)
@@ -136,7 +136,7 @@ eolian_type_enum_fields_get(const Eolian_Type *tp)
    return eina_list_iterator_new(tp->field_list);
 }
 
-EAPI Eolian_Enum_Type_Field *
+EAPI const Eolian_Enum_Type_Field *
 eolian_type_enum_field_get(const Eolian_Type *tp, const char *field)
 {
    Eolian_Enum_Type_Field *ef = NULL;
@@ -185,55 +185,10 @@ eolian_type_enum_field_description_get(const Eolian_Enum_Type_Field *fl)
 }
 
 EAPI const Eolian_Expression *
-eolian_type_enum_field_value_get(Eolian_Enum_Type_Field *fl, Eina_Bool force)
+eolian_type_enum_field_value_get(const Eolian_Enum_Type_Field *fl, Eina_Bool force)
 {
    EINA_SAFETY_ON_NULL_RETURN_VAL(fl, NULL);
    if (!force && !fl->is_public_value) return NULL;
-   if (force && !fl->value)
-     {
-        Eolian_Expression *exp = NULL;
-        Eolian_Expression *rhs = calloc(1, sizeof(Eolian_Expression)),
-                          *bin = calloc(1, sizeof(Eolian_Expression));
-
-        int fl_nadd = 0;
-
-        Eina_List *flist = fl->base_enum->field_list;
-        Eolian_Enum_Type_Field *lfl = eina_list_data_get(flist);
-
-        /* first find our own node */
-        while (lfl && lfl->name != fl->name)
-          {
-             flist = eina_list_next(flist);
-             lfl = eina_list_data_get(flist);
-          }
-
-        /* we've found our list item, now let's go backwards */
-        while (!lfl->value)
-          {
-             ++fl_nadd;
-             flist = eina_list_prev(flist);
-             lfl = eina_list_data_get(flist);
-          }
-
-        /* we've found our first reachable value */
-        exp = lfl->value;
-
-        rhs->base.file = eina_stringshare_ref(exp->base.file);
-        bin->base.file = eina_stringshare_ref(exp->base.file);
-        rhs->base.line = rhs->base.column = -1;
-        bin->base.line = bin->base.column = -1;
-
-        rhs->type = EOLIAN_EXPR_INT;
-        rhs->value.i = fl_nadd;
-
-        bin->type = EOLIAN_EXPR_BINARY;
-        bin->binop = EOLIAN_BINOP_ADD;
-        bin->lhs = exp;
-        bin->rhs = rhs;
-        bin->weak_lhs = EINA_TRUE;
-
-        fl->value = bin;
-     }
    return fl->value;
 }
 
index 7509196..1826e24 100644 (file)
@@ -563,7 +563,8 @@ parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
               check_next(ls, ';');
            }
      }
-   Eolian_Expression *prev_exp = NULL;
+   Eolian_Enum_Type_Field *prev_fl = NULL;
+   int fl_nadd = 0;
    for (;;)
      {
         const char *fname;
@@ -582,15 +583,35 @@ parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
         fdef->name = eina_stringshare_ref(fname);
         if (ls->t.token != '=')
           {
-             if (!prev_exp)
+             if (!prev_fl)
                {
-                  prev_exp = push_expr(ls);
-                  FILL_BASE(prev_exp->base, ls, -1, -1);
-                  prev_exp->type = EOLIAN_EXPR_INT;
-                  prev_exp->value.i = 0;
-                  fdef->value = prev_exp;
+                  Eolian_Expression *eexp = push_expr(ls);
+                  FILL_BASE(eexp->base, ls, -1, -1);
+                  eexp->type = EOLIAN_EXPR_INT;
+                  eexp->value.i = 0;
+                  fdef->value = eexp;
                   fdef->is_public_value = EINA_TRUE;
                   pop_expr(ls);
+                  prev_fl = fdef;
+                  fl_nadd = 0;
+               }
+             else
+               {
+                  Eolian_Expression *rhs = push_expr(ls),
+                                    *bin = push_expr(ls);
+                  FILL_BASE(rhs->base, ls, -1, -1);
+                  FILL_BASE(bin->base, ls, -1, -1);
+
+                  rhs->type = EOLIAN_EXPR_INT;
+                  rhs->value.i = ++fl_nadd;
+
+                  bin->type = EOLIAN_EXPR_BINARY;
+                  bin->binop = EOLIAN_BINOP_ADD;
+                  bin->lhs = prev_fl->value;
+                  bin->rhs = rhs;
+                  bin->weak_lhs = EINA_TRUE;
+
+                  fdef->value = bin;
                }
           }
         else
@@ -600,8 +621,8 @@ parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
              fdef->value = parse_expr(ls);
              fdef->is_public_value = EINA_TRUE;
              ls->expr_mode = EINA_FALSE;
-             if (!prev_exp)
-               prev_exp = fdef->value;
+             prev_fl = fdef;
+             fl_nadd = 0;
              pop_expr(ls);
           }
         Eina_Bool want_next = (ls->t.token == ',');