decompiled_code:
void __fastcall ht_destroy(void *ptr)
{
bool v2; // zf
_QWORD *v3; // rdi
unsigned __int64 v4; // rbx
void **v5; // rbp

v2 = *((_QWORD *)ptr + 1) == 0LL;
v3 = *(_QWORD **)ptr;
if ( !v2 )
{
v4 = 0LL;
do
{
v5 = (void **)v3[v4];
if ( v5 )
{
free(*v5);
free(v5[2]);
free(v5);
v3 = *(_QWORD **)ptr;
}
++v4;
}
while ( *((_QWORD *)ptr + 1) > v4 );
}
free(v3);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func3(void *ptr)
{
bool v2; // zf
_QWORD *v3; // rdi
unsigned __int64 v4; // rbx
void **v5; // rbp

v2 = *((_QWORD *)ptr + 1) == 0LL;
v3 = *(_QWORD **)ptr;
if ( !v2 )
{
v4 = 0LL;
do
{
v5 = (void **)v3[v4];
if ( v5 )
{
free(*v5);
free(v5[2]);
free(v5);
v3 = *(_QWORD **)ptr;
}
++v4;
}
while ( *((_QWORD *)ptr + 1) > v4 );
}
free(v3);
free(ptr);
}

original_code:
void ht_destroy(hashtable *table) {
 for (int i = 0; i < table->max_size; i++) {
  struct _htable_entry *entry = table->entries[i];
  if (entry != ((void *)0)) {
   free(entry->key);
   free(entry->value);
   free(entry);
  }
 }
 free(table->entries);
 free(table);
}

canonical_original_code:
void ht_destroy(struct _htable *table) {
 for (int i = 0; i < table->max_size; i++) {
  struct _htable_entry *entry = table->entries[i];
  if (entry != ((void *)0)) {
   free(entry->key);
   free(entry->value);
   free(entry);
  }
 }
 free(table->entries);
 free(table);
}

variable_types: i int

variable_types: struct _htable_entry { void *key; unsigned long key_size; void *value; unsigned long value_size; } *


repo: ryanashcraft/libprototype

decompiled_code:
__int64 __fastcall ht_remove(__int64 *a1, __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v3; // r12
int v4; // eax
const void *v5; // r10
size_t v6; // r11
int v7; // eax
__int64 v8; // rbx
__int64 v9; // rax
__int64 v10; // r12

v3 = a1[1];
v4 = ht_hash(a2, a3, v3);
v7 = ht_correct_index_if_needed(a1, v4, v5, v6);
if ( v7 < 0 || (v8 = v7, v3 <= v7) )
_assert_fail("index >= 0 && index < table->max_size", "source/hashtable.c", 0x50u, "ht_remove");
v9 = *(_QWORD *)(*a1 + 8LL * v7);
v10 = *(_QWORD *)(v9 + 16);
free(*(void **)v9);
free(*(void **)(*a1 + 8 * v8));
*(_QWORD *)(*a1 + 8 * v8) = 0LL;
return v10;
}

original_code:
void *ht_remove(hashtable *table, void *key, size_t key_size) {
 int hash = ht_hash(key, key_size, table->max_size);
 int index = ht_correct_index_if_needed(table, hash, key, key_size);
 ((index >= 0 && index < table->max_size) ? (void) (0) : __assert_fail ("index >= 0 && index < table->max_size", "source/hashtable.c", 80, __extension__ __PRETTY_FUNCTION__));
 void *value = table->entries[index]->value;
 free(table->entries[index]->key);
 free(table->entries[index]);
 table->entries[index] = ((void *)0);
 return value;
}

canonical_original_code:
void *ht_remove(struct _htable *table, void *key, unsigned long key_size) {
 int hash = ht_hash(key, key_size, table->max_size);
 int index = ht_correct_index_if_needed(table, hash, key, key_size);
 ((index >= 0 && index < table->max_size) ? (void) (0) : __assert_fail ("index >= 0 && index < table->max_size", "source/hashtable.c", 80, __extension__ __PRETTY_FUNCTION__));
 void *value = table->entries[index]->value;
 free(table->entries[index]->key);
 free(table->entries[index]);
 table->entries[index] = ((void *)0);
 return value;
}

variable_types: struct _htable { struct _htable_entry { void *key; unsigned long key_size; void *value; unsigned long value_size; } **entries; unsigned long max_size; unsigned long entry_count; unsigned long resize_ratio; } *

variable_types:
key
void *

variable_types: hash int

variable_types: index int

variable_types:
value
void *

return_type: void *

user_defined_types: struct _htable { struct _htable_entry **entries; unsigned long max_size; unsigned long entry_count; unsigned long resize_ratio; }


decompiled_code:
__int64 __fastcall ht_get(__int64 *a1, __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v3; // rbp
int v4; // eax
const void *v5; // r10
size_t v6; // r11
int v7; // eax
__int64 result; // rax

v3 = a1[1];
v4 = ht_hash(a2, a3, v3);
v7 = ht_correct_index_if_needed(a1, v4, v5, v6);
if ( v7 < 0 || v3 <= v7 )
result = 0LL;
else
result = *(_QWORD *)(*(_QWORD *)(*a1 + 8LL * v7) + 16LL);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 *a1, __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v3; // rbp
int v4; // eax
const void *v5; // r10
size_t v6; // r11
int v7; // eax
__int64 result; // rax

v3 = a1[1];
v4 = func0(a2, a3, v3);
v7 = func2(a1, v4, v5, v6);
if ( v7 < 0 || v3 <= v7 )
result = 0LL;
else
result = *(_QWORD *)(*(_QWORD *)(*a1 + 8LL * v7) + 16LL);
return result;
}

original_code:
void *ht_get(hashtable *table, void *key, size_t key_size) {
 int hash = ht_hash(key, key_size, table->max_size);
 int index = ht_correct_index_if_needed(table, hash, key, key_size);
 if (index < 0 || index >= table->max_size || table->entries[index]->value == ((void *)0)) {
  return ((void *)0);
 }
 return table->entries[index]->value;
}

canonical_original_code:
void *ht_get(struct _htable *table, void *key, unsigned long key_size) {
 int hash = ht_hash(key, key_size, table->max_size);
 int index = ht_correct_index_if_needed(table, hash, key, key_size);
 if (index < 0 || index >= table->max_size || table->entries[index]->value == ((void *)0)) {
  return ((void *)0);
 }
 return table->entries[index]->value;
}

user_defined_types: struct _htable_entry { void *key; unsigned long key_size; void *value; unsigned long value_size; }


decompiled_code:
_DWORD *ll_create()
{
_DWORD *result; // rax

result = malloc(0x18uLL);
if ( !result )
_assert_fail("list", "source/list.c", 0x1Au, "ll_create");
*(_QWORD *)result = 0LL;
result[2] = 0;
return result;
}

canonical_decompiled_code:
_DWORD *func0()
{
_DWORD *result; // rax

result = malloc(0x18uLL);
if ( !result )
_assert_fail("list", "source/list.c", 0x1Au, "ll_create");
*(_QWORD *)result = 0LL;
result[2] = 0;
return result;
}

original_code:
list* ll_create(void) {
  list *list = malloc(sizeof(struct llist));
  ((list) ? (void) (0) : __assert_fail ("list", "source/list.c", 26, __extension__ __PRETTY_FUNCTION__));
  list->head = ((void *)0);
  list->size = 0;
  return list;
}

canonical_original_code:
struct llist *ll_create() {
  struct llist *list = malloc(sizeof(struct llist));
  ((list) ? (void) (0) : __assert_fail ("list", "source/list.c", 26, __extension__ __PRETTY_FUNCTION__));
  list->head = ((void *)0);
  list->size = 0;
  return list;
}

variable_types: struct llist { struct lnode { struct lnode *prev; struct lnode *next; void *data; } *head; unsigned int size; int (*sort_op)(void *, void *); } *

user_defined_types: struct llist { struct lnode *head; unsigned int size; int (*sort_op)(void *, void *); }


decompiled_code:
void __fastcall ll_set_sort_op(__int64 a1, __int64 a2)
{
*(_QWORD *)(a1 + 16) = a2;
}

original_code:
void ll_set_sort_op(list *llist, comp_op compare_func) {
  llist->sort_op = compare_func;
}

canonical_original_code:
void ll_set_sort_op(struct llist *llist, int (*compare_func)(void *, void *)) {
  llist->sort_op = compare_func;
}

return_type: void

user_defined_types: struct lnode { struct lnode *prev; struct lnode *next; void *data; }


decompiled_code:
__int64 __fastcall ll_push_back(__int64 a1, __int64 a2)
{
__int64 result; // rax

ll_push_front(a1, a2);
result = *(_QWORD *)(*(_QWORD *)a1 + 8LL);
*(_QWORD *)a1 = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2)
{
__int64 result; // rax

ll_push_front(a1, a2);
result = *(_QWORD *)(*(_QWORD *)a1 + 8LL);
*(_QWORD *)a1 = result;
return result;
}

original_code:
void ll_push_back(list* llist, void *data) {
  ll_push_front(llist, data);
  llist->head = llist->head->next;
}

canonical_original_code:
void ll_push_back(struct llist *llist, void *data) {
  ll_push_front(llist, data);
  llist->head = llist->head->next;
}

variable_types:
data
void *


original_code:
int ll_remove_front(list* llist, list_op free_func) {
  node *old_head;
  node *new_head;
  node *old_tail;
  if (llist->head == ((void *)0)) {
      return -1;
  }
  old_head = llist->head;
  new_head = llist->head->next;
  old_tail = llist->head->prev;
  old_tail->next = new_head;
  new_head->prev = old_tail;
  if (new_head != old_head) {
      llist->head = new_head;
  } else {
      llist->head = ((void *)0);
  }
  if (free_func) {
    free_func(old_head->data);
  }
  free(old_head);
  llist->size--;
  return 0;
}

canonical_original_code:
int ll_remove_front(struct llist *llist, void (*free_func)(void *)) {
  struct lnode *old_head;
  struct lnode *new_head;
  struct lnode *old_tail;
  if (llist->head == ((void *)0)) {
      return -1;
  }
  old_head = llist->head;
  new_head = llist->head->next;
  old_tail = llist->head->prev;
  old_tail->next = new_head;
  new_head->prev = old_tail;
  if (new_head != old_head) {
      llist->head = new_head;
  } else {
      llist->head = ((void *)0);
  }
  if (free_func) {
    free_func(old_head->data);
  }
  free(old_head);
  llist->size--;
  return 0;
}

variable_types: struct lnode { struct lnode *prev; struct lnode *next; void *data; } *

return_type: int


original_code:
int ll_remove_index(list* llist, int index, list_op free_func) {
  node *n = llist->head;
  node *node_to_remove = ((void *)0);
  if (!n) {
      return -1;
  }
  if (llist->head->next == llist->head) {
      if (index == 0) {
          node_to_remove = llist->head;
      } else {
          return -1;
      }
  }
  if (node_to_remove == ((void *)0)) {
      int i = 0;
      do {
          if (i == index) {
              node_to_remove = n;
              break;
          }
          n = n->next;
          i++;
      } while (n != llist->head);
  }
  if (node_to_remove != ((void *)0)) {
      node *prev_node = node_to_remove->prev;
      node *next_node = node_to_remove->next;
      prev_node->next = next_node;
      next_node->prev = prev_node;
      if (node_to_remove == llist->head) {
          if (llist->head != llist->head->next) {
              llist->head = next_node;
          } else {
              llist->head = ((void *)0);
          }
      }
      free_func(node_to_remove->data);
      free(node_to_remove);
      llist->size--;
      return 0;
  }
  return -1;
}

canonical_original_code:
int ll_remove_index(struct llist *llist, int index, void (*free_func)(void *)) {
  struct lnode *n = llist->head;
  struct lnode *node_to_remove = ((void *)0);
  if (!n) {
      return -1;
  }
  if (llist->head->next == llist->head) {
      if (index == 0) {
          node_to_remove = llist->head;
      } else {
          return -1;
      }
  }
  if (node_to_remove == ((void *)0)) {
      int i = 0;
      do {
          if (i == index) {
              node_to_remove = n;
              break;
          }
          n = n->next;
          i++;
      } while (n != llist->head);
  }
  if (node_to_remove != ((void *)0)) {
      struct lnode *prev_node = node_to_remove->prev;
      struct lnode *next_node = node_to_remove->next;
      prev_node->next = next_node;
      next_node->prev = prev_node;
      if (node_to_remove == llist->head) {
          if (llist->head != llist->head->next) {
              llist->head = next_node;
          } else {
              llist->head = ((void *)0);
          }
      }
      free_func(node_to_remove->data);
      free(node_to_remove);
      llist->size--;
      return 0;
  }
  return -1;
}


decompiled_code:
__int64 __fastcall ll_remove_back(__int64 a1, void (__fastcall *a2)(_QWORD))
{
_QWORD **v2; // rax
_QWORD *v3; // rbp
_QWORD *v4; // rdx

v2 = *(_QWORD ***)a1;
if ( !*(_QWORD *)a1 )
return 0xFFFFFFFFLL;
v3 = *v2;
v4 = (_QWORD *)**v2;
v4[1] = v2;
*v2 = v4;
if ( v2 == v3 )
*(_QWORD *)a1 = 0LL;
a2(v3[2]);
free(v3);
--*(_DWORD *)(a1 + 8);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, void (__fastcall *a2)(_QWORD))
{
_QWORD **v2; // rax
_QWORD *v3; // rbp
_QWORD *v4; // rdx

v2 = *(_QWORD ***)a1;
if ( !*(_QWORD *)a1 )
return 0xFFFFFFFFLL;
v3 = *v2;
v4 = (_QWORD *)**v2;
v4[1] = v2;
*v2 = v4;
if ( v2 == v3 )
*(_QWORD *)a1 = 0LL;
a2(v3[2]);
free(v3);
--*(_DWORD *)(a1 + 8);
return 0LL;
}

original_code:
int ll_remove_back(list* llist, list_op free_func) {
  node *old_tail;
  node *new_tail;
  if (llist->head == ((void *)0)) {
      return -1;
  }
  old_tail = llist->head->prev;
  new_tail = llist->head->prev->prev;
  new_tail->next = llist->head;
  llist->head->prev = new_tail;
  if (old_tail == llist->head) {
      llist->head = ((void *)0);
  }
  free_func(old_tail->data);
  free(old_tail);
  llist->size--;
  return 0;
}

canonical_original_code:
int ll_remove_back(struct llist *llist, void (*free_func)(void *)) {
  struct lnode *old_tail;
  struct lnode *new_tail;
  if (llist->head == ((void *)0)) {
      return -1;
  }
  old_tail = llist->head->prev;
  new_tail = llist->head->prev->prev;
  new_tail->next = llist->head;
  llist->head->prev = new_tail;
  if (old_tail == llist->head) {
      llist->head = ((void *)0);
  }
  free_func(old_tail->data);
  free(old_tail);
  llist->size--;
  return 0;
}


original_code:
int ll_remove_data(list* llist, const void *data, equal_op compare_func, list_op free_func) {
 node *n = llist->head;
 node *node_to_remove = ((void *)0);
 int count = 0;
 unsigned char head_changed = 0;
  node *next_node;
 if (!n) {
  return 0;
 }
 do {
  head_changed = 0;
    next_node = n->next;
  if (compare_func(n->data, data) != 0) {
   node_to_remove = n;
            if (n == n->next) {
                next_node = ((void *)0);
                if (free_func) {
                  free_func(n->data);
                }
                free(n);
                llist->size--;
                count++;
                llist->head = ((void *)0);
            } else {
                node_to_remove->prev->next = node_to_remove->next;
                node_to_remove->next->prev = node_to_remove->prev;
                if (node_to_remove == llist->head) {
                    llist->head = node_to_remove->next;
                    head_changed = 1;
                }
                if (free_func) {
                  free_func(n->data);
                }
                free(node_to_remove);
                llist->size--;
                count++;
                node_to_remove = ((void *)0);
            }
  }
        n = next_node;
        next_node = ((void *)0);
 } while (n != ((void *)0) && (n != llist->head || head_changed));
    return count;
}

canonical_original_code:
int ll_remove_data(struct llist *llist, void *data, int (*compare_func)(void *, void *), void (*free_func)(void *)) {
 struct lnode *n = llist->head;
 struct lnode *node_to_remove = ((void *)0);
 int count = 0;
 unsigned char head_changed = 0;
  struct lnode *next_node;
 if (!n) {
  return 0;
 }
 do {
  head_changed = 0;
    next_node = n->next;
  if (compare_func(n->data, data) != 0) {
   node_to_remove = n;
            if (n == n->next) {
                next_node = ((void *)0);
                if (free_func) {
                  free_func(n->data);
                }
                free(n);
                llist->size--;
                count++;
                llist->head = ((void *)0);
            } else {
                node_to_remove->prev->next = node_to_remove->next;
                node_to_remove->next->prev = node_to_remove->prev;
                if (node_to_remove == llist->head) {
                    llist->head = node_to_remove->next;
                    head_changed = 1;
                }
                if (free_func) {
                  free_func(n->data);
                }
                free(node_to_remove);
                llist->size--;
                count++;
                node_to_remove = ((void *)0);
            }
  }
        n = next_node;
        next_node = ((void *)0);
 } while (n != ((void *)0) && (n != llist->head || head_changed));
    return count;
}

variable_types: count int


original_code:
int ll_remove_if(list* llist, list_pred pred_func, list_op free_func) {
  node *n = llist->head;
 node *node_to_remove = ((void *)0);
 int count = 0;
 unsigned char head_changed = 0;
  node *next_node;
 if (!n) {
  return 0;
 }
 do {
  head_changed = 0;
    next_node = n->next;
  if (pred_func(n->data)) {
   node_to_remove = n;
            if (n == n->next) {
                next_node = ((void *)0);
                free_func(n->data);
                free(n);
                llist->size--;
                count++;
                llist->head = ((void *)0);
            } else {
                node_to_remove->prev->next = node_to_remove->next;
                node_to_remove->next->prev = node_to_remove->prev;
                if (node_to_remove == llist->head) {
                    llist->head = node_to_remove->next;
                    head_changed = 1;
                }
                free_func(n->data);
                free(node_to_remove);
                llist->size--;
                count++;
                node_to_remove = ((void *)0);
            }
  }
  n = next_node;
 } while (n != ((void *)0) && (n != llist->head || head_changed));
    return count;
}

canonical_original_code:
int ll_remove_if(struct llist *llist, int (*pred_func)(void *), void (*free_func)(void *)) {
  struct lnode *n = llist->head;
 struct lnode *node_to_remove = ((void *)0);
 int count = 0;
 unsigned char head_changed = 0;
  struct lnode *next_node;
 if (!n) {
  return 0;
 }
 do {
  head_changed = 0;
    next_node = n->next;
  if (pred_func(n->data)) {
   node_to_remove = n;
            if (n == n->next) {
                next_node = ((void *)0);
                free_func(n->data);
                free(n);
                llist->size--;
                count++;
                llist->head = ((void *)0);
            } else {
                node_to_remove->prev->next = node_to_remove->next;
                node_to_remove->next->prev = node_to_remove->prev;
                if (node_to_remove == llist->head) {
                    llist->head = node_to_remove->next;
                    head_changed = 1;
                }
                free_func(n->data);
                free(node_to_remove);
                llist->size--;
                count++;
                node_to_remove = ((void *)0);
            }
  }
  n = next_node;
 } while (n != ((void *)0) && (n != llist->head || head_changed));
    return count;
}


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

result = *a1;
if ( *a1 )
result = *(_QWORD *)(result + 16);
return result;
}

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

result = *a1;
if ( *a1 )
result = *(_QWORD *)(result + 16);
return result;
}

original_code:
void *ll_front(list* llist) {
  if (llist->head != ((void *)0)) {
      return llist->head->data;
  }
  return ((void *)0);
}

canonical_original_code:
void *ll_front(struct llist *llist) {
  if (llist->head != ((void *)0)) {
      return llist->head->data;
  }
  return ((void *)0);
}


original_code:
void *ll_get_index(list* llist, int index) {
  node *n;
  int i;
  if (index < 0 || index >= llist->size) {
      return ((void *)0);
  }
  n = llist->head;
  if (!n) {
      return ((void *)0);
  }
  if (llist->head->next == llist->head) {
      if (index == 0) {
          return llist->head->data;
      } else {
          return ((void *)0);
      }
  }
  i = 0;
  do {
      if (i == index) {
          return n->data;
      }
      n = n->next;
      i++;
  } while (n != llist->head);
  return ((void *)0);
}

canonical_original_code:
void *ll_get_index(struct llist *llist, int index) {
  struct lnode *n;
  int i;
  if (index < 0 || index >= llist->size) {
      return ((void *)0);
  }
  n = llist->head;
  if (!n) {
      return ((void *)0);
  }
  if (llist->head->next == llist->head) {
      if (index == 0) {
          return llist->head->data;
      } else {
          return ((void *)0);
      }
  }
  i = 0;
  do {
      if (i == index) {
          return n->data;
      }
      n = n->next;
      i++;
  } while (n != llist->head);
  return ((void *)0);
}


decompiled_code:
__int64 ll_get_first_occurrence(__int64 *a1, unsigned int (__fastcall *a2)(_QWORD, __va_list_tag *), ...)
{
__int64 v2; // rbx
__int64 result; // rax
gcc_va_list va; // [rsp+8h] [rbp-E0h] BYREF

va_start(va, a2);
v2 = *a1;
if ( !*a1 )
return 0LL;
if ( *(_QWORD *)(v2 + 8) == v2 )
{
if ( !a2(*(_QWORD *)(v2 + 16), va) )
return 0LL;
result = *(_QWORD *)(*a1 + 16);
}
else
{
while ( !a2(*(_QWORD *)(v2 + 16), va) )
{
v2 = *(_QWORD *)(v2 + 8);
va_end(va);
va_start(va, a2);
if ( *a1 == v2 )
return 0LL;
}
result = *(_QWORD *)(v2 + 16);
}
return result;
}

canonical_decompiled_code:
__int64 func10(__int64 *a1, unsigned int (__fastcall *a2)(_QWORD, __va_list_tag *), ...)
{
__int64 v2; // rbx
__int64 result; // rax
gcc_va_list va; // [rsp+8h] [rbp-E0h] BYREF

va_start(va, a2);
v2 = *a1;
if ( !*a1 )
return 0LL;
if ( *(_QWORD *)(v2 + 8) == v2 )
{
if ( !a2(*(_QWORD *)(v2 + 16), va) )
return 0LL;
result = *(_QWORD *)(*a1 + 16);
}
else
{
while ( !a2(*(_QWORD *)(v2 + 16), va) )
{
v2 = *(_QWORD *)(v2 + 8);
va_end(va);
va_start(va, a2);
if ( *a1 == v2 )
return 0LL;
}
result = *(_QWORD *)(v2 + 16);
}
return result;
}

original_code:
void* ll_get_first_occurrence(list* llist, list_pred_args test_func, ...) {
  node *n;
  va_list args;
  __builtin_va_start(args,test_func);
  n = llist->head;
  if (!n) {
      __builtin_va_end(args);
      return ((void *)0);
  }
  if (llist->head->next == llist->head) {
      if (test_func(llist->head->data, &args)) {
          __builtin_va_end(args);
          return llist->head->data;
      } else {
          __builtin_va_end(args);
          return ((void *)0);
      }
  }
  do {
      if (test_func(n->data, &args)) {
          __builtin_va_end(args);
          return n->data;
      }
      n = n->next;
      __builtin_va_start(args,test_func);
  } while (n != llist->head);
  __builtin_va_end(args);
  return ((void *)0);
}

canonical_original_code:
void *ll_get_first_occurrence(struct llist *llist, int (*test_func)(void *, __builtin_va_list *), ...) {
  struct lnode *n;
  __builtin_va_list args;
  __builtin_va_start(args,test_func);
  n = llist->head;
  if (!n) {
      __builtin_va_end(args);
      return ((void *)0);
  }
  if (llist->head->next == llist->head) {
      if (test_func(llist->head->data, &args)) {
          __builtin_va_end(args);
          return llist->head->data;
      } else {
          __builtin_va_end(args);
          return ((void *)0);
      }
  }
  do {
      if (test_func(n->data, &args)) {
          __builtin_va_end(args);
          return n->data;
      }
      n = n->next;
      __builtin_va_start(args,test_func);
  } while (n != llist->head);
  __builtin_va_end(args);
  return ((void *)0);
}


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

result = *a1;
if ( *a1 )
result = *(_QWORD *)(*(_QWORD *)result + 16LL);
return result;
}

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

result = *a1;
if ( *a1 )
result = *(_QWORD *)(*(_QWORD *)result + 16LL);
return result;
}

original_code:
void *ll_back(list* llist) {
  if (llist->head != ((void *)0)) {
      return llist->head->prev->data;
  }
  return ((void *)0);
}

canonical_original_code:
void *ll_back(struct llist *llist) {
  if (llist->head != ((void *)0)) {
      return llist->head->prev->data;
  }
  return ((void *)0);
}


decompiled_code:
_BOOL8 __fastcall ll_is_empty(_DWORD *a1)
{
_BOOL8 result; // rax

result = 0LL;
if ( !a1[2] )
{
if ( *(_QWORD *)a1 )
result = *(_QWORD *)(*(_QWORD *)a1 + 16LL) == 0LL;
else
result = 1LL;
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func12(_DWORD *a1)
{
_BOOL8 result; // rax

result = 0LL;
if ( !a1[2] )
{
if ( *(_QWORD *)a1 )
result = *(_QWORD *)(*(_QWORD *)a1 + 16LL) == 0LL;
else
result = 1LL;
}
return result;
}

original_code:
int ll_is_empty(list* llist) {
  if (llist->size == 0 && (llist->head == ((void *)0) || llist->head->data == ((void *)0))) {
      return 1;
  }
  return 0;
}

canonical_original_code:
int ll_is_empty(struct llist *llist) {
  if (llist->size == 0 && (llist->head == ((void *)0) || llist->head->data == ((void *)0))) {
      return 1;
  }
  return 0;
}


decompiled_code:
__int64 __fastcall ll_size(__int64 a1)
{
return *(unsigned int *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1)
{
return *(unsigned int *)(a1 + 8);
}

original_code:
int ll_size(list* llist) {
    return llist->size;
}

canonical_original_code:
int ll_size(struct llist *llist) {
    return llist->size;
}


original_code:
int ll_find_occurrence(list* llist, const void *search, equal_op compare_func) {
  node *n = llist->head;
  if (!n) {
    return 0;
  }
  if (llist->head->next == llist->head
    && ((compare_func && compare_func(n->data, search) != 0) || n->data == search)) {
    return 1;
  }
  do {
    if ((compare_func && compare_func(n->data, search) != 0) || n->data == search) {
        return 1;
    }
    n = n->next;
  } while (n != llist->head);
  return 0;
}

canonical_original_code:
int ll_find_occurrence(struct llist *llist, void *search, int (*compare_func)(void *, void *)) {
  struct lnode *n = llist->head;
  if (!n) {
    return 0;
  }
  if (llist->head->next == llist->head
    && ((compare_func && compare_func(n->data, search) != 0) || n->data == search)) {
    return 1;
  }
  do {
    if ((compare_func && compare_func(n->data, search) != 0) || n->data == search) {
        return 1;
    }
    n = n->next;
  } while (n != llist->head);
  return 0;
}

variable_types:
search
void *


decompiled_code:
void __fastcall ll_destroy(void *ptr, void (__fastcall *a2)(_QWORD))
{
ll_empty_list((__int64)ptr, a2);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func16(void *ptr, void (__fastcall *a2)(_QWORD))
{
func15((__int64)ptr, a2);
free(ptr);
}

original_code:
void ll_destroy(list* llist, list_op free_func) {
  ll_empty_list(llist, free_func);
  free(llist);
}

canonical_original_code:
void ll_destroy(struct llist *llist, void (*free_func)(void *)) {
  ll_empty_list(llist, free_func);
  free(llist);
}


decompiled_code:
__int64 __fastcall ll_traverse(__int64 *a1, __int64 (__fastcall *a2)(_QWORD))
{
__int64 v2; // rbx
__int64 result; // rax

v2 = *a1;
if ( *a1 )
{
if ( *(_QWORD *)(v2 + 8) == v2 )
{
result = a2(*(_QWORD *)(v2 + 16));
}
else
{
do
{
if ( a2 )
result = a2(*(_QWORD *)(v2 + 16));
v2 = *(_QWORD *)(v2 + 8);
}
while ( *a1 != v2 );
}
}
return result;
}

original_code:
void ll_traverse(list* llist, list_op do_func) {
  node *n = llist->head;
  if (!n) {
      return;
  }
  if (llist->head->next == llist->head) {
      do_func(n->data);
      return;
  }
  do {
      if (do_func != ((void *)0)) {
          do_func(n->data);
      }
      n = n->next;
  } while (n != llist->head);
}

canonical_original_code:
void ll_traverse(struct llist *llist, void (*do_func)(void *)) {
  struct lnode *n = llist->head;
  if (!n) {
      return;
  }
  if (llist->head->next == llist->head) {
      do_func(n->data);
      return;
  }
  do {
      if (do_func != ((void *)0)) {
          do_func(n->data);
      }
      n = n->next;
  } while (n != llist->head);
}


decompiled_code:
void *ll_traverse_with_args(__int64 *a1, __int64 (__fastcall *a2)(_QWORD, __va_list_tag *), ...)
{
__int64 v2; // rbx
void *result; // rax
gcc_va_list va; // [rsp+8h] [rbp-E0h] BYREF

v2 = *a1;
if ( *a1 )
{
va_start(va, a2);
if ( v2 == *(_QWORD *)(v2 + 8) )
{
result = (void *)a2(*(_QWORD *)(v2 + 16), va);
}
else
{
do
{
if ( a2 )
a2(*(_QWORD *)(v2 + 16), va);
v2 = *(_QWORD *)(v2 + 8);
va_end(va);
va_start(va, a2);
result = va[0].reg_save_area;
}
while ( *a1 != v2 );
}
}
return result;
}

canonical_decompiled_code:
void *func18(__int64 *a1, __int64 (__fastcall *a2)(_QWORD, __va_list_tag *), ...)
{
__int64 v2; // rbx
void *result; // rax
gcc_va_list va; // [rsp+8h] [rbp-E0h] BYREF

v2 = *a1;
if ( *a1 )
{
va_start(va, a2);
if ( v2 == *(_QWORD *)(v2 + 8) )
{
result = (void *)a2(*(_QWORD *)(v2 + 16), va);
}
else
{
do
{
if ( a2 )
a2(*(_QWORD *)(v2 + 16), va);
v2 = *(_QWORD *)(v2 + 8);
va_end(va);
va_start(va, a2);
result = va[0].reg_save_area;
}
while ( *a1 != v2 );
}
}
return result;
}

original_code:
void ll_traverse_with_args(list* llist, list_op_args do_func, ...) {
  node *n = llist->head;
  if (!n) {
      return;
  }
  va_list args;
  __builtin_va_start(args,do_func);
  if (llist->head->next == llist->head) {
      do_func(n->data, &args);
      __builtin_va_end(args);
      return;
  }
  do {
      if (do_func != ((void *)0)) {
          do_func(n->data, &args);
      }
      n = n->next;
      __builtin_va_start(args,do_func);
  } while (n != llist->head);
}

canonical_original_code:
void ll_traverse_with_args(struct llist *llist, void (*do_func)(void *, __builtin_va_list *), ...) {
  struct lnode *n = llist->head;
  if (!n) {
      return;
  }
  __builtin_va_list args;
  __builtin_va_start(args,do_func);
  if (llist->head->next == llist->head) {
      do_func(n->data, &args);
      __builtin_va_end(args);
      return;
  }
  do {
      if (do_func != ((void *)0)) {
          do_func(n->data, &args);
      }
      n = n->next;
      __builtin_va_start(args,do_func);
  } while (n != llist->head);
}


decompiled_code:
// attributes: thunk
__int64 __fastcall list_op_release()
{
return release();
}

canonical_decompiled_code:
__int64 __fastcall func5()
{
return release();
}

original_code:
void list_op_release(void* element) {
 release(element);
}

canonical_original_code:
void list_op_release(void *element) {
 release(element);
}

variable_types:
element
void *


hash

repo: ryanbalsdon/GOOS

original_code:
static unsigned long hash(const char* str) {
    unsigned long hash = 5381;
    int c;
    while ((c = *str++))
        hash = ((hash << 5) + hash) + c;
    return hash;
}

canonical_original_code:
static unsigned long hash(char *str) {
    unsigned long hash = 5381;
    int c;
    while ((c = *str++))
        hash = ((hash << 5) + hash) + c;
    return hash;
}

variable_types:
str
char *

variable_types:
hash
unsigned long

variable_types: c int

return_type: unsigned long


decompiled_code:
void *goos_dispatcher_new()
{
void *v0; // r12

v0 = malloc(0x10uLL);
InitMutablePointerArray(v0);
return v0;
}

canonical_decompiled_code:
void *func1()
{
void *v0; // r12

v0 = malloc(0x10uLL);
InitMutablePointerArray(v0);
return v0;
}

original_code:
static goos_dispatcher* goos_dispatcher_new(void) {
 goos_dispatcher* newDispatcher = (goos_dispatcher*)malloc(sizeof(goos_dispatcher));
 InitMutablePointerArray(&newDispatcher->array);
 return newDispatcher;
}

canonical_original_code:
static struct goos_dispatcher_s *goos_dispatcher_new() {
 struct goos_dispatcher_s *newDispatcher = (goos_dispatcher*)malloc(sizeof(goos_dispatcher));
 InitMutablePointerArray(&newDispatcher->array);
 return newDispatcher;
}

variable_types: struct goos_dispatcher_s { struct MutablePointerArray { void **Array; int ArrayAllocationSize; int ArraySize; } array; } *

user_defined_types: struct goos_dispatcher_s { struct MutablePointerArray array; }


decompiled_code:
void __fastcall goos_dispatcher_delete(void *ptr)
{
FreeMutablePointerArray();
free(ptr);
}

canonical_decompiled_code:
void __fastcall func2(void *ptr)
{
FreeMutablePointerArray();
free(ptr);
}

original_code:
static void goos_dispatcher_delete(goos_dispatcher* self) {
 FreeMutablePointerArray(&self->array);
 free(self);
}

canonical_original_code:
static void goos_dispatcher_delete(struct goos_dispatcher_s *self) {
 FreeMutablePointerArray(&self->array);
 free(self);
}

user_defined_types: struct MutablePointerArray { void **Array; int ArrayAllocationSize; int ArraySize; }


decompiled_code:
__int64 __fastcall goos_dispatcher_addMethod(__int64 a1, __int64 a2, char *a3)
{
_DWORD *v4; // rbp

v4 = malloc(0x60uLL);
goos_dispatcher_objectInfo_init(v4);
*(_QWORD *)v4 = a2;
*((_QWORD *)v4 + 11) = hash(a3);
strncpy((char *)v4 + 24, a3, 0x40uLL);
return MPA_AddPointer(a1, v4);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, __int64 a2, char *a3)
{
_DWORD *v4; // rbp

v4 = malloc(0x60uLL);
func3(v4);
*(_QWORD *)v4 = a2;
*((_QWORD *)v4 + 11) = func0(a3);
strncpy((char *)v4 + 24, a3, 0x40uLL);
return MPA_AddPointer(a1, v4);
}

original_code:
static void goos_dispatcher_addMethod(goos_dispatcher* self, goos_method method, const char* handle) {
 goos_dispatcher_objectInfo* methodInfo = (goos_dispatcher_objectInfo*)malloc(sizeof(goos_dispatcher_objectInfo));
 goos_dispatcher_objectInfo_init(methodInfo);
 methodInfo->method=method;
 methodInfo->hash = hash(handle);
 strncpy(methodInfo->handle, handle, 64);
 MPA_AddPointer(&self->array, methodInfo);
}

canonical_original_code:
static void goos_dispatcher_addMethod(struct goos_dispatcher_s *self, struct goos_data (*method)(struct goos_object_s *, void *), char *handle) {
 struct goos_dispatcher_objectInfo *methodInfo = (goos_dispatcher_objectInfo*)malloc(sizeof(goos_dispatcher_objectInfo));
 goos_dispatcher_objectInfo_init(methodInfo);
 methodInfo->method=method;
 methodInfo->hash = hash(handle);
 strncpy(methodInfo->handle, handle, 64);
 MPA_AddPointer(&self->array, methodInfo);
}

variable_types: struct goos_data { union { struct goos_object_s { struct goos_object_s *baseClass; struct goos_dispatcher_s *dispatch; } *o; int d; float f; void *p; char c; char *s; int *pd; float *pf; }; enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 } e; } (*)(struct goos_object_s *, void *)

variable_types:
handle
char *

variable_types: struct goos_dispatcher_objectInfo { struct goos_data { union { struct goos_object_s { struct goos_object_s *baseClass; struct goos_dispatcher_s { struct MutablePointerArray { void **Array; int ArrayAllocationSize; int ArraySize; } array; } *dispatch; } *o; int d; float f; void *p; char c; char *s; int *pd; float *pf; }; enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 } e; } (*method)(struct goos_object_s *, void *); struct goos_data data; char handle[64]; unsigned long hash; } *

user_defined_types: struct goos_dispatcher_objectInfo { struct goos_data (*method)(struct goos_object_s *, void *); struct goos_data data; char handle[64]; unsigned long hash; }

user_defined_types: struct goos_data { union { struct goos_object_s *o; int d; float f; void *p; char c; char *s; int *pd; float *pf; }; enum goos_errorCode e; }


decompiled_code:
__int64 __fastcall goos_dispatcher_addData(__int64 a1, __int64 a2, __int64 a3, const char *a4)
{
_DWORD *v6; // rbp

v6 = malloc(0x60uLL);
goos_dispatcher_objectInfo_init(v6);
*((_QWORD *)v6 + 1) = a2;
*((_QWORD *)v6 + 2) = a3;
strncpy((char *)v6 + 24, a4, 0x40uLL);
return MPA_AddPointer(a1, v6);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2, __int64 a3, const char *a4)
{
_DWORD *v6; // rbp

v6 = malloc(0x60uLL);
func3(v6);
*((_QWORD *)v6 + 1) = a2;
*((_QWORD *)v6 + 2) = a3;
strncpy((char *)v6 + 24, a4, 0x40uLL);
return MPA_AddPointer(a1, v6);
}

original_code:
static void goos_dispatcher_addData(goos_dispatcher* self, goos_data data, const char* handle) {
 goos_dispatcher_objectInfo* objectInfo = (goos_dispatcher_objectInfo*)malloc(sizeof(goos_dispatcher_objectInfo));
 goos_dispatcher_objectInfo_init(objectInfo);
 objectInfo->data=data;
 strncpy(objectInfo->handle, handle, 64);
 MPA_AddPointer(&self->array, objectInfo);
}

canonical_original_code:
static void goos_dispatcher_addData(struct goos_dispatcher_s *self, struct goos_data data, char *handle) {
 struct goos_dispatcher_objectInfo *objectInfo = (goos_dispatcher_objectInfo*)malloc(sizeof(goos_dispatcher_objectInfo));
 goos_dispatcher_objectInfo_init(objectInfo);
 objectInfo->data=data;
 strncpy(objectInfo->handle, handle, 64);
 MPA_AddPointer(&self->array, objectInfo);
}

variable_types: struct goos_data { union { struct goos_object_s { struct goos_object_s *baseClass; struct goos_dispatcher_s *dispatch; } *o; int d; float f; void *p; char c; char *s; int *pd; float *pf; }; enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 } e; }


decompiled_code:
__int64 __fastcall goos_dispatcher_find(__int64 a1, char *a2)
{
unsigned int i; // er12
__int64 v3; // rbp
__int64 v4; // rax
__int64 v6; // rax

i = 0;
v3 = hash(a2);
while ( (int)MPA_Length(a1) > (int)i )
{
v4 = MPA_PointerAtIndex(a1, i);
if ( *(_QWORD *)(v4 + 88) == v3 && !strncmp((const char *)(v4 + 24), a2, 0x40uLL) )
return i;
++i;
}
for ( i = 0; (int)MPA_Length(a1) > (int)i; ++i )
{
v6 = MPA_PointerAtIndex(a1, i);
if ( !strncmp((const char *)(v6 + 24), a2, 0x40uLL) )
return i;
}
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, char *a2)
{
unsigned int i; // er12
__int64 v3; // rbp
__int64 v4; // rax
__int64 v6; // rax

i = 0;
v3 = func0(a2);
while ( (int)MPA_Length(a1) > (int)i )
{
v4 = MPA_PointerAtIndex(a1, i);
if ( *(_QWORD *)(v4 + 88) == v3 && !strncmp((const char *)(v4 + 24), a2, 0x40uLL) )
return i;
++i;
}
for ( i = 0; (int)MPA_Length(a1) > (int)i; ++i )
{
v6 = MPA_PointerAtIndex(a1, i);
if ( !strncmp((const char *)(v6 + 24), a2, 0x40uLL) )
return i;
}
return 0xFFFFFFFFLL;
}

original_code:
static int goos_dispatcher_find(goos_dispatcher* self, const char* handle) {
 unsigned long handleHash = hash(handle);
 for (int index=0; index<MPA_Length(&self->array); index++) {
  goos_dispatcher_objectInfo* info = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, index);
  if (info->hash == handleHash && strncmp(info->handle, handle, 64) == 0) {
   return index;
  }
 }
 for (int index=0; index<MPA_Length(&self->array); index++) {
  goos_dispatcher_objectInfo* info = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, index);
  if (strncmp(info->handle, handle, 64) == 0) {
   return index;
  }
 }
 return -1;
}

canonical_original_code:
static int goos_dispatcher_find(struct goos_dispatcher_s *self, char *handle) {
 unsigned long handleHash = hash(handle);
 for (int index = 0; index<MPA_Length(&self->array); index++) {
  struct goos_dispatcher_objectInfo *info = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, index);
  if (info->hash == handleHash && strncmp(info->handle, handle, 64) == 0) {
   return index;
  }
 }
 for (int index = 0; index<MPA_Length(&self->array); index++) {
  struct goos_dispatcher_objectInfo *info = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, index);
  if (strncmp(info->handle, handle, 64) == 0) {
   return index;
  }
 }
 return -1;
}

variable_types:
handleHash
unsigned long

user_defined_types: enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 }

user_defined_types: struct goos_object_s { struct goos_object_s *baseClass; struct goos_dispatcher_s *dispatch; }


decompiled_code:
__int64 __fastcall goos_dispatcher_removeHandle(__int64 a1, char *a2)
{
int v2; // eax

while ( 1 )
{
v2 = goos_dispatcher_find(a1, a2);
if ( v2 < 0 )
break;
MPA_RemoveIndex(a1, (unsigned int)v2);
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, char *a2)
{
int v2; // eax

while ( 1 )
{
v2 = func6(a1, a2);
if ( v2 < 0 )
break;
MPA_RemoveIndex(a1, (unsigned int)v2);
}
return 0LL;
}

original_code:
static int goos_dispatcher_removeHandle(goos_dispatcher* self, const char* methodHandle) {
 int removeCount = 0;
 int methodIndex;
 while ((methodIndex = goos_dispatcher_find(self, methodHandle)) >= 0) {
  MPA_RemoveIndex(&self->array, methodIndex);
 }
 return removeCount;
}

canonical_original_code:
static int goos_dispatcher_removeHandle(struct goos_dispatcher_s *self, char *methodHandle) {
 int removeCount = 0;
 int methodIndex;
 while ((methodIndex = goos_dispatcher_find(self, methodHandle)) >= 0) {
  MPA_RemoveIndex(&self->array, methodIndex);
 }
 return removeCount;
}

variable_types:
methodHandle
char *

variable_types: removeCount int

variable_types: methodIndex int


decompiled_code:
__int64 __fastcall goos_dispatcher_call(__int64 a1, char *a2, __int64 a3, __int64 a4)
{
int v6; // eax
unsigned int v7; // er12
__int64 (__fastcall *v9)(__int64, __int64); // rax

v6 = goos_dispatcher_find(a1, a2);
if ( v6 < 0 || (v7 = v6, (int)MPA_Length(a1) <= v6) )
{
printf("ERROR: Handle not found in dispatcher: %s.\n", a2);
return 0LL;
}
v9 = *(__int64 (__fastcall **)(__int64, __int64))MPA_PointerAtIndex(a1, v7);
if ( !v9 )
{
printf("ERROR: Accessing data handle as a method: %s\n", a2);
return 0LL;
}
return v9(a3, a4);
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, char *a2, __int64 a3, __int64 a4)
{
int v6; // eax
unsigned int v7; // er12
__int64 (__fastcall *v9)(__int64, __int64); // rax

v6 = func6(a1, a2);
if ( v6 < 0 || (v7 = v6, (int)MPA_Length(a1) <= v6) )
{
printf("ERROR: Handle not found in dispatcher: %s.\n", a2);
return 0LL;
}
v9 = *(__int64 (__fastcall **)(__int64, __int64))MPA_PointerAtIndex(a1, v7);
if ( !v9 )
{
printf("ERROR: Accessing data handle as a method: %s\n", a2);
return 0LL;
}
return v9(a3, a4);
}

original_code:
static goos_data goos_dispatcher_call(goos_dispatcher* self, const char* handle, goos_object* callee, void* arg) {
 int methodIndex = goos_dispatcher_find(self, handle);
 if (methodIndex < 0 || methodIndex >= MPA_Length(&self->array)) {
  printf("ERROR: Handle not found in dispatcher: %s.\n", handle);
  goos_data error;
  error.e=goos_errorCode_NO_HANDLE;
  return error;
 }
 goos_dispatcher_objectInfo* methodInfo = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, methodIndex);
 if (methodInfo->method == (void*)0) {
  printf("ERROR: Accessing data handle as a method: %s\n", handle);
  goos_data error;
  error.e=goos_errorCode_NOT_A_METHOD;
  return error;
 }
 return methodInfo->method(callee, arg);
}

canonical_original_code:
static struct goos_data goos_dispatcher_call(struct goos_dispatcher_s *self, char *handle, struct goos_object_s *callee, void *arg) {
 int methodIndex = goos_dispatcher_find(self, handle);
 if (methodIndex < 0 || methodIndex >= MPA_Length(&self->array)) {
  printf("ERROR: Handle not found in dispatcher: %s.\n", handle);
  struct goos_data error;
  error.e=goos_errorCode_NO_HANDLE;
  return error;
 }
 struct goos_dispatcher_objectInfo *methodInfo = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, methodIndex);
 if (methodInfo->method == (void *)0) {
  printf("ERROR: Accessing data handle as a method: %s\n", handle);
  struct goos_data error;
  error.e=goos_errorCode_NOT_A_METHOD;
  return error;
 }
 return methodInfo->method(callee, arg);
}

variable_types:
self
struct goos_dispatcher_s *

variable_types:
callee
struct goos_object_s *

variable_types:
arg
void *

variable_types: struct goos_data { union { struct goos_object_s { struct goos_object_s *baseClass; struct goos_dispatcher_s { struct MutablePointerArray { void **Array; int ArrayAllocationSize; int ArraySize; } array; } *dispatch; } *o; int d; float f; void *p; char c; char *s; int *pd; float *pf; }; enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 } e; }


decompiled_code:
__int64 __fastcall goos_dispatcher_set(__int64 a1, char *a2, __int64 a3, __int64 a4)
{
int v6; // eax
unsigned int v7; // er12
__int64 result; // rax
__int64 v9; // rax

v6 = goos_dispatcher_find(a1, a2);
if ( v6 >= 0 && (v7 = v6, (int)MPA_Length(a1) > v6) )
{
v9 = MPA_PointerAtIndex(a1, v7);
if ( *(_DWORD *)(v9 + 16) == 4 )
{
printf("ERROR: Accessing method handle as data: %s\n", a2);
result = 3LL;
}
else
{
*(_QWORD *)(v9 + 8) = a3;
*(_QWORD *)(v9 + 16) = a4;
result = 0LL;
}
}
else
{
printf("ERROR: Handle not found in dispatcher: %s.\n", a2);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, char *a2, __int64 a3, __int64 a4)
{
int v6; // eax
unsigned int v7; // er12
__int64 result; // rax
__int64 v9; // rax

v6 = func6(a1, a2);
if ( v6 >= 0 && (v7 = v6, (int)MPA_Length(a1) > v6) )
{
v9 = MPA_PointerAtIndex(a1, v7);
if ( *(_DWORD *)(v9 + 16) == 4 )
{
printf("ERROR: Accessing method handle as data: %s\n", a2);
result = 3LL;
}
else
{
*(_QWORD *)(v9 + 8) = a3;
*(_QWORD *)(v9 + 16) = a4;
result = 0LL;
}
}
else
{
printf("ERROR: Handle not found in dispatcher: %s.\n", a2);
result = 1LL;
}
return result;
}

original_code:
static goos_errorCode goos_dispatcher_set(goos_dispatcher* self, const char* handle, goos_data data) {
 int dataIndex = goos_dispatcher_find(self, handle);
 if (dataIndex < 0 || dataIndex >= MPA_Length(&self->array)) {
  printf("ERROR: Handle not found in dispatcher: %s.\n", handle);
  return goos_errorCode_NO_HANDLE;
 }
 goos_dispatcher_objectInfo* objectInfo = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, dataIndex);
 if (objectInfo->data.e == goos_errorCode_NOT_VALID_DATA) {
  printf("ERROR: Accessing method handle as data: %s\n", handle);
  return goos_errorCode_NOT_A_VARIABLE;
 }
 objectInfo->data = data;
 return goos_errorCode_HAPPY;
}

canonical_original_code:
static enum goos_errorCode goos_dispatcher_set(struct goos_dispatcher_s *self, char *handle, struct goos_data data) {
 int dataIndex = goos_dispatcher_find(self, handle);
 if (dataIndex < 0 || dataIndex >= MPA_Length(&self->array)) {
  printf("ERROR: Handle not found in dispatcher: %s.\n", handle);
  return goos_errorCode_NO_HANDLE;
 }
 struct goos_dispatcher_objectInfo *objectInfo = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, dataIndex);
 if (objectInfo->data.e == goos_errorCode_NOT_VALID_DATA) {
  printf("ERROR: Accessing method handle as data: %s\n", handle);
  return goos_errorCode_NOT_A_VARIABLE;
 }
 objectInfo->data = data;
 return goos_errorCode_HAPPY;
}

variable_types: dataIndex int

return_type: enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 }


decompiled_code:
__int64 __fastcall goos_dispatcher_get(__int64 a1, char *a2)
{
__int64 v2; // r14
int v3; // eax
unsigned int v4; // er12
__int64 v6; // rax

v3 = goos_dispatcher_find(a1, a2);
if ( v3 < 0 || (v4 = v3, (int)MPA_Length(a1) <= v3) )
{
printf("ERROR: Handle not found in dispatcher: %s.\n", a2);
return v2;
}
v6 = MPA_PointerAtIndex(a1, v4);
if ( *(_DWORD *)(v6 + 16) == 4 )
{
puts("ERROR: Accessing method handle as data");
return v2;
}
return *(_QWORD *)(v6 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, char *a2)
{
__int64 v2; // r14
int v3; // eax
unsigned int v4; // er12
__int64 v6; // rax

v3 = func6(a1, a2);
if ( v3 < 0 || (v4 = v3, (int)MPA_Length(a1) <= v3) )
{
printf("ERROR: Handle not found in dispatcher: %s.\n", a2);
return v2;
}
v6 = MPA_PointerAtIndex(a1, v4);
if ( *(_DWORD *)(v6 + 16) == 4 )
{
puts("ERROR: Accessing method handle as data");
return v2;
}
return *(_QWORD *)(v6 + 8);
}

original_code:
static goos_data goos_dispatcher_get(goos_dispatcher* self, const char* handle) {
 int dataIndex = goos_dispatcher_find(self, handle);
 if (dataIndex < 0 || dataIndex >= MPA_Length(&self->array)) {
  printf("ERROR: Handle not found in dispatcher: %s.\n", handle);
  goos_data error;
  error.e=goos_errorCode_NO_HANDLE;
  return error;
 }
 goos_dispatcher_objectInfo* objectInfo = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, dataIndex);
 if (objectInfo->data.e == goos_errorCode_NOT_VALID_DATA) {
  printf("ERROR: Accessing method handle as data\n");
  goos_data error;
  error.e=goos_errorCode_NOT_A_VARIABLE;
  return error;
 }
 return objectInfo->data;
}

canonical_original_code:
static struct goos_data goos_dispatcher_get(struct goos_dispatcher_s *self, char *handle) {
 int dataIndex = goos_dispatcher_find(self, handle);
 if (dataIndex < 0 || dataIndex >= MPA_Length(&self->array)) {
  printf("ERROR: Handle not found in dispatcher: %s.\n", handle);
  struct goos_data error;
  error.e=goos_errorCode_NO_HANDLE;
  return error;
 }
 struct goos_dispatcher_objectInfo *objectInfo = (goos_dispatcher_objectInfo*)MPA_PointerAtIndex(&self->array, dataIndex);
 if (objectInfo->data.e == goos_errorCode_NOT_VALID_DATA) {
  printf("ERROR: Accessing method handle as data\n");
  struct goos_data error;
  error.e=goos_errorCode_NOT_A_VARIABLE;
  return error;
 }
 return objectInfo->data;
}

return_type: struct goos_data { union { struct goos_object_s { struct goos_object_s *baseClass; struct goos_dispatcher_s { struct MutablePointerArray { void **Array; int ArrayAllocationSize; int ArraySize; } array; } *dispatch; } *o; int d; float f; void *p; char c; char *s; int *pd; float *pf; }; enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 } e; }


decompiled_code:
__int64 goos_version()
{
return 1LL;
}

canonical_decompiled_code:
__int64 func11()
{
return 1LL;
}

original_code:
int goos_version(void) {
 return 1;
}

canonical_original_code:
int goos_version() {
 return 1;
}


decompiled_code:
void goos_init()
{
;
}

canonical_decompiled_code:
void func12()
{
;
}

original_code:
void goos_init(void) {
}

canonical_original_code:
void goos_init() {
}


decompiled_code:
_QWORD *goos_object_new()
{
_QWORD *v0; // r12

v0 = malloc(0x10uLL);
v0[1] = goos_dispatcher_new();
return v0;
}

canonical_decompiled_code:
_QWORD *func13()
{
_QWORD *v0; // r12

v0 = malloc(0x10uLL);
v0[1] = func1();
return v0;
}

original_code:
goos_object* goos_object_new(void) {
 goos_object* newClass = (goos_object*)malloc(sizeof(goos_object));
 newClass->dispatch = goos_dispatcher_new();
 return newClass;
}

canonical_original_code:
struct goos_object_s *goos_object_new() {
 struct goos_object_s *newClass = (goos_object*)malloc(sizeof(goos_object));
 newClass->dispatch = goos_dispatcher_new();
 return newClass;
}

variable_types: struct goos_object_s { struct goos_object_s *baseClass; struct goos_dispatcher_s { struct MutablePointerArray { void **Array; int ArrayAllocationSize; int ArraySize; } array; } *dispatch; } *


decompiled_code:
void __fastcall goos_object_delete(void *ptr)
{
goos_dispatcher_delete(*((void **)ptr + 1));
free(ptr);
}

canonical_decompiled_code:
void __fastcall func14(void *ptr)
{
func2(*((void **)ptr + 1));
free(ptr);
}

original_code:
void goos_object_delete(goos_object* class) {
 goos_dispatcher_delete(class->dispatch);
 free(class);
}

canonical_original_code:
void goos_object_delete(struct goos_object_s *class) {
 goos_dispatcher_delete(class->dispatch);
 free(class);
}


decompiled_code:
__int64 __fastcall goos_object_addMethod(__int64 a1, __int64 a2, char *a3)
{
return goos_dispatcher_addMethod(*(_QWORD *)(a1 + 8), a2, a3);
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1, __int64 a2, char *a3)
{
return func4(*(_QWORD *)(a1 + 8), a2, a3);
}

original_code:
void goos_object_addMethod(goos_object* self, goos_method method, const char* methodHandle) {
 goos_dispatcher_addMethod(self->dispatch, method, methodHandle);
}

canonical_original_code:
void goos_object_addMethod(struct goos_object_s *self, struct goos_data (*method)(struct goos_object_s *, void *), char *methodHandle) {
 goos_dispatcher_addMethod(self->dispatch, method, methodHandle);
}

variable_types: struct goos_data { union { struct goos_object_s *o; int d; float f; void *p; char c; char *s; int *pd; float *pf; }; enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 } e; } (*)(struct goos_object_s *, void *)


decompiled_code:
__int64 __fastcall goos_object_addData(__int64 a1, __int64 a2, __int64 a3, const char *a4)
{
return goos_dispatcher_addData(*(_QWORD *)(a1 + 8), a2, a3, a4);
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1, __int64 a2, __int64 a3, const char *a4)
{
return func5(*(_QWORD *)(a1 + 8), a2, a3, a4);
}

original_code:
void goos_object_addData(goos_object* self, goos_data data, const char* methodHandle) {
 goos_dispatcher_addData(self->dispatch, data, methodHandle);
}

canonical_original_code:
void goos_object_addData(struct goos_object_s *self, struct goos_data data, char *methodHandle) {
 goos_dispatcher_addData(self->dispatch, data, methodHandle);
}

variable_types: struct goos_data { union { struct goos_object_s *o; int d; float f; void *p; char c; char *s; int *pd; float *pf; }; enum goos_errorCode { goos_errorCode_HAPPY=0, goos_errorCode_NO_HANDLE=1, goos_errorCode_NOT_A_METHOD=2, goos_errorCode_NOT_A_VARIABLE=3, goos_errorCode_NOT_VALID_DATA=4, goos_errorCode_WTF=5 } e; }


decompiled_code:
__int64 __fastcall goos_object_removeHandle(__int64 a1, char *a2)
{
return goos_dispatcher_removeHandle(*(_QWORD *)(a1 + 8), a2);
}

canonical_decompiled_code:
__int64 __fastcall func17(__int64 a1, char *a2)
{
return func7(*(_QWORD *)(a1 + 8), a2);
}

original_code:
int goos_object_removeHandle(goos_object* self, const char* handle) {
 return goos_dispatcher_removeHandle(self->dispatch, handle);
}

canonical_original_code:
int goos_object_removeHandle(struct goos_object_s *self, char *handle) {
 return goos_dispatcher_removeHandle(self->dispatch, handle);
}


decompiled_code:
__int64 __fastcall goos_object_call(_QWORD *a1, char *a2, __int64 a3)
{
_QWORD *v4; // rax

v4 = goos_object_respondsTo(a1, a2);
if ( v4 )
return goos_dispatcher_call(v4[1], a2, (__int64)a1, a3);
printf("ERROR: Handle not found: %s\n", a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func18(_QWORD *a1, char *a2, __int64 a3)
{
_QWORD *v4; // rax

v4 = goos_object_respondsTo(a1, a2);
if ( v4 )
return func8(v4[1], a2, (__int64)a1, a3);
printf("ERROR: Handle not found: %s\n", a2);
return 0LL;
}

original_code:
goos_data goos_object_call(goos_object* self, const char* handle, void* arg) {
 goos_object* target = goos_object_respondsTo(self, handle);
 if (target == (void*)0) {
  printf("ERROR: Handle not found: %s\n", handle);
  goos_data error;
  error.e=goos_errorCode_NO_HANDLE;
  return error;
 }
 return goos_dispatcher_call(target->dispatch, handle, self, arg);
}

canonical_original_code:
struct goos_data goos_object_call(struct goos_object_s *self, char *handle, void *arg) {
 struct goos_object_s *target = goos_object_respondsTo(self, handle);
 if (target == (void *)0) {
  printf("ERROR: Handle not found: %s\n", handle);
  struct goos_data error;
  error.e=goos_errorCode_NO_HANDLE;
  return error;
 }
 return goos_dispatcher_call(target->dispatch, handle, self, arg);
}

variable_types:
self
struct goos_object_s *


decompiled_code:
__int64 __fastcall goos_object_callSuper(_QWORD **a1, char *a2, __int64 a3, __int64 a4)
{
_QWORD *v4; // rdi

v4 = *a1;
if ( v4 )
return goos_object_call(v4, a2, a4);
printf("ERROR: Trying to call super on a class without a base: %s\n", a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func19(_QWORD **a1, char *a2, __int64 a3, __int64 a4)
{
_QWORD *v4; // rdi

v4 = *a1;
if ( v4 )
return func18(v4, a2, a4);
printf("ERROR: Trying to call super on a class without a base: %s\n", a2);
return 0LL;
}

original_code:
goos_data goos_object_callSuper(goos_object* self, const char* handle, goos_object* callee, void* arg) {
 if (self->baseClass == (void*)0) {
  printf("ERROR: Trying to call super on a class without a base: %s\n", handle);
  goos_data error;
  error.e=goos_errorCode_WTF;
  return error;
 }
 return goos_object_call(self->baseClass, handle, arg);
}

canonical_original_code:
struct goos_data goos_object_callSuper(struct goos_object_s *self, char *handle, struct goos_object_s *callee, void *arg) {
 if (self->baseClass == (void *)0) {
  printf("ERROR: Trying to call super on a class without a base: %s\n", handle);
  struct goos_data error;
  error.e=goos_errorCode_WTF;
  return error;
 }
 return goos_object_call(self->baseClass, handle, arg);
}


decompiled_code:
__int64 __fastcall goos_object_get(_QWORD *a1, char *a2)
{
_QWORD *v2; // rax

v2 = goos_object_respondsTo(a1, a2);
if ( v2 )
return goos_dispatcher_get(v2[1], a2);
printf("ERROR: Handle not found: %s\n", a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func20(_QWORD *a1, char *a2)
{
_QWORD *v2; // rax

v2 = goos_object_respondsTo(a1, a2);
if ( v2 )
return func10(v2[1], a2);
printf("ERROR: Handle not found: %s\n", a2);
return 0LL;
}

original_code:
goos_data goos_object_get(goos_object* self, const char* handle) {
 goos_object* target = goos_object_respondsTo(self, handle);
 if (target == (void*)0) {
  printf("ERROR: Handle not found: %s\n", handle);
  goos_data error;
  error.e=goos_errorCode_NO_HANDLE;
  return error;
 }
 return goos_dispatcher_get(target->dispatch, handle);
}

canonical_original_code:
struct goos_data goos_object_get(struct goos_object_s *self, char *handle) {
 struct goos_object_s *target = goos_object_respondsTo(self, handle);
 if (target == (void *)0) {
  printf("ERROR: Handle not found: %s\n", handle);
  struct goos_data error;
  error.e=goos_errorCode_NO_HANDLE;
  return error;
 }
 return goos_dispatcher_get(target->dispatch, handle);
}


decompiled_code:
__int64 __fastcall goos_object_set(_QWORD *a1, char *a2, __int64 a3, __int64 a4)
{
_QWORD *v6; // rax

v6 = goos_object_respondsTo(a1, a2);
if ( v6 )
return goos_dispatcher_set(v6[1], a2, a3, a4);
printf("ERROR: Handle not found: %s\n", a2);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func21(_QWORD *a1, char *a2, __int64 a3, __int64 a4)
{
_QWORD *v6; // rax

v6 = goos_object_respondsTo(a1, a2);
if ( v6 )
return func9(v6[1], a2, a3, a4);
printf("ERROR: Handle not found: %s\n", a2);
return 1LL;
}

original_code:
goos_errorCode goos_object_set(goos_object* self, const char* handle, goos_data data) {
 goos_object* target = goos_object_respondsTo(self, handle);
 if (target == (void*)0) {
  printf("ERROR: Handle not found: %s\n", handle);
  return goos_errorCode_NO_HANDLE;
 }
 return goos_dispatcher_set(target->dispatch, handle, data);
}

canonical_original_code:
enum goos_errorCode goos_object_set(struct goos_object_s *self, char *handle, struct goos_data data) {
 struct goos_object_s *target = goos_object_respondsTo(self, handle);
 if (target == (void *)0) {
  printf("ERROR: Handle not found: %s\n", handle);
  return goos_errorCode_NO_HANDLE;
 }
 return goos_dispatcher_set(target->dispatch, handle, data);
}


decompiled_code:
const char *classHello_greetSimple()
{
greetSimple_wasRun = 1;
return "Hello!";
}

canonical_decompiled_code:
const char *func0()
{
greetSimple_wasRun = 1;
return "Hello!";
}

original_code:
goos_data classHello_greetSimple(goos_object* self, void* args) {
 greetSimple_wasRun = 1;
 goos_data output;
 output.s = "Hello!";
 return output;
}

canonical_original_code:
struct goos_data classHello_greetSimple(struct goos_object_s *self, void *args) {
 greetSimple_wasRun = 1;
 struct goos_data output;
 output.s = "Hello!";
 return output;
}

variable_types:
args
void *


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

puts("methodTest1");
result = goos_returnObject_Nil;
methodTestSuccess = 1;
return result;
}

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

puts("methodTest1");
result = goos_returnObject_Nil;
methodTestSuccess = 1;
return result;
}

original_code:
goos_data methodTest1(goos_object* self, void* args) {
 printf("methodTest1\n");
 methodTestSuccess = 1;
 return goos_returnObject_Nil;
}

canonical_original_code:
struct goos_data methodTest1(struct goos_object_s *self, void *args) {
 printf("methodTest1\n");
 methodTestSuccess = 1;
 return goos_returnObject_Nil;
}


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

puts("methodTest2");
result = goos_returnObject_Nil;
methodTestSuccess = 2;
return result;
}

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

puts("methodTest2");
result = goos_returnObject_Nil;
methodTestSuccess = 2;
return result;
}

original_code:
goos_data methodTest2(goos_object* self, void* args) {
 printf("methodTest2\n");
 methodTestSuccess = 2;
 return goos_returnObject_Nil;
}

canonical_original_code:
struct goos_data methodTest2(struct goos_object_s *self, void *args) {
 printf("methodTest2\n");
 methodTestSuccess = 2;
 return goos_returnObject_Nil;
}


methodTestIO

decompiled_code:
__int64 __fastcall methodTestIO(__int64 a1, _DWORD *a2)
{
puts("methodTestIO");
return (unsigned int)(2 * *a2);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, _DWORD *a2)
{
puts("methodTestIO");
return (unsigned int)(2 * *a2);
}

original_code:
goos_data methodTestIO(goos_object* self, void* args) {
 printf("methodTestIO\n");
 goos_data output;
 int input = *(int*)args;
 output.d=input*2;
 return output;
}

canonical_original_code:
struct goos_data methodTestIO(struct goos_object_s *self, void *args) {
 printf("methodTestIO\n");
 struct goos_data output;
 int input = *(int*)args;
 output.d=input*2;
 return output;
}

variable_types: input int


decompiled_code:
__int64 __fastcall classSecondHello_greetHi(__int64 a1)
{
greetLevel = goos_object_get(a1, "height");
return goos_returnObject_Nil;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
greetLevel = goos_object_get(a1, "height");
return goos_returnObject_Nil;
}

original_code:
goos_data classSecondHello_greetHi(goos_object* self, void* args) {
 greetLevel = goos_object_get(self, "height").d;
 return goos_returnObject_Nil;
}

canonical_original_code:
struct goos_data classSecondHello_greetHi(struct goos_object_s *self, void *args) {
 greetLevel = goos_object_get(self, "height").d;
 return goos_returnObject_Nil;
}


decompiled_code:
__int64 __fastcall classHello_greetAwesome(__int64 a1)
{
int i; // ebx
const char *v2; // rax

for ( i = 0; i < (int)goos_object_get(a1, "awesomeness"); ++i )
{
v2 = (const char *)goos_object_get(a1, "name");
printf("Hello %s!\n", v2);
}
greetAwesome_wasRun = goos_object_get(a1, "awesomeness");
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
int i; // ebx
const char *v2; // rax

for ( i = 0; i < (int)goos_object_get(a1, "awesomeness"); ++i )
{
v2 = (const char *)goos_object_get(a1, "name");
printf("Hello %s!\n", v2);
}
greetAwesome_wasRun = goos_object_get(a1, "awesomeness");
return 0LL;
}

original_code:
goos_data classHello_greetAwesome(goos_object* self, void* args) {
 for (int i=0; i<goos_object_get(self, "awesomeness").d; i++) {
  printf("Hello %s!\n", goos_object_get(self, "name").s);
 }
 greetAwesome_wasRun = goos_object_get(self, "awesomeness").d;
 goos_data output;
 return output;
}

canonical_original_code:
struct goos_data classHello_greetAwesome(struct goos_object_s *self, void *args) {
 for (int i = 0; i<goos_object_get(self, "awesomeness").d; i++) {
  printf("Hello %s!\n", goos_object_get(self, "name").s);
 }
 greetAwesome_wasRun = goos_object_get(self, "awesomeness").d;
 struct goos_data output;
 return output;
}

variable_types: i int


testDispatch

decompiled_code:
int testDispatch()
{
__int64 v0; // rbp
int v1; // edx
int v2; // edx
int v3; // edx
int v4; // edx
int v6; // [rsp+8h] [rbp-20h] BYREF
int v7[7]; // [rsp+Ch] [rbp-1Ch] BYREF

puts("Testing goos_dispatcher add and call");
v0 = goos_object_new();
goos_object_addMethod(v0, methodTest1, "methodTest1");
methodTestSuccess = 0;
goos_object_call(v0, "methodTest1", 0LL);
if ( methodTestSuccess != 1 )
goto LABEL_2;
puts("Success");
puts("Testing goos_dispatcher_call on bad methodName");
goos_object_call(v0, "NoMethod", 0LL);
if ( v1 != 1 )
goto LABEL_2;
puts("Success");
puts("Testing goos_dispatcher with second method");
goos_object_addMethod(v0, methodTest2, "methodTest2");
methodTestSuccess = 0;
goos_object_call(v0, "methodTest2", 0LL);
if ( methodTestSuccess != 2 )
goto LABEL_2;
puts("Success");
puts("Double-checking the first method again...");
methodTestSuccess = 0;
goos_object_call(v0, "methodTest1", 0LL);
if ( methodTestSuccess != 1 )
goto LABEL_2;
puts("Success");
puts("Testing input/output");
goos_object_addMethod(v0, methodTestIO, "methodTestIO");
v6 = 21;
if ( (unsigned int)goos_object_call(v0, "methodTestIO", &v6) != 42 )
goto LABEL_2;
puts("Success");
puts("Testing method removal");
goos_object_removeHandle(v0, "methodTest2");
goos_object_call(v0, "methodTest2", 0LL);
if ( v2 != 1 )
goto LABEL_2;
puts("Success");
puts("Double-checking the first method again...");
methodTestSuccess = 0;
goos_object_call(v0, "methodTest1", 0LL);
if ( methodTestSuccess != 1 )
goto LABEL_2;
puts("Success");
puts("...and the third one");
goos_object_addMethod(v0, methodTestIO, "methodTestIO");
if ( (unsigned int)goos_object_call(v0, "methodTestIO", &v6) != 42 )
goto LABEL_2;
puts("Success");
puts("Testing pointer variables");
v7[0] = 100;
goos_object_addData(v0, v7, 0LL, "life");
if ( *(_DWORD *)goos_object_get(v0, "life") != 100 )
goto LABEL_2;
puts("Success");
puts("Modify pointer");
v7[0] = 80;
if ( *(_DWORD *)goos_object_get(v0, "life") != 80 )
goto LABEL_2;
puts("Success");
puts("Testing instance variables");
goos_object_addData(v0, 20LL, 0LL, "maxLife");
if ( (unsigned int)goos_object_get(v0, "maxLife") != 20 )
goto LABEL_2;
puts("Success");
puts("Modify original but instance stays");
if ( (unsigned int)goos_object_get(v0, "maxLife") != 20 )
goto LABEL_2;
puts("Success");
puts("Modify instance variable");
goos_object_set(v0, "maxLife", 10LL, 0LL);
if ( (unsigned int)goos_object_get(v0, "maxLife") != 10
|| (puts("Success"), puts("Access method as data"), goos_object_get(v0, "methodTestIO"), v3 != 3)
|| (puts("Success"), puts("Access data as method"), goos_object_call(v0, "maxLife", 0LL), v4 != 2) )
{
LABEL_2:
puts("Failure");
exit(0);
}
return puts("Success");
}

canonical_decompiled_code:
int func6()
{
__int64 v0; // rbp
int v1; // edx
int v2; // edx
int v3; // edx
int v4; // edx
int v6; // [rsp+8h] [rbp-20h] BYREF
int v7[7]; // [rsp+Ch] [rbp-1Ch] BYREF

puts("Testing goos_dispatcher add and call");
v0 = goos_object_new();
goos_object_addMethod(v0, methodTest1, "methodTest1");
methodTestSuccess = 0;
goos_object_call(v0, "methodTest1", 0LL);
if ( methodTestSuccess != 1 )
goto LABEL_2;
puts("Success");
puts("Testing goos_dispatcher_call on bad methodName");
goos_object_call(v0, "NoMethod", 0LL);
if ( v1 != 1 )
goto LABEL_2;
puts("Success");
puts("Testing goos_dispatcher with second method");
goos_object_addMethod(v0, methodTest2, "methodTest2");
methodTestSuccess = 0;
goos_object_call(v0, "methodTest2", 0LL);
if ( methodTestSuccess != 2 )
goto LABEL_2;
puts("Success");
puts("Double-checking the first method again...");
methodTestSuccess = 0;
goos_object_call(v0, "methodTest1", 0LL);
if ( methodTestSuccess != 1 )
goto LABEL_2;
puts("Success");
puts("Testing input/output");
goos_object_addMethod(v0, methodTestIO, "methodTestIO");
v6 = 21;
if ( (unsigned int)goos_object_call(v0, "methodTestIO", &v6) != 42 )
goto LABEL_2;
puts("Success");
puts("Testing method removal");
goos_object_removeHandle(v0, "methodTest2");
goos_object_call(v0, "methodTest2", 0LL);
if ( v2 != 1 )
goto LABEL_2;
puts("Success");
puts("Double-checking the first method again...");
methodTestSuccess = 0;
goos_object_call(v0, "methodTest1", 0LL);
if ( methodTestSuccess != 1 )
goto LABEL_2;
puts("Success");
puts("...and the third one");
goos_object_addMethod(v0, methodTestIO, "methodTestIO");
if ( (unsigned int)goos_object_call(v0, "methodTestIO", &v6) != 42 )
goto LABEL_2;
puts("Success");
puts("Testing pointer variables");
v7[0] = 100;
goos_object_addData(v0, v7, 0LL, "life");
if ( *(_DWORD *)goos_object_get(v0, "life") != 100 )
goto LABEL_2;
puts("Success");
puts("Modify pointer");
v7[0] = 80;
if ( *(_DWORD *)goos_object_get(v0, "life") != 80 )
goto LABEL_2;
puts("Success");
puts("Testing instance variables");
goos_object_addData(v0, 20LL, 0LL, "maxLife");
if ( (unsigned int)goos_object_get(v0, "maxLife") != 20 )
goto LABEL_2;
puts("Success");
puts("Modify original but instance stays");
if ( (unsigned int)goos_object_get(v0, "maxLife") != 20 )
goto LABEL_2;
puts("Success");
puts("Modify instance variable");
goos_object_set(v0, "maxLife", 10LL, 0LL);
if ( (unsigned int)goos_object_get(v0, "maxLife") != 10
|| (puts("Success"), puts("Access method as data"), goos_object_get(v0, "methodTestIO"), v3 != 3)
|| (puts("Success"), puts("Access data as method"), goos_object_call(v0, "maxLife", 0LL), v4 != 2) )
{
LABEL_2:
puts("Failure");
exit(0);
}
return puts("Success");
}

original_code:
void testDispatch(void) {
 printf("Testing goos_dispatcher add and call\n");
 goos_object* testDispatch = goos_object_new();
 goos_object_addMethod(testDispatch, methodTest1, "methodTest1");
 methodTestSuccess = 0;
 goos_object_call(testDispatch, "methodTest1", (void*)0);
 if (methodTestSuccess == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing goos_dispatcher_call on bad methodName\n");
 if (goos_object_call(testDispatch, "NoMethod", (void*)0).e == goos_errorCode_NO_HANDLE) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing goos_dispatcher with second method\n");
 goos_object_addMethod(testDispatch, methodTest2, "methodTest2");
 methodTestSuccess = 0;
 goos_object_call(testDispatch, "methodTest2", (void*)0);
 if (methodTestSuccess == 2) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Double-checking the first method again...\n");
 methodTestSuccess = 0;
 goos_object_call(testDispatch, "methodTest1", (void*)0);
 if (methodTestSuccess == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing input/output\n");
 goos_object_addMethod(testDispatch, methodTestIO, "methodTestIO");
 int input = 21;
 if (goos_object_call(testDispatch, "methodTestIO", (void*)&input).d == 42) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing method removal\n");
 goos_object_removeHandle(testDispatch, "methodTest2");
 if (goos_object_call(testDispatch, "methodTest2", (void*)0).e == goos_errorCode_NO_HANDLE) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Double-checking the first method again...\n");
 methodTestSuccess = 0;
 goos_object_call(testDispatch, "methodTest1", (void*)0);
 if (methodTestSuccess == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("...and the third one\n");
 goos_object_addMethod(testDispatch, methodTestIO, "methodTestIO");
 if (goos_object_call(testDispatch, "methodTestIO", (void*)&input).d == 42) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing pointer variables\n");
 int life = 100;
 goos_data dLife;
 dLife.pd = &life;
 goos_object_addData(testDispatch, dLife, "life");
 if (*(goos_object_get(testDispatch, "life").pd) == 100) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Modify pointer\n");
 life = 80;
 if (*(goos_object_get(testDispatch, "life").pd) == 80) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing instance variables\n");
 int maxLife = 20;
 goos_data dmLife;
 dmLife.d = maxLife;
 goos_object_addData(testDispatch, dmLife, "maxLife");
 if (goos_object_get(testDispatch, "maxLife").d == 20) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Modify original but instance stays\n");
 maxLife = 0;
 dmLife.d = 0;
 if (goos_object_get(testDispatch, "maxLife").d == 20) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Modify instance variable\n");
 dmLife.d = 10;
 goos_object_set(testDispatch, "maxLife", dmLife);
 if (goos_object_get(testDispatch, "maxLife").d == 10) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Access method as data\n");
 if (goos_object_get(testDispatch, "methodTestIO").e == goos_errorCode_NOT_A_VARIABLE) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Access data as method\n");
 if (goos_object_call(testDispatch, "maxLife", (void*)0).e == goos_errorCode_NOT_A_METHOD) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
}

canonical_original_code:
void testDispatch() {
 printf("Testing goos_dispatcher add and call\n");
 struct goos_object_s *testDispatch = goos_object_new();
 goos_object_addMethod(testDispatch, methodTest1, "methodTest1");
 methodTestSuccess = 0;
 goos_object_call(testDispatch, "methodTest1", (void *)0);
 if (methodTestSuccess == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing goos_dispatcher_call on bad methodName\n");
 if (goos_object_call(testDispatch, "NoMethod", (void *)0).e == goos_errorCode_NO_HANDLE) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing goos_dispatcher with second method\n");
 goos_object_addMethod(testDispatch, methodTest2, "methodTest2");
 methodTestSuccess = 0;
 goos_object_call(testDispatch, "methodTest2", (void *)0);
 if (methodTestSuccess == 2) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Double-checking the first method again...\n");
 methodTestSuccess = 0;
 goos_object_call(testDispatch, "methodTest1", (void *)0);
 if (methodTestSuccess == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing input/output\n");
 goos_object_addMethod(testDispatch, methodTestIO, "methodTestIO");
 int input = 21;
 if (goos_object_call(testDispatch, "methodTestIO", (void *)&input).d == 42) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing method removal\n");
 goos_object_removeHandle(testDispatch, "methodTest2");
 if (goos_object_call(testDispatch, "methodTest2", (void *)0).e == goos_errorCode_NO_HANDLE) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Double-checking the first method again...\n");
 methodTestSuccess = 0;
 goos_object_call(testDispatch, "methodTest1", (void *)0);
 if (methodTestSuccess == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("...and the third one\n");
 goos_object_addMethod(testDispatch, methodTestIO, "methodTestIO");
 if (goos_object_call(testDispatch, "methodTestIO", (void *)&input).d == 42) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing pointer variables\n");
 int life = 100;
 struct goos_data dLife;
 dLife.pd = &life;
 goos_object_addData(testDispatch, dLife, "life");
 if (*(goos_object_get(testDispatch, "life").pd) == 100) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Modify pointer\n");
 life = 80;
 if (*(goos_object_get(testDispatch, "life").pd) == 80) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing instance variables\n");
 int maxLife = 20;
 struct goos_data dmLife;
 dmLife.d = maxLife;
 goos_object_addData(testDispatch, dmLife, "maxLife");
 if (goos_object_get(testDispatch, "maxLife").d == 20) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Modify original but instance stays\n");
 maxLife = 0;
 dmLife.d = 0;
 if (goos_object_get(testDispatch, "maxLife").d == 20) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Modify instance variable\n");
 dmLife.d = 10;
 goos_object_set(testDispatch, "maxLife", dmLife);
 if (goos_object_get(testDispatch, "maxLife").d == 10) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Access method as data\n");
 if (goos_object_get(testDispatch, "methodTestIO").e == goos_errorCode_NOT_A_VARIABLE) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Access data as method\n");
 if (goos_object_call(testDispatch, "maxLife", (void *)0).e == goos_errorCode_NOT_A_METHOD) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
}

variable_types: life int

variable_types: maxLife int


testClass

decompiled_code:
int testClass()
{
__int64 v0; // rbp
const char *v1; // rax
const char *v2; // r12
__int64 v3; // r12
const char *v4; // rax

v0 = goos_object_new();
puts("Testing class functions");
goos_object_addMethod(v0, classHello_greetSimple, "greetSimple");
greetSimple_wasRun = 0;
v1 = (const char *)goos_object_call(v0, "greetSimple", 0LL);
puts(v1);
if ( greetSimple_wasRun != 1 )
goto LABEL_2;
puts("Success");
puts("Testing class vars");
goos_object_addData(v0, "Awesome", 0LL, "name");
v2 = (const char *)goos_object_get(v0, "name");
printf("You are %s\n", v2);
if ( strcmp("Awesome", v2) )
goto LABEL_2;
puts("Success");
puts("Testing class vars in a method");
goos_object_addData(v0, 5LL, 0LL, "awesomeness");
goos_object_addMethod(v0, classHello_greetAwesome, "greetMuch");
goos_object_call(v0, "greetMuch", 0LL);
if ( greetAwesome_wasRun != 5 )
goto LABEL_2;
puts("Success");
puts("Testing subclassing");
v3 = goos_object_new();
goos_object_inherits(v3, v0);
greetSimple_wasRun = 0;
v4 = (const char *)goos_object_call(v3, "greetSimple", 0LL);
puts(v4);
if ( greetSimple_wasRun != 1 )
goto LABEL_2;
puts("Success");
puts("Testing super's methods use self's data");
goos_object_addMethod(v0, classSecondHello_greetHi, "greetHi");
goos_object_addData(v3, 12000LL, 0LL, "height");
goos_object_addData(v0, 12LL, 0LL, "height");
goos_object_call(v3, "greetHi", 0LL);
if ( greetLevel != 12000 || (puts("Success"), goos_object_call(v0, "greetHi", 0LL), greetLevel != 12) )
{
LABEL_2:
puts("Failure");
exit(0);
}
return puts("Success");
}

canonical_decompiled_code:
int func7()
{
__int64 v0; // rbp
const char *v1; // rax
const char *v2; // r12
__int64 v3; // r12
const char *v4; // rax

v0 = goos_object_new();
puts("Testing class functions");
goos_object_addMethod(v0, classHello_greetSimple, "greetSimple");
greetSimple_wasRun = 0;
v1 = (const char *)goos_object_call(v0, "greetSimple", 0LL);
puts(v1);
if ( greetSimple_wasRun != 1 )
goto LABEL_2;
puts("Success");
puts("Testing class vars");
goos_object_addData(v0, "Awesome", 0LL, "name");
v2 = (const char *)goos_object_get(v0, "name");
printf("You are %s\n", v2);
if ( strcmp("Awesome", v2) )
goto LABEL_2;
puts("Success");
puts("Testing class vars in a method");
goos_object_addData(v0, 5LL, 0LL, "awesomeness");
goos_object_addMethod(v0, classHello_greetAwesome, "greetMuch");
goos_object_call(v0, "greetMuch", 0LL);
if ( greetAwesome_wasRun != 5 )
goto LABEL_2;
puts("Success");
puts("Testing subclassing");
v3 = goos_object_new();
goos_object_inherits(v3, v0);
greetSimple_wasRun = 0;
v4 = (const char *)goos_object_call(v3, "greetSimple", 0LL);
puts(v4);
if ( greetSimple_wasRun != 1 )
goto LABEL_2;
puts("Success");
puts("Testing super's methods use self's data");
goos_object_addMethod(v0, classSecondHello_greetHi, "greetHi");
goos_object_addData(v3, 12000LL, 0LL, "height");
goos_object_addData(v0, 12LL, 0LL, "height");
goos_object_call(v3, "greetHi", 0LL);
if ( greetLevel != 12000 || (puts("Success"), goos_object_call(v0, "greetHi", 0LL), greetLevel != 12) )
{
LABEL_2:
puts("Failure");
exit(0);
}
return puts("Success");
}

original_code:
void testClass(void) {
 goos_object* classHello = goos_object_new();
 printf("Testing class functions\n");
 goos_object_addMethod(classHello, classHello_greetSimple, "greetSimple");
 greetSimple_wasRun = 0;
 printf("%s\n", goos_object_call(classHello, "greetSimple", (void*)0).s);
 if (greetSimple_wasRun == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing class vars\n");
 goos_data sAwesome; sAwesome.s = "Awesome";
 goos_object_addData(classHello, sAwesome, "name");
 char* sName = goos_object_get(classHello, "name").s;
 printf("You are %s\n", sName);
 if (strcmp("Awesome", sName) == 0) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing class vars in a method\n");
 goos_data dMultiplier; dMultiplier.d=5;
 goos_object_addData(classHello, dMultiplier, "awesomeness");
 goos_object_addMethod(classHello, classHello_greetAwesome, "greetMuch");
 goos_object_call(classHello, "greetMuch", (void*)0);
 if (greetAwesome_wasRun == 5) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing subclassing\n");
 goos_object* classSecondHello = goos_object_new();
 goos_object_inherits(classSecondHello, classHello);
 greetSimple_wasRun = 0;
 printf("%s\n", goos_object_call(classSecondHello, "greetSimple", (void*)0).s);
 if (greetSimple_wasRun == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing super's methods use self's data\n");
 goos_object_addMethod(classHello, classSecondHello_greetHi, "greetHi");
 goos_data dHeight; dHeight.d=12000;
 goos_object_addData(classSecondHello, dHeight, "height");
 dHeight.d=12;
 goos_object_addData(classHello, dHeight, "height");
 goos_object_call(classSecondHello, "greetHi", (void*)0);
 if (greetLevel == 12000) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 goos_object_call(classHello, "greetHi", (void*)0);
 if (greetLevel == 12) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
}

canonical_original_code:
void testClass() {
 struct goos_object_s *classHello = goos_object_new();
 printf("Testing class functions\n");
 goos_object_addMethod(classHello, classHello_greetSimple, "greetSimple");
 greetSimple_wasRun = 0;
 printf("%s\n", goos_object_call(classHello, "greetSimple", (void *)0).s);
 if (greetSimple_wasRun == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing class vars\n");
 struct goos_data sAwesome; sAwesome.s = "Awesome";
 goos_object_addData(classHello, sAwesome, "name");
 char *sName = goos_object_get(classHello, "name").s;
 printf("You are %s\n", sName);
 if (strcmp("Awesome", sName) == 0) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing class vars in a method\n");
 struct goos_data dMultiplier; dMultiplier.d=5;
 goos_object_addData(classHello, dMultiplier, "awesomeness");
 goos_object_addMethod(classHello, classHello_greetAwesome, "greetMuch");
 goos_object_call(classHello, "greetMuch", (void *)0);
 if (greetAwesome_wasRun == 5) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing subclassing\n");
 struct goos_object_s *classSecondHello = goos_object_new();
 goos_object_inherits(classSecondHello, classHello);
 greetSimple_wasRun = 0;
 printf("%s\n", goos_object_call(classSecondHello, "greetSimple", (void *)0).s);
 if (greetSimple_wasRun == 1) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 printf("Testing super's methods use self's data\n");
 goos_object_addMethod(classHello, classSecondHello_greetHi, "greetHi");
 struct goos_data dHeight; dHeight.d=12000;
 goos_object_addData(classSecondHello, dHeight, "height");
 dHeight.d=12;
 goos_object_addData(classHello, dHeight, "height");
 goos_object_call(classSecondHello, "greetHi", (void *)0);
 if (greetLevel == 12000) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
 goos_object_call(classHello, "greetHi", (void *)0);
 if (greetLevel == 12) printf("Success\n");
 else { printf("Failure\n"); exit(0); }
}

variable_types:
sName
char *


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax

v3 = goos_version(argc, argv, envp);
printf("Testing goos Version %d\n", v3);
testDispatch();
testClass();
puts("All tests passed");
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax

v3 = goos_version(argc, argv, envp);
printf("Testing goos Version %d\n", v3);
func6();
func7();
puts("All tests passed");
return 0;
}

original_code:
int main(void) {
 printf("Testing goos Version %d\n", goos_version());
 testDispatch();
 testClass();
 printf("All tests passed\n");
}

canonical_original_code:
int main() {
 printf("Testing goos Version %d\n", goos_version());
 testDispatch();
 testClass();
 printf("All tests passed\n");
}


decompiled_code:
void __fastcall MPA_IncreaseAllocation(__int64 a1)
{
int v2; // er12
_QWORD *v3; // rax
_QWORD *v4; // rdi
_QWORD *v5; // rbx
__int64 v6; // rax

v2 = *(_DWORD *)(a1 + 8);
v3 = malloc(16LL * v2);
v4 = *(_QWORD **)a1;
v5 = v3;
v6 = 0LL;
if ( v2 > 0 )
{
do
{
v5[v6] = v4[v6];
++v6;
}
while ( v2 != v6 );
}
free(v4);
*(_QWORD *)a1 = v5;
*(_DWORD *)(a1 + 8) *= 2;
}

original_code:
static void MPA_IncreaseAllocation(MutablePointerArray* self) {
    void ** newArray = (void**)malloc(2*self->ArrayAllocationSize*sizeof(void*));
    for (int i=0; i<self->ArrayAllocationSize; i++) {
        newArray[i] = self->Array[i];
    }
    free(self->Array);
    self->Array = newArray;
    self->ArrayAllocationSize *= 2;
}

canonical_original_code:
static void MPA_IncreaseAllocation(struct MutablePointerArray *self) {
    void **newArray = (void**)malloc(2*self->ArrayAllocationSize*sizeof(void*));
    for (int i = 0; i<self->ArrayAllocationSize; i++) {
        newArray[i] = self->Array[i];
    }
    free(self->Array);
    self->Array = newArray;
    self->ArrayAllocationSize *= 2;
}

variable_types: struct MutablePointerArray { void **Array; int ArrayAllocationSize; int ArraySize; } *

variable_types:
newArray
void **


InitMutablePointerArray

decompiled_code:
void *__fastcall InitMutablePointerArray(_QWORD *a1)
{
void *result; // rax

result = malloc(0x400uLL);
a1[1] = 128LL;
*a1 = result;
return result;
}

canonical_decompiled_code:
void *__fastcall func1(_QWORD *a1)
{
void *result; // rax

result = malloc(0x400uLL);
a1[1] = 128LL;
*a1 = result;
return result;
}

original_code:
void InitMutablePointerArray(MutablePointerArray* self) {
    self->Array = (void**)malloc(128*sizeof(void*));
    self->ArrayAllocationSize = 128;
    self->ArraySize = 0;
}

canonical_original_code:
void InitMutablePointerArray(struct MutablePointerArray *self) {
    self->Array = (void **)malloc(128*sizeof(void *));
    self->ArrayAllocationSize = 128;
    self->ArraySize = 0;
}


FreeMutablePointerArray

decompiled_code:
void __fastcall FreeMutablePointerArray(__int64 a1)
{
free(*(void **)a1);
*(_QWORD *)(a1 + 8) = 0LL;
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1)
{
free(*(void **)a1);
*(_QWORD *)(a1 + 8) = 0LL;
}

original_code:
void FreeMutablePointerArray(MutablePointerArray* self) {
    free(self->Array);
    self->ArrayAllocationSize = 0;
    self->ArraySize = 0;
}

canonical_original_code:
void FreeMutablePointerArray(struct MutablePointerArray *self) {
    free(self->Array);
    self->ArrayAllocationSize = 0;
    self->ArraySize = 0;
}


decompiled_code:
__int64 __fastcall MPA_GetSize(__int64 a1)
{
return *(unsigned int *)(a1 + 12);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
return *(unsigned int *)(a1 + 12);
}

original_code:
inline int MPA_GetSize(MutablePointerArray* self) {
    return self->ArraySize;
}

canonical_original_code:
inline int MPA_GetSize(struct MutablePointerArray *self) {
    return self->ArraySize;
}


decompiled_code:
// attributes: thunk
__int64 __fastcall MPA_Length(__int64 a1)
{
return MPA_GetSize(a1);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
return func3(a1);
}

original_code:
inline int MPA_Length(MutablePointerArray* self) {
    return self->ArraySize;
}

canonical_original_code:
inline int MPA_Length(struct MutablePointerArray *self) {
    return self->ArraySize;
}


decompiled_code:
__int64 __fastcall MPA_AddPointer(__int64 a1, __int64 a2)
{
__int64 result; // rax

result = *(unsigned int *)(a1 + 12);
if ( *(_DWORD *)(a1 + 8) <= (int)result )
{
MPA_IncreaseAllocation(a1);
result = *(unsigned int *)(a1 + 12);
}
*(_QWORD *)(*(_QWORD *)a1 + 8LL * (int)result) = a2;
*(_DWORD *)(a1 + 12) = result + 1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2)
{
__int64 result; // rax

result = *(unsigned int *)(a1 + 12);
if ( *(_DWORD *)(a1 + 8) <= (int)result )
{
func0(a1);
result = *(unsigned int *)(a1 + 12);
}
*(_QWORD *)(*(_QWORD *)a1 + 8LL * (int)result) = a2;
*(_DWORD *)(a1 + 12) = result + 1;
return result;
}

original_code:
int MPA_AddPointer(MutablePointerArray* self, void* pointer) {
    if (self->ArrayAllocationSize <= self->ArraySize)
        MPA_IncreaseAllocation(self);
    self->Array[self->ArraySize] = pointer;
    self->ArraySize++;
    return self->ArraySize-1;
}

canonical_original_code:
int MPA_AddPointer(struct MutablePointerArray *self, void *pointer) {
    if (self->ArrayAllocationSize <= self->ArraySize)
        MPA_IncreaseAllocation(self);
    self->Array[self->ArraySize] = pointer;
    self->ArraySize++;
    return self->ArraySize-1;
}

variable_types:
pointer
void *


decompiled_code:
__int64 __fastcall MPA_PointerAtIndex(_QWORD *a1, int a2)
{
return *(_QWORD *)(*a1 + 8LL * a2);
}

canonical_decompiled_code:
__int64 __fastcall func6(_QWORD *a1, int a2)
{
return *(_QWORD *)(*a1 + 8LL * a2);
}

original_code:
inline void* MPA_PointerAtIndex(MutablePointerArray* self, int index) {
    return self->Array[index];
}

canonical_original_code:
inline void *MPA_PointerAtIndex(struct MutablePointerArray *self, int index) {
    return self->Array[index];
}

variable_types: index int


decompiled_code:
__int64 __fastcall MPA_LastPointer(_QWORD *a1)
{
int v1; // eax

v1 = MPA_GetSize((__int64)a1);
return MPA_PointerAtIndex(a1, v1 - 1);
}

canonical_decompiled_code:
__int64 __fastcall func7(_QWORD *a1)
{
int v1; // eax

v1 = func3((__int64)a1);
return func6(a1, v1 - 1);
}

original_code:
void* MPA_LastPointer(MutablePointerArray* self) {
    return MPA_PointerAtIndex(self, MPA_GetSize(self)-1);
}

canonical_original_code:
void *MPA_LastPointer(struct MutablePointerArray *self) {
    return MPA_PointerAtIndex(self, MPA_GetSize(self)-1);
}


original_code:
int MPA_RemoveIndex(MutablePointerArray* self, int index) {
    for (int i=index; i<self->ArraySize-1; i++) {
        self->Array[i] = self->Array[i+1];
    }
    self->ArraySize--;
    self->Array[self->ArraySize] = 0;
    return 1;
}

canonical_original_code:
int MPA_RemoveIndex(struct MutablePointerArray *self, int index) {
    for (int i = index; i<self->ArraySize-1; i++) {
        self->Array[i] = self->Array[i+1];
    }
    self->ArraySize--;
    self->Array[self->ArraySize] = 0;
    return 1;
}


decompiled_code:
void __fastcall MPA_FreeIndex(__int64 *a1, int a2)
{
int v2; // er8
void *v3; // r9

MPA_PointerAtIndex(a1, a2);
MPA_RemoveIndex(a1, v2);
free(v3);
}

canonical_decompiled_code:
void __fastcall func9(__int64 *a1, int a2)
{
int v2; // er8
void *v3; // r9

func6(a1, a2);
func8(a1, v2);
free(v3);
}

original_code:
inline void MPA_FreeIndex(MutablePointerArray* self, int index) {
    void* pointer = MPA_PointerAtIndex(self, index);
    MPA_RemoveIndex(self, index);
    free(pointer);
}

canonical_original_code:
inline void MPA_FreeIndex(struct MutablePointerArray *self, int index) {
    void *pointer = MPA_PointerAtIndex(self, index);
    MPA_RemoveIndex(self, index);
    free(pointer);
}


decompiled_code:
void __fastcall MPA_FreeAll(__int64 *a1)
{
int v1; // eax
int v2; // ebx

v1 = MPA_GetSize((__int64)a1) - 1;
if ( v1 >= 0 )
{
v2 = v1;
do
MPA_FreeIndex(a1, v2);
while ( v2-- != 0 );
}
}

original_code:
void MPA_FreeAll(MutablePointerArray* self) {
    for (int i=MPA_GetSize(self)-1; i>=0; i--) {
        MPA_FreeIndex(self, i);
    }
}

canonical_original_code:
void MPA_FreeAll(struct MutablePointerArray *self) {
    for (int i = MPA_GetSize(self)-1; i>=0; i--) {
        MPA_FreeIndex(self, i);
    }
}


decompiled_code:
__int64 __fastcall MPA_IndexOfPointer(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
__int64 result; // rax

v2 = *(int *)(a1 + 12);
if ( (int)v2 <= 0 )
return 0xFFFFFFFFLL;
result = 0LL;
while ( *(_QWORD *)(*(_QWORD *)a1 + 8 * result) != a2 )
{
if ( ++result == v2 )
return 0xFFFFFFFFLL;
}
return (unsigned int)result;
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1, __int64 a2)
{
__int64 v2; // rdx
__int64 result; // rax

v2 = *(int *)(a1 + 12);
if ( (int)v2 <= 0 )
return 0xFFFFFFFFLL;
result = 0LL;
while ( *(_QWORD *)(*(_QWORD *)a1 + 8 * result) != a2 )
{
if ( ++result == v2 )
return 0xFFFFFFFFLL;
}
return (unsigned int)result;
}

original_code:
int MPA_IndexOfPointer(MutablePointerArray* self, void* pointer) {
    for (int i=0; i<self->ArraySize; i++) {
        if (self->Array[i] == pointer)
            return i;
    }
    return -1;
}

canonical_original_code:
int MPA_IndexOfPointer(struct MutablePointerArray *self, void *pointer) {
    for (int i = 0; i<self->ArraySize; i++) {
        if (self->Array[i] == pointer)
            return i;
    }
    return -1;
}


decompiled_code:
__int64 __fastcall MPA_RemovePointer(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v4; // rsi
__int64 v5; // r9

v2 = *(int *)(a1 + 12);
if ( (int)v2 <= 0 )
return 0LL;
v4 = 0LL;
while ( *(_QWORD *)(*(_QWORD *)a1 + 8 * v4) != a2 )
{
if ( ++v4 == v2 )
return 0LL;
}
MPA_RemoveIndex((__int64 *)a1, v4);
MPA_RemovePointer(a1, v5);
return 1LL;
}

original_code:
int MPA_RemovePointer(MutablePointerArray* self, void* pointer) {
    int i;
    for (i=0; i<self->ArraySize; i++) {
        if (self->Array[i] == pointer)
            break;
    }
    if (i >= self->ArraySize) return 0;
    MPA_RemoveIndex(self, i);
    MPA_RemovePointer(self, pointer);
    return 1;
}

canonical_original_code:
int MPA_RemovePointer(struct MutablePointerArray *self, void *pointer) {
    int i;
    for (i=0; i<self->ArraySize; i++) {
        if (self->Array[i] == pointer)
            break;
    }
    if (i >= self->ArraySize) return 0;
    MPA_RemoveIndex(self, i);
    MPA_RemovePointer(self, pointer);
    return 1;
}


decompiled_code:
__int64 __fastcall MPA_FreePointer(__int64 *a1, __int64 a2)
{
int v2; // eax
__int64 result; // rax

v2 = MPA_IndexOfPointer((__int64)a1, a2);
if ( v2 < 0 )
{
puts("ERROR: Pointer not found in Array");
result = 0LL;
}
else
{
MPA_FreeIndex(a1, v2);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 *a1, __int64 a2)
{
int v2; // eax
__int64 result; // rax

v2 = func11((__int64)a1, a2);
if ( v2 < 0 )
{
puts("ERROR: Pointer not found in Array");
result = 0LL;
}
else
{
func9(a1, v2);
result = 1LL;
}
return result;
}

original_code:
int MPA_FreePointer(MutablePointerArray* self, void* pointer) {
    int index = MPA_IndexOfPointer(self, pointer);
    if (index < 0) {
        printf("ERROR: Pointer not found in Array\n");
        return 0;
    }
    MPA_FreeIndex(self, index);
    return 1;
}

canonical_original_code:
int MPA_FreePointer(struct MutablePointerArray *self, void *pointer) {
    int index = MPA_IndexOfPointer(self, pointer);
    if (index < 0) {
        printf("ERROR: Pointer not found in Array\n");
        return 0;
    }
    MPA_FreeIndex(self, index);
    return 1;
}


decompiled_code:
__int64 __fastcall MPA_Pop(__int64 *a1)
{
int v1; // eax

v1 = MPA_GetSize((__int64)a1);
return MPA_RemoveIndex(a1, v1 - 1);
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 *a1)
{
int v1; // eax

v1 = func3((__int64)a1);
return func8(a1, v1 - 1);
}

original_code:
void MPA_Pop(MutablePointerArray* self) {
    MPA_RemoveIndex(self, MPA_GetSize(self)-1);
}

canonical_original_code:
void MPA_Pop(struct MutablePointerArray *self) {
    MPA_RemoveIndex(self, MPA_GetSize(self)-1);
}


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

while ( 1 )
{
result = MPA_GetSize((__int64)a1);
if ( (int)result <= 0 )
break;
MPA_Pop(a1);
}
return result;
}

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

while ( 1 )
{
result = func3((__int64)a1);
if ( (int)result <= 0 )
break;
func14(a1);
}
return result;
}

original_code:
inline void MPA_RemoveAll(MutablePointerArray* self) {
    while (MPA_GetSize(self) > 0) {
        MPA_Pop(self);
    }
}

canonical_original_code:
inline void MPA_RemoveAll(struct MutablePointerArray *self) {
    while (MPA_GetSize(self) > 0) {
        MPA_Pop(self);
    }
}


original_code:
int MPA_Swap(MutablePointerArray* self, int indexA, int indexB) {
    if (indexA > self->ArraySize || indexB > self->ArraySize)
        return 0;
    void* temp = self->Array[indexA];
    self->Array[indexA] = self->Array[indexB];
    self->Array[indexB] = temp;
    return 1;
}

canonical_original_code:
int MPA_Swap(struct MutablePointerArray *self, int indexA, int indexB) {
    if (indexA > self->ArraySize || indexB > self->ArraySize)
        return 0;
    void *temp = self->Array[indexA];
    self->Array[indexA] = self->Array[indexB];
    self->Array[indexB] = temp;
    return 1;
}

variable_types: indexA int

variable_types: indexB int

variable_types:
temp
void *


decompiled_code:
__int64 __fastcall normal_dac_map_clock(__int64 a1, unsigned int a2)
{
return a2;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned int a2)
{
return a2;
}

original_code:
static int normal_dac_map_clock(int bpp, int pixelclock)
{
    return pixelclock;
}

variable_types: bpp int

variable_types: pixelclock int


decompiled_code:
__int64 __fastcall normal_dac_map_horizontal_crtc(__int64 a1, __int64 a2, unsigned int a3)
{
return a3;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2, unsigned int a3)
{
return a3;
}

original_code:
static int normal_dac_map_horizontal_crtc(int bpp, int pixelclock, int htiming)
{
    return htiming;
}

variable_types: htiming int


decompiled_code:
void normal_dac_savestate()
{
;
}

canonical_decompiled_code:
void func2()
{
;
}

original_code:
static void normal_dac_savestate(unsigned char *regs)
{
}

variable_types:
regs
unsigned char *


decompiled_code:
void normal_dac_restorestate()
{
;
}

canonical_decompiled_code:
void func3()
{
;
}

original_code:
static void normal_dac_restorestate(const unsigned char *regs)
{
}

canonical_original_code:
static void normal_dac_restorestate(unsigned char *regs)
{
}


decompiled_code:
void normal_dac_initializestate()
{
;
}

canonical_decompiled_code:
void func4()
{
;
}

original_code:
static void normal_dac_initializestate(unsigned char *regs, int bpp, int colormode,
           int pixelclock)
{
}

variable_types: colormode int


decompiled_code:
size_t normal_dac_init()
{
size_t result; // rax

result = _svgalib_driver_report;
if ( _svgalib_driver_report )
result = fwrite("svgalib: Using Normal VGA RAMDAC.\n", 1uLL, 0x22uLL, stderr);
return result;
}

canonical_decompiled_code:
size_t func5()
{
size_t result; // rax

result = _svgalib_driver_report;
if ( _svgalib_driver_report )
result = fwrite("svgalib: Using Normal VGA RAMDAC.\n", 1uLL, 0x22uLL, stderr);
return result;
}

original_code:
static void normal_dac_init(void)
{
    if (__svgalib_driver_report)
 fprintf(stderr,"svgalib: Using Normal VGA RAMDAC.\n");
}

canonical_original_code:
static void normal_dac_init()
{
    if (__svgalib_driver_report)
 fprintf(stderr,"svgalib: Using Normal VGA RAMDAC.\n");
}


nothing

decompiled_code:
void nothing()
{
;
}

canonical_decompiled_code:
void func1()
{
;
}

original_code:
static void nothing(void)
{
}

canonical_original_code:
static void nothing()
{
}