Added realloc implementation to GCs

When using the latest wasi-libc I experienced a
panic on an attempt to call realloc. My first attempt to
add it to arch_tinygowasm.go was obviously not good (PR #2194). So here
is another suggestion.
Этот коммит содержится в:
Rouven Broszeit 2021-10-22 21:30:52 +02:00 коммит произвёл Ron Evans
родитель ef8c1a187d
коммит 0f69d016a0
5 изменённых файлов: 41 добавлений и 2 удалений

Просмотреть файл

@ -84,8 +84,7 @@ func libc_calloc(nmemb, size uintptr) unsafe.Pointer {
//export realloc
func libc_realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
runtimePanic("unimplemented: realloc")
return nil
return realloc(ptr, size)
}
//export posix_memalign

Просмотреть файл

@ -341,6 +341,28 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
}
}
func realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
if ptr == nil {
return alloc(size, nil)
}
ptrAddress := uintptr(ptr)
endOfTailAddress := blockFromAddr(ptrAddress).findNext().address()
// this might be a few bytes longer than the original size of
// ptr, because we align to full blocks of size bytesPerBlock
oldSize := endOfTailAddress - ptrAddress
if size <= oldSize {
return ptr
}
newAlloc := alloc(size, nil)
memcpy(newAlloc, ptr, oldSize)
free(ptr)
return newAlloc
}
func free(ptr unsafe.Pointer) {
// TODO: free blocks on request, when the compiler knows they're unused.
}

Просмотреть файл

@ -630,6 +630,10 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
}
}
func realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
runtimePanic("unimplemented: gc_extalloc.realloc")
}
func free(ptr unsafe.Pointer) {
// Currently unimplemented due to bugs in coroutine lowering.
}

Просмотреть файл

@ -35,6 +35,18 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
return unsafe.Pointer(addr)
}
func realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
newAlloc := alloc(size, nil)
if ptr == nil {
return newAlloc
}
// according to POSIX everything beyond the previous pointer's
// size will have indeterminate values so we can just copy garbage
memcpy(newAlloc, ptr, size)
return newAlloc
}
func free(ptr unsafe.Pointer) {
// Memory is never freed.
}

Просмотреть файл

@ -12,6 +12,8 @@ import (
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
func realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer
func free(ptr unsafe.Pointer) {
// Nothing to free when nothing gets allocated.
}