generic function lookup

traversal
cosmonaut 2021-05-20 13:18:57 -07:00
parent 0d94e89045
commit 8a3920918c
4 changed files with 103 additions and 14 deletions

View File

@ -43,10 +43,12 @@ add_executable(
src/codegen.h src/codegen.h
src/identcheck.h src/identcheck.h
src/parser.h src/parser.h
src/util.h
src/ast.c src/ast.c
src/codegen.c src/codegen.c
src/identcheck.c src/identcheck.c
src/parser.c src/parser.c
src/util.c
src/main.c src/main.c
# Generated code # Generated code
${BISON_Parser_OUTPUTS} ${BISON_Parser_OUTPUTS}

View File

@ -14,6 +14,7 @@
#include <llvm-c/Transforms/Utils.h> #include <llvm-c/Transforms/Utils.h>
#include "ast.h" #include "ast.h"
#include "util.h"
typedef struct LocalVariable typedef struct LocalVariable
{ {
@ -56,15 +57,11 @@ typedef struct StructTypeFunction
uint8_t isStatic; uint8_t isStatic;
} StructTypeFunction; } StructTypeFunction;
typedef struct StructTypeGenericFunction
{
char *name;
Node *functionDeclarationNode;
} StructTypeGenericFunction;
typedef struct MonomorphizedGenericFunctionHashEntry typedef struct MonomorphizedGenericFunctionHashEntry
{ {
uint64_t key; uint64_t key;
TypeTag **types;
uint32_t typeCount;
StructTypeFunction function; StructTypeFunction function;
} MonomorphizedGenericFunctionHashEntry; } MonomorphizedGenericFunctionHashEntry;
@ -74,6 +71,17 @@ typedef struct MonomorphizedGenericFunctionHashArray
uint32_t count; uint32_t count;
} MonomorphizedGenericFunctionHashArray; } MonomorphizedGenericFunctionHashArray;
#define NUM_MONOMORPHIZED_HASH_BUCKETS 1031
typedef struct StructTypeGenericFunction
{
char *name;
Node *functionDeclarationNode;
uint8_t isStatic;
MonomorphizedGenericFunctionHashArray
monomorphizedFunctions[NUM_MONOMORPHIZED_HASH_BUCKETS];
} StructTypeGenericFunction;
typedef struct StructTypeDeclaration typedef struct StructTypeDeclaration
{ {
char *name; char *name;
@ -87,8 +95,6 @@ typedef struct StructTypeDeclaration
StructTypeGenericFunction *genericFunctions; StructTypeGenericFunction *genericFunctions;
uint32_t genericFunctionCount; uint32_t genericFunctionCount;
MonomorphizedGenericFunctionHashArray monomorphizedGenericFunctions;
} StructTypeDeclaration; } StructTypeDeclaration;
StructTypeDeclaration *structTypeDeclarations; StructTypeDeclaration *structTypeDeclarations;
@ -296,8 +302,6 @@ static void AddStructDeclaration(
structTypeDeclarations[index].functionCount = 0; structTypeDeclarations[index].functionCount = 0;
structTypeDeclarations[index].genericFunctions = NULL; structTypeDeclarations[index].genericFunctions = NULL;
structTypeDeclarations[index].genericFunctionCount = 0; structTypeDeclarations[index].genericFunctionCount = 0;
structTypeDeclarations[index].monomorphizedGenericFunctions.elements = NULL;
structTypeDeclarations[index].monomorphizedGenericFunctions.count = 0;
for (i = 0; i < fieldDeclarationCount; i += 1) for (i = 0; i < fieldDeclarationCount; i += 1)
{ {
@ -350,9 +354,10 @@ static void DeclareStructFunction(
static void DeclareGenericStructFunction( static void DeclareGenericStructFunction(
LLVMTypeRef wStructPointerType, LLVMTypeRef wStructPointerType,
Node *functionDeclarationNode, Node *functionDeclarationNode,
uint8_t isStatic,
char *name) char *name)
{ {
uint32_t i, index; uint32_t i, j, index;
for (i = 0; i < structTypeDeclarationCount; i += 1) for (i = 0; i < structTypeDeclarationCount; i += 1)
{ {
@ -364,6 +369,21 @@ static void DeclareGenericStructFunction(
structTypeDeclarations[i] structTypeDeclarations[i]
.genericFunctions[index] .genericFunctions[index]
.functionDeclarationNode = functionDeclarationNode; .functionDeclarationNode = functionDeclarationNode;
structTypeDeclarations[i].genericFunctions[index].isStatic =
isStatic;
for (j = 0; j < NUM_MONOMORPHIZED_HASH_BUCKETS; j += 1)
{
structTypeDeclarations[i]
.genericFunctions[index]
.monomorphizedFunctions[j]
.elements = NULL;
structTypeDeclarations[i]
.genericFunctions[index]
.monomorphizedFunctions[j]
.count = 0;
}
structTypeDeclarations[i].genericFunctionCount += 1; structTypeDeclarations[i].genericFunctionCount += 1;
return; return;
@ -411,6 +431,20 @@ static LLVMTypeRef ResolveType(Node *typeNode)
} }
} }
static inline uint64_t HashTypeTags(TypeTag **tags, uint32_t count)
{
const uint64_t HASH_FACTOR = 97;
uint64_t result = 1;
uint32_t i;
for (i = 0; i < count; i += 1)
{
result *= HASH_FACTOR + str_hash(TypeTagToString(tags[i]));
}
return result;
}
static LLVMValueRef LookupGenericFunction( static LLVMValueRef LookupGenericFunction(
StructTypeGenericFunction *genericFunction, StructTypeGenericFunction *genericFunction,
TypeTag **genericArgumentTypes, TypeTag **genericArgumentTypes,
@ -418,8 +452,46 @@ static LLVMValueRef LookupGenericFunction(
LLVMTypeRef *pReturnType, LLVMTypeRef *pReturnType,
uint8_t *pStatic) uint8_t *pStatic)
{ {
/* TODO: hash the argument types */ uint32_t i, j;
/* TODO: compile the monomorphism if doesnt exist */ uint64_t typeHash =
HashTypeTags(genericArgumentTypes, genericArgumentTypeCount);
uint8_t match = 0;
MonomorphizedGenericFunctionHashArray *hashArray =
&genericFunction->monomorphizedFunctions
[typeHash % NUM_MONOMORPHIZED_HASH_BUCKETS];
MonomorphizedGenericFunctionHashEntry *hashEntry = NULL;
for (i = 0; i < hashArray->count; i += 1)
{
match = 1;
for (j = 0; j < hashArray->elements[i].typeCount; j += 1)
{
if (hashArray->elements[i].types[j] != genericArgumentTypes[j])
{
match = 0;
break;
}
}
if (match)
{
hashEntry = &hashArray->elements[i];
break;
}
}
if (hashEntry == NULL)
{
/* TODO: compile */
}
*pReturnType = hashEntry->function.returnType;
*pStatic = hashEntry->function.isStatic;
return hashEntry->function.function;
} }
static LLVMValueRef LookupFunctionByType( static LLVMValueRef LookupFunctionByType(
@ -1257,6 +1329,7 @@ static void CompileFunction(
DeclareGenericStructFunction( DeclareGenericStructFunction(
wStructPointerType, wStructPointerType,
functionDeclaration, functionDeclaration,
isStatic,
functionName); functionName);
} }

View File

@ -1,7 +1,6 @@
#include "util.h" #include "util.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
char *strdup(const char *s) char *strdup(const char *s)
{ {
@ -15,3 +14,16 @@ char *strdup(const char *s)
memcpy(result, s, slen + 1); memcpy(result, s, slen + 1);
return result; return result;
} }
uint64_t str_hash(char *str)
{
uint64_t hash = 5381;
size_t c;
while (c = *str++)
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash;
}

View File

@ -1,8 +1,10 @@
#ifndef WRAITH_UTIL_H #ifndef WRAITH_UTIL_H
#define WRAITH_UTIL_H #define WRAITH_UTIL_H
#include <stdint.h>
#include <string.h> #include <string.h>
char *strdup(const char *s); char *strdup(const char *s);
uint64_t str_hash(char *str);
#endif /* WRAITH_UTIL_H */ #endif /* WRAITH_UTIL_H */