Browse Source

all: swap string from {len, ptr} to {ptr, len} for slice compatibility

Having slices and strings be similar makes other code simpler.
pull/6/head
Ayke van Laethem 6 years ago
parent
commit
31f494e611
No known key found for this signature in database GPG Key ID: E97FF5335DFDFDED
  1. 16
      compiler.go
  2. 8
      src/runtime/string.go

16
compiler.go

@ -1554,7 +1554,7 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
case *types.Basic:
switch typ.Kind() {
case types.String:
return c.builder.CreateExtractValue(value, 0, "len"), nil
return c.builder.CreateExtractValue(value, 1, "len"), nil
default:
return llvm.Value{}, errors.New("todo: len: unknown basic type")
}
@ -2048,7 +2048,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
c.emitBoundsCheck(frame, length, index)
// Lookup byte
buf := c.builder.CreateExtractValue(value, 1, "")
buf := c.builder.CreateExtractValue(value, 0, "")
bufPtr := c.builder.CreateGEP(buf, []llvm.Value{index}, "")
return c.builder.CreateLoad(bufPtr, ""), nil
case *types.Map:
@ -2224,8 +2224,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
return llvm.Value{}, errors.New("unknown slice type: " + typ.String())
}
// slice a string
oldLen := c.builder.CreateExtractValue(value, 0, "")
oldPtr := c.builder.CreateExtractValue(value, 1, "")
oldPtr := c.builder.CreateExtractValue(value, 0, "")
oldLen := c.builder.CreateExtractValue(value, 1, "")
if high.IsNil() {
high = oldLen
}
@ -2235,14 +2235,14 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
c.builder.CreateCall(sliceBoundsCheck, []llvm.Value{oldLen, low, high}, "")
}
newLen := c.builder.CreateSub(high, low, "")
newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "")
newLen := c.builder.CreateSub(high, low, "")
str, err := getZeroValue(c.mod.GetTypeByName("runtime._string"))
if err != nil {
return llvm.Value{}, err
}
str = c.builder.CreateInsertValue(str, newLen, 0, "")
str = c.builder.CreateInsertValue(str, newPtr, 1, "")
str = c.builder.CreateInsertValue(str, newPtr, 0, "")
str = c.builder.CreateInsertValue(str, newLen, 1, "")
return str, nil
default:
@ -2566,7 +2566,7 @@ func (c *Compiler) parseConst(expr *ssa.Const) (llvm.Value, error) {
global.SetGlobalConstant(true)
zero := llvm.ConstInt(llvm.Int32Type(), 0, false)
strPtr := c.builder.CreateInBoundsGEP(global, []llvm.Value{zero, zero}, "")
strObj := llvm.ConstNamedStruct(c.mod.GetTypeByName("runtime._string"), []llvm.Value{strLen, strPtr})
strObj := llvm.ConstNamedStruct(c.mod.GetTypeByName("runtime._string"), []llvm.Value{strPtr, strLen})
return strObj, nil
} else if typ.Kind() == types.UnsafePointer {
if !expr.IsNil() {

8
src/runtime/string.go

@ -8,8 +8,8 @@ import (
// The underlying struct for the Go string type.
type _string struct {
length lenType
ptr *byte
length lenType
}
// Return true iff the strings match.
@ -37,7 +37,7 @@ func stringConcat(x, y _string) _string {
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{lenType(length), (*byte)(buf)}
return _string{ptr: (*byte)(buf), length: lenType(length)}
}
}
@ -49,7 +49,7 @@ func stringFromBytes(x struct {
}) _string {
buf := alloc(uintptr(x.len))
memcpy(buf, unsafe.Pointer(x.ptr), uintptr(x.len))
return _string{lenType(x.len), (*byte)(buf)}
return _string{ptr: (*byte)(buf), length: lenType(x.len)}
}
// Convert a string to a []byte slice.
@ -72,7 +72,7 @@ func stringFromUnicode(x rune) _string {
// Array will be heap allocated.
// The heap most likely doesn't work with blocks below 4 bytes, so there's
// no point in allocating a smaller buffer for the string here.
return _string{length, (*byte)(unsafe.Pointer(&array))}
return _string{ptr: (*byte)(unsafe.Pointer(&array)), length: length}
}
// Convert a Unicode code point into an array of bytes and its length.

Loading…
Cancel
Save