forked from enlightenment/efl
edje: handle reallocation of pointed data properly for limits.
This commit is contained in:
parent
aba7e9892e
commit
4be4076cd4
|
@ -152,6 +152,8 @@ void data_write(void);
|
|||
void data_queue_face_group_lookup(const char *name);
|
||||
void data_queue_group_lookup(const char *name, Edje_Part *part);
|
||||
void data_queue_part_lookup(Edje_Part_Collection *pc, const char *name, int *dest);
|
||||
void data_queue_part_reallocated_lookup(Edje_Part_Collection *pc, const char *name,
|
||||
unsigned char **base, int offset);
|
||||
void data_queue_copied_part_lookup(Edje_Part_Collection *pc, int *src, int *dest);
|
||||
void data_queue_program_lookup(Edje_Part_Collection *pc, const char *name, int *dest);
|
||||
void data_queue_copied_program_lookup(Edje_Part_Collection *pc, int *src, int *dest);
|
||||
|
|
|
@ -2787,6 +2787,8 @@ st_collections_group_inherit(void)
|
|||
pcp2 = (Edje_Part_Collection_Parser *)pc2;
|
||||
pcp->default_mouse_events = pcp2->default_mouse_events;
|
||||
|
||||
// FIXME: Handle limits dup
|
||||
|
||||
#define STRDUP(x) x ? strdup(x) : NULL
|
||||
for (i = 0 ; i < pc2->parts_count ; i++)
|
||||
{
|
||||
|
@ -5507,21 +5509,11 @@ st_collections_group_parts_part_description_limit(void)
|
|||
|
||||
pc = eina_list_data_get(eina_list_last(edje_collections));
|
||||
count = pc->limits.parts_count++;
|
||||
// XXX: the data_queue_part_lookup uses a pointer TO the
|
||||
// int id to fill in with the name in the parts[] array
|
||||
// BUT... we REALLOC it.. which means this memory can
|
||||
// be reloacted on realloc... so the lookups are invalid.
|
||||
//
|
||||
// as a QUICK fix this will just over-allocate a big big blob
|
||||
// so we can queue a lot of limit lookups
|
||||
// OLD code.... fix sometime
|
||||
// pc->limits.parts = realloc(pc->limits.parts,
|
||||
// pc->limits.parts_count * sizeof (Edje_Part_Limit));
|
||||
// temporary over-alloc of 128 slots to fix realloc + lookup bug
|
||||
if (!pc->limits.parts)
|
||||
pc->limits.parts = malloc(128 * sizeof (Edje_Part_Limit));
|
||||
data_queue_part_lookup(pc, current_part->name,
|
||||
&(pc->limits.parts[count].part));
|
||||
pc->limits.parts = realloc(pc->limits.parts,
|
||||
pc->limits.parts_count * sizeof (Edje_Part_Limit));
|
||||
data_queue_part_reallocated_lookup(pc, current_part->name,
|
||||
(unsigned char**) &(pc->limits.parts),
|
||||
(unsigned char*) &pc->limits.parts[count].part - (unsigned char*) pc->limits.parts); //fixme
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
typedef struct _External_Lookup External_Lookup;
|
||||
typedef struct _Part_Lookup Part_Lookup;
|
||||
typedef struct _Part_Lookup_Key Part_Lookup_Key;
|
||||
typedef struct _Program_Lookup Program_Lookup;
|
||||
typedef struct _Group_Lookup Group_Lookup;
|
||||
typedef struct _Image_Lookup Image_Lookup;
|
||||
|
@ -39,11 +40,25 @@ struct _External_Lookup
|
|||
char *name;
|
||||
};
|
||||
|
||||
struct _Part_Lookup
|
||||
struct _Part_Lookup_Key
|
||||
{
|
||||
Edje_Part_Collection *pc;
|
||||
char *name;
|
||||
|
||||
union {
|
||||
int *dest;
|
||||
struct {
|
||||
unsigned char **base;
|
||||
int offset;
|
||||
} reallocated;
|
||||
} mem;
|
||||
|
||||
Eina_Bool stable : 1;
|
||||
};
|
||||
|
||||
struct _Part_Lookup
|
||||
{
|
||||
Part_Lookup_Key key;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct _Program_Lookup
|
||||
|
@ -201,28 +216,96 @@ error_and_abort(Eet_File *ef EINA_UNUSED, const char *fmt, ...)
|
|||
}
|
||||
|
||||
static unsigned int
|
||||
_double_pointer_key_length(const void *key EINA_UNUSED)
|
||||
_part_lookup_key_length(const void *key EINA_UNUSED)
|
||||
{
|
||||
return sizeof (void*) * 2;
|
||||
return sizeof (Part_Lookup_Key);
|
||||
}
|
||||
|
||||
static int
|
||||
_double_pointer_key_cmp(const void *key1, int key1_length,
|
||||
_part_lookup_key_pc_cmp(const void *key1, int key1_length EINA_UNUSED,
|
||||
const void *key2, int key2_length EINA_UNUSED)
|
||||
{
|
||||
return memcmp(key1, key2, key1_length);
|
||||
const Part_Lookup_Key *a = key1;
|
||||
const Part_Lookup_Key *b = key2;
|
||||
uintptr_t delta;
|
||||
|
||||
delta = a->pc - b->pc;
|
||||
if (delta) return delta;
|
||||
|
||||
if (a->stable) return a->mem.dest - b->mem.dest;
|
||||
|
||||
delta = a->mem.reallocated.base - b->mem.reallocated.base;
|
||||
if (delta) return delta;
|
||||
return a->mem.reallocated.offset - b->mem.reallocated.offset;
|
||||
}
|
||||
|
||||
static int
|
||||
_double_pointer_key_hash(const void *key, int key_length EINA_UNUSED)
|
||||
_part_lookup_key_pc_hash(const void *key, int key_length EINA_UNUSED)
|
||||
{
|
||||
const Part_Lookup_Key *a = key;
|
||||
|
||||
if (a->stable)
|
||||
{
|
||||
#ifdef __LP64__
|
||||
return eina_hash_int64(key, sizeof (void*)) ^
|
||||
eina_hash_int64((void*)(((unsigned char*) key) + sizeof (void*)), sizeof (void*));
|
||||
return eina_hash_int64((uintptr_t) &a->pc, sizeof (void*)) ^
|
||||
eina_hash_int64((uintptr_t) &a->mem.dest, sizeof (void*));
|
||||
#else
|
||||
/* double 32 bits pointer is ... 64bits awesome ! */
|
||||
return eina_hash_int64(key, key_length);
|
||||
return eina_hash_int32((uintptr_t*) &a->pc, sizeof (void*)) ^
|
||||
eina_hash_int32((uintptr_t*) &a->mem.dest, sizeof (void*));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __LP64__
|
||||
return eina_hash_int64((uintptr_t *) &a->pc, sizeof (void*)) ^
|
||||
eina_hash_int64((uintptr_t *) &a->mem.reallocated.base, sizeof (void*)) ^
|
||||
eina_hash_int32((unsigned int *) &a->mem.reallocated.offset, sizeof (int));
|
||||
#else
|
||||
return eina_hash_int32((uintptr_t *) &a->pc, sizeof (void*)) ^
|
||||
eina_hash_int32((uintptr_t *) &a->mem.reallocated.base, sizeof (void*)) ^
|
||||
eina_hash_int32((unsigned int *) &a->mem.reallocated.offset, sizeof (int));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_part_lookup_key_cmp(const void *key1, int key1_length EINA_UNUSED,
|
||||
const void *key2, int key2_length EINA_UNUSED)
|
||||
{
|
||||
const Part_Lookup_Key *a = key1;
|
||||
const Part_Lookup_Key *b = key2;
|
||||
uintptr_t delta;
|
||||
|
||||
if (a->stable) return a->mem.dest - b->mem.dest;
|
||||
|
||||
delta = a->mem.reallocated.base - b->mem.reallocated.base;
|
||||
if (delta) return delta;
|
||||
return a->mem.reallocated.offset - b->mem.reallocated.offset;
|
||||
}
|
||||
|
||||
static int
|
||||
_part_lookup_key_hash(const void *key, int key_length EINA_UNUSED)
|
||||
{
|
||||
const Part_Lookup_Key *a = key;
|
||||
|
||||
if (a->stable)
|
||||
{
|
||||
#ifdef __LP64__
|
||||
return eina_hash_int64((uintptr_t *) &a->mem.dest, sizeof (void*));
|
||||
#else
|
||||
return eina_hash_int32((uintptr_t *) &a->mem.dest, sizeof (void*));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __LP64__
|
||||
return eina_hash_int64((uintptr_t *) &a->mem.reallocated.base, sizeof (void*)) ^
|
||||
eina_hash_int32((unsigned int *) &a->mem.reallocated.offset, sizeof (int));
|
||||
#else
|
||||
return eina_hash_int32((uintptr_t *) &a->mem.reallocated.base, sizeof (void*)) ^
|
||||
eina_hash_int32((unsigned int *) &a->mem.reallocated.offset, sizeof (int));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -238,10 +321,14 @@ data_setup(void)
|
|||
edd_edje_file = _edje_edd_edje_file;
|
||||
edd_edje_part_collection = _edje_edd_edje_part_collection;
|
||||
|
||||
part_dest_lookup = eina_hash_pointer_new(EINA_FREE_CB(eina_list_free));
|
||||
part_pc_dest_lookup = eina_hash_new(EINA_KEY_LENGTH(_double_pointer_key_length),
|
||||
EINA_KEY_CMP(_double_pointer_key_cmp),
|
||||
EINA_KEY_HASH(_double_pointer_key_hash),
|
||||
part_dest_lookup = eina_hash_new(EINA_KEY_LENGTH(_part_lookup_key_length),
|
||||
EINA_KEY_CMP(_part_lookup_key_cmp),
|
||||
EINA_KEY_HASH(_part_lookup_key_hash),
|
||||
EINA_FREE_CB(eina_list_free),
|
||||
8);
|
||||
part_pc_dest_lookup = eina_hash_new(EINA_KEY_LENGTH(_part_lookup_key_length),
|
||||
EINA_KEY_CMP(_part_lookup_key_pc_cmp),
|
||||
EINA_KEY_HASH(_part_lookup_key_pc_hash),
|
||||
EINA_FREE_CB(data_part_lookup_free),
|
||||
8);
|
||||
}
|
||||
|
@ -1812,12 +1899,13 @@ data_queue_face_group_lookup(const char *name)
|
|||
void
|
||||
data_queue_part_lookup(Edje_Part_Collection *pc, const char *name, int *dest)
|
||||
{
|
||||
void *key[2];
|
||||
Part_Lookup_Key key;
|
||||
Part_Lookup *pl = NULL;
|
||||
Eina_List *list;
|
||||
|
||||
key[0] = pc;
|
||||
key[1] = dest;
|
||||
key.pc = pc;
|
||||
key.mem.dest = dest;
|
||||
key.stable = EINA_TRUE;
|
||||
|
||||
pl = eina_hash_find(part_pc_dest_lookup, &key);
|
||||
if (pl)
|
||||
|
@ -1829,9 +1917,9 @@ data_queue_part_lookup(Edje_Part_Collection *pc, const char *name, int *dest)
|
|||
}
|
||||
else
|
||||
{
|
||||
list = eina_hash_find(part_dest_lookup, &pl->dest);
|
||||
list = eina_hash_find(part_dest_lookup, &pl->key);
|
||||
list = eina_list_remove(list, pl);
|
||||
eina_hash_set(part_dest_lookup, &pl->dest, list);
|
||||
eina_hash_set(part_dest_lookup, &pl->key, list);
|
||||
eina_hash_del(part_pc_dest_lookup, &key, pl);
|
||||
}
|
||||
return;
|
||||
|
@ -1840,15 +1928,63 @@ data_queue_part_lookup(Edje_Part_Collection *pc, const char *name, int *dest)
|
|||
if (!name[0]) return;
|
||||
|
||||
pl = mem_alloc(SZ(Part_Lookup));
|
||||
pl->pc = pc;
|
||||
pl->name = mem_strdup(name);
|
||||
pl->dest = dest;
|
||||
pl->key.pc = pc;
|
||||
pl->key.mem.dest = dest;
|
||||
pl->key.stable = EINA_TRUE;
|
||||
|
||||
eina_hash_add(part_pc_dest_lookup, &key, pl);
|
||||
|
||||
list = eina_hash_find(part_dest_lookup, &pl->dest);
|
||||
list = eina_hash_find(part_dest_lookup, &pl->key);
|
||||
list = eina_list_prepend(list, pl);
|
||||
eina_hash_set(part_dest_lookup, &pl->dest, list);
|
||||
eina_hash_set(part_dest_lookup, &pl->key, list);
|
||||
}
|
||||
|
||||
void
|
||||
data_queue_part_reallocated_lookup(Edje_Part_Collection *pc, const char *name,
|
||||
unsigned char **base, int offset)
|
||||
{
|
||||
Part_Lookup_Key key;
|
||||
Part_Lookup *pl = NULL;
|
||||
Eina_List *list;
|
||||
|
||||
key.pc = pc;
|
||||
key.mem.reallocated.base = base;
|
||||
key.mem.reallocated.offset = offset;
|
||||
key.stable = EINA_FALSE;
|
||||
|
||||
pl = eina_hash_find(part_pc_dest_lookup, &key);
|
||||
if (pl)
|
||||
{
|
||||
if (name[0])
|
||||
{
|
||||
free(pl->name);
|
||||
pl->name = mem_strdup(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
list = eina_hash_find(part_dest_lookup, &pl->key);
|
||||
list = eina_list_remove(list, pl);
|
||||
eina_hash_set(part_dest_lookup, &pl->key, list);
|
||||
eina_hash_del(part_pc_dest_lookup, &key, pl);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!name[0]) return;
|
||||
|
||||
pl = mem_alloc(SZ(Part_Lookup));
|
||||
pl->name = mem_strdup(name);
|
||||
pl->key.pc = pc;
|
||||
pl->key.mem.reallocated.base = base;
|
||||
pl->key.mem.reallocated.offset = offset;
|
||||
pl->key.stable = EINA_FALSE;
|
||||
|
||||
eina_hash_add(part_pc_dest_lookup, &key, pl);
|
||||
|
||||
list = eina_hash_find(part_dest_lookup, &pl->key);
|
||||
list = eina_list_prepend(list, pl);
|
||||
eina_hash_set(part_dest_lookup, &pl->key, list);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1857,21 +1993,27 @@ data_queue_copied_part_lookup(Edje_Part_Collection *pc, int *src, int *dest)
|
|||
Eina_List *list;
|
||||
Eina_List *l;
|
||||
Part_Lookup *pl;
|
||||
Part_Lookup_Key key;
|
||||
|
||||
list = eina_hash_find(part_dest_lookup, &src);
|
||||
key.pc = NULL;
|
||||
key.mem.dest = src;
|
||||
key.stable = EINA_TRUE;
|
||||
|
||||
list = eina_hash_find(part_dest_lookup, &key);
|
||||
EINA_LIST_FOREACH(list, l, pl)
|
||||
if (pl->key.stable)
|
||||
data_queue_part_lookup(pc, pl->name, dest);
|
||||
}
|
||||
|
||||
void
|
||||
data_queue_anonymous_lookup(Edje_Part_Collection *pc, Edje_Program *ep, int *dest)
|
||||
{
|
||||
Eina_List *l, *l2;
|
||||
Eina_List *l, *l1, *l2, *l3;
|
||||
Program_Lookup *pl;
|
||||
|
||||
if (!ep) return; /* FIXME: should we stop compiling ? */
|
||||
|
||||
EINA_LIST_FOREACH(program_lookups, l, pl)
|
||||
EINA_LIST_FOREACH_SAFE(program_lookups, l, l1, pl)
|
||||
{
|
||||
if (pl->u.ep == ep)
|
||||
{
|
||||
|
@ -1880,16 +2022,16 @@ data_queue_anonymous_lookup(Edje_Part_Collection *pc, Edje_Program *ep, int *des
|
|||
|
||||
cd = eina_list_data_get(eina_list_last(codes));
|
||||
|
||||
EINA_LIST_FOREACH(cd->programs, l2, cp)
|
||||
EINA_LIST_FOREACH_SAFE(cd->programs, l2, l3, cp)
|
||||
{
|
||||
if (&(cp->id) == pl->dest)
|
||||
{
|
||||
cd->programs = eina_list_remove(cd->programs, cp);
|
||||
cd->programs = eina_list_remove_list(cd->programs, l2);
|
||||
free(cp);
|
||||
cp = NULL;
|
||||
}
|
||||
}
|
||||
program_lookups = eina_list_remove(program_lookups, pl);
|
||||
program_lookups = eina_list_remove_list(program_lookups, l);
|
||||
free(pl);
|
||||
}
|
||||
}
|
||||
|
@ -2053,6 +2195,20 @@ handle_slave_lookup(Eina_List *list, int *master, int value)
|
|||
*sl->slave = value;
|
||||
}
|
||||
|
||||
static void
|
||||
data_process_part_set(Part_Lookup *target, int value)
|
||||
{
|
||||
if (target->key.stable)
|
||||
{
|
||||
*(target->key.mem.dest) = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
*((int*)(*target->key.mem.reallocated.base +
|
||||
target->key.mem.reallocated.offset)) = value;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
data_process_lookups(void)
|
||||
{
|
||||
|
@ -2149,30 +2305,43 @@ data_process_lookups(void)
|
|||
|
||||
if (!strcmp(part->name, "-"))
|
||||
{
|
||||
*(part->dest) = -1;
|
||||
data_process_part_set(part, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *alias;
|
||||
alias = eina_hash_find(part->pc->alias, part->name);
|
||||
alias = eina_hash_find(part->key.pc->alias, part->name);
|
||||
if (!alias)
|
||||
alias = part->name;
|
||||
for (i = 0; i < part->pc->parts_count; ++i)
|
||||
for (i = 0; i < part->key.pc->parts_count; ++i)
|
||||
{
|
||||
ep = part->pc->parts[i];
|
||||
ep = part->key.pc->parts[i];
|
||||
|
||||
if ((ep->name) && (!strcmp(ep->name, alias)))
|
||||
{
|
||||
handle_slave_lookup(part_slave_lookups, part->dest, ep->id);
|
||||
*(part->dest) = ep->id;
|
||||
int *master;
|
||||
|
||||
if (part->key.stable)
|
||||
{
|
||||
master = part->key.mem.dest;
|
||||
}
|
||||
else
|
||||
{
|
||||
master = (int*)(*part->key.mem.reallocated.base +
|
||||
part->key.mem.reallocated.offset);
|
||||
}
|
||||
handle_slave_lookup(part_slave_lookups,
|
||||
master,
|
||||
ep->id);
|
||||
data_process_part_set(part, ep->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == part->pc->parts_count)
|
||||
if (i == part->key.pc->parts_count)
|
||||
{
|
||||
ERR("Unable to find part name \"%s\" needed in group '%s'.",
|
||||
alias, part->pc->part);
|
||||
alias, part->key.pc->part);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue