This commit is contained in:
Marcel Hollerbach 2020-07-01 21:16:47 +02:00
parent 7a70e7fc9a
commit 5e6cd86a88
4 changed files with 69 additions and 10 deletions

View File

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

View File

@ -1,13 +1,25 @@
#include <stdio.h>
#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)

View File

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

View File

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