all: swap string from {len, ptr} to {ptr, len} for slice compatibility
Having slices and strings be similar makes other code simpler.
Этот коммит содержится в:
родитель
5aa8b71ae1
коммит
31f494e611
2 изменённых файлов: 12 добавлений и 12 удалений
16
compiler.go
16
compiler.go
|
@ -1554,7 +1554,7 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
|
||||||
case *types.Basic:
|
case *types.Basic:
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case types.String:
|
case types.String:
|
||||||
return c.builder.CreateExtractValue(value, 0, "len"), nil
|
return c.builder.CreateExtractValue(value, 1, "len"), nil
|
||||||
default:
|
default:
|
||||||
return llvm.Value{}, errors.New("todo: len: unknown basic type")
|
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)
|
c.emitBoundsCheck(frame, length, index)
|
||||||
|
|
||||||
// Lookup byte
|
// Lookup byte
|
||||||
buf := c.builder.CreateExtractValue(value, 1, "")
|
buf := c.builder.CreateExtractValue(value, 0, "")
|
||||||
bufPtr := c.builder.CreateGEP(buf, []llvm.Value{index}, "")
|
bufPtr := c.builder.CreateGEP(buf, []llvm.Value{index}, "")
|
||||||
return c.builder.CreateLoad(bufPtr, ""), nil
|
return c.builder.CreateLoad(bufPtr, ""), nil
|
||||||
case *types.Map:
|
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())
|
return llvm.Value{}, errors.New("unknown slice type: " + typ.String())
|
||||||
}
|
}
|
||||||
// slice a string
|
// slice a string
|
||||||
oldLen := c.builder.CreateExtractValue(value, 0, "")
|
oldPtr := c.builder.CreateExtractValue(value, 0, "")
|
||||||
oldPtr := c.builder.CreateExtractValue(value, 1, "")
|
oldLen := c.builder.CreateExtractValue(value, 1, "")
|
||||||
if high.IsNil() {
|
if high.IsNil() {
|
||||||
high = oldLen
|
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}, "")
|
c.builder.CreateCall(sliceBoundsCheck, []llvm.Value{oldLen, low, high}, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
newLen := c.builder.CreateSub(high, low, "")
|
|
||||||
newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "")
|
newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "")
|
||||||
|
newLen := c.builder.CreateSub(high, low, "")
|
||||||
str, err := getZeroValue(c.mod.GetTypeByName("runtime._string"))
|
str, err := getZeroValue(c.mod.GetTypeByName("runtime._string"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return llvm.Value{}, err
|
return llvm.Value{}, err
|
||||||
}
|
}
|
||||||
str = c.builder.CreateInsertValue(str, newLen, 0, "")
|
str = c.builder.CreateInsertValue(str, newPtr, 0, "")
|
||||||
str = c.builder.CreateInsertValue(str, newPtr, 1, "")
|
str = c.builder.CreateInsertValue(str, newLen, 1, "")
|
||||||
return str, nil
|
return str, nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2566,7 +2566,7 @@ func (c *Compiler) parseConst(expr *ssa.Const) (llvm.Value, error) {
|
||||||
global.SetGlobalConstant(true)
|
global.SetGlobalConstant(true)
|
||||||
zero := llvm.ConstInt(llvm.Int32Type(), 0, false)
|
zero := llvm.ConstInt(llvm.Int32Type(), 0, false)
|
||||||
strPtr := c.builder.CreateInBoundsGEP(global, []llvm.Value{zero, zero}, "")
|
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
|
return strObj, nil
|
||||||
} else if typ.Kind() == types.UnsafePointer {
|
} else if typ.Kind() == types.UnsafePointer {
|
||||||
if !expr.IsNil() {
|
if !expr.IsNil() {
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
|
|
||||||
// The underlying struct for the Go string type.
|
// The underlying struct for the Go string type.
|
||||||
type _string struct {
|
type _string struct {
|
||||||
length lenType
|
|
||||||
ptr *byte
|
ptr *byte
|
||||||
|
length lenType
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true iff the strings match.
|
// Return true iff the strings match.
|
||||||
|
@ -37,7 +37,7 @@ func stringConcat(x, y _string) _string {
|
||||||
buf := alloc(length)
|
buf := alloc(length)
|
||||||
memcpy(buf, unsafe.Pointer(x.ptr), uintptr(x.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))
|
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 {
|
}) _string {
|
||||||
buf := alloc(uintptr(x.len))
|
buf := alloc(uintptr(x.len))
|
||||||
memcpy(buf, unsafe.Pointer(x.ptr), 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.
|
// Convert a string to a []byte slice.
|
||||||
|
@ -72,7 +72,7 @@ func stringFromUnicode(x rune) _string {
|
||||||
// Array will be heap allocated.
|
// Array will be heap allocated.
|
||||||
// The heap most likely doesn't work with blocks below 4 bytes, so there's
|
// 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.
|
// 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.
|
// Convert a Unicode code point into an array of bytes and its length.
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче