diff --git a/compiler/compiler.go b/compiler/compiler.go index 7387a44e..675da94a 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -54,7 +54,6 @@ type Compiler struct { intType llvm.Type i8ptrType llvm.Type // for convenience uintptrType llvm.Type - lenType llvm.Type coroIdFunc llvm.Value coroSizeFunc llvm.Value coroBeginFunc llvm.Value @@ -128,14 +127,15 @@ func NewCompiler(pkgName string, config Config) (*Compiler, error) { c.builder = c.ctx.NewBuilder() c.dibuilder = llvm.NewDIBuilder(c.mod) - // Depends on platform (32bit or 64bit), but fix it here for now. - c.intType = c.ctx.Int32Type() c.uintptrType = c.ctx.IntType(c.targetData.PointerSize() * 8) - if c.targetData.PointerSize() < 4 { - // 16 or 8 bits target with smaller length type - c.lenType = c.uintptrType + if c.targetData.PointerSize() <= 4 { + // 8, 16, 32 bits targets + c.intType = c.ctx.Int32Type() + } else if c.targetData.PointerSize() == 8 { + // 64 bits target + c.intType = c.ctx.Int64Type() } else { - c.lenType = c.ctx.Int32Type() // also defined as runtime.lenType + panic("unknown pointer size") } c.i8ptrType = llvm.PointerType(c.ctx.Int8Type(), 0) @@ -668,8 +668,8 @@ func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) { } members := []llvm.Type{ llvm.PointerType(elemType, 0), - c.lenType, // len - c.lenType, // cap + c.uintptrType, // len + c.uintptrType, // cap } return c.ctx.StructType(members, false), nil case *types.Struct: @@ -1077,12 +1077,12 @@ func (c *Compiler) getInterpretedValue(prefix string, value ir.Value) (llvm.Valu bucketPtr := llvm.ConstInBoundsGEP(firstBucketGlobal, []llvm.Value{zero}) hashmapType := c.mod.GetTypeByName("runtime.hashmap") hashmap := llvm.ConstNamedStruct(hashmapType, []llvm.Value{ - llvm.ConstPointerNull(llvm.PointerType(hashmapType, 0)), // next - llvm.ConstBitCast(bucketPtr, c.i8ptrType), // buckets - llvm.ConstInt(c.lenType, uint64(len(value.Keys)), false), // count - llvm.ConstInt(c.ctx.Int8Type(), keySize, false), // keySize - llvm.ConstInt(c.ctx.Int8Type(), valueSize, false), // valueSize - llvm.ConstInt(c.ctx.Int8Type(), 0, false), // bucketBits + llvm.ConstPointerNull(llvm.PointerType(hashmapType, 0)), // next + llvm.ConstBitCast(bucketPtr, c.i8ptrType), // buckets + llvm.ConstInt(c.uintptrType, uint64(len(value.Keys)), false), // count + llvm.ConstInt(c.ctx.Int8Type(), keySize, false), // keySize + llvm.ConstInt(c.ctx.Int8Type(), valueSize, false), // valueSize + llvm.ConstInt(c.ctx.Int8Type(), 0, false), // bucketBits }) // Create a pointer to this hashmap. @@ -1163,7 +1163,7 @@ func (c *Compiler) getInterpretedValue(prefix string, value ir.Value) (llvm.Valu if err != nil { return llvm.Value{}, err } - llvmLen := llvm.ConstInt(c.lenType, arrayLength, false) + llvmLen := llvm.ConstInt(c.uintptrType, arrayLength, false) slice := llvm.ConstNamedStruct(sliceTyp, []llvm.Value{ globalPtr, // ptr llvmLen, // len @@ -2260,7 +2260,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { // Check bounds. arrayLen := expr.X.Type().(*types.Array).Len() - arrayLenLLVM := llvm.ConstInt(c.lenType, uint64(arrayLen), false) + arrayLenLLVM := llvm.ConstInt(c.uintptrType, uint64(arrayLen), false) c.emitBoundsCheck(frame, arrayLenLLVM, index, expr.Index.Type()) // Can't load directly from array (as index is non-constant), so have to @@ -2288,7 +2288,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { switch typ := typ.(type) { case *types.Array: bufptr = val - buflen = llvm.ConstInt(c.lenType, uint64(typ.Len()), false) + buflen = llvm.ConstInt(c.uintptrType, uint64(typ.Len()), false) default: return llvm.Value{}, errors.New("todo: indexaddr: " + typ.String()) } @@ -2412,16 +2412,16 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { slicePtr := c.createRuntimeCall("alloc", []llvm.Value{sliceSize}, "makeslice.buf") slicePtr = c.builder.CreateBitCast(slicePtr, llvm.PointerType(llvmElemType, 0), "makeslice.array") - if c.targetData.TypeAllocSize(sliceLen.Type()) > c.targetData.TypeAllocSize(c.lenType) { - sliceLen = c.builder.CreateTrunc(sliceLen, c.lenType, "") - sliceCap = c.builder.CreateTrunc(sliceCap, c.lenType, "") + if c.targetData.TypeAllocSize(sliceLen.Type()) > c.targetData.TypeAllocSize(c.uintptrType) { + sliceLen = c.builder.CreateTrunc(sliceLen, c.uintptrType, "") + sliceCap = c.builder.CreateTrunc(sliceCap, c.uintptrType, "") } // Create the slice. slice := c.ctx.ConstStruct([]llvm.Value{ llvm.Undef(slicePtr.Type()), - llvm.Undef(c.lenType), - llvm.Undef(c.lenType), + llvm.Undef(c.uintptrType), + llvm.Undef(c.uintptrType), }, false) slice = c.builder.CreateInsertValue(slice, slicePtr, 0, "") slice = c.builder.CreateInsertValue(slice, sliceLen, 1, "") @@ -2513,7 +2513,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { case *types.Pointer: // pointer to array // slice an array length := typ.Elem().(*types.Array).Len() - llvmLen := llvm.ConstInt(c.lenType, uint64(length), false) + llvmLen := llvm.ConstInt(c.uintptrType, uint64(length), false) llvmLenInt := llvm.ConstInt(c.intType, uint64(length), false) if high.IsNil() { high = llvmLenInt @@ -2529,15 +2529,15 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { // This check is optimized away in most cases. c.emitSliceBoundsCheck(frame, llvmLen, low, high) - if c.targetData.TypeAllocSize(sliceLen.Type()) > c.targetData.TypeAllocSize(c.lenType) { - sliceLen = c.builder.CreateTrunc(sliceLen, c.lenType, "") - sliceCap = c.builder.CreateTrunc(sliceCap, c.lenType, "") + if c.targetData.TypeAllocSize(sliceLen.Type()) > c.targetData.TypeAllocSize(c.uintptrType) { + sliceLen = c.builder.CreateTrunc(sliceLen, c.uintptrType, "") + sliceCap = c.builder.CreateTrunc(sliceCap, c.uintptrType, "") } slice := c.ctx.ConstStruct([]llvm.Value{ llvm.Undef(slicePtr.Type()), - llvm.Undef(c.lenType), - llvm.Undef(c.lenType), + llvm.Undef(c.uintptrType), + llvm.Undef(c.uintptrType), }, false) slice = c.builder.CreateInsertValue(slice, slicePtr, 0, "") slice = c.builder.CreateInsertValue(slice, sliceLen, 1, "") @@ -2555,11 +2555,11 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { c.emitSliceBoundsCheck(frame, oldCap, low, high) - if c.targetData.TypeAllocSize(low.Type()) > c.targetData.TypeAllocSize(c.lenType) { - low = c.builder.CreateTrunc(low, c.lenType, "") + if c.targetData.TypeAllocSize(low.Type()) > c.targetData.TypeAllocSize(c.uintptrType) { + low = c.builder.CreateTrunc(low, c.uintptrType, "") } - if c.targetData.TypeAllocSize(high.Type()) > c.targetData.TypeAllocSize(c.lenType) { - high = c.builder.CreateTrunc(high, c.lenType, "") + if c.targetData.TypeAllocSize(high.Type()) > c.targetData.TypeAllocSize(c.uintptrType) { + high = c.builder.CreateTrunc(high, c.uintptrType, "") } newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "") @@ -2567,8 +2567,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { newCap := c.builder.CreateSub(oldCap, low, "") slice := c.ctx.ConstStruct([]llvm.Value{ llvm.Undef(newPtr.Type()), - llvm.Undef(c.lenType), - llvm.Undef(c.lenType), + llvm.Undef(c.uintptrType), + llvm.Undef(c.uintptrType), }, false) slice = c.builder.CreateInsertValue(slice, newPtr, 0, "") slice = c.builder.CreateInsertValue(slice, newLen, 1, "") @@ -2881,7 +2881,7 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) (llvm.Value, error return llvm.ConstInt(llvmType, n, false), nil } else if typ.Info()&types.IsString != 0 { str := constant.StringVal(expr.Value) - strLen := llvm.ConstInt(c.lenType, uint64(len(str)), false) + strLen := llvm.ConstInt(c.uintptrType, uint64(len(str)), false) objname := prefix + "$string" global := llvm.AddGlobal(c.mod, llvm.ArrayType(c.ctx.Int8Type(), len(str)), objname) global.SetInitializer(c.ctx.ConstString(str, false)) @@ -2961,7 +2961,7 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) (llvm.Value, error return llvm.Value{}, err } llvmPtr := llvm.ConstPointerNull(llvm.PointerType(elemType, 0)) - llvmLen := llvm.ConstInt(c.lenType, 0, false) + llvmLen := llvm.ConstInt(c.uintptrType, 0, false) slice := c.ctx.ConstStruct([]llvm.Value{ llvmPtr, // backing array llvmLen, // len diff --git a/src/runtime/arch_amd64.go b/src/runtime/arch_amd64.go index 3cf88368..a69abe46 100644 --- a/src/runtime/arch_amd64.go +++ b/src/runtime/arch_amd64.go @@ -4,8 +4,5 @@ package runtime const GOARCH = "amd64" -// The length type used inside strings and slices. -type lenType uint32 - // The bitness of the CPU (e.g. 8, 32, 64). const TargetBits = 64 diff --git a/src/runtime/arch_avr.go b/src/runtime/arch_avr.go index e7d2b5ff..4964d846 100644 --- a/src/runtime/arch_avr.go +++ b/src/runtime/arch_avr.go @@ -8,9 +8,6 @@ import ( const GOARCH = "avr" -// The length type used inside strings and slices. -type lenType uint16 - // The bitness of the CPU (e.g. 8, 32, 64). const TargetBits = 8 diff --git a/src/runtime/arch_tinygoarm.go b/src/runtime/arch_tinygoarm.go index f3a8e6f3..2a517cfc 100644 --- a/src/runtime/arch_tinygoarm.go +++ b/src/runtime/arch_tinygoarm.go @@ -8,9 +8,6 @@ import ( const GOARCH = "arm" -// The length type used inside strings and slices. -type lenType uint32 - // The bitness of the CPU (e.g. 8, 32, 64). const TargetBits = 32 diff --git a/src/runtime/arch_wasm.go b/src/runtime/arch_wasm.go index 38a12ed1..4e9fa06a 100644 --- a/src/runtime/arch_wasm.go +++ b/src/runtime/arch_wasm.go @@ -8,9 +8,6 @@ import ( const GOARCH = "wasm" -// The length type used inside strings and slices. -type lenType uint32 - // The bitness of the CPU (e.g. 8, 32, 64). const TargetBits = 32 diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index b770745c..934d2bda 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -13,7 +13,7 @@ import ( type hashmap struct { next *hashmap // hashmap after evacuate (for iterators) buckets unsafe.Pointer // pointer to array of buckets - count lenType + count uintptr keySize uint8 // maybe this can store the key type as well? E.g. keysize == 5 means string? valueSize uint8 bucketBits uint8 diff --git a/src/runtime/panic.go b/src/runtime/panic.go index c7d3d14c..fbd5d3c5 100644 --- a/src/runtime/panic.go +++ b/src/runtime/panic.go @@ -28,7 +28,7 @@ func _recover() interface{} { } // Check for bounds in *ssa.Index, *ssa.IndexAddr and *ssa.Lookup. -func lookupBoundsCheck(length lenType, index int) { +func lookupBoundsCheck(length uintptr, index int) { if index < 0 || index >= int(length) { runtimePanic("index out of range") } @@ -36,21 +36,21 @@ func lookupBoundsCheck(length lenType, index int) { // Check for bounds in *ssa.Index, *ssa.IndexAddr and *ssa.Lookup. // Supports 64-bit indexes. -func lookupBoundsCheckLong(length lenType, index int64) { +func lookupBoundsCheckLong(length uintptr, index int64) { if index < 0 || index >= int64(length) { runtimePanic("index out of range") } } // Check for bounds in *ssa.Slice. -func sliceBoundsCheck(capacity lenType, low, high uint) { +func sliceBoundsCheck(capacity uintptr, low, high uint) { if !(0 <= low && low <= high && high <= uint(capacity)) { runtimePanic("slice out of range") } } // Check for bounds in *ssa.Slice. Supports 64-bit indexes. -func sliceBoundsCheckLong(capacity lenType, low, high uint64) { +func sliceBoundsCheckLong(capacity uintptr, low, high uint64) { if !(0 <= low && low <= high && high <= uint64(capacity)) { runtimePanic("slice out of range") } diff --git a/src/runtime/print.go b/src/runtime/print.go index dfc438dd..abde9a20 100644 --- a/src/runtime/print.go +++ b/src/runtime/print.go @@ -217,7 +217,7 @@ func printmap(m *hashmap) { if m == nil { print("nil") } else { - print(m.count) + print(uint(m.count)) } putchar(']') } diff --git a/src/runtime/slice.go b/src/runtime/slice.go index def8df37..3ea0fe44 100644 --- a/src/runtime/slice.go +++ b/src/runtime/slice.go @@ -8,7 +8,7 @@ import ( // Builtin append(src, elements...) function: append elements to src and return // the modified (possibly expanded) slice. -func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen lenType, elemSize uintptr) (unsafe.Pointer, lenType, lenType) { +func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen uintptr, elemSize uintptr) (unsafe.Pointer, uintptr, uintptr) { if elemsLen == 0 { // Nothing to append, return the input slice. return srcBuf, srcLen, srcCap @@ -27,27 +27,27 @@ func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen lenTy // programs). srcCap *= 2 } - buf := alloc(uintptr(srcCap) * elemSize) + buf := alloc(srcCap * elemSize) // Copy the old slice to the new slice. if srcLen != 0 { - memmove(buf, srcBuf, uintptr(srcLen)*elemSize) + memmove(buf, srcBuf, srcLen*elemSize) } srcBuf = buf } // The slice fits (after possibly allocating a new one), append it in-place. - memmove(unsafe.Pointer(uintptr(srcBuf)+uintptr(srcLen)*elemSize), elemsBuf, uintptr(elemsLen)*elemSize) + memmove(unsafe.Pointer(uintptr(srcBuf)+srcLen*elemSize), elemsBuf, elemsLen*elemSize) return srcBuf, srcLen + elemsLen, srcCap } // Builtin copy(dst, src) function: copy bytes from dst to src. -func sliceCopy(dst, src unsafe.Pointer, dstLen, srcLen lenType, elemSize uintptr) lenType { +func sliceCopy(dst, src unsafe.Pointer, dstLen, srcLen uintptr, elemSize uintptr) uintptr { // n = min(srcLen, dstLen) n := srcLen if n > dstLen { n = dstLen } - memmove(dst, src, uintptr(n)*elemSize) + memmove(dst, src, n*elemSize) return n } diff --git a/src/runtime/string.go b/src/runtime/string.go index f3e42df7..73d56a86 100644 --- a/src/runtime/string.go +++ b/src/runtime/string.go @@ -9,13 +9,13 @@ import ( // The underlying struct for the Go string type. type _string struct { ptr *byte - length lenType + length uintptr } // The iterator state for a range over a string. type stringIterator struct { - byteindex lenType - rangeindex lenType + byteindex uintptr + rangeindex uintptr } // Return true iff the strings match. @@ -57,33 +57,33 @@ func stringConcat(x, y _string) _string { } else if y.length == 0 { return x } else { - length := uintptr(x.length + y.length) + length := x.length + y.length buf := alloc(length) - memcpy(buf, unsafe.Pointer(x.ptr), uintptr(x.length)) - memcpy(unsafe.Pointer(uintptr(buf)+uintptr(x.length)), unsafe.Pointer(y.ptr), uintptr(y.length)) - return _string{ptr: (*byte)(buf), length: lenType(length)} + memcpy(buf, unsafe.Pointer(x.ptr), x.length) + memcpy(unsafe.Pointer(uintptr(buf)+x.length), unsafe.Pointer(y.ptr), y.length) + return _string{ptr: (*byte)(buf), length: length} } } // Create a string from a []byte slice. func stringFromBytes(x struct { ptr *byte - len lenType - cap lenType + len uintptr + cap uintptr }) _string { - buf := alloc(uintptr(x.len)) - memcpy(buf, unsafe.Pointer(x.ptr), uintptr(x.len)) - return _string{ptr: (*byte)(buf), length: lenType(x.len)} + buf := alloc(x.len) + memcpy(buf, unsafe.Pointer(x.ptr), x.len) + return _string{ptr: (*byte)(buf), length: x.len} } // Convert a string to a []byte slice. func stringToBytes(x _string) (slice struct { ptr *byte - len lenType - cap lenType + len uintptr + cap uintptr }) { - buf := alloc(uintptr(x.length)) - memcpy(buf, unsafe.Pointer(x.ptr), uintptr(x.length)) + buf := alloc(x.length) + memcpy(buf, unsafe.Pointer(x.ptr), x.length) slice.ptr = (*byte)(buf) slice.len = x.length slice.cap = x.length @@ -112,7 +112,7 @@ func stringNext(s string, it *stringIterator) (bool, int, rune) { } // Convert a Unicode code point into an array of bytes and its length. -func encodeUTF8(x rune) ([4]byte, lenType) { +func encodeUTF8(x rune) ([4]byte, uintptr) { // https://stackoverflow.com/questions/6240055/manually-converting-unicode-codepoints-into-utf-8-and-utf-16 // Note: this code can probably be optimized (in size and speed). switch { @@ -141,8 +141,8 @@ func encodeUTF8(x rune) ([4]byte, lenType) { // Decode a single UTF-8 character from a string. //go:nobounds -func decodeUTF8(s string, index lenType) (rune, lenType) { - remaining := lenType(len(s)) - index // must be >= 1 before calling this function +func decodeUTF8(s string, index uintptr) (rune, uintptr) { + remaining := uintptr(len(s)) - index // must be >= 1 before calling this function x := s[index] switch { case x&0x80 == 0x00: // 0xxxxxxx