Implement printing of int8/uint8/pointers
Этот коммит содержится в:
		
							родитель
							
								
									e171f32493
								
							
						
					
					
						коммит
						320c583221
					
				
					 3 изменённых файлов: 80 добавлений и 6 удалений
				
			
		| 
						 | 
				
			
			@ -1,12 +1,40 @@
 | 
			
		|||
 | 
			
		||||
package runtime
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func printstring(s string) {
 | 
			
		||||
	for i := 0; i < len(s); i++ {
 | 
			
		||||
		putchar(s[i])
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func printuint8(n uint8) {
 | 
			
		||||
	if TargetBits >= 32 {
 | 
			
		||||
		printuint32(uint32(n))
 | 
			
		||||
	} else {
 | 
			
		||||
		prevdigits := n / 10
 | 
			
		||||
		if prevdigits != 0 {
 | 
			
		||||
			printuint8(prevdigits)
 | 
			
		||||
		}
 | 
			
		||||
		putchar(byte((n % 10) + '0'))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func printint8(n int8) {
 | 
			
		||||
	if TargetBits >= 32 {
 | 
			
		||||
		printint32(int32(n))
 | 
			
		||||
	} else {
 | 
			
		||||
		if n < 0 {
 | 
			
		||||
			putchar('-')
 | 
			
		||||
			n = -n
 | 
			
		||||
		}
 | 
			
		||||
		printuint8(uint8(n))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func printuint32(n uint32) {
 | 
			
		||||
	// TODO: don't recurse, but still be compact (and don't divide/mod
 | 
			
		||||
	// more than necessary).
 | 
			
		||||
| 
						 | 
				
			
			@ -64,3 +92,17 @@ func printitf(msg interface{}) {
 | 
			
		|||
		print("???")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func printptr(ptr uintptr) {
 | 
			
		||||
	putchar('0')
 | 
			
		||||
	putchar('x')
 | 
			
		||||
	for i := 0; i < int(unsafe.Sizeof(ptr)) * 2; i++ {
 | 
			
		||||
		nibble := byte(ptr >> (unsafe.Sizeof(ptr) * 8 - 4))
 | 
			
		||||
		if nibble < 10 {
 | 
			
		||||
			putchar(nibble + '0')
 | 
			
		||||
		} else {
 | 
			
		||||
			putchar(nibble - 10 + 'a')
 | 
			
		||||
		}
 | 
			
		||||
		ptr <<= 4
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,9 @@ package runtime
 | 
			
		|||
 | 
			
		||||
const Compiler = "tgo"
 | 
			
		||||
 | 
			
		||||
// The bitness of the CPU (e.g. 8, 32, 64). Set by the compiler as a constant.
 | 
			
		||||
var TargetBits uint8
 | 
			
		||||
 | 
			
		||||
func _panic(message interface{}) {
 | 
			
		||||
	printstring("panic: ")
 | 
			
		||||
	printitf(message)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										41
									
								
								tgo.go
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								tgo.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -113,7 +113,12 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error {
 | 
			
		|||
	tripleSplit := strings.Split(c.triple, "-")
 | 
			
		||||
 | 
			
		||||
	config := loader.Config {
 | 
			
		||||
		// TODO: TypeChecker.Sizes
 | 
			
		||||
		TypeChecker: types.Config{
 | 
			
		||||
			Sizes: &types.StdSizes{
 | 
			
		||||
				int64(c.targetData.PointerSize()),
 | 
			
		||||
				int64(c.targetData.PrefTypeAlignment(c.i8ptrType)),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		Build: &build.Context {
 | 
			
		||||
			GOARCH:      tripleSplit[0],
 | 
			
		||||
			GOOS:        tripleSplit[2],
 | 
			
		||||
| 
						 | 
				
			
			@ -390,11 +395,25 @@ func (c *Compiler) parsePackage(program *ssa.Program, pkg *ssa.Package) error {
 | 
			
		|||
			global := llvm.AddGlobal(c.mod, llvmType, c.getGlobalName(member))
 | 
			
		||||
			if !strings.HasPrefix(member.Name(), "_extern_") {
 | 
			
		||||
				global.SetLinkage(llvm.PrivateLinkage)
 | 
			
		||||
				initializer, err := c.getZeroValue(llvmType)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				if c.getGlobalName(member) == "runtime.TargetBits" {
 | 
			
		||||
					bitness := c.targetData.PointerSize()
 | 
			
		||||
					if bitness < 32 {
 | 
			
		||||
						// Only 8 and 32+ architectures supported at the moment.
 | 
			
		||||
						// On 8 bit architectures, pointers are normally bigger
 | 
			
		||||
						// than 8 bits to do anything meaningful.
 | 
			
		||||
						// TODO: clean up this hack to support 16-bit
 | 
			
		||||
						// architectures.
 | 
			
		||||
						bitness = 8
 | 
			
		||||
					}
 | 
			
		||||
					global.SetInitializer(llvm.ConstInt(llvm.Int8Type(), uint64(bitness), false))
 | 
			
		||||
					global.SetGlobalConstant(true)
 | 
			
		||||
				} else {
 | 
			
		||||
					initializer, err := c.getZeroValue(llvmType)
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return err
 | 
			
		||||
					}
 | 
			
		||||
					global.SetInitializer(initializer)
 | 
			
		||||
				}
 | 
			
		||||
				global.SetInitializer(initializer)
 | 
			
		||||
			}
 | 
			
		||||
		case *ssa.Type:
 | 
			
		||||
			ms := program.MethodSets.MethodSet(member.Type())
 | 
			
		||||
| 
						 | 
				
			
			@ -714,8 +733,10 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
 | 
			
		|||
			switch typ := typ.(type) {
 | 
			
		||||
			case *types.Basic:
 | 
			
		||||
				switch typ.Kind() {
 | 
			
		||||
				case types.Int8:
 | 
			
		||||
					c.builder.CreateCall(c.mod.NamedFunction("runtime.printint8"), []llvm.Value{value}, "")
 | 
			
		||||
				case types.Uint8:
 | 
			
		||||
					c.builder.CreateCall(c.mod.NamedFunction("runtime.printbyte"), []llvm.Value{value}, "")
 | 
			
		||||
					c.builder.CreateCall(c.mod.NamedFunction("runtime.printuint8"), []llvm.Value{value}, "")
 | 
			
		||||
				case types.Int, types.Int32: // TODO: assumes a 32-bit int type
 | 
			
		||||
					c.builder.CreateCall(c.mod.NamedFunction("runtime.printint32"), []llvm.Value{value}, "")
 | 
			
		||||
				case types.Uint, types.Uint32:
 | 
			
		||||
| 
						 | 
				
			
			@ -726,9 +747,17 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
 | 
			
		|||
					c.builder.CreateCall(c.mod.NamedFunction("runtime.printuint64"), []llvm.Value{value}, "")
 | 
			
		||||
				case types.String:
 | 
			
		||||
					c.builder.CreateCall(c.mod.NamedFunction("runtime.printstring"), []llvm.Value{value}, "")
 | 
			
		||||
				case types.Uintptr:
 | 
			
		||||
					c.builder.CreateCall(c.mod.NamedFunction("runtime.printptr"), []llvm.Value{value}, "")
 | 
			
		||||
				case types.UnsafePointer:
 | 
			
		||||
					ptrValue := c.builder.CreatePtrToInt(value, c.uintptrType, "")
 | 
			
		||||
					c.builder.CreateCall(c.mod.NamedFunction("runtime.printptr"), []llvm.Value{ptrValue}, "")
 | 
			
		||||
				default:
 | 
			
		||||
					return llvm.Value{}, errors.New("unknown basic arg type: " + fmt.Sprintf("%#v", typ))
 | 
			
		||||
				}
 | 
			
		||||
			case *types.Pointer:
 | 
			
		||||
				ptrValue := c.builder.CreatePtrToInt(value, c.uintptrType, "")
 | 
			
		||||
				c.builder.CreateCall(c.mod.NamedFunction("runtime.printptr"), []llvm.Value{ptrValue}, "")
 | 
			
		||||
			default:
 | 
			
		||||
				return llvm.Value{}, errors.New("unknown arg type: " + fmt.Sprintf("%#v", typ))
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче