decompiled_code:
__int64 __fastcall ifsm_scriptdone(unsigned int a1, unsigned int a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, char a7)
{
_BOOL4 v7; // ebx
char *v8; // rax
const char *v9; // rdx
__int64 v10; // r9
__int64 v11; // rdx
unsigned int v12; // edi
char *v13; // rax
__int64 v14; // rdx
int v16; // eax
__int64 v17; // rdx
int v18; // eax
__int64 v19; // rdx
char *v20; // rax
__int64 v21; // rdx
__int64 v22; // [rsp+0h] [rbp-48h] BYREF
unsigned int v23; // [rsp+8h] [rbp-40h]
__int16 v24; // [rsp+Ch] [rbp-3Ch] BYREF
int v25; // [rsp+Eh] [rbp-3Ah]
__int16 v26; // [rsp+12h] [rbp-36h]
__int64 *v27; // [rsp+14h] [rbp-34h]
int v28; // [rsp+1Ch] [rbp-2Ch]
char *v29; // [rsp+28h] [rbp-20h]

v23 = a1;
v29 = &a7;
v24 = -17599;
v25 = (int)find_pid_0;
v26 = -17847;
v27 = &v22;
v28 = -1864106167;
if ( (a2 & 0x7F) != 0 )
{
if ( (char)((a2 & 0x7F) + 1) <= 1 )
_assert_fail("WIFEXITED(exitstatus) || WIFSIGNALED(exitstatus)", "if_info.c", 0x124u, "ifsm_scriptdone");
v7 = 0;
}
else
{
v7 = (a2 & 0xFF00) == 0;
}
v22 = 0LL;
for_each_iface((unsigned int (__fastcall *)(_QWORD *))&v24);
if ( !v22 )
return do_log(6LL, "Unexpected child %d exited with status %d", v23, a2);
v8 = statename(*(_DWORD *)(v22 + 48));
do_log(6LL, "%s: state %s pid %d exited status %d", v9, v8, v23, v10);
v11 = v22;
v12 = *(_DWORD *)(v22 + 48);
*(_DWORD *)(v22 + 52) = -1;
switch ( v12 )
{
case 0u:
case 4u:
case 7u:
case 9u:
v20 = statename(v12);
do_log(3LL, "ifsm_scriptdone: %s: bad state %s for script termination", (const char *)(v21 + 32), v20);
exit(1);
case 1u:
*(_DWORD *)(v11 + 48) = 2;
v16 = run_netplug_bg(v11 + 32, "probe");
v17 = v22;
*(_DWORD *)(v22 + 52) = v16;
v12 = *(_DWORD *)(v17 + 48);
break;
case 2u:
if ( !v7 )
{
do_log(4LL, "Could not bring %s back up", (const char *)(v11 + 32));
v11 = v22;
}
*(_DWORD *)(v11 + 48) = 0;
v12 = 0;
break;
case 3u:
case 8u:
*(_DWORD *)(v11 + 48) = 4;
v12 = 4;
break;
case 5u:
if ( v7 )
{
*(_DWORD *)(v11 + 48) = 7;
v12 = 7;
}
else
{
*(_DWORD *)(v11 + 48) = 9;
v12 = 9;
}
break;
case 6u:
v18 = run_netplug_bg(v11 + 32, "out");
v19 = v22;
v12 = 8;
*(_DWORD *)(v22 + 52) = v18;
*(_DWORD *)(v19 + 48) = 8;
break;
default:
break;
}
v13 = statename(v12);
return do_log(7LL, "%s: moved to state %s", (const char *)(v14 + 32), v13);
}

canonical_decompiled_code:
__int64 __fastcall func6(unsigned int a1, unsigned int a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, char a7)
{
_BOOL4 v7; // ebx
char *v8; // rax
const char *v9; // rdx
__int64 v10; // r9
__int64 v11; // rdx
unsigned int v12; // edi
char *v13; // rax
__int64 v14; // rdx
int v16; // eax
__int64 v17; // rdx
int v18; // eax
__int64 v19; // rdx
char *v20; // rax
__int64 v21; // rdx
__int64 v22; // [rsp+0h] [rbp-48h] BYREF
unsigned int v23; // [rsp+8h] [rbp-40h]
__int16 v24; // [rsp+Ch] [rbp-3Ch] BYREF
int v25; // [rsp+Eh] [rbp-3Ah]
__int16 v26; // [rsp+12h] [rbp-36h]
__int64 *v27; // [rsp+14h] [rbp-34h]
int v28; // [rsp+1Ch] [rbp-2Ch]
char *v29; // [rsp+28h] [rbp-20h]

v23 = a1;
v29 = &a7;
v24 = -17599;
v25 = (int)find_pid_0;
v26 = -17847;
v27 = &v22;
v28 = -1864106167;
if ( (a2 & 0x7F) != 0 )
{
if ( (char)((a2 & 0x7F) + 1) <= 1 )
_assert_fail("WIFEXITED(exitstatus) || WIFSIGNALED(exitstatus)", "if_info.c", 0x124u, "ifsm_scriptdone");
v7 = 0;
}
else
{
v7 = (a2 & 0xFF00) == 0;
}
v22 = 0LL;
func3((unsigned int (__fastcall *)(_QWORD *))&v24);
if ( !v22 )
return do_log(6LL, "Unexpected child %d exited with status %d", v23, a2);
v8 = func0(*(_DWORD *)(v22 + 48));
do_log(6LL, "%s: state %s pid %d exited status %d", v9, v8, v23, v10);
v11 = v22;
v12 = *(_DWORD *)(v22 + 48);
*(_DWORD *)(v22 + 52) = -1;
switch ( v12 )
{
case 0u:
case 4u:
case 7u:
case 9u:
v20 = func0(v12);
do_log(3LL, "ifsm_scriptdone: %s: bad state %s for script termination", (const char *)(v21 + 32), v20);
exit(1);
case 1u:
*(_DWORD *)(v11 + 48) = 2;
v16 = run_netplug_bg(v11 + 32, "probe");
v17 = v22;
*(_DWORD *)(v22 + 52) = v16;
v12 = *(_DWORD *)(v17 + 48);
break;
case 2u:
if ( !v7 )
{
do_log(4LL, "Could not bring %s back up", (const char *)(v11 + 32));
v11 = v22;
}
*(_DWORD *)(v11 + 48) = 0;
v12 = 0;
break;
case 3u:
case 8u:
*(_DWORD *)(v11 + 48) = 4;
v12 = 4;
break;
case 5u:
if ( v7 )
{
*(_DWORD *)(v11 + 48) = 7;
v12 = 7;
}
else
{
*(_DWORD *)(v11 + 48) = 9;
v12 = 9;
}
break;
case 6u:
v18 = run_netplug_bg(v11 + 32, "out");
v19 = v22;
v12 = 8;
*(_DWORD *)(v22 + 52) = v18;
*(_DWORD *)(v19 + 48) = 8;
break;
default:
break;
}
v13 = func0(v12);
return do_log(7LL, "%s: moved to state %s", (const char *)(v14 + 32), v13);
}

original_code:
void ifsm_scriptdone(pid_t pid, int exitstatus)
{
    int exitok = (((exitstatus) & 0x7f) == 0) && (((exitstatus) & 0xff00) >> 8) == 0;
    struct if_info *info;
    ((void) sizeof (((((exitstatus) & 0x7f) == 0) || (((signed char) (((exitstatus) & 0x7f) + 1) >> 1) > 0)) ? 1 : 0), __extension__ ({ if ((((exitstatus) & 0x7f) == 0) || (((signed char) (((exitstatus) & 0x7f) + 1) >> 1) > 0)) ; else __assert_fail ("WIFEXITED(exitstatus) || WIFSIGNALED(exitstatus)", "if_info.c", 292, __extension__ __PRETTY_FUNCTION__); }));
    int find_pid(struct if_info *i) {
        if (i->worker == pid) {
            info = i;
            return 1;
        }
        return 0;
    }
    info = ((void *)0);
    for_each_iface(find_pid);
    if (info == ((void *)0)) {
        do_log(6, "Unexpected child %d exited with status %d",
               pid, exitstatus);
        return;
    }
    do_log(6, "%s: state %s pid %d exited status %d",
           info->name, statename(info->state), pid, exitstatus);
    info->worker = -1;
    switch(info->state) {
    case ST_PROBING:
        if (!exitok)
            do_log(4, "Could not bring %s back up", info->name);
        info->state = ST_DOWN;
        break;
    case ST_PROBING_UP:
        info->state = ST_INACTIVE;
        break;
    case ST_DOWNANDOUT:
        info->state = ST_PROBING;
        ((void) sizeof ((info->worker == -1) ? 1 : 0), __extension__ ({ if (info->worker == -1) ; else __assert_fail ("info->worker == -1", "if_info.c", 338, __extension__ __PRETTY_FUNCTION__); }));
        info->worker = run_netplug_bg(info->name, "probe");
        break;
    case ST_INNING:
        if (exitok)
            info->state = ST_ACTIVE;
        else
            info->state = ST_INSANE;
        break;
    case ST_OUTING:
        info->state = ST_INACTIVE;
        break;
    case ST_WAIT_IN:
        ((void) sizeof ((info->worker == -1) ? 1 : 0), __extension__ ({ if (info->worker == -1) ; else __assert_fail ("info->worker == -1", "if_info.c", 355, __extension__ __PRETTY_FUNCTION__); }));
        info->worker = run_netplug_bg(info->name, "out");
        info->state = ST_OUTING;
        break;
    case ST_INACTIVE:
    case ST_ACTIVE:
    case ST_INSANE:
    case ST_DOWN:
        do_log(3, "ifsm_scriptdone: %s: bad state %s for script termination",
               info->name, statename(info->state));
        exit(1);
    }
    do_log(7, "%s: moved to state %s", info->name, statename(info->state));
}

canonical_original_code:
void ifsm_scriptdone(int pid, int exitstatus)
{
    int exitok = (((exitstatus) & 0x7f) == 0) && (((exitstatus) & 0xff00) >> 8) == 0;
    struct if_info *info;
    ((void) sizeof (((((exitstatus) & 0x7f) == 0) || (((char) (((exitstatus) & 0x7f) + 1) >> 1) > 0)) ? 1 : 0), __extension__ ({ if ((((exitstatus) & 0x7f) == 0) || (((char) (((exitstatus) & 0x7f) + 1) >> 1) > 0)) ; else __assert_fail ("WIFEXITED(exitstatus) || WIFSIGNALED(exitstatus)", "if_info.c", 292, __extension__ __PRETTY_FUNCTION__); }));
    int find_pid(struct if_info *i) {
        if (i->worker == pid) {
            info = i;
            return 1;
        }
        return 0;
    }
    info = ((void *)0);
    for_each_iface(find_pid);
    if (info == ((void *)0)) {
        do_log(6, "Unexpected child %d exited with status %d",
               pid, exitstatus);
        return;
    }
    do_log(6, "%s: state %s pid %d exited status %d",
           info->name, statename(info->state), pid, exitstatus);
    info->worker = -1;
    switch(info->state) {
    case ST_PROBING:
        if (!exitok)
            do_log(4, "Could not bring %s back up", info->name);
        info->state = ST_DOWN;
        break;
    case ST_PROBING_UP:
        info->state = ST_INACTIVE;
        break;
    case ST_DOWNANDOUT:
        info->state = ST_PROBING;
        ((void) sizeof ((info->worker == -1) ? 1 : 0), __extension__ ({ if (info->worker == -1) ; else __assert_fail ("info->worker == -1", "if_info.c", 338, __extension__ __PRETTY_FUNCTION__); }));
        info->worker = run_netplug_bg(info->name, "probe");
        break;
    case ST_INNING:
        if (exitok)
            info->state = ST_ACTIVE;
        else
            info->state = ST_INSANE;
        break;
    case ST_OUTING:
        info->state = ST_INACTIVE;
        break;
    case ST_WAIT_IN:
        ((void) sizeof ((info->worker == -1) ? 1 : 0), __extension__ ({ if (info->worker == -1) ; else __assert_fail ("info->worker == -1", "if_info.c", 355, __extension__ __PRETTY_FUNCTION__); }));
        info->worker = run_netplug_bg(info->name, "out");
        info->state = ST_OUTING;
        break;
    case ST_INACTIVE:
    case ST_ACTIVE:
    case ST_INSANE:
    case ST_DOWN:
        do_log(3, "ifsm_scriptdone: %s: bad state %s for script termination",
               info->name, statename(info->state));
        exit(1);
    }
    do_log(7, "%s: moved to state %s", info->name, statename(info->state));
}

variable_types: exitstatus int

variable_types: exitok int


repo: vyos/netplug

decompiled_code:
__int64 __fastcall if_info_get_interface(__int64 a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 *v4; // rbp

result = 0LL;
if ( *(_WORD *)(a1 + 4) == 16 && *(_DWORD *)a1 > 0x17u )
{
result = *(_QWORD *)(a2 + 24);
if ( result )
{
v3 = *(_DWORD *)(a1 + 20) & 0xF;
result = if_info[v3];
if ( result )
{
while ( *(_DWORD *)(a1 + 20) != *(_DWORD *)(result + 8) )
{
if ( !*(_QWORD *)result )
{
v4 = (__int64 *)result;
goto LABEL_12;
}
result = *(_QWORD *)result;
}
}
else
{
v4 = &if_info[v3];
LABEL_12:
result = xmalloc(64LL);
*(_QWORD *)result = *v4;
*(_DWORD *)(result + 8) = *(_DWORD *)(a1 + 20);
*v4 = result;
*(_QWORD *)(result + 48) = 0xFFFFFFFF00000000LL;
*(_QWORD *)(result + 56) = 0LL;
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, __int64 a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 *v4; // rbp

result = 0LL;
if ( *(_WORD *)(a1 + 4) == 16 && *(_DWORD *)a1 > 0x17u )
{
result = *(_QWORD *)(a2 + 24);
if ( result )
{
v3 = *(_DWORD *)(a1 + 20) & 0xF;
result = if_info[v3];
if ( result )
{
while ( *(_DWORD *)(a1 + 20) != *(_DWORD *)(result + 8) )
{
if ( !*(_QWORD *)result )
{
v4 = (__int64 *)result;
goto LABEL_12;
}
result = *(_QWORD *)result;
}
}
else
{
v4 = &if_info[v3];
LABEL_12:
result = xmalloc(64LL);
*(_QWORD *)result = *v4;
*(_DWORD *)(result + 8) = *(_DWORD *)(a1 + 20);
*v4 = result;
*(_QWORD *)(result + 48) = 0xFFFFFFFF00000000LL;
*(_QWORD *)(result + 56) = 0LL;
}
}
}
return result;
}

original_code:
struct if_info *
if_info_get_interface(struct nlmsghdr *hdr, struct rtattr *attrs[])
{
    if (hdr->nlmsg_type != RTM_NEWLINK) {
        return ((void *)0);
    }
    struct ifinfomsg *info = ((void*)(((char*)hdr) + ((0) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))));
    if (hdr->nlmsg_len < ((sizeof(info)) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))) {
        return ((void *)0);
    }
    if (attrs[IFLA_IFNAME] == ((void *)0)) {
        return ((void *)0);
    }
    int x = info->ifi_index & (16 -1);
    struct if_info *i, **ip;
    for (ip = &if_info[x]; (i = *ip) != ((void *)0); ip = &i->next) {
        if (i->index == info->ifi_index) {
            break;
        }
    }
    if (i == ((void *)0)) {
        i = xmalloc(sizeof(*i));
        i->next = *ip;
        i->index = info->ifi_index;
        *ip = i;
        i->state = ST_DOWN;
        i->lastchange = 0;
        i->worker = -1;
    }
    return i;
}

canonical_original_code:
struct if_info *if_info_get_interface(struct nlmsghdr *hdr, struct rtattr *attrs[])
{
    if (hdr->nlmsg_type != RTM_NEWLINK) {
        return ((void *)0);
    }
    struct ifinfomsg *info = ((void*)(((char*)hdr) + ((0) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))));
    if (hdr->nlmsg_len < ((sizeof(info)) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))) {
        return ((void *)0);
    }
    if (attrs[IFLA_IFNAME] == ((void *)0)) {
        return ((void *)0);
    }
    int x = info->ifi_index & (16 -1);
    struct if_info *i; struct if_info **ip;
    for (ip = &if_info[x]; (i = *ip) != ((void *)0); ip = &i->next) {
        if (i->index == info->ifi_index) {
            break;
        }
    }
    if (i == ((void *)0)) {
        i = xmalloc(sizeof(*i));
        i->next = *ip;
        i->index = info->ifi_index;
        *ip = i;
        i->state = ST_DOWN;
        i->lastchange = 0;
        i->worker = -1;
    }
    return i;
}

variable_types: struct nlmsghdr { unsigned int nlmsg_len; unsigned short nlmsg_type; unsigned short nlmsg_flags; unsigned int nlmsg_seq; unsigned int nlmsg_pid; } *

variable_types: struct rtattr { unsigned short rta_len; unsigned short rta_type; } *[]

variable_types: struct ifinfomsg { unsigned char ifi_family; unsigned char __ifi_pad; unsigned short ifi_type; int ifi_index; unsigned int ifi_flags; unsigned int ifi_change; } *

variable_types: x int

variable_types: struct if_info { struct if_info *next; int index; int type; unsigned int flags; int addr_len; unsigned char addr[8]; char name[16]; enum ifstate { ST_DOWN=0, ST_DOWNANDOUT=1, ST_PROBING=2, ST_PROBING_UP=3, ST_INACTIVE=4, ST_INNING=5, ST_WAIT_IN=6, ST_ACTIVE=7, ST_OUTING=8, ST_INSANE=9 } state; int worker; long lastchange; } **

user_defined_types: struct if_info { struct if_info *next; int index; int type; unsigned int flags; int addr_len; unsigned char addr[8]; char name[16]; enum ifstate state; int worker; long lastchange; }


original_code:
struct if_info *
if_info_update_interface(struct nlmsghdr *hdr, struct rtattr *attrs[])
{
    struct ifinfomsg *info = ((void*)(((char*)hdr) + ((0) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))));
    struct if_info *i;
    if ((i = if_info_get_interface(hdr, attrs)) == ((void *)0)) {
        return ((void *)0);
    }
    i->type = info->ifi_type;
    i->flags = info->ifi_flags;
    if (attrs[IFLA_ADDRESS]) {
        int alen;
        i->addr_len = alen = ((int)((attrs[IFLA_ADDRESS])->rta_len) - (( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (0)));
        if (alen > sizeof(i->addr))
            alen = sizeof(i->addr);
        memcpy(i->addr, ((void*)(((char*)(attrs[IFLA_ADDRESS])) + (( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (0)))), alen);
    } else {
        i->addr_len = 0;
        memset(i->addr, 0, sizeof(i->addr));
    }
    strcpy(i->name, ((void*)(((char*)(attrs[IFLA_IFNAME])) + (( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (0)))));
    return i;
}

canonical_original_code:
struct if_info *if_info_update_interface(struct nlmsghdr *hdr, struct rtattr *attrs[])
{
    struct ifinfomsg *info = ((void*)(((char*)hdr) + ((0) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))));
    struct if_info *i;
    if ((i = if_info_get_interface(hdr, attrs)) == ((void *)0)) {
        return ((void *)0);
    }
    i->type = info->ifi_type;
    i->flags = info->ifi_flags;
    if (attrs[IFLA_ADDRESS]) {
        int alen;
        i->addr_len = alen = ((int)((attrs[IFLA_ADDRESS])->rta_len) - (( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (0)));
        if (alen > sizeof(i->addr))
            alen = sizeof(i->addr);
        memcpy(i->addr, ((void *)(((char *)(attrs[IFLA_ADDRESS])) + (( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (0)))), alen);
    } else {
        i->addr_len = 0;
        memset(i->addr, 0, sizeof(i->addr));
    }
    strcpy(i->name, ((void *)(((char *)(attrs[IFLA_IFNAME])) + (( ((sizeof(struct rtattr))+4U -1) & ~(4U -1) ) + (0)))));
    return i;
}

variable_types: struct if_info { struct if_info *next; int index; int type; unsigned int flags; int addr_len; unsigned char addr[8]; char name[16]; enum ifstate { ST_DOWN=0, ST_DOWNANDOUT=1, ST_PROBING=2, ST_PROBING_UP=3, ST_INACTIVE=4, ST_INNING=5, ST_WAIT_IN=6, ST_ACTIVE=7, ST_OUTING=8, ST_INSANE=9 } state; int worker; long lastchange; } *

variable_types: alen int

user_defined_types: struct rtattr { unsigned short rta_len; unsigned short rta_type; }

user_defined_types: struct nlmsghdr { unsigned int nlmsg_len; unsigned short nlmsg_type; unsigned short nlmsg_flags; unsigned int nlmsg_seq; unsigned int nlmsg_pid; }

user_defined_types: struct ifinfomsg { unsigned char ifi_family; unsigned char __ifi_pad; unsigned short ifi_type; int ifi_index; unsigned int ifi_flags; unsigned int ifi_change; }


decompiled_code:
__int64 __fastcall if_info_save_interface(__int64 a1)
{
_BYTE v2[424]; // [rsp+0h] [rbp-1A8h] BYREF

parse_rtattrs(v2, 51, (unsigned __int16 *)(a1 + 32), *(_DWORD *)a1 - 32);
return (unsigned int)-(if_info_update_interface(a1, (__int64)v2) == 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
_BYTE v2[424]; // [rsp+0h] [rbp-1A8h] BYREF

parse_rtattrs(v2, 51, (unsigned __int16 *)(a1 + 32), *(_DWORD *)a1 - 32);
return (unsigned int)-(func8(a1, (__int64)v2) == 0LL);
}

original_code:
int if_info_save_interface(struct nlmsghdr *hdr, void *arg)
{
    struct rtattr *attrs[(__IFLA_MAX - 1) + 1];
    struct ifinfomsg *info = ((void*)(((char*)hdr) + ((0) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))));
    parse_rtattrs(attrs, (__IFLA_MAX - 1), ((struct rtattr*)(((char*)(info)) + ( ((sizeof(struct ifinfomsg))+4U -1) & ~(4U -1) ))), ((hdr)->nlmsg_len - ( (((((sizeof(struct ifinfomsg))) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )));
    return if_info_update_interface(hdr, attrs) ? 0 : -1;
}

canonical_original_code:
int if_info_save_interface(struct nlmsghdr *hdr, void *arg)
{
    struct rtattr *attrs[-1];
    struct ifinfomsg *info = ((void*)(((char*)hdr) + ((0) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))));
    parse_rtattrs(attrs, (__IFLA_MAX - 1), ((struct rtattr *)(((char *)(info)) + ( ((sizeof(struct ifinfomsg))+4U -1) & ~(4U -1) ))), ((hdr)->nlmsg_len - ( (((((sizeof(struct ifinfomsg))) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) ))))+4U -1) & ~(4U -1) )));
    return if_info_update_interface(hdr, attrs) ? 0 : -1;
}

variable_types:
arg
void *

variable_types: struct rtattr { unsigned short rta_len; unsigned short rta_type; } *[-1]

return_type: int


receive

decompiled_code:
__int64 __fastcall receive(int a1, struct msghdr *a2, _DWORD *a3)
{
int v4; // eax
__int64 v5; // rdx
unsigned int v6; // er12
__int64 result; // rax
int v8; // eax

v4 = recvmsg(a1, a2, 0);
*a3 = v4;
if ( v4 == -1 )
{
v6 = 1;
v8 = *_errno_location();
if ( v8 == 4 )
return v6;
v6 = 2;
if ( v8 == 11 )
return v6;
do_log(3LL, "Netlink receive error: %m");
result = 2LL;
}
else
{
if ( !v4 )
{
v6 = 3;
do_log(3LL, "Unexpected EOF on netlink");
return v6;
}
v5 = a2->msg_namelen;
if ( (_DWORD)v5 == 12 )
{
v6 = *((_DWORD *)a2->msg_name + 1);
if ( v6 )
{
do_log(3LL, "Netlink packet came from pid %d, not from kernel", v6);
v6 = 4;
}
return v6;
}
do_log(3LL, "Unexpected sender address length: got %d, expected %d", v5, 12LL);
result = 2LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, struct msghdr *a2, _DWORD *a3)
{
int v4; // eax
__int64 v5; // rdx
unsigned int v6; // er12
__int64 result; // rax
int v8; // eax

v4 = recvmsg(a1, a2, 0);
*a3 = v4;
if ( v4 == -1 )
{
v6 = 1;
v8 = *_errno_location();
if ( v8 == 4 )
return v6;
v6 = 2;
if ( v8 == 11 )
return v6;
do_log(3LL, "Netlink receive error: %m");
result = 2LL;
}
else
{
if ( !v4 )
{
v6 = 3;
do_log(3LL, "Unexpected EOF on netlink");
return v6;
}
v5 = a2->msg_namelen;
if ( (_DWORD)v5 == 12 )
{
v6 = *((_DWORD *)a2->msg_name + 1);
if ( v6 )
{
do_log(3LL, "Netlink packet came from pid %d, not from kernel", v6);
v6 = 4;
}
return v6;
}
do_log(3LL, "Unexpected sender address length: got %d, expected %d", v5, 12LL);
result = 2LL;
}
return result;
}

original_code:
static todo
receive(int fd, struct msghdr *msg, int *status)
{
    *status = recvmsg(fd, msg, 0);
    if (*status == -1) {
 if ((*__errno_location ()) == 4) {
     return skip;
 }
 if ((*__errno_location ()) == 11) {
     return done;
 }
 do_log(3, "Netlink receive error: %m");
 return done;
    }
    else if (*status == 0) {
 do_log(3, "Unexpected EOF on netlink");
 return bail;
    }
    if (msg->msg_namelen != sizeof(struct sockaddr_nl)) {
 do_log(3, "Unexpected sender address length: got %d, expected %d",
        msg->msg_namelen, (int) sizeof(struct sockaddr_nl));
 return done;
    }
    if (((struct sockaddr_nl *) msg->msg_name)->nl_pid != 0) {
 do_log(3, "Netlink packet came from pid %d, not from kernel",
        ((struct sockaddr_nl *) msg->msg_name)->nl_pid);
 return user;
    }
    return ok;
}

canonical_original_code:
static enum todo receive(int fd, struct msghdr *msg, int *status)
{
    *status = recvmsg(fd, msg, 0);
    if (*status == -1) {
 if ((*__errno_location ()) == 4) {
     return skip;
 }
 if ((*__errno_location ()) == 11) {
     return done;
 }
 do_log(3, "Netlink receive error: %m");
 return done;
    }
    else if (*status == 0) {
 do_log(3, "Unexpected EOF on netlink");
 return bail;
    }
    if (msg->msg_namelen != sizeof(struct sockaddr_nl)) {
 do_log(3, "Unexpected sender address length: got %d, expected %d",
        msg->msg_namelen, (int) sizeof(struct sockaddr_nl));
 return done;
    }
    if (((struct sockaddr_nl *) msg->msg_name)->nl_pid != 0) {
 do_log(3, "Netlink packet came from pid %d, not from kernel",
        ((struct sockaddr_nl *) msg->msg_name)->nl_pid);
 return user;
    }
    return ok;
}

variable_types: fd int

variable_types: struct msghdr { void *msg_name; unsigned int msg_namelen; struct iovec { void *iov_base; unsigned long iov_len; } *msg_iov; unsigned long msg_iovlen; void *msg_control; unsigned long msg_controllen; int msg_flags; } *

variable_types:
status
int *

return_type: enum todo { ok=0, skip=1, done=2, bail=3, user=4 }

user_defined_types: struct sockaddr_nl { unsigned short nl_family; unsigned short nl_pad; unsigned int nl_pid; unsigned int nl_groups; }

user_defined_types: struct msghdr { void *msg_name; unsigned int msg_namelen; struct iovec *msg_iov; unsigned long msg_iovlen; void *msg_control; unsigned long msg_controllen; int msg_flags; }


decompiled_code:
__int64 __fastcall netlink_listen(int a1, unsigned int (__fastcall *a2)(int *, __int64), __int64 a3)
{
unsigned int v4; // eax
__int64 v6; // rdx
int *v7; // r15
__int64 v8; // rbx
int v9; // ebx
unsigned int v10; // [rsp+0h] [rbp-2098h] BYREF
__int64 v11; // [rsp+4h] [rbp-2094h] BYREF
int v12; // [rsp+Ch] [rbp-208Ch]
__int64 v13[2]; // [rsp+10h] [rbp-2088h] BYREF
struct msghdr v14; // [rsp+20h] [rbp-2078h] BYREF
char v15[8248]; // [rsp+60h] [rbp-2038h] BYREF

v14.msg_name = &v11;
v14.msg_iov = (struct iovec *)v13;
v13[0] = (__int64)v15;
v13[1] = 0x2000LL;
*(_QWORD *)&v14.msg_namelen = 12LL;
*(_OWORD *)&v14.msg_iovlen = 1uLL;
v12 = 0;
v11 = 16LL;
*(_OWORD *)&v14.msg_controllen = 0LL;
while ( 1 )
{
while ( 1 )
{
LABEL_2:
v4 = receive(a1, &v14, &v10);
if ( v4 == 3 )
return 0LL;
if ( v4 > 3 )
break;
if ( v4 != 1 )
{
if ( v4 == 2 )
return 1LL;
goto LABEL_8;
}
}
if ( v4 == 4 )
return 1LL;
LABEL_8:
v6 = v10;
if ( v10 > 0xF )
break;
LABEL_20:
if ( (v14.msg_flags & 0x20) != 0 )
{
do_log(3LL, "Message truncated");
}
else if ( (_DWORD)v6 )
{
do_log(3LL, "!!!Remnant of size %d", v6);
return 1LL;
}
}
v7 = (int *)v15;
while ( 1 )
{
v9 = *v7;
if ( *v7 - 16 < 0 || v9 > (int)v6 )
break;
if ( a2 && a2(v7, a3) == -1 )
{
do_log(3LL, "Callback failed");
goto LABEL_2;
}
v8 = (v9 + 3) & 0xFFFFFFFC;
v6 = v10 - (unsigned int)v8;
v7 = (int *)((char *)v7 + v8);
v10 = v6;
if ( (unsigned int)v6 <= 0xF )
goto LABEL_20;
}
if ( (v14.msg_flags & 0x20) != 0 )
do_log(3LL, "Truncated message");
else
do_log(3LL, "Malformed netlink message");
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, unsigned int (__fastcall *a2)(int *, __int64), __int64 a3)
{
unsigned int v4; // eax
__int64 v6; // rdx
int *v7; // r15
__int64 v8; // rbx
int v9; // ebx
unsigned int v10; // [rsp+0h] [rbp-2098h] BYREF
__int64 v11; // [rsp+4h] [rbp-2094h] BYREF
int v12; // [rsp+Ch] [rbp-208Ch]
__int64 v13[2]; // [rsp+10h] [rbp-2088h] BYREF
struct msghdr v14; // [rsp+20h] [rbp-2078h] BYREF
char v15[8248]; // [rsp+60h] [rbp-2038h] BYREF

v14.msg_name = &v11;
v14.msg_iov = (struct iovec *)v13;
v13[0] = (__int64)v15;
v13[1] = 0x2000LL;
*(_QWORD *)&v14.msg_namelen = 12LL;
*(_OWORD *)&v14.msg_iovlen = 1uLL;
v12 = 0;
v11 = 16LL;
*(_OWORD *)&v14.msg_controllen = 0LL;
while ( 1 )
{
while ( 1 )
{
LABEL_2:
v4 = func0(a1, &v14, &v10);
if ( v4 == 3 )
return 0LL;
if ( v4 > 3 )
break;
if ( v4 != 1 )
{
if ( v4 == 2 )
return 1LL;
goto LABEL_8;
}
}
if ( v4 == 4 )
return 1LL;
LABEL_8:
v6 = v10;
if ( v10 > 0xF )
break;
LABEL_20:
if ( (v14.msg_flags & 0x20) != 0 )
{
do_log(3LL, "Message truncated");
}
else if ( (_DWORD)v6 )
{
do_log(3LL, "!!!Remnant of size %d", v6);
return 1LL;
}
}
v7 = (int *)v15;
while ( 1 )
{
v9 = *v7;
if ( *v7 - 16 < 0 || v9 > (int)v6 )
break;
if ( a2 && a2(v7, a3) == -1 )
{
do_log(3LL, "Callback failed");
goto LABEL_2;
}
v8 = (v9 + 3) & 0xFFFFFFFC;
v6 = v10 - (unsigned int)v8;
v7 = (int *)((char *)v7 + v8);
v10 = v6;
if ( (unsigned int)v6 <= 0xF )
goto LABEL_20;
}
if ( (v14.msg_flags & 0x20) != 0 )
do_log(3LL, "Truncated message");
else
do_log(3LL, "Malformed netlink message");
return 1LL;
}

original_code:
int
netlink_listen(int fd, netlink_callback callback, void *arg)
{
    char buf[8192];
    struct iovec iov = { buf, sizeof(buf) };
    struct sockaddr_nl addr;
    struct msghdr msg = {
        .msg_name = (void *) &addr,
        .msg_namelen = sizeof(addr),
        .msg_iov = &iov,
        .msg_iovlen = 1,
    };
    memset(&addr, 0, sizeof(addr));
    addr.nl_family = 16;
    addr.nl_pid = 0;
    addr.nl_groups = 0;
    while (1) {
 int status;
 switch (receive(fd, &msg, &status)) {
 case user:
 case done:
     return 1;
 case bail:
     return 0;
 case skip:
     continue;
 case ok:
     break;
 }
        struct nlmsghdr *hdr;
        for (hdr = (struct nlmsghdr*) buf; status >= sizeof(*hdr); ) {
            int len = hdr->nlmsg_len;
            int l = len - sizeof(*hdr);
            if (l < 0 || len > status) {
                if (msg.msg_flags & MSG_TRUNC) {
                    do_log(3, "Truncated message");
                    return 1;
                }
                do_log(3, "Malformed netlink message");
                return 1;
            }
            if (callback) {
                int err;
                if ((err = callback(hdr, arg)) == -1) {
                    do_log(3, "Callback failed");
                    goto outer;
                }
            }
            status -= ( ((len)+4U -1) & ~(4U -1) );
            hdr = (struct nlmsghdr *) ((char *) hdr + ( ((len)+4U -1) & ~(4U -1) ));
        }
        if (msg.msg_flags & MSG_TRUNC) {
            do_log(3, "Message truncated");
            continue;
        }
        if (status) {
            do_log(3, "!!!Remnant of size %d", status);
            return 1;
        }
    outer:
                        ;
    }
}

canonical_original_code:
int netlink_listen(int fd, int (*callback)(struct nlmsghdr *hdr, void *arg), void *arg)
{
    char buf[8192];
    struct iovec iov = { buf, sizeof(buf) };
    struct sockaddr_nl addr;
    struct msghdr msg = {
        .msg_name = (void *) &addr,
        .msg_namelen = sizeof(addr),
        .msg_iov = &iov,
        .msg_iovlen = 1,
    };
    memset(&addr, 0, sizeof(addr));
    addr.nl_family = 16;
    addr.nl_pid = 0;
    addr.nl_groups = 0;
    while (1) {
 int status;
 switch (receive(fd, &msg, &status)) {
 case user:
 case done:
     return 1;
 case bail:
     return 0;
 case skip:
     continue;
 case ok:
     break;
 }
        struct nlmsghdr *hdr;
        for (hdr = (struct nlmsghdr *) buf; status >= sizeof(*hdr); ) {
            int len = hdr->nlmsg_len;
            int l = len - sizeof(*hdr);
            if (l < 0 || len > status) {
                if (msg.msg_flags & MSG_TRUNC) {
                    do_log(3, "Truncated message");
                    return 1;
                }
                do_log(3, "Malformed netlink message");
                return 1;
            }
            if (callback) {
                int err;
                if ((err = callback(hdr, arg)) == -1) {
                    do_log(3, "Callback failed");
                    goto outer;
                }
            }
            status -= ( ((len)+4U -1) & ~(4U -1) );
            hdr = (struct nlmsghdr *) ((char *) hdr + ( ((len)+4U -1) & ~(4U -1) ));
        }
        if (msg.msg_flags & MSG_TRUNC) {
            do_log(3, "Message truncated");
            continue;
        }
        if (status) {
            do_log(3, "!!!Remnant of size %d", status);
            return 1;
        }
    outer:
                        ;
    }
}

variable_types: int (*)(struct nlmsghdr { unsigned int nlmsg_len; unsigned short nlmsg_type; unsigned short nlmsg_flags; unsigned int nlmsg_seq; unsigned int nlmsg_pid; } *hdr, void *arg)

variable_types:
buf
char [8192]

variable_types: struct sockaddr_nl { unsigned short nl_family; unsigned short nl_pad; unsigned int nl_pid; unsigned int nl_groups; }

variable_types: struct msghdr { void *msg_name; unsigned int msg_namelen; struct iovec { void *iov_base; unsigned long iov_len; } *msg_iov; unsigned long msg_iovlen; void *msg_control; unsigned long msg_controllen; int msg_flags; }

variable_types: status int

variable_types: len int

variable_types: l int

variable_types: err int


decompiled_code:
__int64 netlink_open()
{
unsigned int v0; // eax
unsigned int v1; // er12
socklen_t v3; // [rsp+0h] [rbp-18h] BYREF
struct sockaddr addr; // [rsp+4h] [rbp-14h] BYREF

v0 = socket(16, 3, 0);
if ( v0 == -1 )
{
do_log(3LL, "Could not create netlink socket: %m");
goto LABEL_8;
}
v1 = v0;
close_on_exec(v0);
addr.sa_family = 16;
*(_DWORD *)addr.sa_data = 0;
*(_WORD *)&addr.sa_data[4] = 0;
*(_DWORD *)&addr.sa_data[6] = 1;
if ( bind(v1, &addr, 0xCu) == -1 )
{
do_log(3LL, "Could not bind netlink socket: %m");
LABEL_8:
exit(1);
}
v3 = 12;
if ( getsockname(v1, &addr, &v3) == -1 )
{
do_log(3LL, "Could not get socket details: %m");
goto LABEL_8;
}
if ( v3 != 12 )
{
do_log(3LL, "Our netlink socket size does not match the kernel's!");
goto LABEL_8;
}
if ( addr.sa_family != 16 )
{
do_log(3LL, "The kernel has given us an insane address family!");
goto LABEL_8;
}
return v1;
}

canonical_decompiled_code:
__int64 func4()
{
unsigned int v0; // eax
unsigned int v1; // er12
socklen_t v3; // [rsp+0h] [rbp-18h] BYREF
struct sockaddr addr; // [rsp+4h] [rbp-14h] BYREF

v0 = socket(16, 3, 0);
if ( v0 == -1 )
{
do_log(3LL, "Could not create netlink socket: %m");
goto LABEL_8;
}
v1 = v0;
close_on_exec(v0);
addr.sa_family = 16;
*(_DWORD *)addr.sa_data = 0;
*(_WORD *)&addr.sa_data[4] = 0;
*(_DWORD *)&addr.sa_data[6] = 1;
if ( bind(v1, &addr, 0xCu) == -1 )
{
do_log(3LL, "Could not bind netlink socket: %m");
LABEL_8:
exit(1);
}
v3 = 12;
if ( getsockname(v1, &addr, &v3) == -1 )
{
do_log(3LL, "Could not get socket details: %m");
goto LABEL_8;
}
if ( v3 != 12 )
{
do_log(3LL, "Our netlink socket size does not match the kernel's!");
goto LABEL_8;
}
if ( addr.sa_family != 16 )
{
do_log(3LL, "The kernel has given us an insane address family!");
goto LABEL_8;
}
return v1;
}

original_code:
int
netlink_open(void)
{
    int fd;
    if ((fd = socket(16, SOCK_RAW, 0)) == -1) {
        do_log(3, "Could not create netlink socket: %m");
        exit(1);
    }
    close_on_exec(fd);
    struct sockaddr_nl addr;
    memset(&addr, 0, sizeof(addr));
    addr.nl_family = 16;
    addr.nl_groups = 1;
    if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
        do_log(3, "Could not bind netlink socket: %m");
        exit(1);
    }
    socklen_t addr_len = sizeof(addr);
    if (getsockname(fd, (struct sockaddr *) &addr, &addr_len) == -1) {
        do_log(3, "Could not get socket details: %m");
        exit(1);
    }
    if (addr_len != sizeof(addr)) {
        do_log(3, "Our netlink socket size does not match the kernel's!");
        exit(1);
    }
    if (addr.nl_family != 16) {
        do_log(3, "The kernel has given us an insane address family!");
        exit(1);
    }
    return fd;
}

canonical_original_code:
int netlink_open()
{
    int fd;
    if ((fd = socket(16, SOCK_RAW, 0)) == -1) {
        do_log(3, "Could not create netlink socket: %m");
        exit(1);
    }
    close_on_exec(fd);
    struct sockaddr_nl addr;
    memset(&addr, 0, sizeof(addr));
    addr.nl_family = 16;
    addr.nl_groups = 1;
    if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
        do_log(3, "Could not bind netlink socket: %m");
        exit(1);
    }
    unsigned int addr_len = sizeof(addr);
    if (getsockname(fd, (struct sockaddr *) &addr, &addr_len) == -1) {
        do_log(3, "Could not get socket details: %m");
        exit(1);
    }
    if (addr_len != sizeof(addr)) {
        do_log(3, "Our netlink socket size does not match the kernel's!");
        exit(1);
    }
    if (addr.nl_family != 16) {
        do_log(3, "The kernel has given us an insane address family!");
        exit(1);
    }
    return fd;
}

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }


destroy

decompiled_code:
void destroy()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
static void destroy(const KPwindow_painter_event_t *event) {
  (void)(event);;
}

canonical_original_code:
static void destroy(struct KPwindow_painter_event_t *event) {
  (void)(event);;
}

variable_types: struct KPwindow_painter_event_t { enum { KPWindowPaintBegin=0, KPWindowPaintReconfigure=1, KPWindowPaintPaint=2, KPWindowPaintPause=3, KPWindowPaintEnd=4 } type; void *window; void *user_data; struct { unsigned int width; float aspect; } configuration; struct { unsigned long long pts; unsigned long long time_delta; unsigned long long time_delta_frame; } time; } *

return_type: void


kpRenderTag

decompiled_code:
__int64 __fastcall kpRenderTag(_BYTE *a1)
{
int v1; // edx

if ( *a1 )
{
if ( a1[1] )
goto LABEL_3;
}
else
{
kpLog("APP", "KP_RASSERT(name[0] != 0) failed at %s:%d", "../include/kapusha/render.h", 23LL);
kpSysAbort();
if ( a1[1] )
{
LABEL_3:
if ( a1[2] )
goto LABEL_4;
LABEL_8:
kpLog("APP", "KP_RASSERT(name[2] != 0) failed at %s:%d", "../include/kapusha/render.h", 25LL);
kpSysAbort();
v1 = (unsigned __int8)a1[3];
if ( (_BYTE)v1 )
return (v1 << 24) | ((unsigned __int8)a1[2] << 16) | (unsigned int)*(unsigned __int16 *)a1;
LABEL_9:
kpLog("APP", "KP_RASSERT(name[3] != 0) failed at %s:%d", "../include/kapusha/render.h", 26LL);
kpSysAbort();
v1 = (unsigned __int8)a1[3];
return (v1 << 24) | ((unsigned __int8)a1[2] << 16) | (unsigned int)*(unsigned __int16 *)a1;
}
}
kpLog("APP", "KP_RASSERT(name[1] != 0) failed at %s:%d", "../include/kapusha/render.h", 24LL);
kpSysAbort();
if ( !a1[2] )
goto LABEL_8;
LABEL_4:
v1 = (unsigned __int8)a1[3];
if ( !(_BYTE)v1 )
goto LABEL_9;
return (v1 << 24) | ((unsigned __int8)a1[2] << 16) | (unsigned int)*(unsigned __int16 *)a1;
}

canonical_decompiled_code:
__int64 __fastcall func1(_BYTE *a1)
{
int v1; // edx

if ( *a1 )
{
if ( a1[1] )
goto LABEL_3;
}
else
{
kpLog("APP", "KP_RASSERT(name[0] != 0) failed at %s:%d", "../include/kapusha/render.h", 23LL);
kpSysAbort();
if ( a1[1] )
{
LABEL_3:
if ( a1[2] )
goto LABEL_4;
LABEL_8:
kpLog("APP", "KP_RASSERT(name[2] != 0) failed at %s:%d", "../include/kapusha/render.h", 25LL);
kpSysAbort();
v1 = (unsigned __int8)a1[3];
if ( (_BYTE)v1 )
return (v1 << 24) | ((unsigned __int8)a1[2] << 16) | (unsigned int)*(unsigned __int16 *)a1;
LABEL_9:
kpLog("APP", "KP_RASSERT(name[3] != 0) failed at %s:%d", "../include/kapusha/render.h", 26LL);
kpSysAbort();
v1 = (unsigned __int8)a1[3];
return (v1 << 24) | ((unsigned __int8)a1[2] << 16) | (unsigned int)*(unsigned __int16 *)a1;
}
}
kpLog("APP", "KP_RASSERT(name[1] != 0) failed at %s:%d", "../include/kapusha/render.h", 24LL);
kpSysAbort();
if ( !a1[2] )
goto LABEL_8;
LABEL_4:
v1 = (unsigned __int8)a1[3];
if ( !(_BYTE)v1 )
goto LABEL_9;
return (v1 << 24) | ((unsigned __int8)a1[2] << 16) | (unsigned int)*(unsigned __int16 *)a1;
}

original_code:
inline static KPrender_tag_t kpRenderTag(const char *name) {
  if (!(name)) { kpLog("APP", "KP_RASSERT(" "name" ") failed at %s:%d", "../include/kapusha/render.h", 22); kpSysAbort(); };
  if (!(name[0] != 0)) { kpLog("APP", "KP_RASSERT(" "name[0] != 0" ") failed at %s:%d", "../include/kapusha/render.h", 23); kpSysAbort(); };
  if (!(name[1] != 0)) { kpLog("APP", "KP_RASSERT(" "name[1] != 0" ") failed at %s:%d", "../include/kapusha/render.h", 24); kpSysAbort(); };
  if (!(name[2] != 0)) { kpLog("APP", "KP_RASSERT(" "name[2] != 0" ") failed at %s:%d", "../include/kapusha/render.h", 25); kpSysAbort(); };
  if (!(name[3] != 0)) { kpLog("APP", "KP_RASSERT(" "name[3] != 0" ") failed at %s:%d", "../include/kapusha/render.h", 26); kpSysAbort(); };
  KPrender_tag_t tag;
  tag.tag.name[0] = name[0];
  tag.tag.name[1] = name[1];
  tag.tag.name[2] = name[2];
  tag.tag.name[3] = name[3];
  return tag;
}

canonical_original_code:
inline static struct KPrender_tag_t kpRenderTag(char *name) {
  if (!(name)) { kpLog("APP", "KP_RASSERT(" "name" ") failed at %s:%d", "../include/kapusha/render.h", 22); kpSysAbort(); };
  if (!(name[0] != 0)) { kpLog("APP", "KP_RASSERT(" "name[0] != 0" ") failed at %s:%d", "../include/kapusha/render.h", 23); kpSysAbort(); };
  if (!(name[1] != 0)) { kpLog("APP", "KP_RASSERT(" "name[1] != 0" ") failed at %s:%d", "../include/kapusha/render.h", 24); kpSysAbort(); };
  if (!(name[2] != 0)) { kpLog("APP", "KP_RASSERT(" "name[2] != 0" ") failed at %s:%d", "../include/kapusha/render.h", 25); kpSysAbort(); };
  if (!(name[3] != 0)) { kpLog("APP", "KP_RASSERT(" "name[3] != 0" ") failed at %s:%d", "../include/kapusha/render.h", 26); kpSysAbort(); };
  struct KPrender_tag_t tag;
  tag.tag.name[0] = name[0];
  tag.tag.name[1] = name[1];
  tag.tag.name[2] = name[2];
  tag.tag.name[3] = name[3];
  return tag;
}

variable_types:
name
char *

variable_types: struct KPrender_tag_t { union { char name[4]; unsigned int value; } tag; }


configure

original_code:
static void configure(const KPwindow_painter_event_t *event) {
  KPrender_destination_t dest;
  dest.framebuffer = 0;
  dest.viewport.bl.x = dest.viewport.bl.y = 0;
  dest.depth.test = KPRenderDepthTestEnabled;
  dest.depth.write = KPRenderDepthWriteEnabled;
  dest.depth.func = KPRenderDepthFuncLess;
  dest.viewport.tr.x = event->configuration.width;
  dest.viewport.tr.y = event->configuration.height;
  kpRenderSetDestination(&dest);
}

canonical_original_code:
static void configure(struct KPwindow_painter_event_t *event) {
  struct KPrender_destination_t dest;
  dest.framebuffer = 0;
  dest.viewport.bl.x = dest.viewport.bl.y = 0;
  dest.depth.test = KPRenderDepthTestEnabled;
  dest.depth.write = KPRenderDepthWriteEnabled;
  dest.depth.func = KPRenderDepthFuncLess;
  dest.viewport.tr.x = event->configuration.width;
  dest.viewport.tr.y = event->configuration.height;
  kpRenderSetDestination(&dest);
}

variable_types: struct KPrender_destination_t { struct KPrect2i { struct KPvec2i { int x; } bl; } viewport; void *framebuffer; struct { enum { KPRenderDepthTestDisabled=0, KPRenderDepthTestEnabled=1 } test; enum { KPRenderDepthWriteDisabled=0, KPRenderDepthWriteEnabled=1 } write; enum { KPRenderDepthFuncNever=0, KPRenderDepthFuncAlways=1, KPRenderDepthFuncLess=2, KPRenderDepthFuncLessOrEqual=3, KPRenderDepthFuncGreater=4, KPRenderDepthFuncGreaterOrEqual=5, KPRenderDepthFuncNotEqual=6, KPRenderDepthFuncEqual=7 } func; } depth; }

user_defined_types: struct KPrender_destination_t { struct KPrect2i viewport; void *framebuffer; struct { enum { KPRenderDepthTestDisabled=0, KPRenderDepthTestEnabled=1 } test; enum { KPRenderDepthWriteDisabled=0, KPRenderDepthWriteEnabled=1 } write; enum { KPRenderDepthFuncNever=0, KPRenderDepthFuncAlways=1, KPRenderDepthFuncLess=2, KPRenderDepthFuncLessOrEqual=3, KPRenderDepthFuncGreater=4, KPRenderDepthFuncGreaterOrEqual=5, KPRenderDepthFuncNotEqual=6, KPRenderDepthFuncEqual=7 } func; } depth; }

user_defined_types: struct KPwindow_painter_event_t { enum { KPWindowPaintBegin=0, KPWindowPaintReconfigure=1, KPWindowPaintPaint=2, KPWindowPaintPause=3, KPWindowPaintEnd=4 } type; void *window; void *user_data; struct { unsigned int width; float aspect; } configuration; struct { unsigned long long pts; unsigned long long time_delta; unsigned long long time_delta_frame; } time; }


create

decompiled_code:
__int64 create()
{
__int64 v0; // rbx
unsigned int v1; // eax
__int64 v2; // rdi
__int64 v3; // rdx
__int64 v4; // rcx
unsigned int v5; // eax
unsigned int v6; // eax
__int64 v7; // rdi
__int64 v8; // rdx
__int64 v9; // rcx
__int64 result; // rax
__int64 v11[3]; // [rsp+0h] [rbp-48h] BYREF
int v12; // [rsp+18h] [rbp-30h]
int v13; // [rsp+20h] [rbp-28h] BYREF
__int64 v14; // [rsp+28h] [rbp-20h]
__int64 v15; // [rsp+30h] [rbp-18h]
int v16; // [rsp+38h] [rbp-10h]

v0 = kpRenderBufferCreate();
kpRenderBufferUpload(v0, 0LL, 24LL, &vertices);
v11[0] = v0;
v11[1] = 2LL;
v11[2] = 0LL;
v12 = 8;
batch = kpRenderBatchCreate();
v1 = kpRenderTag("VRTX");
kpRenderBatchAttribSet(batch, v1, v11);
v2 = batch;
v14 = 0LL;
v16 = 3;
v15 = 0LL;
v13 = 2;
kpRenderBatchDrawSet(batch, &v13);
program = kpRenderProgramCreate(v2, &v13, v3, v4);
kpRenderProgramModuleSet(
program,
0LL,
146LL,
"attribute vec2 av2_vertex;\n"
"varying vec2 vv2_param;\n"
"void main() {\n"
" gl_Position = vec4(av2_vertex, 0., 1.);\n"
" vv2_param = vec2(.5) - av2_vertex;}\n");
kpRenderProgramModuleSet(
program,
1LL,
140LL,
"varying vec2 vv2_param;\n"
"uniform float uf_time;\n"
"void main() {\n"
" gl_FragColor = vec4(vv2_param, .5+.5*sin(10.*(vv2_param.y+uf_time)), 1.);\n"
"}\n");
v5 = kpRenderTag("TIME");
kpRenderProgramArgumentTag(program, "uf_time", v5);
v6 = kpRenderTag("VRTX");
v7 = program;
kpRenderProgramAttributeTag(program, "av2_vertex", v6);
result = kpRenderProgramEnvCreate(v7, "av2_vertex", v8, v9);
env = result;
return result;
}

canonical_decompiled_code:
__int64 func3()
{
__int64 v0; // rbx
unsigned int v1; // eax
__int64 v2; // rdi
__int64 v3; // rdx
__int64 v4; // rcx
unsigned int v5; // eax
unsigned int v6; // eax
__int64 v7; // rdi
__int64 v8; // rdx
__int64 v9; // rcx
__int64 result; // rax
__int64 v11[3]; // [rsp+0h] [rbp-48h] BYREF
int v12; // [rsp+18h] [rbp-30h]
int v13; // [rsp+20h] [rbp-28h] BYREF
__int64 v14; // [rsp+28h] [rbp-20h]
__int64 v15; // [rsp+30h] [rbp-18h]
int v16; // [rsp+38h] [rbp-10h]

v0 = kpRenderBufferCreate();
kpRenderBufferUpload(v0, 0LL, 24LL, &vertices);
v11[0] = v0;
v11[1] = 2LL;
v11[2] = 0LL;
v12 = 8;
batch = kpRenderBatchCreate();
v1 = func1("VRTX");
kpRenderBatchAttribSet(batch, v1, v11);
v2 = batch;
v14 = 0LL;
v16 = 3;
v15 = 0LL;
v13 = 2;
kpRenderBatchDrawSet(batch, &v13);
program = kpRenderProgramCreate(v2, &v13, v3, v4);
kpRenderProgramModuleSet(
program,
0LL,
146LL,
"attribute vec2 av2_vertex;\n"
"varying vec2 vv2_param;\n"
"void main() {\n"
" gl_Position = vec4(av2_vertex, 0., 1.);\n"
" vv2_param = vec2(.5) - av2_vertex;}\n");
kpRenderProgramModuleSet(
program,
1LL,
140LL,
"varying vec2 vv2_param;\n"
"uniform float uf_time;\n"
"void main() {\n"
" gl_FragColor = vec4(vv2_param, .5+.5*sin(10.*(vv2_param.y+uf_time)), 1.);\n"
"}\n");
v5 = func1("TIME");
kpRenderProgramArgumentTag(program, "uf_time", v5);
v6 = func1("VRTX");
v7 = program;
kpRenderProgramAttributeTag(program, "av2_vertex", v6);
result = kpRenderProgramEnvCreate(v7, "av2_vertex", v8, v9);
env = result;
return result;
}

original_code:
static void create() {
  (void)(create);;
  KPrender_buffer_o buf = kpRenderBufferCreate();
  KPblob_desc_t data;
  data.data = vertices;
  data.size = sizeof(vertices);
  kpRenderBufferUpload(buf, KPRenderBufferFlagNone, data);
  batch = kpRenderBatchCreate();
  KPrender_vertex_attrib_t vertex;
  vertex.buffer = buf;
  vertex.components = 2;
  vertex.offset = 0;
  vertex.stride = sizeof(KPvec2f);
  vertex.type = KPRenderVertexAttribF32;
  kpRenderBatchAttribSet(batch, kpRenderTag("VRTX"), &vertex);
  KPrender_draw_params_t draw;
  draw.buffer = 0;
  draw.count = 3;
  draw.offset = 0;
  draw.primitive = KPRenderDrawPrimitiveTriangleList;
  kpRenderBatchDrawSet(batch, &draw);
  program = kpRenderProgramCreate();
  data.data = shader_vertex;
  data.size = sizeof(shader_vertex);
  kpRenderProgramModuleSet(program, KPRenderProgramModuleVertex, data);
  data.data = shader_fragment;
  data.size = sizeof(shader_fragment);
  kpRenderProgramModuleSet(program, KPRenderProgramModuleFragment, data);
  kpRenderProgramArgumentTag(program, "uf_time", kpRenderTag("TIME"));
  kpRenderProgramAttributeTag(program, "av2_vertex", kpRenderTag("VRTX"));
  env = kpRenderProgramEnvCreate();
}

canonical_original_code:
static void create() {
  (void)(create);;
  void *buf = kpRenderBufferCreate();
  struct KPblob_desc_t data;
  data.data = vertices;
  data.size = sizeof(vertices);
  kpRenderBufferUpload(buf, KPRenderBufferFlagNone, data);
  batch = kpRenderBatchCreate();
  struct KPrender_vertex_attrib_t vertex;
  vertex.buffer = buf;
  vertex.components = 2;
  vertex.offset = 0;
  vertex.stride = sizeof(KPvec2f);
  vertex.type = KPRenderVertexAttribF32;
  kpRenderBatchAttribSet(batch, kpRenderTag("VRTX"), &vertex);
  struct KPrender_draw_params_t draw;
  draw.buffer = 0;
  draw.count = 3;
  draw.offset = 0;
  draw.primitive = KPRenderDrawPrimitiveTriangleList;
  kpRenderBatchDrawSet(batch, &draw);
  program = kpRenderProgramCreate();
  data.data = shader_vertex;
  data.size = sizeof(shader_vertex);
  kpRenderProgramModuleSet(program, KPRenderProgramModuleVertex, data);
  data.data = shader_fragment;
  data.size = sizeof(shader_fragment);
  kpRenderProgramModuleSet(program, KPRenderProgramModuleFragment, data);
  kpRenderProgramArgumentTag(program, "uf_time", kpRenderTag("TIME"));
  kpRenderProgramAttributeTag(program, "av2_vertex", kpRenderTag("VRTX"));
  env = kpRenderProgramEnvCreate();
}

variable_types:
buf
void *

variable_types: struct KPblob_desc_t { unsigned long long size; void *data; }

variable_types: struct KPrender_vertex_attrib_t { void *buffer; unsigned int components; enum KPRenderVertexAttribType { KPRenderVertexAttribF32=0, KPRenderVertexAttribU8=1, KPRenderVertexAttrib_Max=2 } type; unsigned long offset; unsigned int stride; }

variable_types: struct KPrender_draw_params_t { enum KPRenderDrawPrimitiveType { KPRenderDrawPrimitivePoint=0, KPRenderDrawPrimitiveLine=1, KPRenderDrawPrimitiveTriangleList=2, KPRenderDrawPrimitiveTriangleStrip=3, KPRenderDrawPrimitive_Max=4 } primitive; enum KPRenderDrawIndexType { KPRenderDrawIndexU16=0, KPRenderDrawIndexU32=1, KPRenderDrawIndex_Max=2 } index_type; void *buffer; unsigned long offset; unsigned int count; }

user_defined_types: struct KPrender_vertex_attrib_t { void *buffer; unsigned int components; enum KPRenderVertexAttribType type; unsigned long offset; unsigned int stride; }

user_defined_types: struct KPrender_draw_params_t { enum KPRenderDrawPrimitiveType primitive; enum KPRenderDrawIndexType index_type; void *buffer; unsigned long offset; unsigned int count; }


paint

decompiled_code:
__int64 __fastcall paint(__int64 a1, double a2, double a3)
{
__int64 v3; // rax
double v4; // xmm0_8
float v5; // xmm0_4
unsigned int v6; // eax
__int64 v8; // rdx
int v9; // [rsp+10h] [rbp-58h] BYREF
double v10; // [rsp+14h] [rbp-54h]
double v11; // [rsp+1Ch] [rbp-4Ch]
int v12; // [rsp+30h] [rbp-38h] BYREF
__int64 v13; // [rsp+38h] [rbp-30h]
__int64 v14; // [rsp+40h] [rbp-28h]
__int64 *v15; // [rsp+48h] [rbp-20h]
int v16; // [rsp+50h] [rbp-18h]

v3 = *(_QWORD *)(a1 + 40);
if ( v3 < 0 )
{
v8 = *(_QWORD *)(a1 + 40) & 1LL | (*(_QWORD *)(a1 + 40) >> 1);
v4 = (double)(int)v8 + (double)(int)v8;
}
else
{
v4 = (double)(int)v3;
}
v5 = v4 / 1000000000.0;
v6 = kpRenderTag("TIME");
kpRenderProgramEnvSetScalarf(env, v6, v5);
v9 = 0;
v10 = kpVec4f_constprop_0();
v11 = a3;
kpRenderExecuteCommand(&v9);
v12 = 1;
v16 = 1;
v13 = batch;
v15 = &env;
v14 = program;
return kpRenderExecuteCommand(&v12);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, double a2, double a3)
{
__int64 v3; // rax
double v4; // xmm0_8
float v5; // xmm0_4
unsigned int v6; // eax
__int64 v8; // rdx
int v9; // [rsp+10h] [rbp-58h] BYREF
double v10; // [rsp+14h] [rbp-54h]
double v11; // [rsp+1Ch] [rbp-4Ch]
int v12; // [rsp+30h] [rbp-38h] BYREF
__int64 v13; // [rsp+38h] [rbp-30h]
__int64 v14; // [rsp+40h] [rbp-28h]
__int64 *v15; // [rsp+48h] [rbp-20h]
int v16; // [rsp+50h] [rbp-18h]

v3 = *(_QWORD *)(a1 + 40);
if ( v3 < 0 )
{
v8 = *(_QWORD *)(a1 + 40) & 1LL | (*(_QWORD *)(a1 + 40) >> 1);
v4 = (double)(int)v8 + (double)(int)v8;
}
else
{
v4 = (double)(int)v3;
}
v5 = v4 / 1000000000.0;
v6 = func1("TIME");
kpRenderProgramEnvSetScalarf(env, v6, v5);
v9 = 0;
v10 = func4();
v11 = a3;
kpRenderExecuteCommand(&v9);
v12 = 1;
v16 = 1;
v13 = batch;
v15 = &env;
v14 = program;
return kpRenderExecuteCommand(&v12);
}

original_code:
static void paint(const KPwindow_painter_event_t *event) {
  kpRenderProgramEnvSetScalarf(env, kpRenderTag("TIME"), event->time.pts / 1000000000.);
  KPrender_cmd_fill_t fill;
  fill.header.cmd = KPrender_Command_Fill;
  fill.color = kpVec4f(0.f, 0.f, 0.f, 1.f);
  kpRenderExecuteCommand(&fill.header);
  KPrender_cmd_rasterize_t raster;
  raster.header.cmd = KPrender_Command_Rasterize;
  raster.batch = batch;
  raster.program = program;
  raster.env_count = 1;
  raster.env = &env;
  kpRenderExecuteCommand(&raster.header);
}

canonical_original_code:
static void paint(struct KPwindow_painter_event_t *event) {
  kpRenderProgramEnvSetScalarf(env, kpRenderTag("TIME"), event->time.pts / 1000000000.);
  struct KPrender_cmd_fill_t fill;
  fill.header.cmd = KPrender_Command_Fill;
  fill.color = kpVec4f(0.f, 0.f, 0.f, 1.f);
  kpRenderExecuteCommand(&fill.header);
  struct KPrender_cmd_rasterize_t raster;
  raster.header.cmd = KPrender_Command_Rasterize;
  raster.batch = batch;
  raster.program = program;
  raster.env_count = 1;
  raster.env = &env;
  kpRenderExecuteCommand(&raster.header);
}

variable_types: struct KPrender_cmd_fill_t { struct KPrender_cmd_header_t { enum KPrender_Command { KPrender_Command_Fill=0, KPrender_Command_Rasterize=1 } cmd; } header; struct KPvec4f { float x; } color; }

variable_types: struct KPrender_cmd_rasterize_t { struct KPrender_cmd_header_t { enum KPrender_Command { KPrender_Command_Fill=0, KPrender_Command_Rasterize=1 } cmd; } header; void *batch; void *program; void **env; unsigned int env_count; }

user_defined_types: struct KPrender_cmd_fill_t { struct KPrender_cmd_header_t header; struct KPvec4f color; }

user_defined_types: struct KPrender_cmd_rasterize_t { struct KPrender_cmd_header_t header; void *batch; void *program; void **env; unsigned int env_count; }

user_defined_types: struct KPrender_cmd_header_t { enum KPrender_Command cmd; }


kpThreadJoin

decompiled_code:
int __fastcall kpThreadJoin(pthread_t a1)
{
return pthread_join(a1, 0LL);
}

canonical_decompiled_code:
int __fastcall func1(pthread_t a1)
{
return pthread_join(a1, 0LL);
}

original_code:
void kpThreadJoin(KPthread_t thread) {
  pthread_join(thread, 0);
}

canonical_original_code:
void kpThreadJoin(unsigned long thread) {
  pthread_join(thread, 0);
}

variable_types:
thread
unsigned long


decompiled_code:
__int64 os_window_blit()
{
return glXSwapBuffers(display, drawable);
}

canonical_decompiled_code:
__int64 func2()
{
return glXSwapBuffers(display, drawable);
}

original_code:
void os_window_blit() {
  glXSwapBuffers(display, drawable);
}


decompiled_code:
int os_close_window()
{
glXMakeContextCurrent(display, 0LL, 0LL, 0LL);
glXDestroyWindow(display, drawable);
glXDestroyContext(display, context);
XDestroyWindow(display, window);
return XCloseDisplay(display);
}

canonical_decompiled_code:
int func3()
{
glXMakeContextCurrent(display, 0LL, 0LL, 0LL);
glXDestroyWindow(display, drawable);
glXDestroyContext(display, context);
XDestroyWindow(display, window);
return XCloseDisplay(display);
}

original_code:
void os_close_window() {
  glXMakeContextCurrent(display, 0, 0, 0);
  glXDestroyWindow(display, drawable);
  glXDestroyContext(display, context);
  XDestroyWindow(display, window);
  XCloseDisplay(display);
}


decompiled_code:
int __fastcall print_usage(const char *a1)
{
return printf("Usage:\n%s shader.glsl\n", a1);
}

canonical_decompiled_code:
int __fastcall func0(const char *a1)
{
return printf("Usage:\n%s shader.glsl\n", a1);
}

original_code:
void print_usage(const char *name) {
  printf("Usage:\n%s shader.glsl\n", name);
}

canonical_original_code:
void print_usage(char *name) {
  printf("Usage:\n%s shader.glsl\n", name);
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rbx
__int64 v4; // rbp
int v5; // er12
__int64 v6; // rdx
const char *v8; // rax
const char *v9; // rax
char v10[4]; // [rsp+Ch] [rbp-1006Ch] BYREF
__m128i v11; // [rsp+10h] [rbp-10068h] BYREF
int v12; // [rsp+20h] [rbp-10058h]
__m128i v13; // [rsp+30h] [rbp-10048h] BYREF
int v14; // [rsp+40h] [rbp-10038h]
unsigned int v15; // [rsp+50h] [rbp-10028h] BYREF
char v16[65572]; // [rsp+54h] [rbp-10024h] BYREF

if ( argc <= 1 )
{
v5 = 1;
print_usage(*argv);
}
else
{
v3 = argv[1];
if ( !(unsigned int)file_read(&v15, v3, envp) )
report_n_abort("main.c", "sage:\n%s shader.glsl\n", "cannot read input file");
os_open_window();
shader_init();
if ( !(unsigned int)shader_create(&v11, v16, v15) )
{
v8 = (const char *)shader_get_last_error(&v13);
fprintf(stderr, "shader error:\n\t%s\n", v8);
}
v4 = filemon_create(v3);
if ( !v4 )
report_n_abort("main.c", "der.glsl\n", "cannot monitor file changes");
while ( 1 )
{
v5 = os_window_process();
if ( !v5 )
break;
if ( (unsigned int)filemon_changed(v4) == 1 && (unsigned int)file_read(&v15, v3, v6) )
{
if ( (unsigned int)shader_create(&v13, v16, v15) )
{
shader_destroy(&v11);
v11 = _mm_loadu_si128(&v13);
v12 = v14;
}
else
{
v9 = (const char *)shader_get_last_error(v10);
fprintf(stderr, "shader error:\n\t%s\n", v9);
}
}
os_time();
shader_paint(&v11);
os_window_blit();
}
shader_destroy(&v11);
filemon_close(v4);
os_close_window();
}
return v5;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rbx
__int64 v4; // rbp
int v5; // er12
__int64 v6; // rdx
const char *v8; // rax
const char *v9; // rax
char v10[4]; // [rsp+Ch] [rbp-1006Ch] BYREF
__m128i v11; // [rsp+10h] [rbp-10068h] BYREF
int v12; // [rsp+20h] [rbp-10058h]
__m128i v13; // [rsp+30h] [rbp-10048h] BYREF
int v14; // [rsp+40h] [rbp-10038h]
unsigned int v15; // [rsp+50h] [rbp-10028h] BYREF
char v16[65572]; // [rsp+54h] [rbp-10024h] BYREF

if ( argc <= 1 )
{
v5 = 1;
func0(*argv);
}
else
{
v3 = argv[1];
if ( !(unsigned int)file_read(&v15, v3, envp) )
report_n_abort("main.c", "sage:\n%s shader.glsl\n", "cannot read input file");
os_open_window();
shader_init();
if ( !(unsigned int)shader_create(&v11, v16, v15) )
{
v8 = (const char *)shader_get_last_error(&v13);
fprintf(stderr, "shader error:\n\t%s\n", v8);
}
v4 = filemon_create(v3);
if ( !v4 )
report_n_abort("main.c", "der.glsl\n", "cannot monitor file changes");
while ( 1 )
{
v5 = os_window_process();
if ( !v5 )
break;
if ( (unsigned int)filemon_changed(v4) == 1 && (unsigned int)file_read(&v15, v3, v6) )
{
if ( (unsigned int)shader_create(&v13, v16, v15) )
{
shader_destroy(&v11);
v11 = _mm_loadu_si128(&v13);
v12 = v14;
}
else
{
v9 = (const char *)shader_get_last_error(v10);
fprintf(stderr, "shader error:\n\t%s\n", v9);
}
}
os_time();
shader_paint(&v11);
os_window_blit();
}
shader_destroy(&v11);
filemon_close(v4);
os_close_window();
}
return v5;
}

original_code:
int main(int argc, char *argv[]) {
  struct file_t source;
  struct shader_t shader;
  filemon_t filemon;
  const char *filename = argv[1];
  if (argc < 2) {
    print_usage(argv[0]);
    return 1;
  }
  if (!(0 != file_read(&source, filename))) report_n_abort("main.c", 18, "cannot read input file");;
  os_open_window();
  shader_init();
  if (0 == shader_create(&shader, source.text, source.size))
  {
    int size;
    fprintf(stderr, "shader error:\n\t%s\n", shader_get_last_error(&size));
  }
  if (!(0 != (filemon = filemon_create(filename)))) report_n_abort("main.c", 30, "cannot monitor file changes");;
  while (os_window_process() != 0) {
    if (filemon_changed(filemon) == 1) {
      if (0 != file_read(&source, filename)) {
        struct shader_t newshader;
        if (0 != shader_create(&newshader, source.text, source.size)) {
          shader_destroy(&shader);
          shader = newshader;
        } else {
          int size;
          fprintf(stderr, "shader error:\n\t%s\n", shader_get_last_error(&size));
        }
      }
    }
    shader_paint(&shader, os_time());
    os_window_blit();
  }
  shader_destroy(&shader);
  filemon_close(filemon);
  os_close_window();
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  struct file_t source;
  struct shader_t shader;
  void *filemon;
  char *filename = argv[1];
  if (argc < 2) {
    print_usage(argv[0]);
    return 1;
  }
  if (!(0 != file_read(&source, filename))) report_n_abort("main.c", 18, "cannot read input file");;
  os_open_window();
  shader_init();
  if (0 == shader_create(&shader, source.text, source.size))
  {
    int size;
    fprintf(stderr, "shader error:\n\t%s\n", shader_get_last_error(&size));
  }
  if (!(0 != (filemon = filemon_create(filename)))) report_n_abort("main.c", 30, "cannot monitor file changes");;
  while (os_window_process() != 0) {
    if (filemon_changed(filemon) == 1) {
      if (0 != file_read(&source, filename)) {
        struct shader_t newshader;
        if (0 != shader_create(&newshader, source.text, source.size)) {
          shader_destroy(&shader);
          shader = newshader;
        } else {
          int size;
          fprintf(stderr, "shader error:\n\t%s\n", shader_get_last_error(&size));
        }
      }
    }
    shader_paint(&shader, os_time());
    os_window_blit();
  }
  shader_destroy(&shader);
  filemon_close(filemon);
  os_close_window();
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: struct file_t { int size; char text[65536]; }

variable_types: struct shader_t { int program; int fragment; int utime; }

variable_types:
filemon
void *

variable_types:
filename
char *

variable_types: size int


decompiled_code:
void __fastcall __noreturn report_n_abort(const char *a1, unsigned int a2, const char *a3)
{
fprintf(stderr, "error @ %s:%d : %s\n", a1, a2, a3);
exit(-1);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(const char *a1, unsigned int a2, const char *a3)
{
fprintf(stderr, "error @ %s:%d : %s\n", a1, a2, a3);
exit(-1);
}

original_code:
void report_n_abort(const char *file, int line, const char *message) {
  fprintf(stderr, "error @ %s:%d : %s\n", file, line, message);
  exit(-1);
}

canonical_original_code:
void report_n_abort(char *file, int line, char *message) {
  fprintf(stderr, "error @ %s:%d : %s\n", file, line, message);
  exit(-1);
}

variable_types:
file
char *

variable_types: line int

variable_types:
message
char *


decompiled_code:
float os_time()
{
__int32 v0; // edx
int v1; // ecx
struct timespec v3; // [rsp+0h] [rbp-18h] BYREF

if ( clock_gettime(1, &v3) )
report_n_abort("os_linux.c", 0x12u, "clock_gettime(CLOCK_MONOTONIC)");
v1 = DWORD2(start);
v0 = start;
if ( start == 0 )
{
v0 = v3.tv_sec;
start = (__int128)_mm_loadu_si128((const __m128i *)&v3);
v1 = DWORD2(start);
}
return (double)(LODWORD(v3.tv_nsec) - v1) / 1000000000.0 + (double)(LODWORD(v3.tv_sec) - v0);
}

canonical_decompiled_code:
float func1()
{
__int32 v0; // edx
int v1; // ecx
struct timespec v3; // [rsp+0h] [rbp-18h] BYREF

if ( clock_gettime(1, &v3) )
func0("os_linux.c", 0x12u, "clock_gettime(CLOCK_MONOTONIC)");
v1 = DWORD2(start);
v0 = start;
if ( start == 0 )
{
v0 = v3.tv_sec;
start = (__int128)_mm_loadu_si128((const __m128i *)&v3);
v1 = DWORD2(start);
}
return (double)(LODWORD(v3.tv_nsec) - v1) / 1000000000.0 + (double)(LODWORD(v3.tv_sec) - v0);
}

original_code:
float os_time() {
  struct timespec ts;
  if (!(0 == clock_gettime(1, &ts))) report_n_abort("os_linux.c", 18, "clock_gettime(CLOCK_MONOTONIC)");;
  if (start.tv_sec == 0 && start.tv_nsec == 0) start = ts;
  return
    (ts.tv_sec - start.tv_sec) +
    (ts.tv_nsec - start.tv_nsec) / 1e9;
}

variable_types: struct timespec { long tv_sec; long tv_nsec; }

return_type: float


decompiled_code:
__int64 __fastcall file_read(_DWORD *a1, const char *a2)
{
int v2; // eax
int v3; // ebp
unsigned __int64 v4; // rax
__int64 result; // rax

v2 = open(a2, 0);
if ( v2 == -1 )
{
fprintf(stderr, "error: cannot open file \"%s\"\n", a2);
result = 0LL;
}
else
{
v3 = v2;
v4 = read(v2, a1 + 1, 0x10000uLL);
if ( v4 == -1LL )
{
fprintf(stderr, "error: cannot read file \"%s\"\n", a2);
close(v3);
result = 0LL;
}
else if ( v4 == 0x10000 || v4 <= 0x23 )
{
fprintf(stderr, "error: file \"%s\" has unreasonable size (read %d bytes)\n", a2, (unsigned int)v4);
close(v3);
result = 0LL;
}
else
{
*a1 = v4;
close(v3);
result = 1LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(_DWORD *a1, const char *a2)
{
int v2; // eax
int v3; // ebp
unsigned __int64 v4; // rax
__int64 result; // rax

v2 = open(a2, 0);
if ( v2 == -1 )
{
fprintf(stderr, "error: cannot open file \"%s\"\n", a2);
result = 0LL;
}
else
{
v3 = v2;
v4 = read(v2, a1 + 1, 0x10000uLL);
if ( v4 == -1LL )
{
fprintf(stderr, "error: cannot read file \"%s\"\n", a2);
close(v3);
result = 0LL;
}
else if ( v4 == 0x10000 || v4 <= 0x23 )
{
fprintf(stderr, "error: file \"%s\" has unreasonable size (read %d bytes)\n", a2, (unsigned int)v4);
close(v3);
result = 0LL;
}
else
{
*a1 = v4;
close(v3);
result = 1LL;
}
}
return result;
}

original_code:
int file_read(struct file_t *file, const char *filename) {
  ssize_t rd;
  int fd = open(filename, 0);
  if (fd == -1) {
    fprintf(stderr, "error: cannot open file \"%s\"\n", filename);
    return 0;
  }
  rd = read(fd, file->text, sizeof(file->text));
  if (rd == -1) {
    fprintf(stderr, "error: cannot read file \"%s\"\n", filename);
    close(fd);
    return 0;
  }
  if (rd == sizeof(file->text) || rd < sizeof("void main(){gl_FragColor=vec4(0.);}")) {
    fprintf(stderr, "error: file \"%s\" has unreasonable size (read %d bytes)\n",
      filename, (int)rd);
    close(fd);
    return 0;
  }
  file->size = rd;
  close(fd);
  return 1;
}

canonical_original_code:
int file_read(struct file_t *file, char *filename) {
  long rd;
  int fd = open(filename, 0);
  if (fd == -1) {
    fprintf(stderr, "error: cannot open file \"%s\"\n", filename);
    return 0;
  }
  rd = read(fd, file->text, sizeof(file->text));
  if (rd == -1) {
    fprintf(stderr, "error: cannot read file \"%s\"\n", filename);
    close(fd);
    return 0;
  }
  if (rd == sizeof(file->text) || rd < sizeof("void main(){gl_FragColor=vec4(0.);}")) {
    fprintf(stderr, "error: file \"%s\" has unreasonable size (read %d bytes)\n",
      filename, (int)rd);
    close(fd);
    return 0;
  }
  file->size = rd;
  close(fd);
  return 1;
}

variable_types: struct file_t { int size; char text[65536]; } *

variable_types: rd long

variable_types: fd int


decompiled_code:
int *__fastcall filemon_create(void *src)
{
size_t v1; // rbx
char *v2; // rax
const char *v3; // r13
int *v4; // r12
int v5; // eax

v1 = strlen((const char *)src);
v2 = (char *)malloc(v1 + 12);
if ( !v2 )
report_n_abort("os_linux.c", 0x44u, "malloc");
v3 = v2 + 8;
v4 = (int *)v2;
memcpy(v2 + 8, src, v1 + 1);
v5 = inotify_init1(2048);
*v4 = v5;
if ( v5 == -1 )
report_n_abort("os_linux.c", 0x47u, "inotify_init1");
v4[1] = inotify_add_watch(v5, v3, 0xC02u);
return v4;
}

canonical_decompiled_code:
int *__fastcall func3(void *src)
{
size_t v1; // rbx
char *v2; // rax
const char *v3; // r13
int *v4; // r12
int v5; // eax

v1 = strlen((const char *)src);
v2 = (char *)malloc(v1 + 12);
if ( !v2 )
func0("os_linux.c", 0x44u, "malloc");
v3 = v2 + 8;
v4 = (int *)v2;
memcpy(v2 + 8, src, v1 + 1);
v5 = inotify_init1(2048);
*v4 = v5;
if ( v5 == -1 )
func0("os_linux.c", 0x47u, "inotify_init1");
v4[1] = inotify_add_watch(v5, v3, 0xC02u);
return v4;
}

original_code:
filemon_t filemon_create(const char *filename) {
  const size_t size = sizeof(struct filemon_t_) + strlen(filename);
  struct filemon_t_ *f = malloc(size);
  if (!(f != ((void *)0))) report_n_abort("os_linux.c", 68, "malloc");;
  strcpy(f->filename, filename);
  f->ifd = inotify_init1(IN_NONBLOCK);
  if (!(f->ifd != -1)) report_n_abort("os_linux.c", 71, "inotify_init1");;
  f->watch = inotify_add_watch(f->ifd, f->filename,
    0x00000002 | 0x00000400 | 0x00000800);
  return f;
}

canonical_original_code:
void *filemon_create(char *filename) {
  unsigned long size = sizeof(struct filemon_t_) + strlen(filename);
  struct filemon_t_ *f = malloc(size);
  if (!(f != ((void *)0))) report_n_abort("os_linux.c", 68, "malloc");;
  strcpy(f->filename, filename);
  f->ifd = inotify_init1(IN_NONBLOCK);
  if (!(f->ifd != -1)) report_n_abort("os_linux.c", 71, "inotify_init1");;
  f->watch = inotify_add_watch(f->ifd, f->filename,
    0x00000002 | 0x00000400 | 0x00000800);
  return f;
}

variable_types:
size
unsigned long

variable_types: struct filemon_t_ { int ifd; int watch; char filename[1]; } *

return_type: void *


decompiled_code:
__int64 __fastcall filemon_changed(__int64 a1)
{
unsigned int v1; // er12
__int64 result; // rax
int v3; // eax
__int64 v4; // [rsp+0h] [rbp-128h] BYREF

if ( *(_DWORD *)(a1 + 4) == -1 )
{
v3 = inotify_add_watch(*(_DWORD *)a1, (const char *)(a1 + 8), 0xC02u);
*(_DWORD *)(a1 + 4) = v3;
result = v3 != -1;
}
else
{
LABEL_2:
v1 = 0;
while ( read(*(_DWORD *)a1, &v4, 0x110uLL) != -1 )
{
v1 = 1;
if ( (v4 & 0x8C0000000000LL) != 0 )
{
if ( (v4 & 0x80000000000LL) != 0 )
inotify_rm_watch(*(_DWORD *)a1, *(_DWORD *)(a1 + 4));
*(_DWORD *)(a1 + 4) = -1;
goto LABEL_2;
}
}
if ( *_errno_location() != 11 )
report_n_abort("os_linux.c", 0x5Bu, "read inotify fd, errno != EAGAIN");
result = v1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
unsigned int v1; // er12
__int64 result; // rax
int v3; // eax
__int64 v4; // [rsp+0h] [rbp-128h] BYREF

if ( *(_DWORD *)(a1 + 4) == -1 )
{
v3 = inotify_add_watch(*(_DWORD *)a1, (const char *)(a1 + 8), 0xC02u);
*(_DWORD *)(a1 + 4) = v3;
result = v3 != -1;
}
else
{
LABEL_2:
v1 = 0;
while ( read(*(_DWORD *)a1, &v4, 0x110uLL) != -1 )
{
v1 = 1;
if ( (v4 & 0x8C0000000000LL) != 0 )
{
if ( (v4 & 0x80000000000LL) != 0 )
inotify_rm_watch(*(_DWORD *)a1, *(_DWORD *)(a1 + 4));
*(_DWORD *)(a1 + 4) = -1;
goto LABEL_2;
}
}
if ( *_errno_location() != 11 )
func0("os_linux.c", 0x5Bu, "read inotify fd, errno != EAGAIN");
result = v1;
}
return result;
}

original_code:
int filemon_changed(filemon_t fin) {
  char buffer[sizeof(struct inotify_event) + 255 + 1];
  const struct inotify_event *e = (const struct inotify_event*)buffer;
  struct filemon_t_ *f = (struct filemon_t_*)(fin);
  int retval = 0;
  if (f->watch == -1) {
    f->watch = inotify_add_watch(f->ifd, f->filename,
      0x00000002 | 0x00000400 | 0x00000800);
    return (f->watch == -1) ? 0 : 1;
  }
  for (;;) {
    ssize_t rd = read(f->ifd, buffer, sizeof(buffer));
    if (rd == -1) {
      if (!((*__errno_location ()) == 11)) report_n_abort("os_linux.c", 91, "read inotify fd, errno != EAGAIN");;
      break;
    }
    retval = 1;
    if (e->mask & (0x00008000 | 0x00000400 | 0x00000800)) {
      if (e->mask & 0x00000800) inotify_rm_watch(f->ifd, f->watch);
      f->watch = -1;
      retval = 0;
    }
  }
  return retval;
}

canonical_original_code:
int filemon_changed(void *fin) {
  char buffer[-1];
  struct inotify_event *e = (const struct inotify_event*)buffer;
  struct filemon_t_ *f = (struct filemon_t_*)(fin);
  int retval = 0;
  if (f->watch == -1) {
    f->watch = inotify_add_watch(f->ifd, f->filename,
      0x00000002 | 0x00000400 | 0x00000800);
    return (f->watch == -1) ? 0 : 1;
  }
  for (;;) {
    long rd = read(f->ifd, buffer, sizeof(buffer));
    if (rd == -1) {
      if (!((*__errno_location ()) == 11)) report_n_abort("os_linux.c", 91, "read inotify fd, errno != EAGAIN");;
      break;
    }
    retval = 1;
    if (e->mask & (0x00008000 | 0x00000400 | 0x00000800)) {
      if (e->mask & 0x00000800) inotify_rm_watch(f->ifd, f->watch);
      f->watch = -1;
      retval = 0;
    }
  }
  return retval;
}

variable_types:
fin
void *

variable_types:
buffer
char [-1]

variable_types: struct inotify_event { int wd; unsigned int mask; unsigned int cookie; unsigned int len; char name[]; } *

variable_types: retval int

user_defined_types: struct filemon_t_ { int ifd; int watch; char filename[1]; }


decompiled_code:
void __fastcall filemon_close(void *ptr)
{
int v1; // esi

v1 = *((_DWORD *)ptr + 1);
if ( v1 != -1 )
inotify_rm_watch(*(_DWORD *)ptr, v1);
close(*(_DWORD *)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func5(void *ptr)
{
int v1; // esi

v1 = *((_DWORD *)ptr + 1);
if ( v1 != -1 )
inotify_rm_watch(*(_DWORD *)ptr, v1);
close(*(_DWORD *)ptr);
free(ptr);
}

original_code:
void filemon_close(filemon_t fin) {
  struct filemon_t_ *f = (struct filemon_t_*)(fin);
  if (f->watch != -1) inotify_rm_watch(f->ifd, f->watch);
  close(f->ifd);
  free(f);
}

canonical_original_code:
void filemon_close(void *fin) {
  struct filemon_t_ *f = (struct filemon_t_*)(fin);
  if (f->watch != -1) inotify_rm_watch(f->ifd, f->watch);
  close(f->ifd);
  free(f);
}


original_code:
static void cx_array_dtor(void *array) {
  cx_array_ptr this = (cx_array_ptr)array;
  cx_size_t i;
  for(i = 0; i < this->count; ++i)
    cx_release(this->objs[i]);
  free(this->objs);
}

canonical_original_code:
static void cx_array_dtor(void *array) {
  struct cx_array_t *this = (cx_array_ptr)array;
  unsigned long i;
  for(i = 0; i < this->count; ++i)
    cx_release(this->objs[i]);
  free(this->objs);
}

variable_types:
array
void *

variable_types: struct cx_array_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_obj_t **objs; unsigned long count; unsigned long reserved; } *

variable_types:
i
unsigned long

user_defined_types: struct cx_array_t { struct cx_obj_t O; struct cx_obj_t **objs; unsigned long count; unsigned long reserved; }


decompiled_code:
_QWORD *cx_array_create()
{
_QWORD *v0; // rax
_QWORD *v1; // r12

v0 = (_QWORD *)cx_create(48LL, cx_array_class_name, cx_array_dtor);
v0[4] = 0LL;
v1 = v0;
v0[5] = 4LL;
v0[3] = malloc(0x20uLL);
return v1;
}

canonical_decompiled_code:
_QWORD *func1()
{
_QWORD *v0; // rax
_QWORD *v1; // r12

v0 = (_QWORD *)cx_create(48LL, cx_array_class_name, cx_array_dtor);
v0[4] = 0LL;
v1 = v0;
v0[5] = 4LL;
v0[3] = malloc(0x20uLL);
return v1;
}

original_code:
cx_array_ptr cx_array_create() {
  cx_array_ptr this = ((cx_array_ptr)cx_create(sizeof(struct cx_array_t), cx_array_class_name, cx_array_dtor));
  this->count = 0;
  this->reserved = 4;
  this->objs = (cx_obj_ptr*)malloc(this->reserved * sizeof(cx_obj_ptr));
  return this;
}

canonical_original_code:
struct cx_array_t *cx_array_create() {
  struct cx_array_t *this = ((cx_array_ptr)cx_create(sizeof(struct cx_array_t), cx_array_class_name, cx_array_dtor));
  this->count = 0;
  this->reserved = 4;
  this->objs = (struct cx_obj_t **)malloc(this->reserved * sizeof(cx_obj_ptr));
  return this;
}

return_type: struct cx_array_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_obj_t **objs; unsigned long count; unsigned long reserved; } *


decompiled_code:
__int64 __fastcall cx_array_insert_back(_QWORD *a1, __int64 a2)
{
__int64 v4; // rsi
void *v5; // rdi
__int64 result; // rax
void *v7; // rax

v4 = a1[4];
v5 = (void *)a1[3];
if ( v4 == a1[5] )
{
a1[5] = 2 * v4;
v7 = realloc(v5, 16 * v4);
v4 = a1[4];
a1[3] = v7;
v5 = v7;
}
result = cx_retain(a2);
*((_QWORD *)v5 + v4) = result;
++a1[4];
return result;
}

original_code:
void cx_array_insert_back(cx_array_ptr this, void *obj) {
  if (this->count == this->reserved) {
    this->reserved *= 2;
    this->objs = (cx_obj_ptr*)realloc(this->objs, this->reserved * sizeof(cx_obj_ptr));
  }
  this->objs[this->count] = cx_retain(obj);
  ++this->count;
}

canonical_original_code:
void cx_array_insert_back(struct cx_array_t *this, void *obj) {
  if (this->count == this->reserved) {
    this->reserved *= 2;
    this->objs = (struct cx_obj_t **)realloc(this->objs, this->reserved * sizeof(cx_obj_ptr));
  }
  this->objs[this->count] = cx_retain(obj);
  ++this->count;
}

variable_types:
obj
void *

user_defined_types: struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); }


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // r12
__int64 v4; // rbp
int v5; // er12

if ( argc <= 2 )
{
v5 = 1;
fprintf(stderr, "Usage: %s <path_to_scan> <filename.sqlite>\n", *argv);
}
else
{
v3 = argv[1];
cx_log_level = 15;
cx_log(0LL, "################", envp);
if ( cx_log_level >= 0 )
cx_log(0LL, "Staring cifond with media source dir %s", v3);
av_register_all();
avcodec_register_all();
v4 = keeper_create(argv[2]);
sourcer_start(v4, v3);
v5 = server_run(v4, 0LL, 8080LL);
sourcer_stop();
cx_release(v4);
}
return v5;
}

original_code:
int main(int argc, char *argv[]) {
  const char *storage;
  if (argc < 3) {
    fprintf(stderr, "Usage: %s <path_to_scan> <filename.sqlite>\n", argv[0]);
    return 1;
  }
  storage = argv[1];
  cx_log_level = 15;
  if ((0) <= cx_log_level) cx_log((0), "################");
  if ((0) <= cx_log_level) cx_log((0), "Staring cifond with media source dir %s", storage);
  av_register_all();
  avcodec_register_all();
  keeper_ptr keeper = keeper_create(argv[2]);
  sourcer_start(keeper, storage);
  int result = server_run(keeper, ((void *)0), 8080);
  sourcer_stop();
  cx_release(keeper);
  return result;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  char *storage;
  if (argc < 3) {
    fprintf(stderr, "Usage: %s <path_to_scan> <filename.sqlite>\n", argv[0]);
    return 1;
  }
  storage = argv[1];
  cx_log_level = 15;
  if ((0) <= cx_log_level) cx_log((0), "################");
  if ((0) <= cx_log_level) cx_log((0), "Staring cifond with media source dir %s", storage);
  av_register_all();
  avcodec_register_all();
  struct keeper_t *keeper = keeper_create(argv[2]);
  sourcer_start(keeper, storage);
  int result = server_run(keeper, ((void *)0), 8080);
  sourcer_stop();
  cx_release(keeper);
  return result;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
storage
char *

variable_types: struct keeper_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_obj_t *impl; } *

variable_types: result int

user_defined_types: struct keeper_t { struct cx_obj_t O; struct cx_obj_t *impl; }


decompiled_code:
__int64 __fastcall cx_retain(__int64 a1)
{
__int64 result; // rax

result = a1;
if ( a1 )
++*(_DWORD *)(a1 + 8);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int64 result; // rax

result = a1;
if ( a1 )
++*(_DWORD *)(a1 + 8);
return result;
}

original_code:
void *cx_retain(void *o) {
  if (((void *)0) != o)
    ++((cx_obj_ptr)o)->refcount;
  return o;
}

canonical_original_code:
void *cx_retain(void *o) {
  if (((void *)0) != o)
    ++((struct cx_obj_t *)o)->refcount;
  return o;
}

variable_types:
o
void *


decompiled_code:
void __fastcall cx_release(void *ptr)
{
if ( ptr )
{
if ( (*((_DWORD *)ptr + 2))-- == 1 )
{
(*((void (**)(void))ptr + 2))();
free(ptr);
}
}
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
if ( ptr )
{
if ( (*((_DWORD *)ptr + 2))-- == 1 )
{
(*((void (**)(void))ptr + 2))();
free(ptr);
}
}
}

original_code:
void cx_release(void *o) {
  if (((void *)0) == o) return;
  cx_obj_ptr this = (cx_obj_ptr)o;
  if (--(this->refcount) == 0) {
    this->dtor(this);
    free(this);
  }
}

canonical_original_code:
void cx_release(void *o) {
  if (((void *)0) == o) return;
  struct cx_obj_t *this = (cx_obj_ptr)o;
  if (--(this->refcount) == 0) {
    this->dtor(this);
    free(this);
  }
}

variable_types: struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } *


decompiled_code:
__int64 __fastcall keeper_dtor(__int64 a1)
{
return cx_release(*(_QWORD *)(a1 + 24));
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return cx_release(*(_QWORD *)(a1 + 24));
}

original_code:
static void keeper_dtor(void *keeper) {
  keeper_ptr this = (keeper_ptr)keeper;
  cx_release(this->impl);
}

canonical_original_code:
static void keeper_dtor(void *keeper) {
  struct keeper_t *this = (keeper_ptr)keeper;
  cx_release(this->impl);
}

variable_types:
keeper
void *


decompiled_code:
__int64 __fastcall keeper_exec(__int64 a1, const char *a2)
{
unsigned int v2; // er12
const char *v4; // rax

v2 = sqlite3_exec(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL), a2, 0LL, 0LL, 0LL);
if ( !v2 || cx_log_level <= 2 )
return v2;
v4 = (const char *)sqlite3_errmsg(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL));
cx_log(3LL, "Error executins SQL {%s}: %s", a2, v4);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, const char *a2)
{
unsigned int v2; // er12
const char *v4; // rax

v2 = sqlite3_exec(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL), a2, 0LL, 0LL, 0LL);
if ( !v2 || cx_log_level <= 2 )
return v2;
v4 = (const char *)sqlite3_errmsg(*(_QWORD *)(*(_QWORD *)(a1 + 24) + 24LL));
cx_log(3LL, "Error executins SQL {%s}: %s", a2, v4);
return v2;
}

original_code:
static int keeper_exec(keeper_ptr this, const char *sql) {
  int err = sqlite3_exec((((sqlite_ptr)((this)->impl))->db),
    sql, ((void *)0), ((void *)0), ((void *)0));
  if (err != 0) {
    if ((3) <= cx_log_level) cx_log((3), "Error executins SQL {%s}: %s", sql, sqlite3_errmsg((((sqlite_ptr)((this)->impl))->db)));
  }
  return err;
}

canonical_original_code:
static int keeper_exec(struct keeper_t *this, char *sql) {
  int err = sqlite3_exec((((sqlite_ptr)((this)->impl))->db),
    sql, ((void *)0), ((void *)0), ((void *)0));
  if (err != 0) {
    if ((3) <= cx_log_level) cx_log((3), "Error executins SQL {%s}: %s", sql, sqlite3_errmsg((((sqlite_ptr)((this)->impl))->db)));
  }
  return err;
}

variable_types:
sql
char *

variable_types: err int


decompiled_code:
__int64 __fastcall keeper_create(const char *a1)
{
__int64 v1; // rax
__int64 v2; // r12
__int64 v4; // rdi

if ( cx_log_level >= 0 )
cx_log(0LL, "Creating keeper: %s", a1);
database_file = cx_string_create(a1);
v1 = keeper_raw_create();
v2 = v1;
if ( v1 )
{
if ( !(unsigned int)keeper_exec(
v1,
"CREATE TABLE IF NOT EXISTS tracks (id INTEGER PRIMARY KEY,filename TEXT UNIQUE,codec TEXT,bitr"
"ate INTEGER,duration INTEGER)")
&& !(unsigned int)keeper_exec(
v2,
"CREATE TABLE IF NOT EXISTS tag_rels (track_id INTEGER, tag_id INTEGER, UNIQUE(track_id, tag_id))")
&& !(unsigned int)keeper_exec(v2, "CREATE VIRTUAL TABLE IF NOT EXISTS tags USING fts4(key, value)")
&& !(unsigned int)keeper_exec(
v2,
"CREATE TABLE IF NOT EXISTS instances (track_id INTEGER,preset TEXT,status INTEGER,filename TEX"
"T UNIQUE,UNIQUE(track_id, preset))")
&& !(unsigned int)keeper_exec(v2, "CREATE INDEX IF NOT EXISTS tag_rels_idx ON tag_rels (track_id, tag_id)")
&& !(unsigned int)keeper_exec(v2, "CREATE INDEX IF NOT EXISTS tracks_idx ON tracks (id, filename)") )
{
impl_init_statements(*(_QWORD **)(v2 + 24));
return v2;
}
if ( cx_log_level > 2 )
cx_log(3LL, "Error creating tables");
v4 = v2;
v2 = 0LL;
cx_release(v4);
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func15(const char *a1)
{
__int64 v1; // rax
__int64 v2; // r12
__int64 v4; // rdi

if ( cx_log_level >= 0 )
cx_log(0LL, "Creating keeper: %s", a1);
database_file = cx_string_create(a1);
v1 = func4();
v2 = v1;
if ( v1 )
{
if ( !(unsigned int)func3(
v1,
"CREATE TABLE IF NOT EXISTS tracks (id INTEGER PRIMARY KEY,filename TEXT UNIQUE,codec TEXT,bitr"
"ate INTEGER,duration INTEGER)")
&& !(unsigned int)func3(
v2,
"CREATE TABLE IF NOT EXISTS tag_rels (track_id INTEGER, tag_id INTEGER, UNIQUE(track_id, tag_id))")
&& !(unsigned int)func3(v2, "CREATE VIRTUAL TABLE IF NOT EXISTS tags USING fts4(key, value)")
&& !(unsigned int)func3(
v2,
"CREATE TABLE IF NOT EXISTS instances (track_id INTEGER,preset TEXT,status INTEGER,filename TEX"
"T UNIQUE,UNIQUE(track_id, preset))")
&& !(unsigned int)func3(v2, "CREATE INDEX IF NOT EXISTS tag_rels_idx ON tag_rels (track_id, tag_id)")
&& !(unsigned int)func3(v2, "CREATE INDEX IF NOT EXISTS tracks_idx ON tracks (id, filename)") )
{
func6(*(_QWORD **)(v2 + 24));
return v2;
}
if ( cx_log_level > 2 )
cx_log(3LL, "Error creating tables");
v4 = v2;
v2 = 0LL;
cx_release(v4);
}
return v2;
}

original_code:
keeper_ptr keeper_create(const char *filename) {
  keeper_ptr this;
  if ((0) <= cx_log_level) cx_log((0), "Creating keeper: %s", filename);
  database_file = cx_string_create(filename);
  this = keeper_raw_create();
  if (this == ((void *)0)) return ((void *)0);
  if ((0 != keeper_exec(this,
      "CREATE TABLE IF NOT EXISTS tracks ("
        "id INTEGER PRIMARY KEY,"
        "filename TEXT UNIQUE,"
        "codec TEXT,"
        "bitrate INTEGER,"
        "duration INTEGER"
      ")")) || (0 != keeper_exec(this,
      "CREATE TABLE IF NOT EXISTS tag_rels ("
        "track_id INTEGER, tag_id INTEGER, UNIQUE(track_id, tag_id)"
      ")")) || (0 != keeper_exec(this,
      "CREATE VIRTUAL TABLE IF NOT EXISTS tags USING fts4(key, value"
      ")")) || (0 != keeper_exec(this,
      "CREATE TABLE IF NOT EXISTS instances ("
        "track_id INTEGER,"
        "preset TEXT,"
        "status INTEGER,"
        "filename TEXT UNIQUE,"
        "UNIQUE(track_id, preset)"
      ")")) || (0 != keeper_exec(this,
      "CREATE INDEX IF NOT EXISTS tag_rels_idx ON tag_rels ("
        "track_id, tag_id"
      ")")) || (0 != keeper_exec(this,
      "CREATE INDEX IF NOT EXISTS tracks_idx ON tracks ("
        "id, filename"
      ")"))) {
    if ((3) <= cx_log_level) cx_log((3), "Error creating tables");
    cx_release(this);
    return ((void *)0);
  }
  impl_init_statements(this->impl);
  return this;
}

canonical_original_code:
struct keeper_t *keeper_create(char *filename) {
  struct keeper_t *this;
  if ((0) <= cx_log_level) cx_log((0), "Creating keeper: %s", filename);
  database_file = cx_string_create(filename);
  this = keeper_raw_create();
  if (this == ((void *)0)) return ((void *)0);
  if ((0 != keeper_exec(this,
      "CREATE TABLE IF NOT EXISTS tracks ("
        "id INTEGER PRIMARY KEY,"
        "filename TEXT UNIQUE,"
        "codec TEXT,"
        "bitrate INTEGER,"
        "duration INTEGER"
      ")")) || (0 != keeper_exec(this,
      "CREATE TABLE IF NOT EXISTS tag_rels ("
        "track_id INTEGER, tag_id INTEGER, UNIQUE(track_id, tag_id)"
      ")")) || (0 != keeper_exec(this,
      "CREATE VIRTUAL TABLE IF NOT EXISTS tags USING fts4(key, value"
      ")")) || (0 != keeper_exec(this,
      "CREATE TABLE IF NOT EXISTS instances ("
        "track_id INTEGER,"
        "preset TEXT,"
        "status INTEGER,"
        "filename TEXT UNIQUE,"
        "UNIQUE(track_id, preset)"
      ")")) || (0 != keeper_exec(this,
      "CREATE INDEX IF NOT EXISTS tag_rels_idx ON tag_rels ("
        "track_id, tag_id"
      ")")) || (0 != keeper_exec(this,
      "CREATE INDEX IF NOT EXISTS tracks_idx ON tracks ("
        "id, filename"
      ")"))) {
    if ((3) <= cx_log_level) cx_log((3), "Error creating tables");
    cx_release(this);
    return ((void *)0);
  }
  impl_init_statements(this->impl);
  return this;
}

variable_types:
filename
char *

return_type: struct keeper_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_obj_t *impl; } *


decompiled_code:
__int64 keeper_copy()
{
__int64 v0; // r12

v0 = keeper_raw_create();
impl_init_statements(*(_QWORD **)(v0 + 24));
return v0;
}

original_code:
keeper_ptr keeper_copy(keeper_ptr keeper) {
  (void)keeper;
  keeper_ptr this = keeper_raw_create();
  impl_init_statements(this->impl);
  return this;
}

canonical_original_code:
struct keeper_t *keeper_copy(struct keeper_t *keeper) {
  (void)keeper;
  struct keeper_t *this = keeper_raw_create();
  impl_init_statements(this->impl);
  return this;
}

variable_types:
keeper
struct keeper_t *


decompiled_code:
void __fastcall cx_string_dtor(__int64 a1)
{
free(*(void **)(a1 + 32));
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1)
{
free(*(void **)(a1 + 32));
}

original_code:
static void cx_string_dtor(void *s) {
  free(((cx_string_ptr)s)->string);
}

canonical_original_code:
static void cx_string_dtor(void *s) {
  free(((struct cx_string_t *)s)->string);
}

variable_types:
s
void *

user_defined_types: struct cx_string_t { struct cx_obj_t O; unsigned long length; char *string; }


decompiled_code:
__int64 __fastcall cx_string_create(void *src)
{
__int64 v2; // r12
size_t v3; // r13
size_t v4; // rdi
void *v5; // rax

v2 = cx_create(40LL, cx_string_class_name, cx_string_dtor);
if ( src )
{
v3 = strlen((const char *)src);
v4 = v3 + 1;
}
else
{
v4 = 1LL;
v3 = 0LL;
}
*(_QWORD *)(v2 + 24) = v3;
v5 = malloc(v4);
*(_QWORD *)(v2 + 32) = v5;
memcpy(v5, src, v3);
*(_BYTE *)(*(_QWORD *)(v2 + 32) + *(_QWORD *)(v2 + 24)) = 0;
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func1(void *src)
{
__int64 v2; // r12
size_t v3; // r13
size_t v4; // rdi
void *v5; // rax

v2 = cx_create(40LL, cx_string_class_name, cx_string_dtor);
if ( src )
{
v3 = strlen((const char *)src);
v4 = v3 + 1;
}
else
{
v4 = 1LL;
v3 = 0LL;
}
*(_QWORD *)(v2 + 24) = v3;
v5 = malloc(v4);
*(_QWORD *)(v2 + 32) = v5;
memcpy(v5, src, v3);
*(_BYTE *)(*(_QWORD *)(v2 + 32) + *(_QWORD *)(v2 + 24)) = 0;
return v2;
}

original_code:
cx_string_ptr cx_string_create(const char *source) {
  cx_string_ptr this = ((cx_string_ptr)cx_create(sizeof(struct cx_string_t), cx_string_class_name, cx_string_dtor));
  this->length = (source!=((void *)0))?strlen(source):0;
  this->string = malloc(this->length + 1);
  memcpy(this->string, source, this->length);
  this->string[this->length] = 0;
  return this;
}

canonical_original_code:
struct cx_string_t *cx_string_create(char *source) {
  struct cx_string_t *this = ((cx_string_ptr)cx_create(sizeof(struct cx_string_t), cx_string_class_name, cx_string_dtor));
  this->length = (source!=((void *)0))?strlen(source):0;
  this->string = malloc(this->length + 1);
  memcpy(this->string, source, this->length);
  this->string[this->length] = 0;
  return this;
}

variable_types:
source
char *

variable_types: struct cx_string_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; unsigned long length; char *string; } *


original_code:
cx_string_ptr cx_string_append(cx_string_ptr this, const char *suffix) {
  cx_size_t suffix_length = strlen(suffix);
  this->string = realloc(this->string, this->length + suffix_length + 1);
  memcpy(this->string + this->length, suffix, suffix_length + 1);
  this->length += suffix_length;
  return this;
}

canonical_original_code:
struct cx_string_t *cx_string_append(struct cx_string_t *this, char *suffix) {
  unsigned long suffix_length = strlen(suffix);
  this->string = realloc(this->string, this->length + suffix_length + 1);
  memcpy(this->string + this->length, suffix, suffix_length + 1);
  this->length += suffix_length;
  return this;
}

variable_types:
this
struct cx_string_t *

variable_types:
suffix
char *

return_type: struct cx_string_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; unsigned long length; char *string; } *


decompiled_code:
__int64 __fastcall process_track(__int64 a1)
{
return keeper_track_insert(the_keeper, a1);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return keeper_track_insert(the_keeper, a1);
}

original_code:
static void process_track(track_info_ptr track) {
  keeper_track_insert(the_keeper, track);
}

canonical_original_code:
static void process_track(struct track_info_t *track) {
  keeper_track_insert(the_keeper, track);
}

variable_types: struct track_info_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; unsigned int id; struct cx_string_t { struct cx_obj_t O; unsigned long length; char *string; } *filename; unsigned int flags; int duration; int sample_rate; int channels; int bitrate; struct cx_string_t *codec_name; struct cx_array_t { struct cx_obj_t O; struct cx_obj_t **objs; unsigned long count; unsigned long reserved; } *tags; } *

user_defined_types: struct track_info_t { struct cx_obj_t O; unsigned int id; struct cx_string_t *filename; unsigned int flags; int duration; int sample_rate; int channels; int bitrate; struct cx_string_t *codec_name; struct cx_array_t *tags; }


decompiled_code:
__int64 __fastcall sourcer_start(__int64 a1, const char *a2)
{
if ( cx_log_level >= 0 )
cx_log(0LL, "Starting sourcer on dir %s", a2);
the_keeper = keeper_copy(a1);
return scan_filesystem((__int64)a2);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, const char *a2)
{
if ( cx_log_level >= 0 )
cx_log(0LL, "Starting sourcer on dir %s", a2);
the_keeper = keeper_copy(a1);
return func1((__int64)a2);
}

original_code:
void sourcer_start(keeper_ptr keeper, const char *media_storage) {
  if ((0) <= cx_log_level) cx_log((0), "Starting sourcer on dir %s", media_storage);
  the_keeper = keeper_copy(keeper);
  scan_filesystem(media_storage);
}

canonical_original_code:
void sourcer_start(struct keeper_t *keeper, char *media_storage) {
  if ((0) <= cx_log_level) cx_log((0), "Starting sourcer on dir %s", media_storage);
  the_keeper = keeper_copy(keeper);
  scan_filesystem(media_storage);
}


decompiled_code:
__int64 sourcer_stop()
{
if ( cx_log_level >= 0 )
cx_log(0LL, "Stopping sourcer");
return cx_release(the_keeper);
}

canonical_decompiled_code:
__int64 func3()
{
if ( cx_log_level >= 0 )
cx_log(0LL, "Stopping sourcer");
return cx_release(the_keeper);
}

original_code:
void sourcer_stop() {
  if ((0) <= cx_log_level) cx_log((0), "Stopping sourcer");
  cx_release(the_keeper);
}


decompiled_code:
__int64 __fastcall tag_dtor(__int64 a1)
{
cx_release(*(_QWORD *)(a1 + 24));
return cx_release(*(_QWORD *)(a1 + 32));
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
cx_release(*(_QWORD *)(a1 + 24));
return cx_release(*(_QWORD *)(a1 + 32));
}

original_code:
void tag_dtor(void *obj) {
  tag_ptr this = (tag_ptr)obj;
  cx_release(this->key);
  cx_release(this->value);
}

canonical_original_code:
void tag_dtor(void *obj) {
  struct tag_t *this = (tag_ptr)obj;
  cx_release(this->key);
  cx_release(this->value);
}

variable_types:
obj
void *

variable_types: struct tag_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_string_t { struct cx_obj_t O; unsigned long length; char *string; } *key; } *

user_defined_types: struct tag_t { struct cx_obj_t O; struct cx_string_t *key; }


decompiled_code:
__int64 __fastcall tag_create_string(__int64 a1, __int64 a2)
{
__int64 v2; // r12

v2 = cx_create(40LL, tag_class_name, tag_dtor);
*(_QWORD *)(v2 + 24) = cx_retain(a1);
*(_QWORD *)(v2 + 32) = cx_retain(a2);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2)
{
__int64 v2; // r12

v2 = cx_create(40LL, tag_class_name, tag_dtor);
*(_QWORD *)(v2 + 24) = cx_retain(a1);
*(_QWORD *)(v2 + 32) = cx_retain(a2);
return v2;
}

original_code:
tag_ptr tag_create_string(cx_string_ptr key, cx_string_ptr value) {
  tag_ptr this = ((tag_ptr)cx_create(sizeof(struct tag_t), tag_class_name, tag_dtor));
  this->key = cx_retain(key);
  this->value = cx_retain(value);
  return this;
}

canonical_original_code:
struct tag_t *tag_create_string(struct cx_string_t *key, struct cx_string_t *value) {
  struct tag_t *this = ((tag_ptr)cx_create(sizeof(struct tag_t), tag_class_name, tag_dtor));
  this->key = cx_retain(key);
  this->value = cx_retain(value);
  return this;
}

variable_types:
key
struct cx_string_t *

variable_types:
value
struct cx_string_t *

return_type: struct tag_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_string_t { struct cx_obj_t O; unsigned long length; char *string; } *key; } *


decompiled_code:
__int64 __fastcall tag_create(__int64 a1, __int64 a2)
{
__int64 v2; // r12

v2 = cx_create(40LL, tag_class_name, tag_dtor);
*(_QWORD *)(v2 + 24) = cx_string_create(a1);
*(_QWORD *)(v2 + 32) = cx_string_create(a2);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2)
{
__int64 v2; // r12

v2 = cx_create(40LL, tag_class_name, tag_dtor);
*(_QWORD *)(v2 + 24) = cx_string_create(a1);
*(_QWORD *)(v2 + 32) = cx_string_create(a2);
return v2;
}

original_code:
tag_ptr tag_create(const char *key, const char *value) {
  tag_ptr this = ((tag_ptr)cx_create(sizeof(struct tag_t), tag_class_name, tag_dtor));
  this->key = cx_string_create(key);
  this->value = cx_string_create(value);
  return this;
}

canonical_original_code:
struct tag_t *tag_create(char *key, char *value) {
  struct tag_t *this = ((tag_ptr)cx_create(sizeof(struct tag_t), tag_class_name, tag_dtor));
  this->key = cx_string_create(key);
  this->value = cx_string_create(value);
  return this;
}

variable_types:
key
char *

variable_types:
value
char *


decompiled_code:
__int64 tags_create()
{
return cx_array_create();
}

canonical_decompiled_code:
__int64 func3()
{
return cx_array_create();
}

original_code:
tags_ptr tags_create() {
  return cx_array_create();
}

canonical_original_code:
struct cx_array_t *tags_create() {
  return cx_array_create();
}


decompiled_code:
__int64 __fastcall tags_insert(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v3; // rbp

v3 = tag_create(a2, a3);
cx_array_insert_back(a1, v3);
return cx_release(v3);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v3; // rbp

v3 = func2(a2, a3);
cx_array_insert_back(a1, v3);
return cx_release(v3);
}

original_code:
void tags_insert(tags_ptr this, const char *key, const char *value) {
  tag_ptr tag = tag_create(key, value);
  cx_array_insert_back(this, tag);
  cx_release(tag);
}

canonical_original_code:
void tags_insert(struct cx_array_t *this, char *key, char *value) {
  struct tag_t *tag = tag_create(key, value);
  cx_array_insert_back(this, tag);
  cx_release(tag);
}

variable_types: struct cx_array_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_obj_t **objs; unsigned long count; unsigned long reserved; } *


decompiled_code:
__int64 __fastcall tags_insert_string(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v3; // rbp

v3 = tag_create_string(a2, a3);
cx_array_insert_back(a1, v3);
return cx_release(v3);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v3; // rbp

v3 = func1(a2, a3);
cx_array_insert_back(a1, v3);
return cx_release(v3);
}

original_code:
void tags_insert_string(tags_ptr this, cx_string_ptr key, cx_string_ptr value) {
  tag_ptr tag = tag_create_string(key, value);
  cx_array_insert_back(this, tag);
  cx_release(tag);
}

canonical_original_code:
void tags_insert_string(struct cx_array_t *this, struct cx_string_t *key, struct cx_string_t *value) {
  struct tag_t *tag = tag_create_string(key, value);
  cx_array_insert_back(this, tag);
  cx_release(tag);
}

variable_types: struct cx_string_t { struct cx_obj_t O; unsigned long length; char *string; } *


decompiled_code:
__int64 __fastcall tags_count(__int64 a1)
{
return *(_QWORD *)(a1 + 32);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
return *(_QWORD *)(a1 + 32);
}

original_code:
cx_size_t tags_count(tags_ptr this) {
  return this->count;
}

canonical_original_code:
unsigned long tags_count(struct cx_array_t *this) {
  return this->count;
}

return_type: unsigned long


original_code:
tag_ptr tags_get(tags_ptr this, cx_size_t index) {
  return ((tag_ptr)(((cx_array_ptr)this)->objs[index]));
}

canonical_original_code:
struct tag_t *tags_get(struct cx_array_t *this, unsigned long index) {
  return ((tag_ptr)(((struct cx_array_t *)this)->objs[index]));
}

variable_types: struct cx_array_t { struct cx_obj_t O; struct cx_obj_t **objs; unsigned long count; unsigned long reserved; } *

variable_types:
index
unsigned long


decompiled_code:
void __fastcall cx_list_dtor(__int64 a1)
{
_QWORD *v1; // rbx
void *v2; // rdi

v1 = *(_QWORD **)(a1 + 24);
if ( v1 )
{
while ( 1 )
{
do
{
cx_release(v1[1]);
v1 = (_QWORD *)v1[2];
v2 = (void *)v1[3];
}
while ( !v2 );
free(v2);
}
}
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1)
{
_QWORD *v1; // rbx
void *v2; // rdi

v1 = *(_QWORD **)(a1 + 24);
if ( v1 )
{
while ( 1 )
{
do
{
cx_release(v1[1]);
v1 = (_QWORD *)v1[2];
v2 = (void *)v1[3];
}
while ( !v2 );
free(v2);
}
}
}

original_code:
static void cx_list_dtor(void *list) {
  cx_list_ptr this = (cx_list_ptr)list;
  cx_list_item_ptr item = this->front;
  while (item != ((void *)0)) {
    cx_release(item->obj);
    item = item->next;
    if (item->prev != ((void *)0)) free(item->prev);
  }
}

canonical_original_code:
static void cx_list_dtor(void *list) {
  struct cx_list_t *this = (cx_list_ptr)list;
  struct cx_list_item_t *item = this->front;
  while (item != ((void *)0)) {
    cx_release(item->obj);
    item = item->next;
    if (item->prev != ((void *)0)) free(item->prev);
  }
}

variable_types:
list
void *

variable_types: struct cx_list_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_list_item_t { struct cx_list_t *list; struct cx_obj_t *obj; struct cx_list_item_t *next; struct cx_list_item_t *prev; } *front; struct cx_list_item_t *back; } *

variable_types: struct cx_list_item_t { struct cx_list_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_list_item_t *front; struct cx_list_item_t *back; } *list; struct cx_obj_t *obj; struct cx_list_item_t *next; struct cx_list_item_t *prev; } *

user_defined_types: struct cx_list_t { struct cx_obj_t O; struct cx_list_item_t *front; struct cx_list_item_t *back; }


decompiled_code:
__int64 cx_list_create()
{
__int64 result; // rax

result = cx_create(40LL, cx_list_class_name, cx_list_dtor);
*(_QWORD *)(result + 32) = 0LL;
*(_QWORD *)(result + 24) = 0LL;
return result;
}

canonical_decompiled_code:
__int64 func1()
{
__int64 result; // rax

result = cx_create(40LL, cx_list_class_name, cx_list_dtor);
*(_QWORD *)(result + 32) = 0LL;
*(_QWORD *)(result + 24) = 0LL;
return result;
}

original_code:
cx_list_ptr cx_list_create() {
  cx_list_ptr this = ((cx_list_ptr)cx_create(sizeof(struct cx_list_t), cx_list_class_name, cx_list_dtor));
  this->front = this->back = ((void *)0);
  return this;
}

canonical_original_code:
struct cx_list_t *cx_list_create() {
  struct cx_list_t *this = ((cx_list_ptr)cx_create(sizeof(struct cx_list_t), cx_list_class_name, cx_list_dtor));
  this->front = this->back = ((void *)0);
  return this;
}

return_type: struct cx_list_t { struct cx_obj_t { char *class_name; unsigned int refcount; void (*dtor)(void *); } O; struct cx_list_item_t { struct cx_list_t *list; struct cx_obj_t *obj; struct cx_list_item_t *next; struct cx_list_item_t *prev; } *front; struct cx_list_item_t *back; } *