summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2020-07-08 14:20:23 +0200
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-07-08 14:20:23 +0200
commitc724083d063cefe10862289de528213ff368e4e5 (patch)
tree0bbfdf86e0e3d17ef5e55a201fab2a0c68cfdc2a
parent500d938c7f90322700d4fe25340bfcd3ea909a76 (diff)
downloadefl-c724083d063cefe10862289de528213ff368e4e5.tar.gz
wip - we are finally replacing calls
and we are crashing ... but we are getting there ... :)
-rw-r--r--src/bin/eolian/sources.c13
-rw-r--r--src/compiler-plugins/myplugin.cc46
-rw-r--r--src/lib/eo/eo.c16
3 files changed, 67 insertions, 8 deletions
diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c
index 14c7a08528..7016fce361 100644
--- a/src/bin/eolian/sources.c
+++ b/src/bin/eolian/sources.c
@@ -1088,7 +1088,7 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf, Eina_Hash *refh, Eina
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, "%s_pd_offset = efl_class_offset(klass);\n", eolian_class_c_name_get(cl)/*, eolian_class_c_get_function_name_get(cl)*/);
+ eina_strbuf_append_printf(name, " %s_pd_offset = efl_class_offset(klass);\n", eolian_class_c_name_get(cl)/*, eolian_class_c_get_function_name_get(cl)*/);
eina_strbuf_tolower(name);
eina_strbuf_append(buf, "#ifdef COMPILER_PLUGIN_REGISTER_NEXT_SUPPORT\n");
eina_strbuf_append_buffer(buf, name);
@@ -1098,7 +1098,7 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf, Eina_Hash *refh, Eina
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, "%s_%s_pd_offset = efl_class_mixin_offset(klass, %s());\n", eolian_class_c_name_get(cl), eolian_class_c_name_get(called), /*eolian_class_c_macro_get(cl),*/ eolian_class_c_get_function_name_get(called));
+ eina_strbuf_append_printf(name, " %s_%s_pd_offset = efl_class_mixin_offset(klass, %s());\n", eolian_class_c_name_get(cl), eolian_class_c_name_get(called), /*eolian_class_c_macro_get(cl),*/ eolian_class_c_get_function_name_get(called));
eina_strbuf_tolower(name);
eina_strbuf_append_buffer(buf, name);
eina_strbuf_reset(name);
@@ -1170,7 +1170,10 @@ _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_%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));
+ char *class_name = eina_strdup(eolian_class_c_name_get(next_implemen_class));
+ eina_str_tolower(&class_name);
+
+ eina_strbuf_append_printf(buf, "COMPILER_PLUGIN_REGISTER_NEXT(\"%s\", \"%s\",\"_%s_%s\", %d)\n", eolian_function_full_c_name_get(fid, ftype), class_name, impl_name, eolian_function_full_c_name_get(fid, ftype), eolian_class_type_get(next_implemen_class) == EOLIAN_CLASS_MIXIN ? 1 : 0);
}
static void
@@ -1356,9 +1359,9 @@ 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, c) __attribute__((register_next(a, b, c)))\n");
+ eina_strbuf_append(buf, " #define COMPILER_PLUGIN_REGISTER_NEXT(a, b, c, d) __attribute__((register_next(a, b, c, d)))\n");
eina_strbuf_append(buf, "#else\n");
- eina_strbuf_append(buf, " #define COMPILER_PLUGIN_REGISTER_NEXT(a, b, c) /* NOP */\n");
+ eina_strbuf_append(buf, " #define COMPILER_PLUGIN_REGISTER_NEXT(a, b, c, d) /* NOP */\n");
eina_strbuf_append(buf, "#endif\n");
diff --git a/src/compiler-plugins/myplugin.cc b/src/compiler-plugins/myplugin.cc
index 56fc017df6..92d39f3114 100644
--- a/src/compiler-plugins/myplugin.cc
+++ b/src/compiler-plugins/myplugin.cc
@@ -54,6 +54,7 @@ struct Caller {
const char *called_api;
const char *klass;
tree klass_decl;
+ tree called_api_decl;
};
typedef struct _Fetch_Result {
@@ -77,6 +78,7 @@ _fetch_first_argument(const_gimple arg, unsigned int narg)
if (!ret.first_argument) return ret;
if (!is_gimple_call(ret.first_argument)) return ret;
tree tmp = gimple_call_fndecl(ret.first_argument);
+
if (!tmp) return ret;
ret.api_name = IDENTIFIER_POINTER(DECL_NAME(tmp));
ret.api = tmp;
@@ -102,6 +104,7 @@ static Caller fetch_efl_super_class(const_gimple stmt)
Fetch_Result first = _fetch_first_argument(stmt, 0);
if (!first.valid) return ret;
ret.called_api = IDENTIFIER_POINTER(DECL_NAME(called_api_tree));
+ ret.called_api_decl = called_api_tree;
if (!!strncmp(first.api_name, "efl_super", 9)) return ret;
//copy the name we have inside efl_super
@@ -109,6 +112,7 @@ static Caller fetch_efl_super_class(const_gimple stmt)
if (!argument_efl_super.valid) return ret;
ret.klass = argument_efl_super.api_name;
ret.klass_decl = argument_efl_super.api;
+
ret.valid = true;
return ret;
@@ -121,6 +125,9 @@ static unsigned int eo_execute(void)
//fprintf(stderr, "Function %s eval\n", get_name(cfun->decl));
+ //FIXME check if this is a real eo op, with Eo *obj, and *pd as next agument
+ //FIXME therefore we need *something* to check if this is really
+
gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
entry_bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
@@ -133,6 +140,7 @@ static unsigned int eo_execute(void)
struct Caller c = fetch_efl_super_class(stmt);
tree replacement_candidate = NULL;
+ tree provider_of_replacement_candidate = NULL;
if (!c.klass)
continue;
@@ -156,10 +164,46 @@ static unsigned int eo_execute(void)
if (!!strncmp(TREE_STRING_POINTER(call), c.called_api, strlen(c.called_api))) continue;
+ provider_of_replacement_candidate = providing_class;
replacement_candidate = implementation;
}
if (!replacement_candidate) continue;
fprintf(stderr, "Replace! %s %s\n", c.called_api, TREE_STRING_POINTER(replacement_candidate));
+
+ //Create a new call to the found replacement candidate
+
+ //FIXME we need here:
+ //replace the called api with the replacement_candidate
+ //add another argument "pd - <my_class>_pd_offset + <providing_class>_pd_offset" (TODO check if these are mixins)
+ vec<tree> argument_types;
+ unsigned int i = 0;
+ argument_types.create(10);
+ for (tree argument = DECL_ARGUMENTS(c.called_api_decl); argument; argument = TREE_CHAIN(argument), i++)
+ {
+ if (!argument_types.space(i + 1))
+ argument_types.safe_grow(i + 1);
+ if (i == 0) {
+ argument_types[i] = argument;
+ } else {
+ argument_types[i + 1] = argument;
+ }
+ }
+ argument_types[1] = argument_types[0]; //FIXME fill the second argument to contain the pd argument
+ tree result = DECL_RESULT(c.called_api_decl);
+ if (!result)
+ result = void_type_node;
+ tree implementation_function_types = build_function_type_array(result, i + 1, argument_types.address()); //CRASH
+ tree implementation_function_declaration = build_fn_decl(TREE_STRING_POINTER(replacement_candidate), implementation_function_types);
+ vec<tree> new_arguments;
+ new_arguments.create(gimple_call_num_args(stmt) + 1);
+ new_arguments[0] = gimple_call_arg(stmt, 0);
+ new_arguments[1] = new_arguments[0]; //FIXME create calls to second argument of cfun pd + and -
+ for (unsigned int i = 1; i < gimple_call_num_args(stmt); ++i)
+ {
+ new_arguments[i + 1] = gimple_call_arg(stmt, i);
+ }
+ gcall *new_call = gimple_build_call_vec(implementation_function_declaration, new_arguments);
+ gsi_replace(&gsi, new_call, true);
}
}
return 0;
@@ -202,7 +246,7 @@ handle_user_attribute (tree *node, tree name, tree args,
}
static struct attribute_spec next_hop_attr =
- { "register_next", 3, 3, true, false, false, true, handle_user_attribute, NULL};
+ { "register_next", 4, 4, 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.c b/src/lib/eo/eo.c
index f978a59dac..d043fd914a 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -1818,9 +1818,21 @@ efl_class_offset(const Efl_Class *klass_id)
EAPI unsigned int
efl_class_mixin_offset(const Efl_Class *klass_id, const Efl_Class *mixin_id)
{
- /* FIXME */
+ EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, 0);
+ EO_CLASS_POINTER_RETURN_VAL(mixin_id, mixin, 0);
+ Eo_Extension_Data_Offset *doff_itr = klass->extn_data_off;
+
+ if (!doff_itr)
+ return 0;
+
+ while (doff_itr->klass)
+ {
+ if (doff_itr->klass == mixin)
+ return doff_itr->offset;
+ doff_itr++;
+ }
- return -1;
+ return 0;
}