mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 19:17:47 +00:00
runtime: add cap and len support for chans
This commit is contained in:
@@ -1201,9 +1201,7 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
|
||||
var llvmCap llvm.Value
|
||||
switch args[0].Type().(type) {
|
||||
case *types.Chan:
|
||||
// Channel. Buffered channels haven't been implemented yet so always
|
||||
// return 0.
|
||||
llvmCap = llvm.ConstInt(b.intType, 0, false)
|
||||
llvmCap = b.createRuntimeCall("chanCap", []llvm.Value{value}, "cap")
|
||||
case *types.Slice:
|
||||
llvmCap = b.CreateExtractValue(value, 2, "cap")
|
||||
default:
|
||||
@@ -1259,9 +1257,7 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
|
||||
// string or slice
|
||||
llvmLen = b.CreateExtractValue(value, 1, "len")
|
||||
case *types.Chan:
|
||||
// Channel. Buffered channels haven't been implemented yet so always
|
||||
// return 0.
|
||||
llvmLen = llvm.ConstInt(b.intType, 0, false)
|
||||
llvmLen = b.createRuntimeCall("chanLen", []llvm.Value{value}, "len")
|
||||
case *types.Map:
|
||||
llvmLen = b.createRuntimeCall("hashmapLen", []llvm.Value{value}, "len")
|
||||
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.
|
||||
// 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 {
|
||||
|
||||
Vendored
+5
-1
@@ -9,7 +9,11 @@ import (
|
||||
var wg sync.WaitGroup
|
||||
|
||||
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)
|
||||
|
||||
wg.Add(1)
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
len, cap of channel: 1 2 false
|
||||
len, cap of channel: 0 0 false
|
||||
recv from open channel: 1 true
|
||||
received num: 2
|
||||
|
||||
Reference in New Issue
Block a user