q66 pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=aa313ccfb6e89f49471c6aa98b64fc4a6e992d7e
commit aa313ccfb6e89f49471c6aa98b64fc4a6e992d7e Author: Daniel Kolesa <[email protected]> Date: Thu Mar 15 15:31:08 2018 +0100 eolian: store types in node hash --- src/lib/eolian/eo_lexer.c | 87 +++++++++++++++++++++++++--------------------- src/lib/eolian/eo_lexer.h | 15 +++++++- src/lib/eolian/eo_parser.c | 57 +++++++++--------------------- 3 files changed, 78 insertions(+), 81 deletions(-) diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c index 653a8ba0c9..76e076d14a 100644 --- a/src/lib/eolian/eo_lexer.c +++ b/src/lib/eolian/eo_lexer.c @@ -1014,6 +1014,42 @@ get_filename(Eo_Lexer *ls) } static void +_node_free(Eolian_Object *obj) +{ +#if 0 + /* for when we have a proper node allocator and collect on shutdown */ + if (obj->refcount > 1) + { + _eolian_log("node %p (type %d, name %s at %s:%d:%d)" + " dangling ref (count: %d)", obj, obj->type, obj->name, + obj->file, obj->line, obj->column, obj->refcount); + } +#endif + switch (obj->type) + { + case EOLIAN_OBJECT_CLASS: + database_class_del((Eolian_Class *)obj); + break; + case EOLIAN_OBJECT_TYPEDECL: + database_typedecl_del((Eolian_Typedecl *)obj); + break; + case EOLIAN_OBJECT_TYPE: + database_type_del((Eolian_Type *)obj); + break; + case EOLIAN_OBJECT_VARIABLE: + database_var_del((Eolian_Variable *)obj); + break; + case EOLIAN_OBJECT_EXPRESSION: + database_expr_del((Eolian_Expression *)obj); + break; + default: + /* normally unreachable, just for debug */ + assert(0); + break; + } +} + +static void eo_lexer_set_input(Eo_Lexer *ls, Eolian_State *state, const char *source) { Eina_File *f = eina_file_open(source, EINA_FALSE); @@ -1034,6 +1070,7 @@ eo_lexer_set_input(Eo_Lexer *ls, Eolian_State *state, const char *source) ls->iline_number = ls->line_number = 1; ls->icolumn = ls->column = -1; ls->decpoint = '.'; + ls->nodes = eina_hash_pointer_new(EINA_FREE_CB(_node_free)); next_char(ls); Eolian_Unit *ncunit = calloc(1, sizeof(Eolian_Unit)); @@ -1056,47 +1093,19 @@ Eolian_Object * eo_lexer_node_new(Eo_Lexer *ls, size_t objsize) { Eolian_Object *obj = calloc(1, objsize); - ls->tmp.nodes = eina_list_prepend(ls->tmp.nodes, obj); + eina_hash_add(ls->nodes, &obj, obj); eolian_object_ref(obj); return obj; } -int -_node_free(Eolian_Object *obj) +Eolian_Object * +eo_lexer_node_release(Eo_Lexer *ls, Eolian_Object *obj) { - int rc = obj->refcount; -#if 0 - /* for when we have a proper node allocator and collect on shutdown */ - if (rc > 1) - { - _eolian_log("node %p (type %d, name %s at %s:%d:%d)" - " dangling ref (count: %d)", obj, obj->type, obj->name, - obj->file, obj->line, obj->column); - } -#endif - switch (obj->type) - { - case EOLIAN_OBJECT_CLASS: - database_class_del((Eolian_Class *)obj); - break; - case EOLIAN_OBJECT_TYPEDECL: - database_typedecl_del((Eolian_Typedecl *)obj); - break; - case EOLIAN_OBJECT_TYPE: - database_type_del((Eolian_Type *)obj); - break; - case EOLIAN_OBJECT_VARIABLE: - database_var_del((Eolian_Variable *)obj); - break; - case EOLIAN_OBJECT_EXPRESSION: - database_expr_del((Eolian_Expression *)obj); - break; - default: - /* normally unreachable, just for debug */ - assert(0); - break; - } - return rc; + /* just for debug */ + assert(eina_hash_find(ls->nodes, &obj) && (obj->refcount >= 1)); + eolian_object_unref(obj); + eina_hash_set(ls->nodes, &obj, NULL); + return obj; } static void @@ -1104,7 +1113,6 @@ _temps_free(Eo_Lexer_Temps *tmp) { Eolian_Type *tp; Eolian_Typedecl *tpd; - Eolian_Object *obj; if (tmp->kls) database_class_del(tmp->kls); @@ -1117,9 +1125,6 @@ _temps_free(Eo_Lexer_Temps *tmp) EINA_LIST_FREE(tmp->type_decls, tpd) database_typedecl_del(tpd); - - EINA_LIST_FREE(tmp->nodes, obj) - _node_free(obj); } static void @@ -1176,6 +1181,8 @@ eo_lexer_free(Eo_Lexer *ls) EINA_LIST_FREE(ls->dtors, dtor) dtor->free_cb(dtor->data); + eina_hash_free(ls->nodes); + free(ls); } diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h index af0cb352ec..1d6b312d23 100644 --- a/src/lib/eolian/eo_lexer.h +++ b/src/lib/eolian/eo_lexer.h @@ -126,7 +126,6 @@ typedef struct _Eo_Lexer_Temps Eina_List *type_defs; Eina_List *type_decls; Eina_List *expr_defs; - Eina_List *nodes; } Eo_Lexer_Temps; typedef struct _Eo_Lexer_Dtor @@ -189,6 +188,7 @@ typedef struct _Eo_Lexer Eolian_Class *klass; Eina_List *dtors; + Eina_Hash *nodes; /* whether we allow lexing expression related tokens */ Eina_Bool expr_mode; @@ -227,6 +227,19 @@ void eo_lexer_context_clear (Eo_Lexer *ls); /* node ("heap") management */ Eolian_Object *eo_lexer_node_new(Eo_Lexer *ls, size_t objsize); +Eolian_Object *eo_lexer_node_release(Eo_Lexer *ls, Eolian_Object *obj); + +static inline Eolian_Type * +eo_lexer_type_new(Eo_Lexer *ls) +{ + return (Eolian_Type *)eo_lexer_node_new(ls, sizeof(Eolian_Type)); +} + +static inline Eolian_Type * +eo_lexer_type_release(Eo_Lexer *ls, Eolian_Type *tp) +{ + return (Eolian_Type *)eo_lexer_node_release(ls, (Eolian_Object *)tp); +} /* "stack" management, only to protect against errors (jumps) in parsing */ void eo_lexer_dtor_push(Eo_Lexer *ls, Eina_Free_Cb free_cb, void *data); diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index bdbb175d4f..4f21bc7efd 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -97,14 +97,6 @@ check_match(Eo_Lexer *ls, int what, int who, int where, int col) } } -static Eolian_Type * -push_type(Eo_Lexer *ls) -{ - Eolian_Type *def = calloc(1, sizeof(Eolian_Type)); - ls->tmp.type_defs = eina_list_prepend(ls->tmp.type_defs, def); - return def; -} - static Eolian_Typedecl * push_typedecl(Eo_Lexer *ls) { @@ -114,12 +106,6 @@ push_typedecl(Eo_Lexer *ls) } static void -pop_type(Eo_Lexer *ls) -{ - ls->tmp.type_defs = eina_list_remove_list(ls->tmp.type_defs, ls->tmp.type_defs); -} - -static void pop_typedecl(Eo_Lexer *ls) { ls->tmp.type_decls = eina_list_remove_list(ls->tmp.type_decls, ls->tmp.type_decls); @@ -501,9 +487,8 @@ parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern, check_next(ls, ':'); tp = parse_type(ls); FILL_BASE(fdef->base, ls, fline, fcol, STRUCT_FIELD); - fdef->type = tp; + fdef->type = eo_lexer_type_release(ls, tp); fdef->base.name = eina_stringshare_ref(fname); - pop_type(ls); if ((fdef->type->owned = (ls->t.kw == KW_at_owned))) eo_lexer_get(ls); check_next(ls, ';'); @@ -727,7 +712,7 @@ parse_type_void(Eo_Lexer *ls) default: break; } - def = push_type(ls); + def = eo_lexer_type_new(ls); FILL_BASE(def->base, ls, line, col, TYPE); if (ls->t.kw == KW_void) { @@ -755,24 +740,23 @@ parse_type_void(Eo_Lexer *ls) int bline = ls->line_number, bcol = ls->column; check_next(ls, '<'); if (tpid == KW_future) - def->base_type = parse_type_void(ls); + def->base_type = eo_lexer_type_release(ls, parse_type_void(ls)); else - def->base_type = parse_type(ls); - pop_type(ls); + def->base_type = eo_lexer_type_release(ls, parse_type(ls)); if ((def->base_type->owned = (ls->t.kw == KW_at_owned))) eo_lexer_get(ls); if (tpid == KW_hash) { check_next(ls, ','); - def->base_type->next_type = parse_type(ls); - pop_type(ls); + def->base_type->next_type = + eo_lexer_type_release(ls, parse_type(ls)); if ((def->base_type->next_type->owned = (ls->t.kw == KW_at_owned))) eo_lexer_get(ls); } else if((tpid == KW_future) && test_next(ls, ',')) { - def->base_type->next_type = parse_type_void(ls); - pop_type(ls); + def->base_type->next_type = + eo_lexer_type_release(ls, parse_type_void(ls)); } check_match(ls, '>', '<', bline, bcol); } @@ -840,8 +824,7 @@ parse_typedef(Eo_Lexer *ls) } eo_lexer_context_pop(ls); check_next(ls, ':'); - def->base_type = parse_type(ls); - pop_type(ls); + def->base_type = eo_lexer_type_release(ls, parse_type(ls)); check_next(ls, ';'); FILL_DOC(ls, def, doc); eo_lexer_dtor_pop(ls); @@ -875,8 +858,7 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global) } eo_lexer_context_pop(ls); check_next(ls, ':'); - def->base_type = parse_type(ls); - pop_type(ls); + def->base_type = eo_lexer_type_release(ls, parse_type(ls)); /* constants are required to have a value */ if (!global) check(ls, '='); @@ -981,10 +963,9 @@ parse_param(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout, eo_lexer_get(ls); check_next(ls, ':'); if (par->param_dir == EOLIAN_OUT_PARAM || par->param_dir == EOLIAN_INOUT_PARAM) - par->type = parse_type_void(ls); + par->type = eo_lexer_type_release(ls, parse_type_void(ls)); else - par->type = parse_type(ls); - pop_type(ls); + par->type = eo_lexer_type_release(ls, parse_type(ls)); if ((is_vals || (par->param_dir == EOLIAN_OUT_PARAM)) && (ls->t.token == '(')) { int line = ls->line_number, col = ls->column; @@ -1131,11 +1112,10 @@ parse_accessor: CASE_LOCK(ls, return, "return") Eo_Ret_Def ret; parse_return(ls, &ret, is_get, EINA_TRUE, EINA_FALSE); - pop_type(ls); if (ret.default_ret_val) pop_expr(ls); if (is_get) { - prop->get_ret_type = ret.type; + prop->get_ret_type = eo_lexer_type_release(ls, ret.type); prop->get_return_doc = ret.doc; prop->get_ret_val = ret.default_ret_val; prop->get_return_warn_unused = ret.warn_unused; @@ -1143,7 +1123,7 @@ parse_accessor: } else { - prop->set_ret_type = ret.type; + prop->set_ret_type = eo_lexer_type_release(ls, ret.type); prop->set_return_doc = ret.doc; prop->set_ret_val = ret.default_ret_val; prop->set_return_warn_unused = ret.warn_unused; @@ -1348,8 +1328,7 @@ parse_function_pointer(Eo_Lexer *ls) CASE_LOCK(ls, return, "return"); Eo_Ret_Def ret; parse_return(ls, &ret, EINA_FALSE, EINA_FALSE, EINA_TRUE); - pop_type(ls); - meth->get_ret_type = ret.type; + meth->get_ret_type = eo_lexer_type_release(ls, ret.type); meth->get_return_doc = ret.doc; meth->get_ret_val = NULL; meth->get_return_warn_unused = EINA_FALSE; @@ -1443,9 +1422,8 @@ body: CASE_LOCK(ls, return, "return") Eo_Ret_Def ret; parse_return(ls, &ret, EINA_FALSE, EINA_TRUE, EINA_FALSE); - pop_type(ls); if (ret.default_ret_val) pop_expr(ls); - meth->get_ret_type = ret.type; + meth->get_ret_type = eo_lexer_type_release(ls, ret.type); meth->get_return_doc = ret.doc; meth->get_ret_val = ret.default_ret_val; meth->get_return_warn_unused = ret.warn_unused; @@ -1790,9 +1768,8 @@ end: if (ls->t.token == ':') { eo_lexer_get(ls); - ev->type = parse_type(ls); + ev->type = eo_lexer_type_release(ls, parse_type(ls)); ev->type->owned = has_owned; - pop_type(ls); } check(ls, ';'); eo_lexer_get(ls); --
