wip - we are finally replacing calls

and we are crashing ... but we are getting there ... :)
This commit is contained in:
Marcel Hollerbach 2020-07-08 14:20:23 +02:00
parent 500d938c7f
commit c724083d06
3 changed files with 67 additions and 8 deletions

View File

@ -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");

View File

@ -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)

View File

@ -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;
return -1;
if (!doff_itr)
return 0;
while (doff_itr->klass)
{
if (doff_itr->klass == mixin)
return doff_itr->offset;
doff_itr++;
}
return 0;
}