Port sp_symhash to C++.
This commit is contained in:
parent
f5efdbf6f5
commit
5a4c50ce55
@ -42,6 +42,7 @@ binary = SM.Program(builder, 'spcomp')
|
|||||||
compiler = binary.compiler
|
compiler = binary.compiler
|
||||||
compiler.includes += [
|
compiler.includes += [
|
||||||
os.path.join(builder.sourcePath, 'public'),
|
os.path.join(builder.sourcePath, 'public'),
|
||||||
|
os.path.join(builder.sourcePath, 'public', 'amtl'),
|
||||||
os.path.join(builder.sourcePath, 'public', 'sourcepawn'),
|
os.path.join(builder.sourcePath, 'public', 'sourcepawn'),
|
||||||
os.path.join(builder.sourcePath, 'sourcepawn', 'compiler'),
|
os.path.join(builder.sourcePath, 'sourcepawn', 'compiler'),
|
||||||
os.path.join(builder.buildPath, 'includes'),
|
os.path.join(builder.buildPath, 'includes'),
|
||||||
@ -50,7 +51,8 @@ compiler.includes += [
|
|||||||
compiler.sourcedeps += packed_includes
|
compiler.sourcedeps += packed_includes
|
||||||
|
|
||||||
if compiler.cc.behavior == 'gcc':
|
if compiler.cc.behavior == 'gcc':
|
||||||
compiler.cflags += ['-std=c99', '-Wno-format']
|
compiler.cflags += ['-Wno-format']
|
||||||
|
compiler.c_only_flags += ['-std=c99']
|
||||||
if builder.target_platform == 'linux':
|
if builder.target_platform == 'linux':
|
||||||
compiler.postlink += ['-lgcc', '-lm']
|
compiler.postlink += ['-lgcc', '-lm']
|
||||||
elif compiler.cc.behavior == 'msvc':
|
elif compiler.cc.behavior == 'msvc':
|
||||||
@ -107,7 +109,7 @@ binary.sources += [
|
|||||||
'zlib/trees.c',
|
'zlib/trees.c',
|
||||||
'zlib/uncompr.c',
|
'zlib/uncompr.c',
|
||||||
'zlib/zutil.c',
|
'zlib/zutil.c',
|
||||||
'sp_symhash.c'
|
'sp_symhash.cpp'
|
||||||
]
|
]
|
||||||
if builder.target_platform != 'windows':
|
if builder.target_platform != 'windows':
|
||||||
binary.sources.append('binreloc.c')
|
binary.sources.append('binreloc.c')
|
||||||
|
@ -599,7 +599,11 @@ long pc_lengthbin(void *handle); /* return the length of the file */
|
|||||||
* files are "external"
|
* files are "external"
|
||||||
*/
|
*/
|
||||||
#if !defined SC_FUNC
|
#if !defined SC_FUNC
|
||||||
#define SC_FUNC
|
# if defined(__cplusplus)
|
||||||
|
# define SC_FUNC extern "C"
|
||||||
|
# else
|
||||||
|
# define SC_FUNC
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined SC_VDECL
|
#if !defined SC_VDECL
|
||||||
#define SC_VDECL extern
|
#define SC_VDECL extern
|
||||||
@ -616,7 +620,7 @@ SC_FUNC void set_extension(char *filename,char *extension,int force);
|
|||||||
SC_FUNC symbol *fetchfunc(char *name);
|
SC_FUNC symbol *fetchfunc(char *name);
|
||||||
SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag);
|
SC_FUNC char *operator_symname(char *symname,char *opername,int tag1,int tag2,int numtags,int resulttag);
|
||||||
SC_FUNC char *funcdisplayname(char *dest,char *funcname);
|
SC_FUNC char *funcdisplayname(char *dest,char *funcname);
|
||||||
SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr);
|
SC_FUNC int exprconst(cell *val,int *tag,symbol **symptr);
|
||||||
SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,int index);
|
SC_FUNC constvalue *append_constval(constvalue *table,const char *name,cell val,int index);
|
||||||
SC_FUNC constvalue *find_constval(constvalue *table,char *name,int index);
|
SC_FUNC constvalue *find_constval(constvalue *table,char *name,int index);
|
||||||
SC_FUNC void delete_consttable(constvalue *table);
|
SC_FUNC void delete_consttable(constvalue *table);
|
||||||
|
@ -2794,7 +2794,7 @@ static cell init(int ident,int *tag,int *errorfound)
|
|||||||
litidx=1; /* reset literal queue */
|
litidx=1; /* reset literal queue */
|
||||||
} /* if */
|
} /* if */
|
||||||
*tag=pc_tag_string;
|
*tag=pc_tag_string;
|
||||||
} else if (constexpr(&i,tag,NULL)){
|
} else if (exprconst(&i,tag,NULL)){
|
||||||
litadd(i); /* store expression result in literal table */
|
litadd(i); /* store expression result in literal table */
|
||||||
} else {
|
} else {
|
||||||
if (errorfound!=NULL)
|
if (errorfound!=NULL)
|
||||||
@ -2819,7 +2819,7 @@ static cell needsub(int *tag,constvalue **enumroot)
|
|||||||
if (matchtoken(']')) /* we have already seen "[" */
|
if (matchtoken(']')) /* we have already seen "[" */
|
||||||
return 0; /* zero size (like "char msg[]") */
|
return 0; /* zero size (like "char msg[]") */
|
||||||
|
|
||||||
constexpr(&val,tag,&sym); /* get value (must be constant expression) */
|
exprconst(&val,tag,&sym); /* get value (must be constant expression) */
|
||||||
if (val<0) {
|
if (val<0) {
|
||||||
error(9); /* negative array size is invalid; assumed zero */
|
error(9); /* negative array size is invalid; assumed zero */
|
||||||
val=0;
|
val=0;
|
||||||
@ -2891,7 +2891,7 @@ static void decl_const(int vclass)
|
|||||||
|
|
||||||
symbolline=fline; /* save line where symbol was found */
|
symbolline=fline; /* save line where symbol was found */
|
||||||
needtoken('=');
|
needtoken('=');
|
||||||
constexpr(&val,&exprtag,NULL); /* get value */
|
exprconst(&val,&exprtag,NULL); /* get value */
|
||||||
|
|
||||||
/* add_constant() checks for duplicate definitions */
|
/* add_constant() checks for duplicate definitions */
|
||||||
/* temporarily reset the line number to where the symbol was defined */
|
/* temporarily reset the line number to where the symbol was defined */
|
||||||
@ -4523,11 +4523,11 @@ static void decl_enum(int vclass)
|
|||||||
multiplier=1;
|
multiplier=1;
|
||||||
if (matchtoken('(')) {
|
if (matchtoken('(')) {
|
||||||
if (matchtoken(taADD)) {
|
if (matchtoken(taADD)) {
|
||||||
constexpr(&increment,NULL,NULL);
|
exprconst(&increment,NULL,NULL);
|
||||||
} else if (matchtoken(taMULT)) {
|
} else if (matchtoken(taMULT)) {
|
||||||
constexpr(&multiplier,NULL,NULL);
|
exprconst(&multiplier,NULL,NULL);
|
||||||
} else if (matchtoken(taSHL)) {
|
} else if (matchtoken(taSHL)) {
|
||||||
constexpr(&val,NULL,NULL);
|
exprconst(&val,NULL,NULL);
|
||||||
while (val-->0)
|
while (val-->0)
|
||||||
multiplier*=2;
|
multiplier*=2;
|
||||||
} /* if */
|
} /* if */
|
||||||
@ -4568,12 +4568,12 @@ static void decl_enum(int vclass)
|
|||||||
size=increment; /* default increment of 'val' */
|
size=increment; /* default increment of 'val' */
|
||||||
fieldtag=0; /* default field tag */
|
fieldtag=0; /* default field tag */
|
||||||
if (matchtoken('[')) {
|
if (matchtoken('[')) {
|
||||||
constexpr(&size,&fieldtag,NULL); /* get size */
|
exprconst(&size,&fieldtag,NULL); /* get size */
|
||||||
needtoken(']');
|
needtoken(']');
|
||||||
} /* if */
|
} /* if */
|
||||||
/* :TODO: do we need a size modifier here for pc_tag_string? */
|
/* :TODO: do we need a size modifier here for pc_tag_string? */
|
||||||
if (matchtoken('='))
|
if (matchtoken('='))
|
||||||
constexpr(&value,NULL,NULL); /* get value */
|
exprconst(&value,NULL,NULL); /* get value */
|
||||||
/* add_constant() checks whether a variable (global or local) or
|
/* add_constant() checks whether a variable (global or local) or
|
||||||
* a constant with the same name already exists
|
* a constant with the same name already exists
|
||||||
*/
|
*/
|
||||||
@ -5125,7 +5125,7 @@ static symbol *funcstub(int tokid, declinfo_t *decl, const int *thistag)
|
|||||||
tokeninfo(&val,&str);
|
tokeninfo(&val,&str);
|
||||||
insert_alias(sym->name,str);
|
insert_alias(sym->name,str);
|
||||||
} else {
|
} else {
|
||||||
constexpr(&val,NULL,NULL);
|
exprconst(&val,NULL,NULL);
|
||||||
sym->addr=val;
|
sym->addr=val;
|
||||||
/* At the moment, I have assumed that this syntax is only valid if
|
/* At the moment, I have assumed that this syntax is only valid if
|
||||||
* val < 0. To properly mix "normal" native functions and indexed
|
* val < 0. To properly mix "normal" native functions and indexed
|
||||||
@ -5728,7 +5728,7 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
|||||||
while (paranthese--)
|
while (paranthese--)
|
||||||
needtoken(')');
|
needtoken(')');
|
||||||
} else {
|
} else {
|
||||||
constexpr(&arg->defvalue.val,&arg->defvalue_tag,NULL);
|
exprconst(&arg->defvalue.val,&arg->defvalue_tag,NULL);
|
||||||
assert(type->numtags > 0);
|
assert(type->numtags > 0);
|
||||||
matchtag(type->tags[0], arg->defvalue_tag, TRUE);
|
matchtag(type->tags[0], arg->defvalue_tag, TRUE);
|
||||||
} /* if */
|
} /* if */
|
||||||
@ -6901,9 +6901,9 @@ static int doexpr2(int comma,int chkeffect,int allowarray,int mark_endexpr,
|
|||||||
return ident;
|
return ident;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* constexpr
|
/* exprconst
|
||||||
*/
|
*/
|
||||||
SC_FUNC int constexpr(cell *val,int *tag,symbol **symptr)
|
SC_FUNC int exprconst(cell *val,int *tag,symbol **symptr)
|
||||||
{
|
{
|
||||||
int ident,index;
|
int ident,index;
|
||||||
cell cidx;
|
cell cidx;
|
||||||
@ -7294,7 +7294,7 @@ static void doswitch(void)
|
|||||||
* parse all expressions until that special token.
|
* parse all expressions until that special token.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
constexpr(&val,NULL,NULL);
|
exprconst(&val,NULL,NULL);
|
||||||
/* Search the insertion point (the table is kept in sorted order, so
|
/* Search the insertion point (the table is kept in sorted order, so
|
||||||
* that advanced abstract machines can sift the case table with a
|
* that advanced abstract machines can sift the case table with a
|
||||||
* binary search). Check for duplicate case values at the same time.
|
* binary search). Check for duplicate case values at the same time.
|
||||||
|
@ -796,7 +796,7 @@ static int preproc_expr(cell *val,int *tag)
|
|||||||
term=strchr((char*)pline,'\0');
|
term=strchr((char*)pline,'\0');
|
||||||
assert(term!=NULL);
|
assert(term!=NULL);
|
||||||
chrcat((char*)pline,PREPROC_TERM); /* the "DEL" code (see SC.H) */
|
chrcat((char*)pline,PREPROC_TERM); /* the "DEL" code (see SC.H) */
|
||||||
result=constexpr(val,tag,NULL); /* get value (or 0 on error) */
|
result=exprconst(val,tag,NULL); /* get value (or 0 on error) */
|
||||||
*term='\0'; /* erase the token (if still present) */
|
*term='\0'; /* erase the token (if still present) */
|
||||||
lexclr(FALSE); /* clear any "pushed" tokens */
|
lexclr(FALSE); /* clear any "pushed" tokens */
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,230 +0,0 @@
|
|||||||
/* vim: set ts=4 sw=4 tw=99 et: */
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "sp_file_headers.h"
|
|
||||||
#include "sc.h"
|
|
||||||
#include "sp_symhash.h"
|
|
||||||
|
|
||||||
SC_FUNC uint32_t
|
|
||||||
NameHash(const char *str)
|
|
||||||
{
|
|
||||||
size_t len = strlen(str);
|
|
||||||
const uint8_t *data = (uint8_t *)str;
|
|
||||||
#undef get16bits
|
|
||||||
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|
|
||||||
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
|
|
||||||
#define get16bits(d) (*((const uint16_t *) (d)))
|
|
||||||
#endif
|
|
||||||
#if !defined (get16bits)
|
|
||||||
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
|
||||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
|
||||||
#endif
|
|
||||||
uint32_t hash = len, tmp;
|
|
||||||
int rem;
|
|
||||||
|
|
||||||
if (len <= 0 || data == NULL) return 0;
|
|
||||||
|
|
||||||
rem = len & 3;
|
|
||||||
len >>= 2;
|
|
||||||
|
|
||||||
/* Main loop */
|
|
||||||
for (;len > 0; len--) {
|
|
||||||
hash += get16bits (data);
|
|
||||||
tmp = (get16bits (data+2) << 11) ^ hash;
|
|
||||||
hash = (hash << 16) ^ tmp;
|
|
||||||
data += 2*sizeof (uint16_t);
|
|
||||||
hash += hash >> 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle end cases */
|
|
||||||
switch (rem) {
|
|
||||||
case 3: hash += get16bits (data);
|
|
||||||
hash ^= hash << 16;
|
|
||||||
hash ^= data[sizeof (uint16_t)] << 18;
|
|
||||||
hash += hash >> 11;
|
|
||||||
break;
|
|
||||||
case 2: hash += get16bits (data);
|
|
||||||
hash ^= hash << 11;
|
|
||||||
hash += hash >> 17;
|
|
||||||
break;
|
|
||||||
case 1: hash += *data;
|
|
||||||
hash ^= hash << 10;
|
|
||||||
hash += hash >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force "avalanching" of final 127 bits */
|
|
||||||
hash ^= hash << 3;
|
|
||||||
hash += hash >> 5;
|
|
||||||
hash ^= hash << 4;
|
|
||||||
hash += hash >> 17;
|
|
||||||
hash ^= hash << 25;
|
|
||||||
hash += hash >> 6;
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
|
|
||||||
#undef get16bits
|
|
||||||
}
|
|
||||||
|
|
||||||
SC_FUNC HashTable *NewHashTable()
|
|
||||||
{
|
|
||||||
HashTable *ht = (HashTable*)malloc(sizeof(HashTable));
|
|
||||||
if (!ht)
|
|
||||||
return ht;
|
|
||||||
ht->buckets = (HashEntry **)calloc(32, sizeof(HashEntry *));
|
|
||||||
if (!ht->buckets) {
|
|
||||||
free(ht);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ht->nbuckets = 32;
|
|
||||||
ht->nused = 0;
|
|
||||||
ht->bucketmask = 32 - 1;
|
|
||||||
return ht;
|
|
||||||
}
|
|
||||||
|
|
||||||
SC_FUNC void
|
|
||||||
DestroyHashTable(HashTable *ht)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
if (!ht)
|
|
||||||
return;
|
|
||||||
for (i = 0; i < ht->nbuckets; i++) {
|
|
||||||
HashEntry *he = ht->buckets[i];
|
|
||||||
while (he != NULL) {
|
|
||||||
HashEntry *next = he->next;
|
|
||||||
free(he);
|
|
||||||
he = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(ht->buckets);
|
|
||||||
free(ht);
|
|
||||||
}
|
|
||||||
|
|
||||||
SC_FUNC symbol *
|
|
||||||
FindTaggedInHashTable(HashTable *ht, const char *name, int fnumber,
|
|
||||||
int *cmptag)
|
|
||||||
{
|
|
||||||
int count=0;
|
|
||||||
symbol *firstmatch=NULL;
|
|
||||||
uint32_t hash = NameHash(name);
|
|
||||||
uint32_t bucket = hash & ht->bucketmask;
|
|
||||||
HashEntry *he = ht->buckets[bucket];
|
|
||||||
|
|
||||||
assert(cmptag!=NULL);
|
|
||||||
|
|
||||||
while (he != NULL) {
|
|
||||||
symbol *sym = he->sym;
|
|
||||||
if ((sym->parent==NULL || sym->ident==iCONSTEXPR) &&
|
|
||||||
(sym->fnumber<0 || sym->fnumber==fnumber) &&
|
|
||||||
(strcmp(sym->name, name) == 0))
|
|
||||||
{
|
|
||||||
/* return closest match or first match; count number of matches */
|
|
||||||
if (firstmatch==NULL)
|
|
||||||
firstmatch=sym;
|
|
||||||
if (*cmptag==0)
|
|
||||||
count++;
|
|
||||||
if (*cmptag==sym->tag) {
|
|
||||||
*cmptag=1; /* good match found, set number of matches to 1 */
|
|
||||||
return sym;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
he = he->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstmatch!=NULL)
|
|
||||||
*cmptag=count;
|
|
||||||
return firstmatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
SC_FUNC symbol *
|
|
||||||
FindInHashTable(HashTable *ht, const char *name, int fnumber)
|
|
||||||
{
|
|
||||||
uint32_t hash = NameHash(name);
|
|
||||||
uint32_t bucket = hash & ht->bucketmask;
|
|
||||||
HashEntry *he = ht->buckets[bucket];
|
|
||||||
|
|
||||||
while (he != NULL) {
|
|
||||||
symbol *sym = he->sym;
|
|
||||||
if ((sym->parent==NULL || sym->ident==iCONSTEXPR) &&
|
|
||||||
(sym->fnumber<0 || sym->fnumber==fnumber) &&
|
|
||||||
(strcmp(sym->name, name) == 0))
|
|
||||||
{
|
|
||||||
return sym;
|
|
||||||
}
|
|
||||||
he = he->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ResizeHashTable(HashTable *ht)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t xnbuckets = ht->nbuckets * 2;
|
|
||||||
uint32_t xbucketmask = xnbuckets - 1;
|
|
||||||
HashEntry **xbuckets = (HashEntry **)calloc(xnbuckets, sizeof(HashEntry*));
|
|
||||||
if (!xbuckets)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < ht->nbuckets; i++) {
|
|
||||||
HashEntry *he = ht->buckets[i];
|
|
||||||
while (he != NULL) {
|
|
||||||
HashEntry *next = he->next;
|
|
||||||
uint32_t bucket = he->sym->hash & xbucketmask;
|
|
||||||
he->next = xbuckets[bucket];
|
|
||||||
xbuckets[bucket] = he;
|
|
||||||
he = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(ht->buckets);
|
|
||||||
ht->buckets = xbuckets;
|
|
||||||
ht->nbuckets = xnbuckets;
|
|
||||||
ht->bucketmask = xbucketmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
SC_FUNC void
|
|
||||||
AddToHashTable(HashTable *ht, symbol *sym)
|
|
||||||
{
|
|
||||||
uint32_t bucket = sym->hash & ht->bucketmask;
|
|
||||||
HashEntry **hep, *he;
|
|
||||||
|
|
||||||
hep = &ht->buckets[bucket];
|
|
||||||
while (*hep) {
|
|
||||||
assert((*hep)->sym != sym);
|
|
||||||
hep = &(*hep)->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
he = (HashEntry *)malloc(sizeof(HashEntry));
|
|
||||||
if (!he)
|
|
||||||
error(163);
|
|
||||||
he->sym = sym;
|
|
||||||
he->next = NULL;
|
|
||||||
*hep = he;
|
|
||||||
ht->nused++;
|
|
||||||
|
|
||||||
if (ht->nused > ht->nbuckets && ht->nbuckets <= INT_MAX / 2)
|
|
||||||
ResizeHashTable(ht);
|
|
||||||
}
|
|
||||||
|
|
||||||
SC_FUNC void
|
|
||||||
RemoveFromHashTable(HashTable *ht, symbol *sym)
|
|
||||||
{
|
|
||||||
uint32_t bucket = sym->hash & ht->bucketmask;
|
|
||||||
HashEntry **hep = &ht->buckets[bucket];
|
|
||||||
HashEntry *he = *hep;
|
|
||||||
|
|
||||||
while (he != NULL) {
|
|
||||||
if (he->sym == sym) {
|
|
||||||
*hep = he->next;
|
|
||||||
free(he);
|
|
||||||
ht->nused--;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hep = &he->next;
|
|
||||||
he = *hep;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
156
sourcepawn/compiler/sp_symhash.cpp
Normal file
156
sourcepawn/compiler/sp_symhash.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
// vim: set ts=8 sts=2 sw=2 tw=99 et:
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "sp_file_headers.h"
|
||||||
|
#include "sc.h"
|
||||||
|
#include "sp_symhash.h"
|
||||||
|
#include <am-hashtable.h>
|
||||||
|
|
||||||
|
struct NameAndScope
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
int fnumber;
|
||||||
|
int *cmptag;
|
||||||
|
mutable symbol *matched;
|
||||||
|
mutable int count;
|
||||||
|
|
||||||
|
NameAndScope(const char *name, int fnumber, int *cmptag)
|
||||||
|
: name(name),
|
||||||
|
fnumber(fnumber),
|
||||||
|
cmptag(cmptag),
|
||||||
|
matched(nullptr),
|
||||||
|
count(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SymbolHashPolicy
|
||||||
|
{
|
||||||
|
typedef symbol *Payload;
|
||||||
|
|
||||||
|
// Everything with the same name has the same hash, because the compiler
|
||||||
|
// wants to know two names that have the same tag for some reason. Even
|
||||||
|
// so, we can't be that accurate, since we might match the right symbol
|
||||||
|
// very early.
|
||||||
|
static uint32_t hash(const NameAndScope &key) {
|
||||||
|
return ke::HashCharSequence(key.name, strlen(key.name));
|
||||||
|
}
|
||||||
|
static uint32_t hash(const symbol *s) {
|
||||||
|
return ke::HashCharSequence(s->name, strlen(s->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool matches(const NameAndScope &key, symbol *sym) {
|
||||||
|
if (sym->parent && sym->ident != iCONSTEXPR)
|
||||||
|
return false;
|
||||||
|
if (sym->fnumber >= 0 && sym->fnumber != key.fnumber)
|
||||||
|
return false;
|
||||||
|
if (strcmp(key.name, sym->name) != 0)
|
||||||
|
return false;
|
||||||
|
if (key.cmptag) {
|
||||||
|
key.count++;
|
||||||
|
key.matched = sym;
|
||||||
|
if (*key.cmptag != sym->tag)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static bool matches(const symbol *key, symbol *sym) {
|
||||||
|
return key == sym;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HashTable : public ke::HashTable<SymbolHashPolicy>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
SC_FUNC uint32_t
|
||||||
|
NameHash(const char *str)
|
||||||
|
{
|
||||||
|
return ke::HashCharSequence(str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC HashTable *NewHashTable()
|
||||||
|
{
|
||||||
|
HashTable *ht = new HashTable();
|
||||||
|
if (!ht->init()) {
|
||||||
|
delete ht;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return ht;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void
|
||||||
|
DestroyHashTable(HashTable *ht)
|
||||||
|
{
|
||||||
|
delete ht;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC symbol *
|
||||||
|
FindTaggedInHashTable(HashTable *ht, const char *name, int fnumber, int *cmptag)
|
||||||
|
{
|
||||||
|
NameAndScope nas(name, fnumber, cmptag);
|
||||||
|
HashTable::Result r = ht->find(nas);
|
||||||
|
if (!r.found()) {
|
||||||
|
if (nas.matched) {
|
||||||
|
*cmptag = nas.count;
|
||||||
|
return nas.matched;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
*cmptag = 1;
|
||||||
|
return *r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC symbol *
|
||||||
|
FindInHashTable(HashTable *ht, const char *name, int fnumber)
|
||||||
|
{
|
||||||
|
NameAndScope nas(name, fnumber, nullptr);
|
||||||
|
HashTable::Result r = ht->find(nas);
|
||||||
|
if (!r.found())
|
||||||
|
return nullptr;
|
||||||
|
return *r;
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void
|
||||||
|
AddToHashTable(HashTable *ht, symbol *sym)
|
||||||
|
{
|
||||||
|
HashTable::Insert i = ht->findForAdd(sym);
|
||||||
|
assert(!i.found());
|
||||||
|
ht->add(i, sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
SC_FUNC void
|
||||||
|
RemoveFromHashTable(HashTable *ht, symbol *sym)
|
||||||
|
{
|
||||||
|
HashTable::Result r = ht->find(sym);
|
||||||
|
assert(r.found());
|
||||||
|
ht->remove(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined __linux__ || defined __APPLE__
|
||||||
|
extern "C" void __cxa_pure_virtual(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new(size_t size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](size_t size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void *ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void * ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
#endif
|
@ -1,28 +1,18 @@
|
|||||||
/* vim: set ts=4 sw=4 tw=99 et: */
|
/* vim: set ts=4 sw=4 tw=99 et: */
|
||||||
#ifndef _INCLUDE_SPCOMP_SYMHASH_H_
|
#ifndef _INCLUDE_SPCOMP_SYMHASH_H_
|
||||||
#define _INCLUDE_SPCOMP_SYMHASH_H_
|
#define _INCLUDE_SPCOMP_SYMHASH_H_
|
||||||
|
|
||||||
SC_FUNC uint32_t NameHash(const char *str);
|
SC_FUNC uint32_t NameHash(const char *str);
|
||||||
|
|
||||||
typedef struct HashEntry {
|
struct HashTable;
|
||||||
symbol *sym;
|
|
||||||
struct HashEntry *next;
|
SC_FUNC HashTable *NewHashTable();
|
||||||
} HashEntry;
|
SC_FUNC void DestroyHashTable(HashTable *ht);
|
||||||
|
SC_FUNC void AddToHashTable(HashTable *ht, symbol *sym);
|
||||||
struct HashTable {
|
SC_FUNC void RemoveFromHashTable(HashTable *ht, symbol *sym);
|
||||||
uint32_t nbuckets;
|
SC_FUNC symbol *FindInHashTable(HashTable *ht, const char *name, int fnumber);
|
||||||
uint32_t nused;
|
SC_FUNC symbol *FindTaggedInHashTable(HashTable *ht, const char *name, int fnumber,
|
||||||
uint32_t bucketmask;
|
int *cmptag);
|
||||||
HashEntry **buckets;
|
|
||||||
};
|
#endif /* _INCLUDE_SPCOMP_SYMHASH_H_ */
|
||||||
|
|
||||||
SC_FUNC HashTable *NewHashTable();
|
|
||||||
SC_FUNC void DestroyHashTable(HashTable *ht);
|
|
||||||
SC_FUNC void AddToHashTable(HashTable *ht, symbol *sym);
|
|
||||||
SC_FUNC void RemoveFromHashTable(HashTable *ht, symbol *sym);
|
|
||||||
SC_FUNC symbol *FindInHashTable(HashTable *ht, const char *name, int fnumber);
|
|
||||||
SC_FUNC symbol *FindTaggedInHashTable(HashTable *ht, const char *name, int fnumber,
|
|
||||||
int *cmptag);
|
|
||||||
|
|
||||||
#endif /* _INCLUDE_SPCOMP_SYMHASH_H_ */
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user