From: Michael Beck Date: Mon, 27 Sep 2004 14:54:33 +0000 (+0000) Subject: Added a "virtualization" layer for the ident module. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=109b367e18cda22744a532c734ecfbf6220d6c2d;p=libfirm Added a "virtualization" layer for the ident module. The ident module can now be exchanged by an user implementation using the ident_if_t structure. [r3970] --- diff --git a/ir/common/firm.c b/ir/common/firm.c index a1e2655b5..40936852f 100644 --- a/ir/common/firm.c +++ b/ir/common/firm.c @@ -51,7 +51,7 @@ init_firm(const firm_parameter_t *param) } /* initialize all ident stuff */ - init_ident(1024); + init_ident(def_params.id_if, 1024); /* enhanced statistics, need idents */ init_stat(def_params.enable_statistics); /* create the type kinds. */ @@ -76,10 +76,9 @@ init_firm(const firm_parameter_t *param) /* Constructs some idents needed. */ init_type(); /* allocate a hash table. */ - init_type_identify(def_params.compare_types_func, def_params.hash_types_func); + init_type_identify(def_params.ti_if); /* Init reflection facility. */ init_rflct(); - } diff --git a/ir/common/firm.h b/ir/common/firm.h index fd8ef54f7..a9cf7ae3e 100644 --- a/ir/common/firm.h +++ b/ir/common/firm.h @@ -142,17 +142,17 @@ struct _firm_parameter_t { default_initialize_local_variable_func_t *initialize_local_func; /** - * The compare function is used to identify equal types. If not set - * it is initialized with the function compare_strict(). + * The interface functions for the type identification module. + * If not set, the default implementation with compare_strict() and + * hash_name() will be used. */ - compare_types_func_t *compare_types_func; + type_identify_if_t *ti_if; + /** - * The hash function is used to identify equal types. It calculates a hash - * value of a type. Note, that the hash value for equal types must be identical. - * If not set it is initialized with the function hash_name(). + * The interface for the ident module. + * If not set, the default libFirm ident module (using hash sets). */ - hash_types_func_t *hash_types_func; - + ident_if_t *id_if; }; diff --git a/ir/ident/ident.c b/ir/ident/ident.c index 19d9aabe3..3d014a712 100644 --- a/ir/ident/ident.c +++ b/ir/ident/ident.c @@ -21,58 +21,166 @@ #include #include "ident_t.h" +#include "set.h" + +/** The current ident module implementation. */ +static ident_if_t impl; + +/** + * Stores a string in the ident module and returns a handle for the string. + * + * @param handle the handle for the set + * @param str the string which shall be stored + * + * @return id - a handle for the generated ident + * + * Default implementation using libfirm sets. + */ +static ident *set_new_id_from_chars(void *handle, const char *str, int len) +{ + set *id_set = handle; + + assert(len > 0); + return (ident *)set_hinsert0(id_set, str, len, ID_HASH(str, len)); +} + +/** + * Stores a string in the ident module and returns a handle for the string. + * + * @param handle the handle for the set + * @param str the string (or whatever) which shall be stored + * @param len the length of the data in bytes + * + * Default implementation using libfirm sets. + */ +static ident *set_new_id_from_str(void *handle, const char *str) +{ + assert(str); + return (ident *)set_new_id_from_chars(handle, str, strlen(str)); +} + +/** + * Returns a string represented by an ident. + * + * @param handle the handle for the set + * @param id the ident + * + * Default implementation using libfirm sets. + */ +static const char *set_get_id_str(void *handle, ident *id) +{ + struct set_entry *entry = (struct set_entry *)id; + + return (const char *)entry->dptr; +} + +/** + * Returns the length of the string represented by an ident. + * + * @param handle the handle for the set + * @param id the ident + * + * Default implementation using libfirm sets. + */ +static int set_get_id_strlen(void *handle, ident *id) +{ + struct set_entry *entry = (struct set_entry *)id; + + return entry->size; +} -set *__id_set; +/** + * Default implementation using libfirm sets. + */ +void set_finish_ident(void *handle) { + set *id_set = handle; + + del_set(id_set); +} -void init_ident(int initial_n_idents) +/** + * Default implementation if no new_id_from_str() is provided. + */ +static ident *def_new_id_from_str(void *handle, const char *str) { - __id_set = new_set(memcmp, initial_n_idents); + return impl.new_id_from_chars(handle, str, strlen(str)); } -void finish_ident (void) { - del_set(__id_set); - __id_set = NULL; +/** + * Default implementation if no get_id_strlen() is provided. + */ +static int def_get_id_strlen(void *handle, ident *id) +{ + return strlen(impl.get_id_str(handle, id)); } -ident *(new_id_from_chars)(const char *str, int len) +/* Initialize the ident module. */ +void init_ident(ident_if_t *id_if, int initial_n_idents) { - return __id_from_str(str, len); + if (id_if) { + memcpy(&impl, id_if, sizeof(impl)); + + if (! impl.new_id_from_str) + impl.new_id_from_str = def_new_id_from_str; + if (! impl.get_id_strlen) + impl.get_id_strlen = def_get_id_strlen; + } + else { + impl.new_id_from_str = set_new_id_from_str; + impl.new_id_from_chars = set_new_id_from_chars; + impl.get_id_str = set_get_id_str; + impl.get_id_strlen = set_get_id_strlen; + impl.finish_ident = set_finish_ident; + + impl.handle = new_set(memcmp, initial_n_idents); + } } ident *new_id_from_str(const char *str) { assert(str); - return new_id_from_chars(str, strlen(str)); + return impl.new_id_from_str(impl.handle, str); } -const char *(get_id_str)(ident *id) +ident *new_id_from_chars(const char *str, int len) { - return __get_id_str(id); + assert(len > 0); + return impl.new_id_from_chars(impl.handle, str, len); } -int (get_id_strlen)(ident *id) +const char *get_id_str(ident *id) { - return __get_id_strlen(id); + return impl.get_id_str(impl.handle, id); +} + +int get_id_strlen(ident *id) +{ + return impl.get_id_strlen(impl.handle, id); +} + +void finish_ident(void) { + if (impl.finish_ident) + impl.finish_ident(impl.handle); } int id_is_prefix(ident *prefix, ident *id) { if (get_id_strlen(prefix) > get_id_strlen(id)) return 0; - return 0 == memcmp(prefix->dptr, id->dptr, get_id_strlen(prefix)); + return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix)); } int id_is_suffix(ident *suffix, ident *id) { int suflen = get_id_strlen(suffix); int idlen = get_id_strlen(id); - char *part; + const char *part; if (suflen > idlen) return 0; - part = (char *)id->dptr; + part = get_id_str(id); part = part + (idlen - suflen); - return 0 == memcmp(suffix->dptr, part, suflen); + return 0 == memcmp(get_id_str(suffix), part, suflen); } int id_contains_char(ident *id, char c) diff --git a/ir/ident/ident.h b/ir/ident/ident.h index 27c406847..64550b925 100644 --- a/ir/ident/ident.h +++ b/ir/ident/ident.h @@ -33,7 +33,52 @@ * An ident represents an unique string. The == operator * is sufficient to compare two idents. */ -typedef const struct set_entry ident; +typedef const struct ident ident; + +/** + * The ident module interface. + */ +typedef struct _ident_if_t { + /** + * Store a string and create an ident. + * This function may be NULL, new_id_from_chars() + * is then used to emulate it's behavior. + * + * @param str - the string which shall be stored + */ + ident *(*new_id_from_str)(void *handle, const char *str); + + /** + * Store a string and create an ident. + * + * @param str - the string (or whatever) which shall be stored + * @param len - the length of the data in bytes + */ + ident *(*new_id_from_chars)(void *handle, const char *str, int len); + + /** + * Returns a string represented by an ident. + */ + const char *(*get_id_str)(void *handle, ident *id); + + /** + * Returns the length of the string represented by an ident. + * This function may be NULL, get_id_str() is then used + * to emulate it's behavior. + * + * @param id - the ident + */ + int (*get_id_strlen)(void *handle, ident *id); + + /** + * Finish the ident module and frees all idents, may be NULL. + */ + void (*finish_ident)(void *handle); + + /** The handle. */ + void *handle; + +} ident_if_t; /** * Store a string and create an ident. diff --git a/ir/ident/ident_t.h b/ir/ident/ident_t.h index fd18d85c0..2aa19470d 100644 --- a/ir/ident/ident_t.h +++ b/ir/ident/ident_t.h @@ -14,37 +14,27 @@ # define _IDENT_T_H_ # include "ident.h" -# include "set.h" -void init_ident (int initial_n_idents); +/** + * Initialize the ident module. + * + * @param id_if The ident module interface, if NULL, the default + * libFirm ident module will be used. + * @param initial_n_idents Only used in the default libFirm ident module, initial + * number of entries in the hash table. + */ +void init_ident (ident_if_t *id_if, int initial_n_idents); + +/** + * Finishes the ident module, frees all entries. + */ void finish_ident (void); +/** The hash function of the internal ident module implementation. */ #define ID_HASH(str, len) \ ((( ((unsigned char *)(str))[0] * 33 \ + ((unsigned char *)(str))[(len)>>1]) * 31 \ + ((unsigned char *)(str))[(len)-1]) * 9 \ + (len)) - -/* ------------------------ * - * inline functions * - * ------------------------ */ -extern set *__id_set; - -static INLINE ident * -__id_from_str(const char *str, int len) -{ - assert(len > 0); - return set_hinsert0(__id_set, str, len, ID_HASH(str, len)); -} - -static INLINE const char * __get_id_str(ident *id) { return (const char *)id->dptr; } - -static INLINE int __get_id_strlen(ident *id) { return id->size; } - - -#define new_id_from_chars(str, len) __id_from_str(str, len) -#define get_id_str(id) __get_id_str(id) -#define get_id_strlen(id) __get_id_strlen(id) - # endif /* _IDENT_T_H_ */