From 957a89168ba327c7c754af45894b9345a971561d Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Wed, 13 May 2015 18:10:02 +0100 Subject: [PATCH] eolian: precompute all enum field values (faster runtime, constness) --- src/bin/eolian/types_generator.c | 2 +- src/bindings/luajit/eolian.lua | 6 ++--- src/lib/eolian/Eolian.h | 10 ++++---- src/lib/eolian/database_expr.c | 2 +- src/lib/eolian/database_type_api.c | 49 ++------------------------------------ src/lib/eolian/eo_parser.c | 39 +++++++++++++++++++++++------- 6 files changed, 41 insertions(+), 67 deletions(-) diff --git a/src/bin/eolian/types_generator.c b/src/bin/eolian/types_generator.c index 90b62bd..7e6e483 100644 --- a/src/bin/eolian/types_generator.c +++ b/src/bin/eolian/types_generator.c @@ -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; diff --git a/src/bindings/luajit/eolian.lua b/src/bindings/luajit/eolian.lua index 334d141..f9f6168 100644 --- a/src/bindings/luajit/eolian.lua +++ b/src/bindings/luajit/eolian.lua @@ -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, diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index 317d657..7ee0237 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -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, diff --git a/src/lib/eolian/database_expr.c b/src/lib/eolian/database_expr.c index 7fe8108..d954506 100644 --- a/src/lib/eolian/database_expr.c +++ b/src/lib/eolian/database_expr.c @@ -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; diff --git a/src/lib/eolian/database_type_api.c b/src/lib/eolian/database_type_api.c index 709f541..81a769c 100644 --- a/src/lib/eolian/database_type_api.c +++ b/src/lib/eolian/database_type_api.c @@ -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; } diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index 7509196..1826e24 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -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 == ','); -- 2.7.4