Move hashmap creation to runtime
Этот коммит содержится в:
		
							родитель
							
								
									ae2fc3c8a7
								
							
						
					
					
						коммит
						005665aee6
					
				
					 2 изменённых файлов: 17 добавлений и 36 удалений
				
			
		
							
								
								
									
										41
									
								
								compiler.go
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								compiler.go
									
										
									
									
									
								
							|  | @ -1529,44 +1529,13 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { | ||||||
| 		switch keyType := mapType.Key().Underlying().(type) { | 		switch keyType := mapType.Key().Underlying().(type) { | ||||||
| 		case *types.Basic: | 		case *types.Basic: | ||||||
| 			if keyType.Kind() == types.String { | 			if keyType.Kind() == types.String { | ||||||
| 				// Create hashmap |  | ||||||
| 				llvmType := c.mod.GetTypeByName("runtime.hashmap") |  | ||||||
| 				size := llvm.ConstInt(c.uintptrType, c.targetData.TypeAllocSize(llvmType), false) |  | ||||||
| 				buf := c.builder.CreateCall(c.allocFunc, []llvm.Value{size}, "") |  | ||||||
| 				buf = c.builder.CreateBitCast(buf, llvm.PointerType(llvmType, 0), "") |  | ||||||
| 
 |  | ||||||
| 				// Set keySize |  | ||||||
| 				keySize := c.targetData.TypeAllocSize(llvmKeyType) | 				keySize := c.targetData.TypeAllocSize(llvmKeyType) | ||||||
| 				keyIndices := []llvm.Value{ |  | ||||||
| 					llvm.ConstInt(llvm.Int32Type(), 0, false), |  | ||||||
| 					llvm.ConstInt(llvm.Int32Type(), 3, false), // keySize uint8 |  | ||||||
| 				} |  | ||||||
| 				keySizePtr := c.builder.CreateGEP(buf, keyIndices, "hashmap.keySize") |  | ||||||
| 				c.builder.CreateStore(llvm.ConstInt(llvm.Int8Type(), keySize, false), keySizePtr) |  | ||||||
| 
 |  | ||||||
| 				// Set valueSize |  | ||||||
| 				valueSize := c.targetData.TypeAllocSize(llvmValueType) | 				valueSize := c.targetData.TypeAllocSize(llvmValueType) | ||||||
| 				valueIndices := []llvm.Value{ | 				hashmapMake := c.mod.NamedFunction("runtime.hashmapMake") | ||||||
| 					llvm.ConstInt(llvm.Int32Type(), 0, false), | 				llvmKeySize := llvm.ConstInt(llvm.Int8Type(), keySize, false) | ||||||
| 					llvm.ConstInt(llvm.Int32Type(), 4, false), // valueSize uint8 | 				llvmValueSize := llvm.ConstInt(llvm.Int8Type(), valueSize, false) | ||||||
| 				} | 				hashmap := c.builder.CreateCall(hashmapMake, []llvm.Value{llvmKeySize, llvmValueSize}, "") | ||||||
| 				valueSizePtr := c.builder.CreateGEP(buf, valueIndices, "hashmap.valueSize") | 				return hashmap, nil | ||||||
| 				c.builder.CreateStore(llvm.ConstInt(llvm.Int8Type(), valueSize, false), valueSizePtr) |  | ||||||
| 
 |  | ||||||
| 				// Create initial bucket |  | ||||||
| 				bucketType := c.mod.GetTypeByName("runtime.hashmapBucket") |  | ||||||
| 				bucketSize := c.targetData.TypeAllocSize(bucketType) + keySize*8 + valueSize*8 |  | ||||||
| 				bucketSizeValue := llvm.ConstInt(c.uintptrType, bucketSize, false) |  | ||||||
| 				bucket := c.builder.CreateCall(c.allocFunc, []llvm.Value{bucketSizeValue}, "") |  | ||||||
| 
 |  | ||||||
| 				// Set initial bucket |  | ||||||
| 				bucketIndices := []llvm.Value{ |  | ||||||
| 					llvm.ConstInt(llvm.Int32Type(), 0, false), |  | ||||||
| 					llvm.ConstInt(llvm.Int32Type(), 1, false), // buckets unsafe.Pointer |  | ||||||
| 				} |  | ||||||
| 				bucketsElementPtr := c.builder.CreateGEP(buf, bucketIndices, "hashmap.buckets") |  | ||||||
| 				c.builder.CreateStore(bucket, bucketsElementPtr) |  | ||||||
| 				return buf, nil |  | ||||||
| 			} else { | 			} else { | ||||||
| 				return llvm.Value{}, errors.New("todo: map key type: " + keyType.String()) | 				return llvm.Value{}, errors.New("todo: map key type: " + keyType.String()) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -42,6 +42,18 @@ func stringhash(s *string) uint32 { | ||||||
| 	return result | 	return result | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Create a new hashmap with the given keySize and valueSize. | ||||||
|  | func hashmapMake(keySize, valueSize uint8) *hashmap { | ||||||
|  | 	bucketBufSize := unsafe.Sizeof(hashmapBucket{}) + uintptr(keySize)*8 + uintptr(valueSize)*8 | ||||||
|  | 	bucket := alloc(bucketBufSize) | ||||||
|  | 	return &hashmap{ | ||||||
|  | 		buckets:    bucket, | ||||||
|  | 		keySize:    keySize, | ||||||
|  | 		valueSize:  valueSize, | ||||||
|  | 		bucketBits: 0, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Set a specified key to a given value. Grow the map if necessary. | // Set a specified key to a given value. Grow the map if necessary. | ||||||
| func hashmapSet(m *hashmap, key string, value unsafe.Pointer) { | func hashmapSet(m *hashmap, key string, value unsafe.Pointer) { | ||||||
| 	hash := stringhash(&key) | 	hash := stringhash(&key) | ||||||
|  |  | ||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Ayke van Laethem
						Ayke van Laethem