From 5e6cd86a88c277eb7a272b1c79e3007a80b2b539 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 1 Jul 2020 21:16:47 +0200 Subject: wip --- src/bin/eolian/sources.c | 34 ++++++++++++++++++++++++++++++---- src/compiler-plugins/myplugin.cc | 25 +++++++++++++++++++------ src/lib/eo/Eo.h | 3 +++ src/lib/eo/eo.c | 17 +++++++++++++++++ 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c index a892cd7192..577ad6ee83 100644 --- a/src/bin/eolian/sources.c +++ b/src/bin/eolian/sources.c @@ -1147,7 +1147,7 @@ _gen_next_super_implementation_registering(Eina_Array *call_chain, const Eolian_ eo_gen_class_names_get(next_implemen_class, NULL, NULL, &impl_name); - eina_strbuf_append_printf(buf, "COMPILER_PLUGIN_REGISTER_NEXT(\"%s\",\"_%s_%s\")\n", eolian_function_full_c_name_get(fid, ftype), impl_name, eolian_function_full_c_name_get(fid, ftype)); + eina_strbuf_append_printf(buf, "COMPILER_PLUGIN_REGISTER_NEXT(\"%s\", \"%s\",\"_%s_%s\")\n", eolian_function_full_c_name_get(fid, ftype), eolian_class_c_name_get(next_implemen_class), impl_name, eolian_function_full_c_name_get(fid, ftype)); } static void @@ -1200,6 +1200,8 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf) if (!cl) return; + Eina_Array *call_chain = _gen_call_chain(cl); + _funcs_params_init_get = eina_hash_pointer_new(NULL); _funcs_params_init_set = eina_hash_pointer_new(NULL); @@ -1256,6 +1258,31 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf) eina_iterator_free(itr); } + /* generate unsigned int field that will contain the pd offset */ + { + if (eolian_class_type_get(cl) == EOLIAN_CLASS_REGULAR || eolian_class_type_get(cl) == EOLIAN_CLASS_ABSTRACT) + { + Eina_Strbuf *name = eina_strbuf_new(); + eina_strbuf_append_printf(name, "unsigned int %s_pd_offset = -1;\n", eolian_class_c_name_get(cl)); + eina_strbuf_tolower(name); + eina_strbuf_append(buf, "#ifdef COMPILER_PLUGIN_REGISTER_NEXT_SUPPORT\n"); + eina_strbuf_append_buffer(buf, name); + eina_strbuf_reset(name); + for (unsigned int i = 0; i < eina_array_count_get(call_chain); ++i) + { + Eolian_Class *called = eina_array_data_get(call_chain, i); + if (eolian_class_type_get(called) != EOLIAN_CLASS_MIXIN) + break; + eina_strbuf_append_printf(name, "unsigned int %s_%s_pd_offset = -1;\n", eolian_class_c_name_get(cl), eolian_class_c_name_get(called)); + eina_strbuf_tolower(name); + eina_strbuf_append_buffer(buf, name); + eina_strbuf_reset(name); + } + eina_strbuf_append(buf, "#endif\n"); + eina_strbuf_free(name); + } + } + /* class initializer - contains method defs */ _gen_initializer(cl, buf, refh); eina_hash_free(refh); @@ -1306,14 +1333,13 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf) /* create macro for COMPILER_PLUGIN_REGISTER_NEXT */ eina_strbuf_append(buf, "#ifdef COMPILER_PLUGIN_REGISTER_NEXT_SUPPORT\n"); - eina_strbuf_append(buf, " #define COMPILER_PLUGIN_REGISTER_NEXT(a, b) __attribute__((register_next(a, b)))\n"); + eina_strbuf_append(buf, " #define COMPILER_PLUGIN_REGISTER_NEXT(a, b, c) __attribute__((register_next(a, b, c)))\n"); eina_strbuf_append(buf, "#else\n"); - eina_strbuf_append(buf, " #define COMPILER_PLUGIN_REGISTER_NEXT(a, b) /* NOP */\n"); + eina_strbuf_append(buf, " #define COMPILER_PLUGIN_REGISTER_NEXT(a, b, c) /* NOP */\n"); eina_strbuf_append(buf, "#endif\n"); /* add implementation details to the declaration */ - Eina_Array *call_chain = _gen_call_chain(cl); const Eolian_Implement *imp; Eina_Iterator *itr = eolian_class_implements_get(cl); EINA_ITERATOR_FOREACH(itr, imp) diff --git a/src/compiler-plugins/myplugin.cc b/src/compiler-plugins/myplugin.cc index 446b677bb0..56fc017df6 100644 --- a/src/compiler-plugins/myplugin.cc +++ b/src/compiler-plugins/myplugin.cc @@ -1,13 +1,25 @@ #include #include "gcc-common.h" +/* + * Why all this ? + * + * In eo we have super calls, these super calls already validated to have a valid obj pointer, and the pd pointer is already enough to calculate one, *without* the need to call eo again. + * + * How: + * + * - First of all, in eolian we are calculating the next call candidates for a overriden function, for them we are storing the name of the symbol *and* and class providing it. + * - Additionally, eolian generates more symbols: + * a) One symbol containing the offset over logical 0 address in pd's + * b) For each mixin in the inheritance of the class, the offset to reach exactly *that* mixin + * - In the plugin here we are fetching all the calls of foo(efl_super(obj, XXX), aaa, bbb, ccc); then we are fetching from the eolian output what the actaul implementation for foo is, after the class XXX + * - Then we are replacing the foo call with the actaul implementation, 2 arguments for the calls are preprended (obj, pd - A + B) where A is the offset from XXX to logical 0, and B is the offset from B to logical 0. + * + */ + /* TODO: - * Find all efl_super calls - * Traverse back to find function calling it (foo) - * Calculate the private data pointer diff * Replace foo(efl_super(obj, MY_CLASS),...) calls with the next lower level function for foo and * adjust private data with diff - * Make eolian more expressive (We need the implemented methods of classes, accross the tree) */ __visible int plugin_is_GPL_compatible; @@ -139,7 +151,8 @@ static unsigned int eo_execute(void) //this here assumes a special tree_list structure tree attribute_arguments = TREE_VALUE(attribute); tree call = TREE_VALUE(attribute_arguments); - tree implementation = TREE_VALUE(TREE_CHAIN(attribute_arguments)); + tree providing_class = TREE_VALUE(TREE_CHAIN(attribute_arguments)); + tree implementation = TREE_VALUE(TREE_CHAIN(TREE_CHAIN(attribute_arguments))); if (!!strncmp(TREE_STRING_POINTER(call), c.called_api, strlen(c.called_api))) continue; @@ -189,7 +202,7 @@ handle_user_attribute (tree *node, tree name, tree args, } static struct attribute_spec next_hop_attr = - { "register_next", 2, 2, true, false, false, true, handle_user_attribute, NULL}; + { "register_next", 3, 3, true, false, false, true, handle_user_attribute, NULL}; static void register_next_hop_attribute (void *event_data, void *data) diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 12a29d0555..84f2578268 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -954,6 +954,9 @@ EAPI const Efl_Class *efl_class_new(const Efl_Class_Description *desc, const Efl */ EAPI Eina_Bool efl_class_functions_set(const Efl_Class *klass_id, const Efl_Object_Ops *object_ops, const Efl_Object_Property_Reflection_Ops *reflection_table); + +EAPI unsigned int efl_class_offset(const Efl_Class *klass_id); + /** * @brief Override Eo functions of this object. * @param ops The op description to override with. diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index 7f21e0c0f3..f978a59dac 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -1807,6 +1807,23 @@ efl_class_new(const Efl_Class_Description *desc, const Efl_Class *parent_id, ... return _eo_class_id_get(klass); } +EAPI unsigned int +efl_class_offset(const Efl_Class *klass_id) +{ + EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, 0); + + return klass->data_offset; +} + +EAPI unsigned int +efl_class_mixin_offset(const Efl_Class *klass_id, const Efl_Class *mixin_id) +{ + /* FIXME */ + + return -1; +} + + EAPI Eina_Bool efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops) { -- cgit v1.2.1