aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2018-03-15 15:31:08 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2018-03-15 16:34:39 +0100
commitaa313ccfb6e89f49471c6aa98b64fc4a6e992d7e (patch)
treeab53ef186f58374c0b4c788812e13732eedddd37
parenteolian: generic dtor management for lexer (diff)
downloadefl-aa313ccfb6e89f49471c6aa98b64fc4a6e992d7e.tar.gz
eolian: store types in node hash
-rw-r--r--src/lib/eolian/eo_lexer.c87
-rw-r--r--src/lib/eolian/eo_lexer.h15
-rw-r--r--src/lib/eolian/eo_parser.c57
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);