Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions class.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,23 @@ void freeMethodLists(Class aClass);

void objc_load_class(struct objc_class *cls);

/**
* Enumerator for a class table. Must have the same layout as the internal
* version.
*/
struct class_table_enumerator
{
void *table;
unsigned int seen;
unsigned int index;
};

/**
* Iterate over the class table returning the next class and then NULL after
* all classes have been enumerated.
*/
PRIVATE Class class_table_next(struct class_table_enumerator *e);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
27 changes: 18 additions & 9 deletions class_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,6 @@ PRIVATE Class class_table_get_safe(const char *class_name)
return class_table_internal_table_get(class_table, class_name);
}

PRIVATE Class class_table_next(void **e)
{
return class_table_internal_next(class_table,
(struct class_table_internal_table_enumerator**)e);
}

PRIVATE BOOL objc_resolve_class(Class cls);
PRIVATE void init_class_tables(void)
{
Expand Down Expand Up @@ -500,6 +494,11 @@ PRIVATE void class_table_remove(Class cls)
class_table_internal_remove(class_table, (void*)cls->name);
}

PRIVATE Class class_table_next(struct class_table_enumerator *e)
{
return class_table_internal_next(class_table, (struct class_table_internal_table_enumerator*)e);
}


////////////////////////////////////////////////////////////////////////////////
// Public API
Expand All @@ -512,14 +511,13 @@ int objc_getClassList(Class *buffer, int bufferLen)
return class_table->table_used;
}
int count = 0;
struct class_table_internal_table_enumerator *e = NULL;
struct class_table_internal_table_enumerator e = MAP_TABLE_ENUMERATOR_INITIALISER;
Class next;
while (count < bufferLen &&
(next = class_table_internal_next(class_table, &e)))
{
buffer[count++] = next;
}
free(e);
return count;
}
Class *objc_copyClassList(unsigned int *outCount)
Expand Down Expand Up @@ -595,7 +593,18 @@ id objc_get_meta_class(const char *name)

Class objc_next_class(void **enum_state)
{
return class_table_next ( enum_state);
if (*enum_state == NULL)
{
*enum_state = calloc(1, sizeof(struct class_table_internal_table_enumerator));
}
Class next = class_table_internal_next(class_table,
*(struct class_table_internal_table_enumerator**)enum_state);
if (next == NULL)
{
free(*enum_state);
*enum_state = NULL;
}
return next;
}

Class class_pose_as(Class impostor, Class super_class)
Expand Down
4 changes: 1 addition & 3 deletions dtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,6 @@ PRIVATE dtable_t create_dtable_for_class(Class class, dtable_t root_dtable)
}


Class class_table_next(void **e);

PRIVATE void objc_resize_dtables(uint32_t newSize)
{
// If dtables already have enough space to store all registered selectors, do nothing
Expand All @@ -636,7 +634,7 @@ PRIVATE void objc_resize_dtables(uint32_t newSize)
}
}
// Resize all existing dtables
void *e = NULL;
struct class_table_enumerator e = {NULL, 0, 0};
struct objc_class *next;
while ((next = class_table_next(&e)))
{
Expand Down
37 changes: 21 additions & 16 deletions hash_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ struct PREFIX(_table_enumerator)
unsigned int index;
};

/**
* Initialisation value for a new map enumerator.
*/
#define MAP_TABLE_ENUMERATOR_INITIALISER {NULL, 0, 0}


static inline PREFIX(_table_cell) PREFIX(_table_lookup)(PREFIX(_table) *table,
uint32_t hash)
{
Expand Down Expand Up @@ -465,42 +471,41 @@ static MAP_TABLE_VALUE_TYPE*
static MAP_TABLE_VALUE_TYPE
#endif
PREFIX(_next)(PREFIX(_table) *table,
struct PREFIX(_table_enumerator) **state)
struct PREFIX(_table_enumerator) *state)
{
if (NULL == *state)
if (NULL == state->table)
{
*state = CALLOC(1, sizeof(struct PREFIX(_table_enumerator)));
// Make sure that we are not reallocating the table when we start
// enumerating
MAP_LOCK();
(*state)->table = table;
(*state)->index = -1;
state->table = table;
state->index = -1;
IF_NO_GC(__sync_fetch_and_add(&table->enumerator_count, 1);)
MAP_UNLOCK();
}
if ((*state)->seen >= (*state)->table->table_used)
if (state->seen >= state->table->table_used)
{
#ifndef ENABLE_GC
MAP_LOCK();
__sync_fetch_and_sub(&table->enumerator_count, 1);
MAP_UNLOCK();
free(*state);
state->table = NULL;
#endif
#ifdef MAP_TABLE_ACCESS_BY_REFERENCE
return NULL;
#else
return MAP_TABLE_VALUE_PLACEHOLDER;
#endif
}
while ((++((*state)->index)) < TABLE_SIZE((*state)->table))
while ((++(state->index)) < TABLE_SIZE(state->table))
{
if (!MAP_TABLE_VALUE_NULL((*state)->table->table[(*state)->index].value))
if (!MAP_TABLE_VALUE_NULL(state->table->table[state->index].value))
{
(*state)->seen++;
state->seen++;
#ifdef MAP_TABLE_ACCESS_BY_REFERENCE
return &(*state)->table->table[(*state)->index].value;
return &state->table->table[state->index].value;
#else
return (*state)->table->table[(*state)->index].value;
return state->table->table[state->index].value;
#endif
}
}
Expand All @@ -509,7 +514,7 @@ PREFIX(_next)(PREFIX(_table) *table,
MAP_LOCK();
table->enumerator_count--;
MAP_UNLOCK();
free(*state);
state->table = NULL;
#endif
#ifdef MAP_TABLE_ACCESS_BY_REFERENCE
return NULL;
Expand All @@ -529,12 +534,12 @@ static MAP_TABLE_VALUE_TYPE*
static MAP_TABLE_VALUE_TYPE
#endif
PREFIX(_current)(PREFIX(_table) *table,
struct PREFIX(_table_enumerator) **state)
struct PREFIX(_table_enumerator) *state)
{
#ifdef MAP_TABLE_ACCESS_BY_REFERENCE
return &(*state)->table->table[(*state)->index].value;
return &state->table->table[state->index].value;
#else
return (*state)->table->table[(*state)->index].value;
return state->table->table[state->index].value;
#endif
}

Expand Down
6 changes: 1 addition & 5 deletions protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,18 +508,14 @@ Protocol*__unsafe_unretained* objc_copyProtocolList(unsigned int *outCount)
unsigned int total = known_protocol_table->table_used;
Protocol **p = calloc(known_protocol_table->table_used, sizeof(Protocol*));

struct protocol_table_enumerator *e = NULL;
struct protocol_table_enumerator e = MAP_TABLE_ENUMERATOR_INITIALISER;
Protocol *next;

unsigned int count = 0;
while ((count < total) && (next = protocol_next(known_protocol_table, &e)))
{
p[count++] = next;
}
if (NULL != e)
{
free(e);
}
if (NULL != outCount)
{
*outCount = total;
Expand Down
Loading