mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 19:17:47 +00:00
compiler: add support for the append builtin
This commit is contained in:
@@ -83,17 +83,6 @@ func memequal(x, y unsafe.Pointer, n uintptr) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Builtin copy(dst, src) function: copy bytes from dst to src.
|
||||
func sliceCopy(dst, src unsafe.Pointer, dstLen, srcLen lenType, elemSize uintptr) lenType {
|
||||
// n = min(srcLen, dstLen)
|
||||
n := srcLen
|
||||
if n > dstLen {
|
||||
n = dstLen
|
||||
}
|
||||
memmove(dst, src, uintptr(n)*elemSize)
|
||||
return n
|
||||
}
|
||||
|
||||
//go:linkname sleep time.Sleep
|
||||
func sleep(d int64) {
|
||||
sleepTicks(timeUnit(d / tickMicros))
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package runtime
|
||||
|
||||
// This file implements compiler builtins for slices: append() and copy().
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// 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) {
|
||||
if elemsLen == 0 {
|
||||
// Nothing to append, return the input slice.
|
||||
return srcBuf, srcLen, srcCap
|
||||
}
|
||||
|
||||
if srcLen+elemsLen > srcCap {
|
||||
// Slice does not fit, allocate a new buffer that's large enough.
|
||||
srcCap = srcCap * 2
|
||||
if srcCap == 0 { // e.g. zero slice
|
||||
srcCap = 1
|
||||
}
|
||||
for srcLen+elemsLen > srcCap {
|
||||
// This algorithm may be made more memory-efficient: don't multiply
|
||||
// by two but by 1.5 or something. As far as I can see, that's
|
||||
// allowed by the Go language specification (but may be observed by
|
||||
// programs).
|
||||
srcCap *= 2
|
||||
}
|
||||
buf := alloc(uintptr(srcCap) * elemSize)
|
||||
|
||||
// Copy the old slice to the new slice.
|
||||
if srcLen != 0 {
|
||||
memmove(buf, srcBuf, uintptr(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)
|
||||
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 {
|
||||
// n = min(srcLen, dstLen)
|
||||
n := srcLen
|
||||
if n > dstLen {
|
||||
n = dstLen
|
||||
}
|
||||
memmove(dst, src, uintptr(n)*elemSize)
|
||||
return n
|
||||
}
|
||||
Reference in New Issue
Block a user