user: Converte this assembly snippet into its equivalent C code:

```asm
<_js_decode_string>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %rcx,-0x50(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x40(%rbp),%rax
  mov    (%rax),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x10(%rbp)
  movl   $0x0,-0x24(%rbp)
  movl   $0x0,-0x1c(%rbp)
  movl   $0x0,-0x18(%rbp)
L505:
  jmp    L619
L332:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%edx
  lea    -0x20(%rbp),%rcx
  lea    -0x24(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <decode@plt>
  test   %rax,%rax
  je     L299
  mov    -0x24(%rbp),%eax
  cmp    $0xc,%eax
  jne    L619
  mov    $0xffffffff,%eax
  jmp    L389
L299:
  mov    -0x20(%rbp),%eax
  cmp    $0x5c,%eax
  jne    L595
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L58
  mov    $0xffffffff,%eax
  jmp    L389
L58:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%eax
  mov    %eax,-0x20(%rbp)
  nop
  mov    -0x20(%rbp),%eax
  cmp    $0x5c,%eax
  jg     L334
  jmp    L673
L595:
  mov    -0x20(%rbp),%eax
  cmp    $0xffff,%eax
  jg     L281
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  mov    -0x20(%rbp),%edx
  mov    %edx,(%rax)
  jmp    L619
L281:
  mov    -0x20(%rbp),%eax
  sar    $0xa,%eax
  mov    %eax,%ecx
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  lea    0xd7c0(%rcx),%edx
  mov    %edx,(%rax)
  mov    -0x20(%rbp),%eax
  and    $0x3ff,%eax
  mov    %eax,%ecx
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  lea    0xdc00(%rcx),%edx
  mov    %edx,(%rax)
L619:
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L332
  mov    -0x10(%rbp),%rax
  sub    -0x38(%rbp),%rax
  sar    $0x2,%rax
  mov    %rax,%rdx
  mov    -0x40(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x24(%rbp),%eax
  test   %eax,%eax
  setne  %al
  movzbl %al,%eax
  jmp    L389
L673:
  cmp    $0x22,%eax
  jge    L256
  jmp    L603
L143:
  sub    $0x62,%eax
  cmp    $0x13,%eax
  ja     L603
  mov    %eax,%eax
  lea    0x0(,%rax,4),%rdx
  lea    D2(%rip),%rax
  mov    (%rdx,%rax,1),%eax
  cltq
  lea    D2(%rip),%rdx
  add    %rdx,%rax
  notrack jmp *%rax
L256:
  sub    $0x22,%eax
  movabs $0x400000000002001,%rdx
  mov    %eax,%ecx
  shr    %cl,%rdx
  mov    %rdx,%rax
  and    $0x1,%eax
  test   %rax,%rax
  setne  %al
  test   %al,%al
  jne    L364
  jmp    L603
L334:
  cmp    $0x75,%eax
  jg     L603
  cmp    $0x62,%eax
  jge    L143
  jmp    L603
L364:
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  mov    -0x20(%rbp),%edx
  mov    %edx,(%rax)
  jmp    L505
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movl   $0x8,(%rax)
  jmp    L505
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movl   $0xc,(%rax)
  jmp    L505
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movl   $0xa,(%rax)
  jmp    L505
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movl   $0xd,(%rax)
  jmp    L505
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movl   $0x9,(%rax)
  jmp    L505
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L657
  mov    $0xffffffff,%eax
  jmp    L389
L657:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%eax
  mov    %eax,-0x20(%rbp)
  jmp    L563
L603:
  mov    $0xffffffff,%eax
  jmp    L389
L563:
  mov    -0x20(%rbp),%eax
  mov    %eax,%edi
  call   <decode_hex@plt>
  mov    %eax,-0x18(%rbp)
  cmpl   $0xffff,-0x18(%rbp)
  jne    L45
  mov    $0xffffffff,%eax
  jmp    L389
L45:
  mov    -0x18(%rbp),%eax
  shl    $0xc,%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L154
  mov    $0xffffffff,%eax
  jmp    L389
L154:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%eax
  mov    %eax,-0x20(%rbp)
  nop
  mov    -0x20(%rbp),%eax
  mov    %eax,%edi
  call   <decode_hex@plt>
  mov    %eax,-0x18(%rbp)
  cmpl   $0xffff,-0x18(%rbp)
  jne    L224
  mov    $0xffffffff,%eax
  jmp    L389
L224:
  mov    -0x18(%rbp),%eax
  shl    $0x8,%eax
  or     %eax,-0x14(%rbp)
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L436
  mov    $0xffffffff,%eax
  jmp    L389
L436:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%eax
  mov    %eax,-0x20(%rbp)
  nop
  mov    -0x20(%rbp),%eax
  mov    %eax,%edi
  call   <decode_hex@plt>
  mov    %eax,-0x18(%rbp)
  cmpl   $0xffff,-0x18(%rbp)
  jne    L92
  mov    $0xffffffff,%eax
  jmp    L389
L92:
  mov    -0x18(%rbp),%eax
  shl    $0x4,%eax
  or     %eax,-0x14(%rbp)
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L231
  mov    $0xffffffff,%eax
  jmp    L389
L231:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%eax
  mov    %eax,-0x20(%rbp)
  nop
  mov    -0x20(%rbp),%eax
  mov    %eax,%edi
  call   <decode_hex@plt>
  mov    %eax,-0x18(%rbp)
  cmpl   $0xffff,-0x18(%rbp)
  jne    L528
  mov    $0xffffffff,%eax
  jmp    L389
L528:
  mov    -0x18(%rbp),%eax
  or     %eax,-0x14(%rbp)
  mov    -0x10(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  mov    -0x14(%rbp),%edx
  mov    %edx,(%rax)
  cmpl   $0x0,-0x1c(%rbp)
  je     L345
  cmpl   $0xdbff,-0x14(%rbp)
  jle    L56
  cmpl   $0xdfff,-0x14(%rbp)
  jle    L186
L56:
  mov    $0xffffffff,%eax
  jmp    L389
L186:
  movl   $0x0,-0x1c(%rbp)
  jmp    L505
L345:
  cmpl   $0xd7ff,-0x14(%rbp)
  jle    L171
  cmpl   $0xdbff,-0x14(%rbp)
  jg     L171
  movl   $0x1,-0x1c(%rbp)
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L372
  mov    $0xffffffff,%eax
  jmp    L389
L372:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%eax
  mov    %eax,-0x20(%rbp)
  nop
  mov    -0x20(%rbp),%eax
  cmp    $0x5c,%eax
  je     L367
  jmp    L450
L171:
  cmpl   $0xdbff,-0x14(%rbp)
  jle    L505
  cmpl   $0xdfff,-0x14(%rbp)
  jg     L505
  mov    $0xffffffff,%eax
  jmp    L389
L450:
  mov    $0xffffffff,%eax
  jmp    L389
L367:
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L496
  mov    $0xffffffff,%eax
  jmp    L389
L496:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%eax
  mov    %eax,-0x20(%rbp)
  nop
  mov    -0x20(%rbp),%eax
  cmp    $0x75,%eax
  je     L280
  mov    $0xffffffff,%eax
  jmp    L389
L280:
  mov    -0x48(%rbp),%rax
  cmp    -0x50(%rbp),%rax
  jb     L438
  mov    $0xffffffff,%eax
  jmp    L389
L438:
  mov    -0x48(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%eax
  mov    %eax,-0x20(%rbp)
  jmp    L563
L389:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L463
  call   <__stack_chk_fail@plt>
L463:
  leave
  ret
```

assistant: ```c
int _js_decode_string(uint16_t *const dest, size_t *destoff, const uint8_t *s, const uint8_t *const srcend) {
  uint16_t *d = dest + *destoff;
  uint32_t state = 0;
  uint32_t codepoint;
  uint8_t surrogate = 0;
  uint16_t temp_hex = 0;
  uint16_t unidata;
standard:
  while (s < srcend) {
    if (decode(&state, &codepoint, *s++) != 0) {
      if (state == 12) {
        return -1;
      }
      continue;
    }
    if (codepoint == '\\') {
      if (s >= srcend) {
        return -1;
      }
      codepoint = *s++;
      goto backslash;
    } else if (codepoint <= 0xffff)
      *d++ = (uint16_t)codepoint;
    else {
      *d++ = (uint16_t)(0xD7C0 + (codepoint >> 10));
      *d++ = (uint16_t)(0xDC00 + (codepoint & 0x3FF));
    }
  }
  *destoff = d - dest;
  return (state != 0);
backslash:
  switch (codepoint) {
  case '"':
  case '\\':
  case '/':
    *d++ = (uint16_t)codepoint;
    goto standard;
    break;
  case 'b':
    *d++ = '\b';
    goto standard;
  case 'f':
    *d++ = '\f';
    goto standard;
  case 'n':
    *d++ = '\n';
    goto standard;
  case 'r':
    *d++ = '\r';
    goto standard;
  case 't':
    *d++ = '\t';
    goto standard;
  case 'u': {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode1;
  };
    ;
    break;
  default:
    return -1;
  }
unicode1:
  temp_hex = decode_hex(codepoint);
  if (temp_hex == 0xFFFF) {
    return -1;
  } else
    unidata = temp_hex << 12;
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode2;
  };
unicode2:
  temp_hex = decode_hex(codepoint);
  if (temp_hex == 0xFFFF) {
    return -1;
  } else
    unidata |= temp_hex << 8;
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode3;
  };
unicode3:
  temp_hex = decode_hex(codepoint);
  if (temp_hex == 0xFFFF) {
    return -1;
  } else
    unidata |= temp_hex << 4;
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode4;
  };
unicode4:
  temp_hex = decode_hex(codepoint);
  if (temp_hex == 0xFFFF) {
    return -1;
  } else
    unidata |= temp_hex;
  *d++ = (uint16_t)unidata;
  if (surrogate) {
    if (unidata < 0xDC00 || unidata > 0xDFFF)
      return -1;
    surrogate = 0;
  } else if (unidata >= 0xD800 && unidata <= 0xDBFF) {
    surrogate = 1;
    {
      if (s >= srcend) {
        return -1;
      }
      codepoint = *s++;
      goto surrogate1;
    };
  } else if (unidata >= 0xDC00 && unidata <= 0xDFFF) {
    return -1;
  }
  goto standard;
surrogate1:
  if (codepoint != '\\') {
    return -1;
  }
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto surrogate2;
  }
surrogate2:
  if (codepoint != 'u') {
    return -1;
  }
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode1;
  }
}
```