compiler: fix unsafe.Sizeof and friends for AVR
This fixes runtime.printptr().
Этот коммит содержится в:
		
							родитель
							
								
									e04f0868ed
								
							
						
					
					
						коммит
						94358959f5
					
				
					 2 изменённых файлов: 150 добавлений и 7 удалений
				
			
		
							
								
								
									
										11
									
								
								compiler.go
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								compiler.go
									
										
									
									
									
								
							|  | @ -139,15 +139,12 @@ func NewCompiler(pkgName, triple string, dumpSSA bool) (*Compiler, error) { | |||
| func (c *Compiler) Parse(mainPath string, buildTags []string) error { | ||||
| 	tripleSplit := strings.Split(c.triple, "-") | ||||
| 
 | ||||
| 	wordSize := c.targetData.PointerSize() | ||||
| 	if wordSize < 4 { | ||||
| 		wordSize = 4 | ||||
| 	} | ||||
| 	config := loader.Config{ | ||||
| 		TypeChecker: types.Config{ | ||||
| 			Sizes: &types.StdSizes{ | ||||
| 				int64(wordSize), | ||||
| 				int64(c.targetData.PrefTypeAlignment(c.i8ptrType)), | ||||
| 			Sizes: &StdSizes{ | ||||
| 				IntSize:  int64(c.targetData.TypeAllocSize(c.intType)), | ||||
| 				PtrSize:  int64(c.targetData.PointerSize()), | ||||
| 				MaxAlign: int64(c.targetData.PrefTypeAlignment(c.i8ptrType)), | ||||
| 			}, | ||||
| 		}, | ||||
| 		Build: &build.Context{ | ||||
|  |  | |||
							
								
								
									
										146
									
								
								sizes.go
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										146
									
								
								sizes.go
									
										
									
									
									
										Обычный файл
									
								
							|  | @ -0,0 +1,146 @@ | |||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"go/types" | ||||
| ) | ||||
| 
 | ||||
| // The code in this file has been copied from | ||||
| // https://golang.org/src/go/types/sizes.go and modified to allow for int and | ||||
| // pointer sizes to differ. | ||||
| // The original license can be found here: | ||||
| //     https://golang.org/LICENSE | ||||
| 
 | ||||
| type StdSizes struct { | ||||
| 	IntSize  int64 | ||||
| 	PtrSize  int64 | ||||
| 	MaxAlign int64 | ||||
| } | ||||
| 
 | ||||
| func (s *StdSizes) Alignof(T types.Type) int64 { | ||||
| 	// For arrays and structs, alignment is defined in terms | ||||
| 	// of alignment of the elements and fields, respectively. | ||||
| 	switch t := T.Underlying().(type) { | ||||
| 	case *types.Array: | ||||
| 		// spec: "For a variable x of array type: unsafe.Alignof(x) | ||||
| 		// is the same as unsafe.Alignof(x[0]), but at least 1." | ||||
| 		return s.Alignof(t.Elem()) | ||||
| 	case *types.Struct: | ||||
| 		// spec: "For a variable x of struct type: unsafe.Alignof(x) | ||||
| 		// is the largest of the values unsafe.Alignof(x.f) for each | ||||
| 		// field f of x, but at least 1." | ||||
| 		max := int64(1) | ||||
| 		for i := 0; i < t.NumFields(); i++ { | ||||
| 			f := t.Field(i) | ||||
| 			if a := s.Alignof(f.Type()); a > max { | ||||
| 				max = a | ||||
| 			} | ||||
| 		} | ||||
| 		return max | ||||
| 	case *types.Slice, *types.Interface: | ||||
| 		// Multiword data structures are effectively structs | ||||
| 		// in which each element has size WordSize. | ||||
| 		return s.PtrSize | ||||
| 	case *types.Basic: | ||||
| 		// Strings are like slices and interfaces. | ||||
| 		if t.Info()&types.IsString != 0 { | ||||
| 			return s.PtrSize | ||||
| 		} | ||||
| 	} | ||||
| 	a := s.Sizeof(T) // may be 0 | ||||
| 	// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1." | ||||
| 	if a < 1 { | ||||
| 		return 1 | ||||
| 	} | ||||
| 	// complex{64,128} are aligned like [2]float{32,64}. | ||||
| 	if t, ok := T.Underlying().(*types.Basic); ok && t.Info()&types.IsComplex != 0 { | ||||
| 		a /= 2 | ||||
| 	} | ||||
| 	if a > s.MaxAlign { | ||||
| 		return s.MaxAlign | ||||
| 	} | ||||
| 	return a | ||||
| } | ||||
| 
 | ||||
| func (s *StdSizes) Offsetsof(fields []*types.Var) []int64 { | ||||
| 	offsets := make([]int64, len(fields)) | ||||
| 	var o int64 | ||||
| 	for i, f := range fields { | ||||
| 		a := s.Alignof(f.Type()) | ||||
| 		o = align(o, a) | ||||
| 		offsets[i] = o | ||||
| 		o += s.Sizeof(f.Type()) | ||||
| 	} | ||||
| 	return offsets | ||||
| } | ||||
| 
 | ||||
| var basicSizes = [...]byte{ | ||||
| 	types.Bool:       1, | ||||
| 	types.Int8:       1, | ||||
| 	types.Int16:      2, | ||||
| 	types.Int32:      4, | ||||
| 	types.Int64:      8, | ||||
| 	types.Uint8:      1, | ||||
| 	types.Uint16:     2, | ||||
| 	types.Uint32:     4, | ||||
| 	types.Uint64:     8, | ||||
| 	types.Float32:    4, | ||||
| 	types.Float64:    8, | ||||
| 	types.Complex64:  8, | ||||
| 	types.Complex128: 16, | ||||
| } | ||||
| 
 | ||||
| func (s *StdSizes) Sizeof(T types.Type) int64 { | ||||
| 	switch t := T.Underlying().(type) { | ||||
| 	case *types.Basic: | ||||
| 		k := t.Kind() | ||||
| 		if int(k) < len(basicSizes) { | ||||
| 			if s := basicSizes[k]; s > 0 { | ||||
| 				return int64(s) | ||||
| 			} | ||||
| 		} | ||||
| 		if k == types.String { | ||||
| 			return s.PtrSize * 2 | ||||
| 		} | ||||
| 		if k == types.Int || k == types.Uint { | ||||
| 			return s.IntSize | ||||
| 		} | ||||
| 		if k == types.Uintptr { | ||||
| 			return s.PtrSize | ||||
| 		} | ||||
| 		panic("unknown basic type: " + t.String()) | ||||
| 	case *types.Array: | ||||
| 		n := t.Len() | ||||
| 		if n <= 0 { | ||||
| 			return 0 | ||||
| 		} | ||||
| 		// n > 0 | ||||
| 		a := s.Alignof(t.Elem()) | ||||
| 		z := s.Sizeof(t.Elem()) | ||||
| 		return align(z, a)*(n-1) + z | ||||
| 	case *types.Slice: | ||||
| 		return s.PtrSize * 3 | ||||
| 	case *types.Struct: | ||||
| 		n := t.NumFields() | ||||
| 		if n == 0 { | ||||
| 			return 0 | ||||
| 		} | ||||
| 		fields := make([]*types.Var, t.NumFields()) | ||||
| 		for i := range fields { | ||||
| 			fields[i] = t.Field(i) | ||||
| 		} | ||||
| 		offsets := s.Offsetsof(fields) | ||||
| 		return offsets[n-1] + s.Sizeof(fields[n-1].Type()) | ||||
| 	case *types.Interface: | ||||
| 		return s.PtrSize * 2 | ||||
| 	case *types.Pointer: | ||||
| 		return s.PtrSize | ||||
| 	default: | ||||
| 		panic("unknown type: " + t.String()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // align returns the smallest y >= x such that y % a == 0. | ||||
| func align(x, a int64) int64 { | ||||
| 	y := x + a - 1 | ||||
| 	return y - y%a | ||||
| } | ||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Ayke van Laethem
						Ayke van Laethem