user: 请从给定的汇编指令推导出C源代码：

```asm
<pvasprintf>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %edx,-0x44(%rbp)
  movq   $0x0,-0x20(%rbp)
  movq   $0x0,-0x18(%rbp)
  movq   $0x0,-0x8(%rbp)
  movq   $0x0,-0x10(%rbp)
  movl   $0x0,-0x28(%rbp)
  movq   $0x0,-0x18(%rbp)
L108:
  cmpq   $0x0,-0x18(%rbp)
  jne    L93
  mov    $0x80,%edi
  call   <malloc@plt>
  mov    %rax,-0x20(%rbp)
  cmpq   $0x0,-0x20(%rbp)
  jne    L126
  mov    -0x38(%rbp),%rax
  movq   $0x0,(%rax)
  mov    $0xffffffff,%eax
  jmp    L84
L126:
  movq   $0x1,-0x18(%rbp)
  jmp    L29
L93:
  mov    -0x10(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <realloc@plt>
  mov    %rax,-0x8(%rbp)
  cmpq   $0x0,-0x8(%rbp)
  je     L64
  mov    -0x8(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x10(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  jmp    L29
L64:
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  movq   $0x0,-0x20(%rbp)
  mov    -0x38(%rbp),%rax
  movq   $0x0,(%rax)
  mov    $0xffffffff,%eax
  jmp    L84
L29:
  mov    -0x44(%rbp),%edx
  mov    -0x24(%rbp),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <va_copy@plt>
  mov    -0x24(%rbp),%ecx
  mov    -0x40(%rbp),%rdx
  mov    -0x18(%rbp),%rsi
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <vsnprintf@plt>
  mov    %eax,-0x28(%rbp)
  mov    -0x24(%rbp),%eax
  mov    %eax,%edi
  call   <va_end@plt>
  cmpl   $0xffffffff,-0x28(%rbp)
  jne    L76
  mov    -0x18(%rbp),%rax
  add    %eax,%eax
  cltq
  mov    %rax,-0x10(%rbp)
  jmp    L108
L76:
  mov    -0x18(%rbp),%rax
  cmp    %eax,-0x28(%rbp)
  jne    L70
  mov    -0x18(%rbp),%rax
  add    %eax,%eax
  cltq
  mov    %rax,-0x10(%rbp)
  jmp    L108
L70:
  mov    -0x18(%rbp),%rax
  cmp    %eax,-0x28(%rbp)
  jle    L92
  mov    -0x28(%rbp),%eax
  add    $0x2,%eax
  cltq
  mov    %rax,-0x10(%rbp)
  jmp    L108
L92:
  mov    -0x18(%rbp),%rax
  sub    $0x1,%eax
  cmp    %eax,-0x28(%rbp)
  jne    L54
  mov    -0x18(%rbp),%rax
  add    %eax,%eax
  cltq
  mov    %rax,-0x10(%rbp)
  jmp    L108
L54:
  nop
  mov    -0x38(%rbp),%rax
  mov    -0x20(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
L84:
  leave
  ret
```

assistant: ```c
int pvasprintf(char **ret, const char *fmt, va_list ap) {
  char *buf = NULL;
  size_t bufsize = 0;
  char *newbuf = NULL;
  size_t nextsize = 0;
  int outsize = 0;
  bufsize = 0;
  for (;;) {
    if (bufsize == 0) {
      if ((buf = (char *)malloc(128)) == NULL) {
        *ret = NULL;
        return -1;
      }
      bufsize = 1;
    } else if ((newbuf = (char *)realloc(buf, nextsize)) != NULL) {
      buf = newbuf;
      bufsize = nextsize;
    } else {
      free(buf);
      buf = NULL;
      *ret = NULL;
      return -1;
    }
    {
      va_list copy;
      va_copy(copy, ap);
      outsize = vsnprintf(buf, bufsize, fmt, copy);
      va_end(copy);
    }
    if (outsize == -1) {
      nextsize = (int)bufsize * 2;
    } else if (outsize == (int)bufsize) {
      nextsize = (int)bufsize * 2;
    } else if (outsize > (int)bufsize) {
      nextsize = outsize + 2;
    } else if (outsize == (int)bufsize - 1) {
      nextsize = (int)bufsize * 2;
    } else {
      break;
    }
  }
  *ret = buf;
  return (int)strlen(buf);
}
```