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.
Этот коммит содержится в:
родитель
ef8c1a187d
коммит
0f69d016a0
5 изменённых файлов: 41 добавлений и 2 удалений
|
@ -84,8 +84,7 @@ func libc_calloc(nmemb, size uintptr) unsafe.Pointer {
|
||||||
|
|
||||||
//export realloc
|
//export realloc
|
||||||
func libc_realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
|
func libc_realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
|
||||||
runtimePanic("unimplemented: realloc")
|
return realloc(ptr, size)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//export posix_memalign
|
//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) {
|
func free(ptr unsafe.Pointer) {
|
||||||
// TODO: free blocks on request, when the compiler knows they're unused.
|
// 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) {
|
func free(ptr unsafe.Pointer) {
|
||||||
// Currently unimplemented due to bugs in coroutine lowering.
|
// 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)
|
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) {
|
func free(ptr unsafe.Pointer) {
|
||||||
// Memory is never freed.
|
// Memory is never freed.
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import (
|
||||||
|
|
||||||
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
|
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
|
||||||
|
|
||||||
|
func realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer
|
||||||
|
|
||||||
func free(ptr unsafe.Pointer) {
|
func free(ptr unsafe.Pointer) {
|
||||||
// Nothing to free when nothing gets allocated.
|
// Nothing to free when nothing gets allocated.
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче