runtime: add cap and len support for chans
Этот коммит содержится в:
родитель
1461563e3f
коммит
7e64bc8f77
4 изменённых файлов: 40 добавлений и 7 удалений
|
@ -1201,9 +1201,7 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
|
||||||
var llvmCap llvm.Value
|
var llvmCap llvm.Value
|
||||||
switch args[0].Type().(type) {
|
switch args[0].Type().(type) {
|
||||||
case *types.Chan:
|
case *types.Chan:
|
||||||
// Channel. Buffered channels haven't been implemented yet so always
|
llvmCap = b.createRuntimeCall("chanCap", []llvm.Value{value}, "cap")
|
||||||
// return 0.
|
|
||||||
llvmCap = llvm.ConstInt(b.intType, 0, false)
|
|
||||||
case *types.Slice:
|
case *types.Slice:
|
||||||
llvmCap = b.CreateExtractValue(value, 2, "cap")
|
llvmCap = b.CreateExtractValue(value, 2, "cap")
|
||||||
default:
|
default:
|
||||||
|
@ -1259,9 +1257,7 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
|
||||||
// string or slice
|
// string or slice
|
||||||
llvmLen = b.CreateExtractValue(value, 1, "len")
|
llvmLen = b.CreateExtractValue(value, 1, "len")
|
||||||
case *types.Chan:
|
case *types.Chan:
|
||||||
// Channel. Buffered channels haven't been implemented yet so always
|
llvmLen = b.createRuntimeCall("chanLen", []llvm.Value{value}, "len")
|
||||||
// return 0.
|
|
||||||
llvmLen = llvm.ConstInt(b.intType, 0, false)
|
|
||||||
case *types.Map:
|
case *types.Map:
|
||||||
llvmLen = b.createRuntimeCall("hashmapLen", []llvm.Value{value}, "len")
|
llvmLen = b.createRuntimeCall("hashmapLen", []llvm.Value{value}, "len")
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -136,6 +136,38 @@ func chanMake(elementSize uintptr, bufSize uintptr) *channel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the number of entries in this chan, called from the len builtin.
|
||||||
|
// A nil chan is defined as having length 0.
|
||||||
|
//go:inline
|
||||||
|
func chanLen(c *channel) int {
|
||||||
|
if c == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int(c.bufUsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrapper for use in reflect
|
||||||
|
func chanLenUnsafePointer(p unsafe.Pointer) int {
|
||||||
|
c := (*channel)(p)
|
||||||
|
return chanLen(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the capacity of this chan, called from the cap builtin.
|
||||||
|
// A nil chan is defined as having capacity 0.
|
||||||
|
//go:inline
|
||||||
|
func chanCap(c *channel) int {
|
||||||
|
if c == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int(c.bufSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrapper for use in reflect
|
||||||
|
func chanCapUnsafePointer(p unsafe.Pointer) int {
|
||||||
|
c := (*channel)(p)
|
||||||
|
return chanCap(c)
|
||||||
|
}
|
||||||
|
|
||||||
// resumeRX resumes the next receiver and returns the destination pointer.
|
// resumeRX resumes the next receiver and returns the destination pointer.
|
||||||
// If the ok value is true, then the caller is expected to store a value into this pointer.
|
// If the ok value is true, then the caller is expected to store a value into this pointer.
|
||||||
func (ch *channel) resumeRX(ok bool) unsafe.Pointer {
|
func (ch *channel) resumeRX(ok bool) unsafe.Pointer {
|
||||||
|
|
6
testdata/channel.go
предоставленный
6
testdata/channel.go
предоставленный
|
@ -9,7 +9,11 @@ import (
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ch := make(chan int)
|
ch := make(chan int, 2)
|
||||||
|
ch <- 1
|
||||||
|
println("len, cap of channel:", len(ch), cap(ch), ch == nil)
|
||||||
|
|
||||||
|
ch = make(chan int)
|
||||||
println("len, cap of channel:", len(ch), cap(ch), ch == nil)
|
println("len, cap of channel:", len(ch), cap(ch), ch == nil)
|
||||||
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
1
testdata/channel.txt
предоставленный
1
testdata/channel.txt
предоставленный
|
@ -1,3 +1,4 @@
|
||||||
|
len, cap of channel: 1 2 false
|
||||||
len, cap of channel: 0 0 false
|
len, cap of channel: 0 0 false
|
||||||
recv from open channel: 1 true
|
recv from open channel: 1 true
|
||||||
received num: 2
|
received num: 2
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче