generic function lookup
							parent
							
								
									0d94e89045
								
							
						
					
					
						commit
						8a3920918c
					
				|  | @ -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} | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								src/util.c
								
								
								
								
							
							
						
						
									
										14
									
								
								src/util.c
								
								
								
								
							|  | @ -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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -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 */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue