eraseLine

decompiled_code:
__int64 __fastcall eraseLine(_QWORD *a1, int a2)
{
__int64 result; // rax
__int64 v3; // r12
int v4; // ebx
__int64 v5; // r13
__int64 v6; // r14
__int64 v7; // rsi

result = getGameLine((__int64)a1, a2);
if ( result )
{
v3 = result;
v4 = getGameAreaNumLines((__int64)a1);
v5 = getNextLine(v3);
v6 = getPreviousLine(v3);
if ( v5 )
{
setPreviousLine(v5, v6);
v7 = v5;
if ( v6 )
{
LABEL_4:
setNextLine(v6, v7);
LABEL_5:
setGameAreaNumLines((__int64)a1, v4 - 1);
fixHeightMap((__int64)a1);
insertSortDeletedLine((__int64)a1, v3);
return eraseTLocations(a1, v3);
}
}
else
{
setGameAreaLast((__int64)a1, v6);
v7 = 0LL;
if ( v6 )
goto LABEL_4;
}
setGameAreaFirst(a1, v7);
goto LABEL_5;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func33(_QWORD *a1, int a2)
{
__int64 result; // rax
__int64 v3; // r12
int v4; // ebx
__int64 v5; // r13
__int64 v6; // r14
__int64 v7; // rsi

result = func20((__int64)a1, a2);
if ( result )
{
v3 = result;
v4 = func2((__int64)a1);
v5 = getNextLine(v3);
v6 = getPreviousLine(v3);
if ( v5 )
{
setPreviousLine(v5, v6);
v7 = v5;
if ( v6 )
{
LABEL_4:
setNextLine(v6, v7);
LABEL_5:
func12((__int64)a1, v4 - 1);
func29((__int64)a1);
func32((__int64)a1, v3);
return eraseTLocations(a1, v3);
}
}
else
{
func11((__int64)a1, v6);
v7 = 0LL;
if ( v6 )
goto LABEL_4;
}
func10(a1, v7);
goto LABEL_5;
}
return result;
}

original_code:
void eraseLine(GameArea *g, int line) {
 Line *l = getGameLine(g, line);
 Line *next;
 Line *previous;
 int num_lines = getGameAreaNumLines(g);
 if (l != ((void *)0)) {
  next = getNextLine(l);
  previous = getPreviousLine(l);
 }
 else {
  return;
 }
 if (next != ((void *)0)) {
  setPreviousLine(next, previous);
 }
 else {
  setGameAreaLast(g, previous);
 }
 if (previous != ((void *)0)) {
  setNextLine(previous, next);
 }
 else {
  setGameAreaFirst(g, next);
 }
 setGameAreaNumLines(g, --num_lines);
 fixHeightMap(g);
 insertSortDeletedLine(g, l);
 eraseTLocations(g, l);
 return;
}

canonical_original_code:
void eraseLine(struct GameArea *g, int line) {
 struct Line *l = getGameLine(g, line);
 struct Line *next;
 struct Line *previous;
 int num_lines = getGameAreaNumLines(g);
 if (l != ((void *)0)) {
  next = getNextLine(l);
  previous = getPreviousLine(l);
 }
 else {
  return;
 }
 if (next != ((void *)0)) {
  setPreviousLine(next, previous);
 }
 else {
  setGameAreaLast(g, previous);
 }
 if (previous != ((void *)0)) {
  setNextLine(previous, next);
 }
 else {
  setGameAreaFirst(g, next);
 }
 setGameAreaNumLines(g, --num_lines);
 fixHeightMap(g);
 insertSortDeletedLine(g, l);
 eraseTLocations(g, l);
 return;
}

variable_types: struct GameArea { struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *gameLineFirst; struct Line *gameLineLast; int num_lines; struct HeightMap { int columns[10]; } *heightMap; struct Line *deletedLinesFirst; struct Line *deletedLinesLast; int num_deleted_lines; int score; int *piece_count; } *


newTHash

repo: joaomlneto/iaed-tetraminos

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

v0 = malloc(0x78uLL);
vectorInit(v0, 30LL, 0LL);
return v0;
}

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

v0 = malloc(0x78uLL);
vectorInit(v0, 30LL, 0LL);
return v0;
}

original_code:
int* newTHash() {
 int *hash = malloc(5*6*sizeof(int));
 vectorInit(hash, 5*6, 0);
 return hash;
}

canonical_original_code:
int *newTHash() {
 int *hash = malloc(5*6*sizeof(int));
 vectorInit(hash, 5*6, 0);
 return hash;
}

variable_types:
hash
int *

return_type: int *


getTHashPos

decompiled_code:
__int64 __fastcall getTHashPos(__int64 a1)
{
int v1; // ebx
char v2; // al

v1 = getPieceType();
v2 = getPieceColor(a1);
return (unsigned int)color2int((unsigned int)v2) + 2 * (3 * v1 - 3) - 1;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
int v1; // ebx
char v2; // al

v1 = getPieceType();
v2 = getPieceColor(a1);
return (unsigned int)color2int((unsigned int)v2) + 2 * (3 * v1 - 3) - 1;
}

original_code:
int getTHashPos(tetromino *t) {
 int type = getPieceType(t);
 char color = getPieceColor(t);
 return (6*(type-1) + color2int(color) - 1);
}

canonical_original_code:
int getTHashPos(struct tetromino *t) {
 int type = getPieceType(t);
 char color = getPieceColor(t);
 return (6*(type-1) + color2int(color) - 1);
}

variable_types: struct tetromino { struct position { int line; int column; } position; int type; char color; } *

variable_types: type int

variable_types: color char

return_type: int

user_defined_types: struct tetromino { struct position position; int type; char color; }


deletePiece

decompiled_code:
// attributes: thunk
void deletePiece(void *ptr)
{
free(ptr);
}

canonical_decompiled_code:
void func0(void *ptr)
{
free(ptr);
}

original_code:
void deletePiece(tetromino* piece) {
 free(piece);
}

canonical_original_code:
void deletePiece(struct tetromino *piece) {
 free(piece);
}

return_type: void

user_defined_types: struct position { int line; int column; }


getPieceLine

decompiled_code:
// attributes: thunk
__int64 getPieceLine()
{
return getLine();
}

canonical_decompiled_code:
__int64 func1()
{
return getLine();
}

original_code:
int getPieceLine(tetromino *t) {
 return getLine(&(t->position));
}

canonical_original_code:
int getPieceLine(struct tetromino *t) {
 return getLine(&(t->position));
}


getPieceColumn

decompiled_code:
// attributes: thunk
__int64 getPieceColumn()
{
return getColumn();
}

canonical_decompiled_code:
__int64 func2()
{
return getColumn();
}

original_code:
int getPieceColumn(tetromino *t) {
 return getColumn(&(t->position));
}

canonical_original_code:
int getPieceColumn(struct tetromino *t) {
 return getColumn(&(t->position));
}


getPieceType

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

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

original_code:
int getPieceType(tetromino *t) {
 return t->type;
}

canonical_original_code:
int getPieceType(struct tetromino *t) {
 return t->type;
}


getPieceColor

decompiled_code:
__int64 __fastcall getPieceColor(__int64 a1)
{
return *(unsigned __int8 *)(a1 + 12);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
return *(unsigned __int8 *)(a1 + 12);
}

original_code:
char getPieceColor(tetromino *t) {
 return t->color;
}

canonical_original_code:
char getPieceColor(struct tetromino *t) {
 return t->color;
}

return_type: char


setPieceLine

decompiled_code:
// attributes: thunk
__int64 setPieceLine()
{
return setLine();
}

canonical_decompiled_code:
__int64 func5()
{
return setLine();
}

original_code:
void setPieceLine(tetromino *t, int line) {
 setLine(&(t->position), line);
}

canonical_original_code:
void setPieceLine(struct tetromino *t, int line) {
 setLine(&(t->position), line);
}

variable_types: line int


setPieceColumn

decompiled_code:
// attributes: thunk
__int64 setPieceColumn()
{
return setColumn();
}

canonical_decompiled_code:
__int64 func6()
{
return setColumn();
}

original_code:
void setPieceColumn(tetromino *t, int column) {
 setColumn(&(t->position), column);
}

canonical_original_code:
void setPieceColumn(struct tetromino *t, int column) {
 setColumn(&(t->position), column);
}

variable_types: column int


setPieceType

decompiled_code:
void __fastcall setPieceType(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 8) = a2;
}

canonical_decompiled_code:
void __fastcall func7(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 8) = a2;
}

original_code:
void setPieceType(tetromino *t, int type) {
 t->type = type;
}

canonical_original_code:
void setPieceType(struct tetromino *t, int type) {
 t->type = type;
}


setPieceColor

decompiled_code:
void __fastcall setPieceColor(__int64 a1, char a2)
{
*(_BYTE *)(a1 + 12) = a2;
}

canonical_decompiled_code:
void __fastcall func8(__int64 a1, char a2)
{
*(_BYTE *)(a1 + 12) = a2;
}

original_code:
void setPieceColor(tetromino *t, char color) {
 t->color = color;
}

canonical_original_code:
void setPieceColor(struct tetromino *t, char color) {
 t->color = color;
}


newPiece

decompiled_code:
void __fastcall newPiece(int a1, unsigned int a2, unsigned int a3, char a4)
{
void *v6; // r12

v6 = malloc(0x10uLL);
setPieceLine(v6, a2);
setPieceColumn(v6, a3);
setPieceType((__int64)v6, a1);
setPieceColor((__int64)v6, a4);
}

canonical_decompiled_code:
void __fastcall func9(int a1, unsigned int a2, unsigned int a3, char a4)
{
void *v6; // r12

v6 = malloc(0x10uLL);
func5(v6, a2);
func6(v6, a3);
func7((__int64)v6, a1);
func8((__int64)v6, a4);
}

original_code:
tetromino* newPiece(int type, int line, int column, char color) {
 tetromino *t;
 t = malloc(sizeof(tetromino));
 setPieceLine(t, line);
 setPieceColumn(t, column);
 setPieceType(t, type);
 setPieceColor(t, color);
 return t;
}

canonical_original_code:
struct tetromino *newPiece(int type, int line, int column, char color) {
 struct tetromino *t;
 t = malloc(sizeof(tetromino));
 setPieceLine(t, line);
 setPieceColumn(t, column);
 setPieceType(t, type);
 setPieceColor(t, color);
 return t;
}

return_type: struct tetromino { struct position { int line; int column; } position; int type; char color; } *


getPositionsL

decompiled_code:
__int64 __fastcall getPositionsL(_DWORD *a1, int a2, int a3)
{
__int64 result; // rax

*a1 = a2;
a1[2] = a2;
a1[3] = a3 + 1;
result = (unsigned int)(a3 + 2);
a1[4] = a2;
a1[1] = a3;
a1[5] = result;
a1[6] = a2 - 1;
a1[7] = a3;
return result;
}

original_code:
void getPositionsL(position *pos, int line, int column) {
 pos[0].line = line;
 pos[0].column = column;
 pos[1].line = line;
 pos[1].column = column + 1;
 pos[2].line = line;
 pos[2].column = column + 2;
 pos[3].line = line - 1;
 pos[3].column = column;
 return;
}

canonical_original_code:
void getPositionsL(struct position *pos, int line, int column) {
 pos[0].line = line;
 pos[0].column = column;
 pos[1].line = line;
 pos[1].column = column + 1;
 pos[2].line = line;
 pos[2].column = column + 2;
 pos[3].line = line - 1;
 pos[3].column = column;
 return;
}

variable_types: struct position { int line; int column; } *


getFloorSize

decompiled_code:
__int64 __fastcall getFloorSize(__int64 a1)
{
int v1; // eax
unsigned int v2; // er8
__int64 v3; // rax

v1 = getPieceType(a1);
v2 = 0;
v3 = (unsigned int)(v1 - 1);
if ( (unsigned int)v3 <= 4 )
v2 = CSWTCH_17[v3];
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1)
{
int v1; // eax
unsigned int v2; // er8
__int64 v3; // rax

v1 = func3(a1);
v2 = 0;
v3 = (unsigned int)(v1 - 1);
if ( (unsigned int)v3 <= 4 )
v2 = CSWTCH_17[v3];
return v2;
}

original_code:
int getFloorSize(tetromino *t) {
 int piece_type = getPieceType(t);
 switch(piece_type) {
  case 1: return 4;
  case 2: return 2;
  case 3: return 3;
  case 4: return 3;
  case 5: return 3;
 }
 return 0;
}

canonical_original_code:
int getFloorSize(struct tetromino *t) {
 int piece_type = getPieceType(t);
 switch(piece_type) {
  case 1: return 4;
  case 2: return 2;
  case 3: return 3;
  case 4: return 3;
  case 5: return 3;
 }
 return 0;
}


getColumnSpan

decompiled_code:
// attributes: thunk
__int64 __fastcall getColumnSpan(__int64 a1)
{
return getFloorSize(a1);
}

canonical_decompiled_code:
__int64 __fastcall func22(__int64 a1)
{
return func15(a1);
}

original_code:
int getColumnSpan(tetromino *t) {
 int piece_type = getPieceType(t);
 switch(piece_type) {
  case 1: return 4;
  case 2: return 2;
  case 3: return 3;
  case 4: return 3;
  case 5: return 3;
 }
 return 0;
}

canonical_original_code:
int getColumnSpan(struct tetromino *t) {
 int piece_type = getPieceType(t);
 switch(piece_type) {
  case 1: return 4;
  case 2: return 2;
  case 3: return 3;
  case 4: return 3;
  case 5: return 3;
 }
 return 0;
}


getLineSpan

decompiled_code:
__int64 __fastcall getLineSpan(__int64 a1)
{
int v1; // eax
unsigned int v2; // er8
__int64 v3; // rax

v1 = getPieceType(a1);
v2 = 0;
v3 = (unsigned int)(v1 - 1);
if ( (unsigned int)v3 <= 4 )
v2 = CSWTCH_27[v3];
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func23(__int64 a1)
{
int v1; // eax
unsigned int v2; // er8
__int64 v3; // rax

v1 = func3(a1);
v2 = 0;
v3 = (unsigned int)(v1 - 1);
if ( (unsigned int)v3 <= 4 )
v2 = CSWTCH_27[v3];
return v2;
}

original_code:
int getLineSpan(tetromino *t) {
 int piece_type = getPieceType(t);
 switch(piece_type) {
  case 1: return 1;
  case 2: return 2;
  case 3: return 2;
  case 4: return 2;
  case 5: return 2;
 }
 return 0;
}

canonical_original_code:
int getLineSpan(struct tetromino *t) {
 int piece_type = getPieceType(t);
 switch(piece_type) {
  case 1: return 1;
  case 2: return 2;
  case 3: return 2;
  case 4: return 2;
  case 5: return 2;
 }
 return 0;
}


decompiled_code:
__int64 __fastcall color2int(char a1)
{
unsigned __int8 v1; // di
__int64 result; // rax

v1 = a1 - 66;
result = 0LL;
if ( v1 <= 0x17u )
result = (unsigned int)CSWTCH_31[v1];
return result;
}

canonical_decompiled_code:
__int64 __fastcall func24(char a1)
{
unsigned __int8 v1; // di
__int64 result; // rax

v1 = a1 - 66;
result = 0LL;
if ( v1 <= 0x17u )
result = (unsigned int)CSWTCH_31[v1];
return result;
}

original_code:
int color2int(char color) {
 switch(color) {
  case 'B': return 1;
  case 'G': return 2;
  case 'O': return 3;
  case 'R': return 4;
  case 'V': return 5;
  case 'Y': return 6;
 }
 return 0;
}


decompiled_code:
__int64 __fastcall int2color(int a1)
{
__int64 v1; // rdi
__int64 result; // rax

v1 = (unsigned int)(a1 - 1);
result = 0LL;
if ( (unsigned int)v1 <= 5 )
result = (unsigned __int8)CSWTCH_33[v1];
return result;
}

canonical_decompiled_code:
__int64 __fastcall func25(int a1)
{
__int64 v1; // rdi
__int64 result; // rax

v1 = (unsigned int)(a1 - 1);
result = 0LL;
if ( (unsigned int)v1 <= 5 )
result = (unsigned __int8)CSWTCH_33[v1];
return result;
}

original_code:
char int2color(int color) {
 switch(color) {
  case 1: return 'B';
  case 2: return 'G';
  case 3: return 'O';
  case 4: return 'R';
  case 5: return 'V';
  case 6: return 'Y';
 }
 return 0;
}

variable_types: color int


getTLocationHashPos

decompiled_code:
__int64 __fastcall getTLocationHashPos(unsigned int *a1)
{
return *a1;
}

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

original_code:
int getTLocationHashPos(t_location *loc) {
 return loc->hash_pos;
}

canonical_original_code:
int getTLocationHashPos(struct t_location *loc) {
 return loc->hash_pos;
}

variable_types: struct t_location { int hash_pos; int num_lines; struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location **pieces; int num_t_locations; } **lines; } *

user_defined_types: struct t_location { int hash_pos; int num_lines; struct Line **lines; }


getTLocationNumLines

decompiled_code:
__int64 __fastcall getTLocationNumLines(__int64 a1)
{
return *(unsigned int *)(a1 + 4);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return *(unsigned int *)(a1 + 4);
}

original_code:
int getTLocationNumLines(t_location *loc) {
 return loc->num_lines;
}

canonical_original_code:
int getTLocationNumLines(struct t_location *loc) {
 return loc->num_lines;
}

user_defined_types: struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location **pieces; int num_t_locations; }


getTLocationLines

decompiled_code:
__int64 __fastcall getTLocationLines(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

original_code:
Line** getTLocationLines(t_location *loc) {
 return loc->lines;
}

canonical_original_code:
struct Line **getTLocationLines(struct t_location *loc) {
 return loc->lines;
}

variable_types:
loc
struct t_location *

return_type: struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } **


setTLocationNumLines

decompiled_code:
void __fastcall setTLocationNumLines(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 4) = a2;
}

canonical_decompiled_code:
void __fastcall func4(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 4) = a2;
}

original_code:
void setTLocationNumLines(t_location *loc, int num) {
 loc->num_lines = num;
 return;
}

canonical_original_code:
void setTLocationNumLines(struct t_location *loc, int num) {
 loc->num_lines = num;
 return;
}

variable_types: num int


setTLocationLines

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

canonical_decompiled_code:
void __fastcall func5(__int64 a1, __int64 a2)
{
*(_QWORD *)(a1 + 8) = a2;
}

original_code:
void setTLocationLines(t_location *loc, Line* *lines) {
 loc->lines = lines;
 return;
}

canonical_original_code:
void setTLocationLines(struct t_location *loc, struct Line **lines) {
 loc->lines = lines;
 return;
}

variable_types:
lines
struct Line **


processTLocation

decompiled_code:
void __fastcall processTLocation(void *ptr)
{
int v1; // eax
__int64 v2; // r13
__int64 v3; // r14
__int64 v4; // r15
int v5; // eax
__int64 v6; // rbx
__int64 v7; // rbp
void *v8; // rax

v1 = getTLocationNumLines((__int64)ptr);
if ( v1 > 0 )
{
v2 = 0LL;
v3 = 8LL * v1;
do
{
v4 = *(_QWORD *)(getTLocationLines((__int64)ptr) + v2);
v5 = getLineTLIndex(v4);
if ( v5 > 0 )
{
v6 = 0LL;
v7 = 8LL * v5;
while ( *(void **)(getLineT_location(v4) + v6) != ptr )
{
v6 += 8LL;
if ( v7 == v6 )
goto LABEL_8;
}
*(_QWORD *)(getLineT_location(v4) + v6) = 0LL;
}
LABEL_8:
v2 += 8LL;
}
while ( v2 != v3 );
}
v8 = (void *)getTLocationLines((__int64)ptr);
free(v8);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func6(void *ptr)
{
int v1; // eax
__int64 v2; // r13
__int64 v3; // r14
__int64 v4; // r15
int v5; // eax
__int64 v6; // rbx
__int64 v7; // rbp
void *v8; // rax

v1 = func1((__int64)ptr);
if ( v1 > 0 )
{
v2 = 0LL;
v3 = 8LL * v1;
do
{
v4 = *(_QWORD *)(func2((__int64)ptr) + v2);
v5 = getLineTLIndex(v4);
if ( v5 > 0 )
{
v6 = 0LL;
v7 = 8LL * v5;
while ( *(void **)(getLineT_location(v4) + v6) != ptr )
{
v6 += 8LL;
if ( v7 == v6 )
goto LABEL_8;
}
*(_QWORD *)(getLineT_location(v4) + v6) = 0LL;
}
LABEL_8:
v2 += 8LL;
}
while ( v2 != v3 );
}
v8 = (void *)func2((__int64)ptr);
free(v8);
free(ptr);
}

original_code:
void processTLocation(t_location* loc) {
 int i, j, num_lines, line_num_pieces, found;
 Line* line;
 num_lines = getTLocationNumLines(loc);
 for(i=0; i<num_lines; i++) {
  line = getTLocationLines(loc)[i];
  line_num_pieces = getLineTLIndex(line);
  found = 0;
  for(j=0; j<line_num_pieces && (!found); j++) {
   if(getLineT_location(line)[j] == loc) {
    getLineT_location(line)[j] = ((void *)0);
    found = 1;
   }
  }
 }
 free(getTLocationLines(loc));
 free(loc);
}

canonical_original_code:
void processTLocation(struct t_location *loc) {
 int i; int j; int num_lines; int line_num_pieces; int found;
 struct Line *line;
 num_lines = getTLocationNumLines(loc);
 for(i=0; i<num_lines; i++) {
  line = getTLocationLines(loc)[i];
  line_num_pieces = getLineTLIndex(line);
  found = 0;
  for(j=0; j<line_num_pieces && (!found); j++) {
   if(getLineT_location(line)[j] == loc) {
    getLineT_location(line)[j] = ((void *)0);
    found = 1;
   }
  }
 }
 free(getTLocationLines(loc));
 free(loc);
}

variable_types: i int

variable_types: j int

variable_types: found int

variable_types: struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *


eraseTLocations

decompiled_code:
void __fastcall eraseTLocations(__int64 a1, __int64 a2)
{
int v2; // eax
__int64 v3; // rbx
__int64 v4; // r13
__int64 v5; // rax
int v6; // ebp
__int64 v7; // rax
__int64 v8; // rax

v2 = getLineTLIndex(a2);
if ( v2 > 0 )
{
v3 = 0LL;
v4 = 8LL * v2;
do
{
if ( *(_QWORD *)(getLineT_location(a2) + v3) )
{
v5 = getLineT_location(a2);
v6 = getTLocationHashPos(*(unsigned int **)(v5 + v3));
v7 = getGameAreaPieceCounts(a1);
--*(_DWORD *)(v7 + 4LL * v6);
v8 = getLineT_location(a2);
processTLocation(*(void **)(v8 + v3));
}
v3 += 8LL;
}
while ( v3 != v4 );
}
}

canonical_decompiled_code:
void __fastcall func7(__int64 a1, __int64 a2)
{
int v2; // eax
__int64 v3; // rbx
__int64 v4; // r13
__int64 v5; // rax
int v6; // ebp
__int64 v7; // rax
__int64 v8; // rax

v2 = getLineTLIndex(a2);
if ( v2 > 0 )
{
v3 = 0LL;
v4 = 8LL * v2;
do
{
if ( *(_QWORD *)(getLineT_location(a2) + v3) )
{
v5 = getLineT_location(a2);
v6 = func0(*(unsigned int **)(v5 + v3));
v7 = getGameAreaPieceCounts(a1);
--*(_DWORD *)(v7 + 4LL * v6);
v8 = getLineT_location(a2);
func6(*(void **)(v8 + v3));
}
v3 += 8LL;
}
while ( v3 != v4 );
}
}

original_code:
void eraseTLocations(GameArea *g, Line* l) {
 int i, index, hashpos;
 index = getLineTLIndex(l);
 for(i=0; i<index; i++) {
  if(getLineT_location(l)[i] != ((void *)0)) {
   hashpos = getTLocationHashPos(getLineT_location(l)[i]);
   getGameAreaPieceCounts(g)[hashpos] -= 1;
   processTLocation(getLineT_location(l)[i]);
  }
 }
 return;
}

canonical_original_code:
void eraseTLocations(struct GameArea *g, struct Line *l) {
 int i; int index; int hashpos;
 index = getLineTLIndex(l);
 for(i=0; i<index; i++) {
  if(getLineT_location(l)[i] != ((void *)0)) {
   hashpos = getTLocationHashPos(getLineT_location(l)[i]);
   getGameAreaPieceCounts(g)[hashpos] -= 1;
   processTLocation(getLineT_location(l)[i]);
  }
 }
 return;
}

variable_types: struct GameArea { struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *gameLineFirst; struct Line *gameLineLast; int num_lines; struct HeightMap { int columns[10]; } *heightMap; struct Line *deletedLinesFirst; struct Line *deletedLinesLast; int num_deleted_lines; int score; int *piece_count; } *

variable_types:
l
struct Line *

variable_types: index int

variable_types: hashpos int

user_defined_types: struct GameArea { struct Line *gameLineFirst; struct Line *gameLineLast; int num_lines; struct HeightMap *heightMap; struct Line *deletedLinesFirst; struct Line *deletedLinesLast; int num_deleted_lines; int score; int *piece_count; }


getNextLine

decompiled_code:
__int64 __fastcall getNextLine(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

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

original_code:
Line* getNextLine(Line *l) {
 return l->next;
}

canonical_original_code:
struct Line *getNextLine(struct Line *l) {
 return l->next;
}

return_type: struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *


getPreviousLine

decompiled_code:
__int64 __fastcall getPreviousLine(__int64 a1)
{
return *(_QWORD *)a1;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return *(_QWORD *)a1;
}

original_code:
Line* getPreviousLine(Line *l) {
 return l->previous;
}

canonical_original_code:
struct Line *getPreviousLine(struct Line *l) {
 return l->previous;
}


getLineColumn

decompiled_code:
__int64 __fastcall getLineColumn(__int64 a1)
{
return a1 + 16;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
return a1 + 16;
}

original_code:
char* getLineColumn(Line *l) {
 return l->column;
}

canonical_original_code:
char *getLineColumn(struct Line *l) {
 return l->column;
}

return_type: char *


setNextLine

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

canonical_decompiled_code:
void __fastcall func3(__int64 a1, __int64 a2)
{
*(_QWORD *)(a1 + 8) = a2;
}

original_code:
void setNextLine(Line *line, Line *next_line) {
 line->next = next_line;
}

canonical_original_code:
void setNextLine(struct Line *line, struct Line *next_line) {
 line->next = next_line;
}


setLineColumn

decompiled_code:
void __fastcall setLineColumn(__int64 a1, int a2, char a3)
{
*(_BYTE *)(a2 - 1 + a1 + 16) = a3;
}

canonical_decompiled_code:
void __fastcall func5(__int64 a1, int a2, char a3)
{
*(_BYTE *)(a2 - 1 + a1 + 16) = a3;
}

original_code:
void setLineColumn(Line *l, int c, char contents) {
 l->column[c-1] = contents;
}

canonical_original_code:
void setLineColumn(struct Line *l, int c, char contents) {
 l->column[c-1] = contents;
}

variable_types: c int

variable_types: contents char


lineDiversity

decompiled_code:
__int64 __fastcall lineDiversity(__int64 a1)
{
char v1; // r15
__int64 v2; // rbx
__int64 v3; // r8
int v4; // er14
char v5; // di
int v6; // er13
int v7; // er12
_BYTE *v8; // rdx
char v9; // r11
int v10; // ebp
int v11; // er10
_BYTE *v12; // rcx
char v13; // r9
char v14; // bl
char v15; // si
__int64 result; // rax
int v17; // [rsp+0h] [rbp-68h] BYREF
unsigned int v18; // [rsp+4h] [rbp-64h]
int v19; // [rsp+8h] [rbp-60h]
int v20; // [rsp+Ch] [rbp-5Ch]
int v21; // [rsp+10h] [rbp-58h]
int v22; // [rsp+14h] [rbp-54h]

if ( !a1 )
return 0LL;
v1 = 0;
v2 = getLineColumn(a1);
vectorInit(&v17, 10LL);
v3 = v18;
v4 = v17;
v5 = 0;
v6 = v22;
v7 = v21;
v8 = (_BYTE *)v2;
v9 = 0;
v10 = v20;
v11 = v19;
v12 = (_BYTE *)(v2 + 10);
v13 = 0;
v14 = 0;
v15 = 0;
while ( 2 )
{
switch ( *v8 )
{
case 'B':
++v8;
v5 = 1;
v11 = 1;
if ( v8 != v12 )
continue;
goto LABEL_6;
case 'G':
++v8;
v13 = 1;
v10 = 1;
if ( v8 != v12 )
continue;
goto LABEL_6;
case 'O':
++v8;
v9 = 1;
v7 = 1;
if ( v8 != v12 )
continue;
goto LABEL_6;
case 'R':
++v8;
v1 = 1;
v4 = 1;
if ( v8 != v12 )
continue;
goto LABEL_6;
case 'V':
v14 = 1;
v6 = 1;
goto LABEL_5;
case 'Y':
++v8;
v15 = 1;
v3 = 1LL;
if ( v8 != v12 )
continue;
goto LABEL_6;
default:
LABEL_5:
if ( ++v8 != v12 )
continue;
LABEL_6:
if ( v1 )
v17 = v4;
if ( v15 )
v18 = v3;
if ( v5 )
v19 = v11;
if ( v13 )
v20 = v10;
if ( v9 )
v21 = v7;
if ( v14 )
v22 = v6;
result = vectorSum(&v17, 6LL, v8, v12, v3);
break;
}
return result;
}
}

original_code:
int lineDiversity(Line *line) {
 char *column;
 int i, diversityMap[10];
 if (line == ((void *)0)) {
  return 0;
 }
 column = getLineColumn(line);
 vectorInit(diversityMap, 10, 0);
 for (i=0; i<10; i++) {
  switch(column[i]) {
   case 'R': diversityMap[0] = 1; break;
   case 'Y': diversityMap[1] = 1; break;
   case 'B': diversityMap[2] = 1; break;
   case 'G': diversityMap[3] = 1; break;
   case 'O': diversityMap[4] = 1; break;
   case 'V': diversityMap[5] = 1; break;
  }
 }
 return vectorSum(diversityMap, 6);
}

canonical_original_code:
int lineDiversity(struct Line *line) {
 char *column;
 int i; int diversityMap[10];
 if (line == ((void *)0)) {
  return 0;
 }
 column = getLineColumn(line);
 vectorInit(diversityMap, 10, 0);
 for (i=0; i<10; i++) {
  switch(column[i]) {
   case 'R': diversityMap[0] = 1; break;
   case 'Y': diversityMap[1] = 1; break;
   case 'B': diversityMap[2] = 1; break;
   case 'G': diversityMap[3] = 1; break;
   case 'O': diversityMap[4] = 1; break;
   case 'V': diversityMap[5] = 1; break;
  }
 }
 return vectorSum(diversityMap, 6);
}

variable_types:
column
char *

variable_types:
diversityMap
int [10]


lineFilled

decompiled_code:
__int64 __fastcall lineFilled(__int64 a1)
{
_BYTE *v1; // rax
_BYTE *v2; // rdx

if ( a1 )
{
v1 = (_BYTE *)getLineColumn(a1);
v2 = v1 + 10;
while ( *v1 != 32 )
{
if ( ++v1 == v2 )
return 1LL;
}
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
_BYTE *v1; // rax
_BYTE *v2; // rdx

if ( a1 )
{
v1 = (_BYTE *)func2(a1);
v2 = v1 + 10;
while ( *v1 != 32 )
{
if ( ++v1 == v2 )
return 1LL;
}
}
return 0LL;
}

original_code:
int lineFilled(Line *line) {
 int i;
 char *col;
 if (line == ((void *)0)) {
  return 0;
 }
 col = getLineColumn(line);
 for (i=0; i<10; i++) {
  if (col[i] == ' ') {
   return 0;
  }
 }
 return 1;
}

canonical_original_code:
int lineFilled(struct Line *line) {
 int i;
 char *col;
 if (line == ((void *)0)) {
  return 0;
 }
 col = getLineColumn(line);
 for (i=0; i<10; i++) {
  if (col[i] == ' ') {
   return 0;
  }
 }
 return 1;
}

variable_types:
col
char *


hasAdjacentMonocolors

decompiled_code:
__int64 __fastcall hasAdjacentMonocolors(__int64 a1)
{
__int64 v2; // rax
__int64 v3; // rdi
__int64 v4; // rdi
__int64 result; // rax

v2 = getNextLine(a1);
if ( !v2 || (v3 = v2, !(unsigned int)lineFilled(v2)) || (result = lineDiversity(v3), (_DWORD)result != 1) )
{
v4 = getPreviousLine(a1);
result = 0LL;
if ( v4 )
{
result = lineFilled(v4);
if ( (_DWORD)result )
result = (unsigned int)lineDiversity(v4) == 1;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
__int64 v2; // rax
__int64 v3; // rdi
__int64 v4; // rdi
__int64 result; // rax

v2 = func0(a1);
if ( !v2 || (v3 = v2, !(unsigned int)func7(v2)) || (result = func6(v3), (_DWORD)result != 1) )
{
v4 = func1(a1);
result = 0LL;
if ( v4 )
{
result = func7(v4);
if ( (_DWORD)result )
result = (unsigned int)func6(v4) == 1;
}
}
return result;
}

original_code:
int hasAdjacentMonocolors(Line *line) {
 Line *aux;
 aux = getNextLine(line);
 if(aux != ((void *)0) && lineFilled(aux) && (lineDiversity(aux) == 1))
  return 1;
 aux = getPreviousLine(line);
 if(aux != ((void *)0) && lineFilled(aux) && (lineDiversity(aux) == 1))
  return 1;
 return 0;
}

canonical_original_code:
int hasAdjacentMonocolors(struct Line *line) {
 struct Line *aux;
 aux = getNextLine(line);
 if(aux != ((void *)0) && lineFilled(aux) && (lineDiversity(aux) == 1))
  return 1;
 aux = getPreviousLine(line);
 if(aux != ((void *)0) && lineFilled(aux) && (lineDiversity(aux) == 1))
  return 1;
 return 0;
}


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

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

original_code:
t_location** getLineT_location(Line *l) {
 return (l->pieces);
}

canonical_original_code:
struct t_location **getLineT_location(struct Line *l) {
 return (l->pieces);
}

return_type: struct t_location { int hash_pos; int num_lines; struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location **pieces; int num_t_locations; } **lines; } **


deleteLine

decompiled_code:
void __fastcall deleteLine(void *ptr)
{
void *v2; // rdi

if ( ptr )
{
v2 = (void *)getLineT_location((__int64)ptr);
if ( v2 )
free(v2);
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func10(void *ptr)
{
void *v2; // rdi

if ( ptr )
{
v2 = (void *)func9((__int64)ptr);
if ( v2 )
free(v2);
free(ptr);
}
}

original_code:
void deleteLine(Line *line) {
 if(line != ((void *)0)) {
  if(getLineT_location(line) != ((void *)0))
   free(getLineT_location(line));
  free(line);
 }
}

canonical_original_code:
void deleteLine(struct Line *line) {
 if(line != ((void *)0)) {
  if(getLineT_location(line) != ((void *)0))
   free(getLineT_location(line));
  free(line);
 }
}


getLineTLIndex

decompiled_code:
__int64 __fastcall getLineTLIndex(__int64 a1)
{
return *(unsigned int *)(a1 + 40);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
return *(unsigned int *)(a1 + 40);
}

original_code:
int getLineTLIndex(Line *l) {
 return l->num_t_locations;
}

canonical_original_code:
int getLineTLIndex(struct Line *l) {
 return l->num_t_locations;
}


setLineTLIndex

decompiled_code:
void __fastcall setLineTLIndex(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 40) = a2;
}

canonical_decompiled_code:
void __fastcall func12(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 40) = a2;
}

original_code:
void setLineTLIndex(Line *l, int i) {
 (l->num_t_locations) = i;
}

canonical_original_code:
void setLineTLIndex(struct Line *l, int i) {
 (l->num_t_locations) = i;
}


newLine

decompiled_code:
void newLine()
{
_QWORD *v0; // r12
__int64 v1; // rax

v0 = malloc(0x30uLL);
setNextLine((__int64)v0, 0LL);
setPreviousLine(v0, 0LL);
v1 = getLineColumn((__int64)v0);
vectorCharInit(v1, 10LL);
setLineTLIndex((__int64)v0, 0);
v0[4] = 0LL;
}

original_code:
Line* newLine() {
 Line *l = malloc(sizeof(Line));
 setNextLine(l, ((void *)0));
 setPreviousLine(l, ((void *)0));
 vectorCharInit(getLineColumn(l), 10, ' ');
 setLineTLIndex(l, 0);
 l->pieces = ((void *)0);
 return l;
}

canonical_original_code:
struct Line *newLine() {
 struct Line *l = malloc(sizeof(Line));
 setNextLine(l, ((void *)0));
 setPreviousLine(l, ((void *)0));
 vectorCharInit(getLineColumn(l), 10, ' ');
 setLineTLIndex(l, 0);
 l->pieces = ((void *)0);
 return l;
}


processBuffer

decompiled_code:
__int64 __fastcall processBuffer(__int64 a1, char *a2)
{
char *v2; // rax
unsigned int v3; // er12
char *v4; // rax
unsigned int v5; // er13
char *v6; // rax
__int64 v7; // r13
char *v8; // r14
int v9; // eax
char *v10; // rbx
__int64 v11; // r12
__int64 v12; // rsi
unsigned int v13; // eax
int v14; // ebx
int v15; // eax

v2 = strtok(a2, " \n");
v3 = atoi(v2);
v4 = strtok(0LL, " \n");
v5 = atoi(v4);
v6 = strtok(0LL, " \n");
v7 = newPiece(v3, 0LL, v5, (unsigned int)*v6);
v8 = (char *)getPieceColumns(v7);
getColumnSpan(v7);
v9 = getColumnSpan(v7);
if ( v9 > 0 )
{
v10 = &v8[4 * v9];
v11 = (__int64)&v10[-4 * (v9 - 1) - 4];
do
{
v12 = *((unsigned int *)v10 - 1);
v10 -= 4;
*(_DWORD *)v10 = getGameAreaColumnHeight(a1, v12);
}
while ( v10 != (char *)v11 );
}
v13 = getColumnSpan(v7);
v14 = vectorMax(v8, v13);
v15 = getLineSpan(v7);
setPieceLine(v7, (unsigned int)(v14 + v15));
free(v8);
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, char *a2)
{
char *v2; // rax
unsigned int v3; // er12
char *v4; // rax
unsigned int v5; // er13
char *v6; // rax
__int64 v7; // r13
char *v8; // r14
int v9; // eax
char *v10; // rbx
__int64 v11; // r12
__int64 v12; // rsi
unsigned int v13; // eax
int v14; // ebx
int v15; // eax

v2 = strtok(a2, " \n");
v3 = atoi(v2);
v4 = strtok(0LL, " \n");
v5 = atoi(v4);
v6 = strtok(0LL, " \n");
v7 = newPiece(v3, 0LL, v5, (unsigned int)*v6);
v8 = (char *)getPieceColumns(v7);
getColumnSpan(v7);
v9 = getColumnSpan(v7);
if ( v9 > 0 )
{
v10 = &v8[4 * v9];
v11 = (__int64)&v10[-4 * (v9 - 1) - 4];
do
{
v12 = *((unsigned int *)v10 - 1);
v10 -= 4;
*(_DWORD *)v10 = getGameAreaColumnHeight(a1, v12);
}
while ( v10 != (char *)v11 );
}
v13 = getColumnSpan(v7);
v14 = vectorMax(v8, v13);
v15 = getLineSpan(v7);
setPieceLine(v7, (unsigned int)(v14 + v15));
free(v8);
return v7;
}

original_code:
tetromino* processBuffer(GameArea *gameArea, char *buffer) {
 tetromino *t;
 int piece_type;
 int *piece_columns, num_cols;
 int piece_column;
 char piece_color;
 piece_type = atoi(strtok(buffer, " \n\0"));
 piece_column = atoi(strtok(((void *)0), " \n\0"));
 piece_color = *strtok(((void *)0), " \n\0");
 t = newPiece(piece_type, 0, piece_column, piece_color);
 piece_columns = getPieceColumns(t);
 num_cols = getColumnSpan(t);
 for(num_cols = getColumnSpan(t); num_cols > 0; num_cols--) {
  piece_columns[num_cols-1] = getGameAreaColumnHeight(gameArea, piece_columns[num_cols-1]);
 }
 setPieceLine(t, vectorMax(piece_columns, getColumnSpan(t)) + getLineSpan(t));
 free(piece_columns);
 return t;
}

canonical_original_code:
struct tetromino *processBuffer(struct GameArea *gameArea, char *buffer) {
 struct tetromino *t;
 int piece_type;
 int *piece_columns; int num_cols;
 int piece_column;
 char piece_color;
 piece_type = atoi(strtok(buffer, " \n\0"));
 piece_column = atoi(strtok(((void *)0), " \n\0"));
 piece_color = *strtok(((void *)0), " \n\0");
 t = newPiece(piece_type, 0, piece_column, piece_color);
 piece_columns = getPieceColumns(t);
 num_cols = getColumnSpan(t);
 for(num_cols = getColumnSpan(t); num_cols > 0; num_cols--) {
  piece_columns[num_cols-1] = getGameAreaColumnHeight(gameArea, piece_columns[num_cols-1]);
 }
 setPieceLine(t, vectorMax(piece_columns, getColumnSpan(t)) + getLineSpan(t));
 free(piece_columns);
 return t;
}

variable_types:
buffer
char *

variable_types: struct tetromino { struct position { int line; int column; } position; int type; char color; } *


gravity

decompiled_code:
void __fastcall gravity(__int64 a1, __int64 a2)
{
int v3; // er15
char *v4; // r14
char *v5; // rbx
int v6; // eax
char *v7; // rdi
int v8; // eax

v3 = getFloorSize(a2);
v4 = (char *)getFloor(a2);
while ( v3 <= 0 )
{
LABEL_7:
v8 = getPieceLine(a2);
setPieceLine(a2, (unsigned int)(v8 - 1));
}
v5 = v4;
while ( (unsigned __int8)getPosition(a1, v5) == 32 )
{
v6 = getLine(v5);
v7 = v5;
v5 += 8;
setLine(v7, (unsigned int)(v6 - 1));
if ( v5 == &v4[8 * (v3 - 1) + 8] )
goto LABEL_7;
}
free(v4);
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1, __int64 a2)
{
int v3; // er15
char *v4; // r14
char *v5; // rbx
int v6; // eax
char *v7; // rdi
int v8; // eax

v3 = getFloorSize(a2);
v4 = (char *)getFloor(a2);
while ( v3 <= 0 )
{
LABEL_7:
v8 = getPieceLine(a2);
setPieceLine(a2, (unsigned int)(v8 - 1));
}
v5 = v4;
while ( (unsigned __int8)getPosition(a1, v5) == 32 )
{
v6 = getLine(v5);
v7 = v5;
v5 += 8;
setLine(v7, (unsigned int)(v6 - 1));
if ( v5 == &v4[8 * (v3 - 1) + 8] )
goto LABEL_7;
}
free(v4);
}

original_code:
void gravity(GameArea *gameArea, tetromino *t) {
 int i, floor_size;
 position *floor;
 floor_size = getFloorSize(t);
 floor = getFloor(t);
 while(1) {
  for (i=0; i<floor_size; i++) {
   if(getPosition(gameArea, &floor[i]) != ' ') {
    free(floor);
    return;
   }
   else {
    setLine(&floor[i], getLine(&floor[i])-1);
   }
  }
  setPieceLine(t, getPieceLine(t) - 1);
 }
 return;
}

canonical_original_code:
void gravity(struct GameArea *gameArea, struct tetromino *t) {
 int i; int floor_size;
 struct position *floor;
 floor_size = getFloorSize(t);
 floor = getFloor(t);
 while(1) {
  for (i=0; i<floor_size; i++) {
   if(getPosition(gameArea, &floor[i]) != ' ') {
    free(floor);
    return;
   }
   else {
    setLine(&floor[i], getLine(&floor[i])-1);
   }
  }
  setPieceLine(t, getPieceLine(t) - 1);
 }
 return;
}

variable_types: struct position { int line; int column; } *


deleteFilledLines

decompiled_code:
void __fastcall deleteFilledLines(__int64 a1, __int64 a2)
{
_DWORD *v2; // r14
int v3; // eax
_DWORD *v4; // rbx
__int64 v5; // r13
__int64 v6; // rbp
__int64 v7; // rsi

v2 = (_DWORD *)getPieceLines(a2);
v3 = getLineSpan(a2);
if ( v3 > 0 )
{
v4 = v2;
v5 = (__int64)&v2[v3 - 1 + 1];
while ( 1 )
{
v6 = getGameLine(a1, (unsigned int)*v4);
if ( !(unsigned int)lineFilled(v6) )
goto LABEL_3;
if ( (unsigned int)hasAdjacentMonocolors(v6) )
{
v7 = 3LL;
if ( (unsigned int)lineDiversity(v6) != 1 )
goto LABEL_3;
LABEL_7:
++v4;
increaseScore(a1, v7);
eraseLine(a1, (unsigned int)*(v4 - 1));
if ( v4 == (_DWORD *)v5 )
break;
}
else
{
v7 = 1LL;
if ( (unsigned int)lineDiversity(v6) != 1 )
goto LABEL_7;
increaseScore(a1, 3LL);
eraseLine(a1, (unsigned int)(*v4 + 1));
eraseLine(a1, (unsigned int)*v4);
eraseLine(a1, (unsigned int)(*v4 - 1));
LABEL_3:
if ( ++v4 == (_DWORD *)v5 )
break;
}
}
}
free(v2);
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1, __int64 a2)
{
_DWORD *v2; // r14
int v3; // eax
_DWORD *v4; // rbx
__int64 v5; // r13
__int64 v6; // rbp
__int64 v7; // rsi

v2 = (_DWORD *)getPieceLines(a2);
v3 = getLineSpan(a2);
if ( v3 > 0 )
{
v4 = v2;
v5 = (__int64)&v2[v3 - 1 + 1];
while ( 1 )
{
v6 = getGameLine(a1, (unsigned int)*v4);
if ( !(unsigned int)lineFilled(v6) )
goto LABEL_3;
if ( (unsigned int)hasAdjacentMonocolors(v6) )
{
v7 = 3LL;
if ( (unsigned int)lineDiversity(v6) != 1 )
goto LABEL_3;
LABEL_7:
++v4;
increaseScore(a1, v7);
eraseLine(a1, (unsigned int)*(v4 - 1));
if ( v4 == (_DWORD *)v5 )
break;
}
else
{
v7 = 1LL;
if ( (unsigned int)lineDiversity(v6) != 1 )
goto LABEL_7;
increaseScore(a1, 3LL);
eraseLine(a1, (unsigned int)(*v4 + 1));
eraseLine(a1, (unsigned int)*v4);
eraseLine(a1, (unsigned int)(*v4 - 1));
LABEL_3:
if ( ++v4 == (_DWORD *)v5 )
break;
}
}
}
free(v2);
}

original_code:
void deleteFilledLines(GameArea *gameArea, tetromino *t) {
 int* lines = getPieceLines(t);
 int linespan = getLineSpan(t);
 int i;
 Line* line;
 for(i=0; i<linespan; i++) {
  line = getGameLine(gameArea, lines[i]);
  if(lineFilled(line)) {
   if(hasAdjacentMonocolors(line)) {
    if(lineDiversity(line) == 1) {
     increaseScore(gameArea, 3);
     eraseLine(gameArea, lines[i]);
    }
   }
   else {
    if(lineDiversity(line) == 1) {
     increaseScore(gameArea, 3);
     eraseLine(gameArea, lines[i]+1);
     eraseLine(gameArea, lines[i]);
     eraseLine(gameArea, lines[i]-1);
    }
    else {
     increaseScore(gameArea, 1);
     eraseLine(gameArea, lines[i]);
    }
   }
  }
 }
 free(lines);
 return;
}

canonical_original_code:
void deleteFilledLines(struct GameArea *gameArea, struct tetromino *t) {
 int *lines = getPieceLines(t);
 int linespan = getLineSpan(t);
 int i;
 struct Line *line;
 for(i=0; i<linespan; i++) {
  line = getGameLine(gameArea, lines[i]);
  if(lineFilled(line)) {
   if(hasAdjacentMonocolors(line)) {
    if(lineDiversity(line) == 1) {
     increaseScore(gameArea, 3);
     eraseLine(gameArea, lines[i]);
    }
   }
   else {
    if(lineDiversity(line) == 1) {
     increaseScore(gameArea, 3);
     eraseLine(gameArea, lines[i]+1);
     eraseLine(gameArea, lines[i]);
     eraseLine(gameArea, lines[i]-1);
    }
    else {
     increaseScore(gameArea, 1);
     eraseLine(gameArea, lines[i]);
    }
   }
  }
 }
 free(lines);
 return;
}

variable_types:
lines
int *

variable_types: linespan int


readInput

decompiled_code:
int __fastcall readInput(__int64 a1)
{
int result; // eax
int v2; // er13
int v3; // er12
__int64 v4; // rbp
char v5[56]; // [rsp+0h] [rbp-38h] BYREF

fgets(v5, 16, stdin);
result = atoi(v5);
if ( result > 0 )
{
v2 = result;
v3 = 0;
do
{
++v3;
fgets(v5, 16, stdin);
v4 = processBuffer(a1, v5);
gravity(a1, v4);
insertPiece(a1, v4);
deleteFilledLines(a1, v4);
result = deletePiece(v4);
}
while ( v2 != v3 );
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
int result; // eax
int v2; // er13
int v3; // er12
__int64 v4; // rbp
char v5[56]; // [rsp+0h] [rbp-38h] BYREF

fgets(v5, 16, stdin);
result = atoi(v5);
if ( result > 0 )
{
v2 = result;
v3 = 0;
do
{
++v3;
fgets(v5, 16, stdin);
v4 = func0(a1, v5);
func1(a1, v4);
insertPiece(a1, v4);
func2(a1, v4);
result = deletePiece(v4);
}
while ( v2 != v3 );
}
return result;
}

original_code:
void readInput(GameArea *gameArea) {
 int i, num_pieces;
 char buffer[16];
 tetromino *piece;
 fgets(buffer, 16, stdin);
 num_pieces = atoi(buffer);
 for(i=0; i<num_pieces; i++) {
  fgets(buffer, 16, stdin);
  piece = processBuffer(gameArea, buffer);
  gravity(gameArea, piece);
  insertPiece(gameArea, piece);
  deleteFilledLines(gameArea, piece);
  deletePiece(piece);
 }
 return;
}

canonical_original_code:
void readInput(struct GameArea *gameArea) {
 int i; int num_pieces;
 char buffer[16];
 struct tetromino *piece;
 fgets(buffer, 16, stdin);
 num_pieces = atoi(buffer);
 for(i=0; i<num_pieces; i++) {
  fgets(buffer, 16, stdin);
  piece = processBuffer(gameArea, buffer);
  gravity(gameArea, piece);
  insertPiece(gameArea, piece);
  deleteFilledLines(gameArea, piece);
  deletePiece(piece);
 }
 return;
}

variable_types: i int

variable_types:
buffer
char [16]


writeOutput

decompiled_code:
int __fastcall writeOutput(__int64 a1)
{
__int64 v1; // rbp
int v2; // er12
unsigned int v3; // eax
unsigned int v4; // eax
__int64 v5; // rbx
int v6; // edi
int v7; // ebx
unsigned int v8; // er13
__int64 v9; // rax
unsigned int v10; // eax
int *v11; // rbp
int v12; // er15
char v13; // al
double v15; // xmm0_8
__m128d v16; // xmm3
__m128d v17; // xmm1
__int64 v18; // rbp
int v19; // ebx
__int64 v20; // rbx
int v21; // edi

v1 = getGameAreaLast();
v2 = getGameAreaNumLines(a1);
v3 = getGameAreaNumLines(a1);
printf("%d\n", v3);
v4 = getGameAreaScore(a1);
printf("%d\n", v4);
putchar(10);
if ( v2 > 0 )
{
do
{
v5 = 0LL;
putchar(124);
do
{
v6 = *(char *)(getLineColumn(v1) + v5++);
putchar(v6);
}
while ( v5 != 10 );
printf("| %d\n", (unsigned int)v2);
v1 = getPreviousLine(v1);
--v2;
}
while ( v2 );
}
v7 = 10;
putchar(32);
do
{
putchar(45);
--v7;
}
while ( v7 );
v8 = 0;
puts("\n");
v9 = getGameAreaPieceCounts(a1);
v10 = vectorSum(v9, 30LL);
printf("%d\n", v10);
v11 = (int *)getGameAreaPieceCounts(a1);
do
{
if ( *v11 > 0 )
{
v12 = 0;
do
{
++v12;
v13 = int2color(v8 % 6 + 1);
printf("%d %c\n", v8 / 6 + 1, (unsigned int)v13);
}
while ( *v11 > v12 );
}
++v8;
++v11;
}
while ( v8 != 30 );
putchar(10);
if ( (unsigned int)getGameAreaNumDeletedLines(a1) )
{
v15 = (double)(int)getGameAreaNumDeletedLines(a1) * 0.5;
if ( COERCE_DOUBLE(*(_QWORD *)&v15 & LC8) < 4.503599627370496e15 )
{
v16.m128d_f64[0] = v15;
v17.m128d_f64[0] = (double)(int)v15;
*(_QWORD *)&v15 = COERCE_UNSIGNED_INT64(v17.m128d_f64[0] + COERCE_DOUBLE(*(_OWORD *)&_mm_cmpgt_sd(v16, v17) & LC9)) | ~LC8 & *(_QWORD *)&v15;
}
v18 = getGameAreaDeletedFirst(a1);
v19 = (int)v15 - 1;
if ( (int)v15 > 1 )
{
do
{
v18 = getNextLine(v18);
--v19;
}
while ( v19 );
}
v20 = 0LL;
do
{
if ( *(_BYTE *)(getLineColumn(v18) + v20) == 32 )
break;
v21 = *(char *)(getLineColumn(v18) + v20++);
putchar(v21);
}
while ( v20 != 10 );
}
else
{
printf("No eliminations");
}
return putchar(10);
}

canonical_decompiled_code:
int __fastcall func4(__int64 a1)
{
__int64 v1; // rbp
int v2; // er12
unsigned int v3; // eax
unsigned int v4; // eax
__int64 v5; // rbx
int v6; // edi
int v7; // ebx
unsigned int v8; // er13
__int64 v9; // rax
unsigned int v10; // eax
int *v11; // rbp
int v12; // er15
char v13; // al
double v15; // xmm0_8
__m128d v16; // xmm3
__m128d v17; // xmm1
__int64 v18; // rbp
int v19; // ebx
__int64 v20; // rbx
int v21; // edi

v1 = getGameAreaLast();
v2 = getGameAreaNumLines(a1);
v3 = getGameAreaNumLines(a1);
printf("%d\n", v3);
v4 = getGameAreaScore(a1);
printf("%d\n", v4);
putchar(10);
if ( v2 > 0 )
{
do
{
v5 = 0LL;
putchar(124);
do
{
v6 = *(char *)(getLineColumn(v1) + v5++);
putchar(v6);
}
while ( v5 != 10 );
printf("| %d\n", (unsigned int)v2);
v1 = getPreviousLine(v1);
--v2;
}
while ( v2 );
}
v7 = 10;
putchar(32);
do
{
putchar(45);
--v7;
}
while ( v7 );
v8 = 0;
puts("\n");
v9 = getGameAreaPieceCounts(a1);
v10 = vectorSum(v9, 30LL);
printf("%d\n", v10);
v11 = (int *)getGameAreaPieceCounts(a1);
do
{
if ( *v11 > 0 )
{
v12 = 0;
do
{
++v12;
v13 = int2color(v8 % 6 + 1);
printf("%d %c\n", v8 / 6 + 1, (unsigned int)v13);
}
while ( *v11 > v12 );
}
++v8;
++v11;
}
while ( v8 != 30 );
putchar(10);
if ( (unsigned int)getGameAreaNumDeletedLines(a1) )
{
v15 = (double)(int)getGameAreaNumDeletedLines(a1) * 0.5;
if ( COERCE_DOUBLE(*(_QWORD *)&v15 & LC8) < 4.503599627370496e15 )
{
v16.m128d_f64[0] = v15;
v17.m128d_f64[0] = (double)(int)v15;
*(_QWORD *)&v15 = COERCE_UNSIGNED_INT64(v17.m128d_f64[0] + COERCE_DOUBLE(*(_OWORD *)&_mm_cmpgt_sd(v16, v17) & LC9)) | ~LC8 & *(_QWORD *)&v15;
}
v18 = getGameAreaDeletedFirst(a1);
v19 = (int)v15 - 1;
if ( (int)v15 > 1 )
{
do
{
v18 = getNextLine(v18);
--v19;
}
while ( v19 );
}
v20 = 0LL;
do
{
if ( *(_BYTE *)(getLineColumn(v18) + v20) == 32 )
break;
v21 = *(char *)(getLineColumn(v18) + v20++);
putchar(v21);
}
while ( v20 != 10 );
}
else
{
printf("No eliminations");
}
return putchar(10);
}

original_code:
void writeOutput(GameArea *gameArea) {
 int i, j, num_lines, *num_pieces, median, color, type;
 Line* line = getGameAreaLast(gameArea);
 num_lines = getGameAreaNumLines(gameArea);
 printf("%d\n", getGameAreaNumLines(gameArea));
 printf("%d\n", getGameAreaScore(gameArea));
 printf("\n");
 for (i=num_lines; i>=1; i--) {
  printf("|");
  for (j=0; j<10; j++) {
   printf("%c", getLineColumn(line)[j]);
  }
  printf("| %d\n", i);
  line = getPreviousLine(line);
 }
 printf(" ");
 for(i=0; i<10; i++) {
  printf("-");
 }
 printf("\n\n");
 printf("%d\n", vectorSum(getGameAreaPieceCounts(gameArea), 5*6));
 num_pieces = getGameAreaPieceCounts(gameArea);
 for(i=0; i<(6*5); i++) {
  color = (i % 6) + 1;
  type = (i / 6) + 1;
  for(j=0; j<num_pieces[i]; j++) {
   printf("%d %c\n", type, int2color(color));
  }
 }
 printf("\n");
 if(getGameAreaNumDeletedLines(gameArea) == 0)
  printf("No eliminations");
 else {
  median = (int)ceil((double)getGameAreaNumDeletedLines(gameArea)/2);
  line = getGameAreaDeletedFirst(gameArea);
  while((median--) > 1)
   line = getNextLine(line);
  for(i=0; i<10 && getLineColumn(line)[i] != ' '; i++) {
   printf("%c", getLineColumn(line)[i]);
  }
 }
 printf("\n");
 return;
}

canonical_original_code:
void writeOutput(struct GameArea *gameArea) {
 int i; int j; int num_lines; int *num_pieces; int median; int color; int type;
 struct Line *line = getGameAreaLast(gameArea);
 num_lines = getGameAreaNumLines(gameArea);
 printf("%d\n", getGameAreaNumLines(gameArea));
 printf("%d\n", getGameAreaScore(gameArea));
 printf("\n");
 for (i=num_lines; i>=1; i--) {
  printf("|");
  for (j=0; j<10; j++) {
   printf("%c", getLineColumn(line)[j]);
  }
  printf("| %d\n", i);
  line = getPreviousLine(line);
 }
 printf(" ");
 for(i=0; i<10; i++) {
  printf("-");
 }
 printf("\n\n");
 printf("%d\n", vectorSum(getGameAreaPieceCounts(gameArea), 5*6));
 num_pieces = getGameAreaPieceCounts(gameArea);
 for(i=0; i<(6*5); i++) {
  color = (i % 6) + 1;
  type = (i / 6) + 1;
  for(j=0; j<num_pieces[i]; j++) {
   printf("%d %c\n", type, int2color(color));
  }
 }
 printf("\n");
 if(getGameAreaNumDeletedLines(gameArea) == 0)
  printf("No eliminations");
 else {
  median = (int)ceil((double)getGameAreaNumDeletedLines(gameArea)/2);
  line = getGameAreaDeletedFirst(gameArea);
  while((median--) > 1)
   line = getNextLine(line);
  for(i=0; i<10 && getLineColumn(line)[i] != ' '; i++) {
   printf("%c", getLineColumn(line)[i]);
  }
 }
 printf("\n");
 return;
}

variable_types: j int

variable_types: median int

variable_types: color int

variable_types: type int

variable_types: struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *


main

canonical_name: main

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

v3 = newGameArea(argc, argv, envp);
readInput(v3);
writeOutput(v3);
clearGameArea(v3);
return 0;
}

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

v3 = newGameArea(argc, argv, envp);
func3(v3);
func4(v3);
clearGameArea(v3);
return 0;
}

original_code:
int main() {
 GameArea *gameArea = newGameArea();
 readInput(gameArea);
 writeOutput(gameArea);
 clearGameArea(gameArea);
 return 0;
}

canonical_original_code:
int main() {
 struct GameArea *gameArea = newGameArea();
 readInput(gameArea);
 writeOutput(gameArea);
 clearGameArea(gameArea);
 return 0;
}

variable_types: struct GameArea { struct Line { struct Line *previous; struct Line *next; char column[10]; struct t_location { int hash_pos; int num_lines; struct Line **lines; } **pieces; int num_t_locations; } *gameLineFirst; struct Line *gameLineLast; int num_lines; struct HeightMap { int columns[10]; } *heightMap; struct Line *deletedLinesFirst; struct Line *deletedLinesLast; int num_deleted_lines; int score; int *piece_count; } *


getLine

decompiled_code:
__int64 __fastcall getLine(unsigned int *a1)
{
return *a1;
}

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

original_code:
int getLine(position *pos) {
 return pos->line;
}

canonical_original_code:
int getLine(struct position *pos) {
 return pos->line;
}


getColumn

decompiled_code:
__int64 __fastcall getColumn(__int64 a1)
{
return *(unsigned int *)(a1 + 4);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return *(unsigned int *)(a1 + 4);
}

original_code:
int getColumn(position *pos) {
 return pos->column;
}

canonical_original_code:
int getColumn(struct position *pos) {
 return pos->column;
}


setColumn

decompiled_code:
void __fastcall setColumn(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 4) = a2;
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1, int a2)
{
*(_DWORD *)(a1 + 4) = a2;
}

original_code:
void setColumn(position *pos, int column) {
 pos->column = column;
}

canonical_original_code:
void setColumn(struct position *pos, int column) {
 pos->column = column;
}

variable_types: column int


DoRotateRR

repo: joaomlneto/lan-chat

original_code:
static void DoRotateRR(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* node0 = node->m_parent;
    struct AvlTreeNode* node1 = node;
    struct AvlTreeNode* node2 = node->m_child2;
    node1->m_child2 = node2->m_child1;
    node1->m_child2->m_parent = node1;
    node2->m_child1 = node1;
    node2->m_child1->m_parent = node2;
    DoUpdateHeight(tree, node1);
    DoUpdateHeight(tree, node2);
    if(node0->m_child1 == node1)
    {
        node0->m_child1 = node2;
        node0->m_child1->m_parent = node0;
        return;
    }
    if(node0->m_child2 == node1)
    {
        node0->m_child2 = node2;
        node0->m_child2->m_parent = node0;
        return;
    }
    tree->m_rootNode = node2;
    tree->m_rootNode->m_parent = tree->m_nullNode;
    return;
}

canonical_original_code:
static void DoRotateRR(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *node0 = node->m_parent;
    struct AvlTreeNode *node1 = node;
    struct AvlTreeNode *node2 = node->m_child2;
    node1->m_child2 = node2->m_child1;
    node1->m_child2->m_parent = node1;
    node2->m_child1 = node1;
    node2->m_child1->m_parent = node2;
    DoUpdateHeight(tree, node1);
    DoUpdateHeight(tree, node2);
    if(node0->m_child1 == node1)
    {
        node0->m_child1 = node2;
        node0->m_child1->m_parent = node0;
        return;
    }
    if(node0->m_child2 == node1)
    {
        node0->m_child2 = node2;
        node0->m_child2->m_parent = node0;
        return;
    }
    tree->m_rootNode = node2;
    tree->m_rootNode->m_parent = tree->m_nullNode;
    return;
}

variable_types: struct AvlTree { int (*m_dataComparator)(void *data1, void *data2); int m_keySize; int m_dataSize; int m_avlTreeSize; struct AvlTreeNode { void *m_key; void *m_data; int m_height; struct AvlTreeNode *m_child1; struct AvlTreeNode *m_child2; struct AvlTreeNode *m_parent; } *m_rootNode; struct AvlTreeNode *m_nullNode; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; } *

variable_types:
node
struct AvlTreeNode *

user_defined_types: struct AvlTree { int (*m_dataComparator)(void *data1, void *data2); int m_keySize; int m_dataSize; int m_avlTreeSize; struct AvlTreeNode *m_rootNode; struct AvlTreeNode *m_nullNode; union pthread_mutex_t mutex; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


DoRotateLL

original_code:
static void DoRotateLL(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* node0 = node->m_parent;
    struct AvlTreeNode* node1 = node;
    struct AvlTreeNode* node2 = node->m_child1;
    node1->m_child1 = node2->m_child2;
    node1->m_child1->m_parent = node1;
    node2->m_child2 = node1;
    node2->m_child2->m_parent = node2;
    DoUpdateHeight(tree, node1);
    DoUpdateHeight(tree, node2);
    if(node0->m_child1 == node1)
    {
        node0->m_child1 = node2;
        node0->m_child1->m_parent = node0;
        return;
    }
    if(node0->m_child2 == node1)
    {
        node0->m_child2 = node2;
        node0->m_child2->m_parent = node0;
        return;
    }
    tree->m_rootNode = node2;
    tree->m_rootNode->m_parent = tree->m_nullNode;
    return;
}

canonical_original_code:
static void DoRotateLL(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *node0 = node->m_parent;
    struct AvlTreeNode *node1 = node;
    struct AvlTreeNode *node2 = node->m_child1;
    node1->m_child1 = node2->m_child2;
    node1->m_child1->m_parent = node1;
    node2->m_child2 = node1;
    node2->m_child2->m_parent = node2;
    DoUpdateHeight(tree, node1);
    DoUpdateHeight(tree, node2);
    if(node0->m_child1 == node1)
    {
        node0->m_child1 = node2;
        node0->m_child1->m_parent = node0;
        return;
    }
    if(node0->m_child2 == node1)
    {
        node0->m_child2 = node2;
        node0->m_child2->m_parent = node0;
        return;
    }
    tree->m_rootNode = node2;
    tree->m_rootNode->m_parent = tree->m_nullNode;
    return;
}

variable_types: struct AvlTreeNode { void *m_key; void *m_data; int m_height; struct AvlTreeNode *m_child1; struct AvlTreeNode *m_child2; struct AvlTreeNode *m_parent; } *

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }


DoRotateLR

decompiled_code:
void __fastcall DoRotateLR(__int64 a1, __int64 a2)
{
DoRotateRR(a1, *(_QWORD *)(a2 + 24));
DoRotateLL(a1, a2);
}

original_code:
static void DoRotateLR(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* node1 = node;
    struct AvlTreeNode* node2 = node->m_child1;
    DoRotateRR(tree, node2);
    DoRotateLL(tree, node1);
    return;
}

canonical_original_code:
static void DoRotateLR(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *node1 = node;
    struct AvlTreeNode *node2 = node->m_child1;
    DoRotateRR(tree, node2);
    DoRotateLL(tree, node1);
    return;
}

user_defined_types: struct AvlTreeNode { void *m_key; void *m_data; int m_height; struct AvlTreeNode *m_child1; struct AvlTreeNode *m_child2; struct AvlTreeNode *m_parent; }


DoRotateRL

decompiled_code:
void __fastcall DoRotateRL(__int64 a1, __int64 a2)
{
DoRotateLL(a1, *(_QWORD *)(a2 + 32));
DoRotateRR(a1, a2);
}

original_code:
static void DoRotateRL(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* node1 = node;
    struct AvlTreeNode* node2 = node->m_child2;
    DoRotateLL(tree, node2);
    DoRotateRR(tree, node1);
    return;
}

canonical_original_code:
static void DoRotateRL(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *node1 = node;
    struct AvlTreeNode *node2 = node->m_child2;
    DoRotateLL(tree, node2);
    DoRotateRR(tree, node1);
    return;
}


DoInsertNode

decompiled_code:
void __fastcall DoInsertNode(__int64 a1, _QWORD *a2, _QWORD *a3)
{
__int64 v5; // rsi

if ( (*(int (__fastcall **)(_QWORD, _QWORD))a1)(*a3, *a2) < 0 )
{
v5 = a2[3];
if ( v5 != *(_QWORD *)(a1 + 32) )
goto LABEL_3;
a2[3] = a3;
a3[5] = a2;
DoUpdateHeight_isra_0(*(_QWORD *)(a1 + 32), (__int64)a2);
}
else
{
v5 = a2[4];
if ( v5 != *(_QWORD *)(a1 + 32) )
{
LABEL_3:
DoInsertNode(a1, v5, a3);
DoUpdateHeight_isra_0(*(_QWORD *)(a1 + 32), (__int64)a2);
return;
}
a2[4] = a3;
a3[5] = a2;
DoUpdateHeight_isra_0(*(_QWORD *)(a1 + 32), (__int64)a2);
}
}

original_code:
static void DoInsertNode(
        struct AvlTree* tree,
        struct AvlTreeNode* root,
        struct AvlTreeNode* node)
{
    if(tree->m_dataComparator(node->m_key, root->m_key) < 0)
    {
        if(root->m_child1 != tree->m_nullNode)
            DoInsertNode(tree, root->m_child1, node);
        else
        {
            root->m_child1 = node;
            root->m_child1->m_parent = root;
        }
        DoUpdateHeight(tree, root);
    }
    else
    {
        if(root->m_child2 != tree->m_nullNode)
            DoInsertNode(tree, root->m_child2, node);
        else
        {
            root->m_child2 = node;
            root->m_child2->m_parent = root;
        }
        DoUpdateHeight(tree, root);
    }
    return;
}

canonical_original_code:
static void DoInsertNode(struct AvlTree *tree, struct AvlTreeNode *root, struct AvlTreeNode *node)
{
    if(tree->m_dataComparator(node->m_key, root->m_key) < 0)
    {
        if(root->m_child1 != tree->m_nullNode)
            DoInsertNode(tree, root->m_child1, node);
        else
        {
            root->m_child1 = node;
            root->m_child1->m_parent = root;
        }
        DoUpdateHeight(tree, root);
    }
    else
    {
        if(root->m_child2 != tree->m_nullNode)
            DoInsertNode(tree, root->m_child2, node);
        else
        {
            root->m_child2 = node;
            root->m_child2->m_parent = root;
        }
        DoUpdateHeight(tree, root);
    }
    return;
}

variable_types:
root
struct AvlTreeNode *


decompiled_code:
void __fastcall avl_destroy(void *ptr)
{
DoDestroyNode_isra_0(*((_QWORD *)ptr + 4), *((_QWORD *)ptr + 3));
free(*((void **)ptr + 4));
pthread_mutex_destroy((pthread_mutex_t *)ptr + 1);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func9(void *ptr)
{
func8(*((_QWORD *)ptr + 4), *((_QWORD *)ptr + 3));
free(*((void **)ptr + 4));
pthread_mutex_destroy((pthread_mutex_t *)ptr + 1);
free(ptr);
}

original_code:
void avl_destroy(avltree_t* tree)
{
    DoDestroyNode(tree, tree->m_rootNode);
    free(tree->m_nullNode);
    pthread_mutex_destroy(&tree->mutex);
    free(tree);
    return;
}

canonical_original_code:
void avl_destroy(struct AvlTree *tree)
{
    DoDestroyNode(tree, tree->m_rootNode);
    free(tree->m_nullNode);
    pthread_mutex_destroy(&tree->mutex);
    free(tree);
    return;
}


AvlTreeGetSize

decompiled_code:
__int64 __fastcall AvlTreeGetSize(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

original_code:
int AvlTreeGetSize(struct AvlTree* tree)
{
    return tree->m_avlTreeSize;
}

canonical_original_code:
int AvlTreeGetSize(struct AvlTree *tree)
{
    return tree->m_avlTreeSize;
}


AvlTreeNodeData

decompiled_code:
__int64 __fastcall AvlTreeNodeData(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

original_code:
void* AvlTreeNodeData(struct AvlTreeNode* node)
{
    return node->m_data;
}

canonical_original_code:
void *AvlTreeNodeData(struct AvlTreeNode *node)
{
    return node->m_data;
}

return_type: void *


decompiled_code:
__int64 __fastcall avl_insert(pthread_mutex_t *a1, __int64 a2, __int64 a3)
{
_QWORD *v4; // rax
__int64 v5; // r12
struct __pthread_internal_list *v6; // rax
struct __pthread_internal_list *v7; // rsi

v4 = malloc(0x30uLL);
v4[1] = a3;
v5 = (__int64)v4;
*v4 = a2;
v6 = a1->__list.__next;
*(_DWORD *)(v5 + 16) = 0;
*(_QWORD *)(v5 + 24) = v6;
*(_QWORD *)(v5 + 32) = v6;
*(_QWORD *)(v5 + 40) = v6;
pthread_mutex_lock(a1 + 1);
v7 = a1->__list.__prev;
if ( v7 == a1->__list.__next )
{
a1->__list.__prev = (struct __pthread_internal_list *)v5;
}
else
{
DoInsertNode((__int64)a1, v7, (_QWORD *)v5);
DoRebalance((__int64)a1, v5);
}
++a1->__kind;
pthread_mutex_unlock(a1 + 1);
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func12(pthread_mutex_t *a1, __int64 a2, __int64 a3)
{
_QWORD *v4; // rax
__int64 v5; // r12
struct __pthread_internal_list *v6; // rax
struct __pthread_internal_list *v7; // rsi

v4 = malloc(0x30uLL);
v4[1] = a3;
v5 = (__int64)v4;
*v4 = a2;
v6 = a1->__list.__next;
*(_DWORD *)(v5 + 16) = 0;
*(_QWORD *)(v5 + 24) = v6;
*(_QWORD *)(v5 + 32) = v6;
*(_QWORD *)(v5 + 40) = v6;
pthread_mutex_lock(a1 + 1);
v7 = a1->__list.__prev;
if ( v7 == a1->__list.__next )
{
a1->__list.__prev = (struct __pthread_internal_list *)v5;
}
else
{
func7((__int64)a1, v7, (_QWORD *)v5);
func6((__int64)a1, v5);
}
++a1->__kind;
pthread_mutex_unlock(a1 + 1);
return v5;
}

original_code:
struct AvlTreeNode* avl_insert(
        struct AvlTree* tree,
        void* key,
        void* data)
{
    struct AvlTreeNode* newNode = malloc(sizeof(struct AvlTreeNode));
    newNode->m_key = key;
    newNode->m_data = data;
    newNode->m_child1 = tree->m_nullNode;
    newNode->m_child2 = tree->m_nullNode;
    newNode->m_parent = tree->m_nullNode;
    newNode->m_height = 0;
 pthread_mutex_lock(&tree->mutex);
    if(tree->m_rootNode == tree->m_nullNode)
    {
        tree->m_rootNode = newNode;
    }
    else
    {
        DoInsertNode(tree, tree->m_rootNode, newNode);
        DoRebalance(tree, newNode);
    }
    tree->m_avlTreeSize += 1;
 pthread_mutex_unlock(&tree->mutex);
    return newNode;
}

canonical_original_code:
struct AvlTreeNode *avl_insert(struct AvlTree *tree, void *key, void *data)
{
    struct AvlTreeNode *newNode = malloc(sizeof(struct AvlTreeNode));
    newNode->m_key = key;
    newNode->m_data = data;
    newNode->m_child1 = tree->m_nullNode;
    newNode->m_child2 = tree->m_nullNode;
    newNode->m_parent = tree->m_nullNode;
    newNode->m_height = 0;
 pthread_mutex_lock(&tree->mutex);
    if(tree->m_rootNode == tree->m_nullNode)
    {
        tree->m_rootNode = newNode;
    }
    else
    {
        DoInsertNode(tree, tree->m_rootNode, newNode);
        DoRebalance(tree, newNode);
    }
    tree->m_avlTreeSize += 1;
 pthread_mutex_unlock(&tree->mutex);
    return newNode;
}

variable_types: struct AvlTree { int (*m_dataComparator)(void *data1, void *data2); int m_keySize; int m_dataSize; int m_avlTreeSize; struct AvlTreeNode *m_rootNode; struct AvlTreeNode *m_nullNode; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; } *

variable_types:
key
void *

variable_types:
data
void *

return_type: struct AvlTreeNode { void *m_key; void *m_data; int m_height; struct AvlTreeNode *m_child1; struct AvlTreeNode *m_child2; struct AvlTreeNode *m_parent; } *


AvlTreeDeleteNode

decompiled_code:
void __fastcall AvlTreeDeleteNode(__int64 a1, __int64 a2)
{
void *v4; // rdi
__int64 v5; // rax
const void **v6; // rbx
__int64 v7; // rbp
__int64 v8; // rax

while ( 1 )
{
v5 = DoFindDeletionScapegoat_isra_0(*(_QWORD *)(a1 + 32), a2);
v6 = (const void **)v5;
if ( a2 == v5 )
break;
memcpy(*(void **)a2, *(const void **)v5, *(int *)(a1 + 8));
v4 = *(void **)(a2 + 8);
a2 = (__int64)v6;
memcpy(v4, v6[1], *(int *)(a1 + 12));
}
v7 = *(_QWORD *)(v5 + 40);
free(*(void **)v5);
free((void *)v6[1]);
free(v6);
v8 = *(_QWORD *)(a1 + 32);
if ( v8 == v7 )
{
*(_QWORD *)(a1 + 24) = v7;
goto LABEL_8;
}
if ( *(const void ***)(v7 + 24) == v6 )
{
*(_QWORD *)(v7 + 24) = v8;
if ( *(const void ***)(v7 + 32) != v6 )
goto LABEL_7;
goto LABEL_9;
}
if ( *(const void ***)(v7 + 32) == v6 )
LABEL_9:
*(_QWORD *)(v7 + 32) = v8;
LABEL_7:
DoUpdateHeight_isra_0(*(_QWORD *)(a1 + 32), v7);
LABEL_8:
DoRebalance(a1, v7);
--*(_DWORD *)(a1 + 16);
}

original_code:
void AvlTreeDeleteNode(struct AvlTree* tree, struct AvlTreeNode* node)
{
    struct AvlTreeNode* scapegoatNode;
    struct AvlTreeNode* checkNode;
    scapegoatNode = DoFindDeletionScapegoat(tree, node);
    if(node != scapegoatNode)
    {
        memcpy(node->m_key, scapegoatNode->m_key, tree->m_keySize);
        memcpy(node->m_data, scapegoatNode->m_data, tree->m_dataSize);
        AvlTreeDeleteNode(tree, scapegoatNode);
        return;
    }
    checkNode = scapegoatNode->m_parent;
    free(scapegoatNode->m_key);
    free(scapegoatNode->m_data);
    free(scapegoatNode);
    if(checkNode != tree->m_nullNode)
    {
        if(checkNode->m_child1 == scapegoatNode)
            checkNode->m_child1 = tree->m_nullNode;
        if(checkNode->m_child2 == scapegoatNode)
            checkNode->m_child2 = tree->m_nullNode;
        DoUpdateHeight(tree, checkNode);
    }
    else tree->m_rootNode = tree->m_nullNode;
    DoRebalance(tree, checkNode);
    tree->m_avlTreeSize -= 1;
    return;
}

canonical_original_code:
void AvlTreeDeleteNode(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *scapegoatNode;
    struct AvlTreeNode *checkNode;
    scapegoatNode = DoFindDeletionScapegoat(tree, node);
    if(node != scapegoatNode)
    {
        memcpy(node->m_key, scapegoatNode->m_key, tree->m_keySize);
        memcpy(node->m_data, scapegoatNode->m_data, tree->m_dataSize);
        AvlTreeDeleteNode(tree, scapegoatNode);
        return;
    }
    checkNode = scapegoatNode->m_parent;
    free(scapegoatNode->m_key);
    free(scapegoatNode->m_data);
    free(scapegoatNode);
    if(checkNode != tree->m_nullNode)
    {
        if(checkNode->m_child1 == scapegoatNode)
            checkNode->m_child1 = tree->m_nullNode;
        if(checkNode->m_child2 == scapegoatNode)
            checkNode->m_child2 = tree->m_nullNode;
        DoUpdateHeight(tree, checkNode);
    }
    else tree->m_rootNode = tree->m_nullNode;
    DoRebalance(tree, checkNode);
    tree->m_avlTreeSize -= 1;
    return;
}


decompiled_code:
__int64 __fastcall avl_search(__int64 a1, __int64 a2)
{
pthread_mutex_t *v2; // r13
_QWORD *v3; // rbx
__int64 result; // rax

v2 = (pthread_mutex_t *)(a1 + 40);
v3 = *(_QWORD **)(a1 + 24);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 40));
LABEL_2:
if ( v3 == *(_QWORD **)(a1 + 32) )
{
LABEL_7:
pthread_mutex_unlock(v2);
result = 0LL;
}
else
{
while ( (*(unsigned int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) )
{
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) < 0 )
{
v3 = (_QWORD *)v3[3];
goto LABEL_2;
}
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) <= 0 )
goto LABEL_2;
v3 = (_QWORD *)v3[4];
if ( v3 == *(_QWORD **)(a1 + 32) )
goto LABEL_7;
}
pthread_mutex_unlock(v2);
result = v3[1];
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1, __int64 a2)
{
pthread_mutex_t *v2; // r13
_QWORD *v3; // rbx
__int64 result; // rax

v2 = (pthread_mutex_t *)(a1 + 40);
v3 = *(_QWORD **)(a1 + 24);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 40));
LABEL_2:
if ( v3 == *(_QWORD **)(a1 + 32) )
{
LABEL_7:
pthread_mutex_unlock(v2);
result = 0LL;
}
else
{
while ( (*(unsigned int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) )
{
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) < 0 )
{
v3 = (_QWORD *)v3[3];
goto LABEL_2;
}
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) <= 0 )
goto LABEL_2;
v3 = (_QWORD *)v3[4];
if ( v3 == *(_QWORD **)(a1 + 32) )
goto LABEL_7;
}
pthread_mutex_unlock(v2);
result = v3[1];
}
return result;
}

original_code:
struct AvlTreeNode* avl_search(struct AvlTree* tree, void* key)
{
    struct AvlTreeNode* currentNode = tree->m_rootNode;
    pthread_mutex_lock(&tree->mutex);
    while(currentNode != tree->m_nullNode)
    {
        if(tree->m_dataComparator(key, currentNode->m_key) == 0) {
    pthread_mutex_unlock(&tree->mutex);
            return currentNode->m_data;
        }
        else if(tree->m_dataComparator(key, currentNode->m_key) < 0)
            currentNode = currentNode->m_child1;
        else if(tree->m_dataComparator(key, currentNode->m_key) > 0)
            currentNode = currentNode->m_child2;
    }
    pthread_mutex_unlock(&tree->mutex);
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *avl_search(struct AvlTree *tree, void *key)
{
    struct AvlTreeNode *currentNode = tree->m_rootNode;
    pthread_mutex_lock(&tree->mutex);
    while(currentNode != tree->m_nullNode)
    {
        if(tree->m_dataComparator(key, currentNode->m_key) == 0) {
    pthread_mutex_unlock(&tree->mutex);
            return currentNode->m_data;
        }
        else if(tree->m_dataComparator(key, currentNode->m_key) < 0)
            currentNode = currentNode->m_child1;
        else if(tree->m_dataComparator(key, currentNode->m_key) > 0)
            currentNode = currentNode->m_child2;
    }
    pthread_mutex_unlock(&tree->mutex);
    return ((void *)0);
}


AvlTreeIterateHead

original_code:
struct AvlTreeNode* AvlTreeIterateHead(struct AvlTree* tree)
{
    struct AvlTreeNode* currentNode = tree->m_rootNode;
    if(currentNode != tree->m_nullNode)
    {
        while(currentNode->m_child1 != tree->m_nullNode)
            currentNode = currentNode->m_child1;
        return currentNode;
    }
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *AvlTreeIterateHead(struct AvlTree *tree)
{
    struct AvlTreeNode *currentNode = tree->m_rootNode;
    if(currentNode != tree->m_nullNode)
    {
        while(currentNode->m_child1 != tree->m_nullNode)
            currentNode = currentNode->m_child1;
        return currentNode;
    }
    return ((void *)0);
}


AvlTreeIterateTail

original_code:
struct AvlTreeNode* AvlTreeIterateTail(struct AvlTree* tree)
{
    struct AvlTreeNode* currentNode = tree->m_rootNode;
    if(currentNode != tree->m_nullNode)
    {
        while(currentNode->m_child2 != tree->m_nullNode)
            currentNode = currentNode->m_child2;
        return currentNode;
    }
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *AvlTreeIterateTail(struct AvlTree *tree)
{
    struct AvlTreeNode *currentNode = tree->m_rootNode;
    if(currentNode != tree->m_nullNode)
    {
        while(currentNode->m_child2 != tree->m_nullNode)
            currentNode = currentNode->m_child2;
        return currentNode;
    }
    return ((void *)0);
}


AvlTreeIterateNext

original_code:
struct AvlTreeNode* AvlTreeIterateNext(
        struct AvlTree* tree,
        struct AvlTreeNode* node)
{
    struct AvlTreeNode* currentNode;
    if(node->m_child2 != tree->m_nullNode)
    {
        currentNode = node->m_child2;
        while(currentNode->m_child1 != tree->m_nullNode)
            currentNode = currentNode->m_child1;
        return currentNode;
    }
    else if(node->m_parent != tree->m_nullNode)
    {
        currentNode = node;
        while(currentNode != tree->m_rootNode)
            if(currentNode->m_parent->m_child2 != currentNode)
                return currentNode->m_parent;
            else currentNode = currentNode->m_parent;
    }
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *AvlTreeIterateNext(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *currentNode;
    if(node->m_child2 != tree->m_nullNode)
    {
        currentNode = node->m_child2;
        while(currentNode->m_child1 != tree->m_nullNode)
            currentNode = currentNode->m_child1;
        return currentNode;
    }
    else if(node->m_parent != tree->m_nullNode)
    {
        currentNode = node;
        while(currentNode != tree->m_rootNode)
            if(currentNode->m_parent->m_child2 != currentNode)
                return currentNode->m_parent;
            else currentNode = currentNode->m_parent;
    }
    return ((void *)0);
}


AvlTreeIteratePrev

original_code:
struct AvlTreeNode* AvlTreeIteratePrev(
        struct AvlTree* tree,
        struct AvlTreeNode* node)
{
    struct AvlTreeNode* currentNode;
    if(node->m_child1 != tree->m_nullNode)
    {
        currentNode = node->m_child1;
        while(currentNode->m_child2 != tree->m_nullNode)
            currentNode = currentNode->m_child2;
        return currentNode;
    }
    else if(node->m_parent != tree->m_nullNode)
    {
        currentNode = node;
        while(currentNode != tree->m_rootNode)
            if(currentNode->m_parent->m_child1 != currentNode)
                return currentNode->m_parent;
            else currentNode = currentNode->m_parent;
    }
    return ((void *)0);
}

canonical_original_code:
struct AvlTreeNode *AvlTreeIteratePrev(struct AvlTree *tree, struct AvlTreeNode *node)
{
    struct AvlTreeNode *currentNode;
    if(node->m_child1 != tree->m_nullNode)
    {
        currentNode = node->m_child1;
        while(currentNode->m_child2 != tree->m_nullNode)
            currentNode = currentNode->m_child2;
        return currentNode;
    }
    else if(node->m_parent != tree->m_nullNode)
    {
        currentNode = node;
        while(currentNode != tree->m_rootNode)
            if(currentNode->m_parent->m_child1 != currentNode)
                return currentNode->m_parent;
            else currentNode = currentNode->m_parent;
    }
    return ((void *)0);
}


decompiled_code:
int __fastcall avl_remove(__int64 a1, __int64 a2)
{
pthread_mutex_t *v2; // r13
_QWORD *v3; // rbp

v2 = (pthread_mutex_t *)(a1 + 40);
v3 = *(_QWORD **)(a1 + 24);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 40));
if ( v3 == *(_QWORD **)(a1 + 32) )
{
LABEL_9:
v3 = 0LL;
}
else
{
while ( (*(unsigned int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) )
{
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) >= 0 )
{
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) > 0 )
v3 = (_QWORD *)v3[4];
if ( *(_QWORD **)(a1 + 32) == v3 )
goto LABEL_9;
}
else
{
v3 = (_QWORD *)v3[3];
if ( *(_QWORD **)(a1 + 32) == v3 )
goto LABEL_9;
}
}
pthread_mutex_unlock(v2);
}
AvlTreeDeleteNode(a1, (__int64)v3);
return pthread_mutex_unlock(v2);
}

canonical_decompiled_code:
int __fastcall func19(__int64 a1, __int64 a2)
{
pthread_mutex_t *v2; // r13
_QWORD *v3; // rbp

v2 = (pthread_mutex_t *)(a1 + 40);
v3 = *(_QWORD **)(a1 + 24);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 40));
if ( v3 == *(_QWORD **)(a1 + 32) )
{
LABEL_9:
v3 = 0LL;
}
else
{
while ( (*(unsigned int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) )
{
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) >= 0 )
{
if ( (*(int (__fastcall **)(__int64, _QWORD))a1)(a2, *v3) > 0 )
v3 = (_QWORD *)v3[4];
if ( *(_QWORD **)(a1 + 32) == v3 )
goto LABEL_9;
}
else
{
v3 = (_QWORD *)v3[3];
if ( *(_QWORD **)(a1 + 32) == v3 )
goto LABEL_9;
}
}
pthread_mutex_unlock(v2);
}
func13(a1, (__int64)v3);
return pthread_mutex_unlock(v2);
}

original_code:
void avl_remove(avltree_t* tree, void* key) {
    struct AvlTreeNode* node = ((void *)0);
    struct AvlTreeNode* currentNode = tree->m_rootNode;
    pthread_mutex_lock(&tree->mutex);
    while(currentNode != tree->m_nullNode)
    {
        if(tree->m_dataComparator(key, currentNode->m_key) == 0) {
            pthread_mutex_unlock(&tree->mutex);
            node = currentNode;
            break;
        }
        else if(tree->m_dataComparator(key, currentNode->m_key) < 0)
            currentNode = currentNode->m_child1;
        else if(tree->m_dataComparator(key, currentNode->m_key) > 0)
            currentNode = currentNode->m_child2;
    }
    AvlTreeDeleteNode(tree, node);
    pthread_mutex_unlock(&tree->mutex);
}

canonical_original_code:
void avl_remove(struct AvlTree *tree, void *key) {
    struct AvlTreeNode *node = ((void *)0);
    struct AvlTreeNode *currentNode = tree->m_rootNode;
    pthread_mutex_lock(&tree->mutex);
    while(currentNode != tree->m_nullNode)
    {
        if(tree->m_dataComparator(key, currentNode->m_key) == 0) {
            pthread_mutex_unlock(&tree->mutex);
            node = currentNode;
            break;
        }
        else if(tree->m_dataComparator(key, currentNode->m_key) < 0)
            currentNode = currentNode->m_child1;
        else if(tree->m_dataComparator(key, currentNode->m_key) > 0)
            currentNode = currentNode->m_child2;
    }
    AvlTreeDeleteNode(tree, node);
    pthread_mutex_unlock(&tree->mutex);
}


decompiled_code:
// attributes: thunk
__int64 __fastcall avl_lookup(__int64 a1, __int64 a2)
{
return avl_search(a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func20(__int64 a1, __int64 a2)
{
return func14(a1, a2);
}

original_code:
void* avl_lookup(avltree_t* tree, void* key) {
 struct AvlTreeNode* node;
 node = avl_search(tree, key);
 return node ;
}

canonical_original_code:
void *avl_lookup(struct AvlTree *tree, void *key) {
 struct AvlTreeNode *node;
 node = avl_search(tree, key);
 return node ;
}


decompiled_code:
int __fastcall avl_print_aux(__int64 a1, unsigned int **a2)
{
unsigned int **v2; // rbp

if ( a2 )
{
v2 = a2;
do
{
printf("KEY = %d\n", **v2);
v2 = (unsigned int **)AvlTreeIterateNext(a1, (__int64)v2);
}
while ( v2 );
}
return puts("#### END PRINT ####");
}

canonical_decompiled_code:
int __fastcall func21(__int64 a1, unsigned int **a2)
{
unsigned int **v2; // rbp

if ( a2 )
{
v2 = a2;
do
{
printf("KEY = %d\n", **v2);
v2 = (unsigned int **)func17(a1, (__int64)v2);
}
while ( v2 );
}
return puts("#### END PRINT ####");
}

original_code:
void avl_print_aux(avltree_t* tree, struct AvlTreeNode* node) {
 if (node == ((void *)0)) {
  printf("#### END PRINT ####\n");
  return;
 }
 printf("KEY = %d\n", *(int*)node->m_key);
 avl_print_aux(tree, AvlTreeIterateNext(tree, node));
}

canonical_original_code:
void avl_print_aux(struct AvlTree *tree, struct AvlTreeNode *node) {
 if (node == ((void *)0)) {
  printf("#### END PRINT ####\n");
  return;
 }
 printf("KEY = %d\n", *(int *)node->m_key);
 avl_print_aux(tree, AvlTreeIterateNext(tree, node));
}


decompiled_code:
int __fastcall avl_print(__int64 a1)
{
unsigned int **v1; // rax

puts("\n#### AVL PRINT ####");
v1 = (unsigned int **)AvlTreeIterateHead(a1);
return avl_print_aux(a1, v1);
}

canonical_decompiled_code:
int __fastcall func22(__int64 a1)
{
unsigned int **v1; // rax

puts("\n#### AVL PRINT ####");
v1 = (unsigned int **)func15(a1);
return func21(a1, v1);
}

original_code:
void avl_print(avltree_t* tree) {
 printf("\n#### AVL PRINT ####\n");
 avl_print_aux(tree, AvlTreeIterateHead(tree));
}

canonical_original_code:
void avl_print(struct AvlTree *tree) {
 printf("\n#### AVL PRINT ####\n");
 avl_print_aux(tree, AvlTreeIterateHead(tree));
}


decompiled_code:
__int64 __fastcall int_comparator(_DWORD *a1, _DWORD *a2)
{
return (unsigned int)(*a1 - *a2);
}

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

original_code:
int int_comparator(const void* a, const void* b) {
 return *(int*)a - *(int*)b;
}

canonical_original_code:
int int_comparator(void *a, void *b) {
 return *(int *)a - *(int *)b;
}

variable_types:
a
void *

variable_types:
b
void *


decompiled_code:
void __fastcall __noreturn thr_handler(void *a1)
{
_QWORD *v1; // rbp
__int64 v2; // rax
int v3; // ebx
int v4; // [rsp+Ch] [rbp-13Ch] BYREF
int buf[78]; // [rsp+10h] [rbp-138h] BYREF

mysql_thread_init(a1);
while ( 1 )
{
sem_wait(&Sem_client_requests);
v1 = (_QWORD *)queue_remove(Queue_client_requests);
memset(buf, 0, 0x108uLL);
v2 = 0LL;
while ( *(_DWORD *)v1 != LODWORD(Service[2 * v2]) )
{
if ( ++v2 == 4 )
{
buf[1] = 3;
v4 = 8;
puts("[xlcom_server] [H] Unknown request.");
goto LABEL_6;
}
}
((void (__fastcall *)(_QWORD *, int *, int *))Service[2 * (int)v2 + 1])(v1, buf, &v4);
LABEL_6:
v3 = send(*(_DWORD *)(v1[67] + 40LL), buf, v4, 64);
if ( v3 < 0 )
puts("[xlcom_server] [H] Error sending response.");
if ( v4 != v3 )
puts("[xlcom_server] [H] Message size mismatch.");
free(v1);
}
}

canonical_decompiled_code:
void __fastcall __noreturn func1(void *a1)
{
_QWORD *v1; // rbp
__int64 v2; // rax
int v3; // ebx
int v4; // [rsp+Ch] [rbp-13Ch] BYREF
int buf[78]; // [rsp+10h] [rbp-138h] BYREF

mysql_thread_init(a1);
while ( 1 )
{
sem_wait(&Sem_client_requests);
v1 = (_QWORD *)queue_remove(Queue_client_requests);
memset(buf, 0, 0x108uLL);
v2 = 0LL;
while ( *(_DWORD *)v1 != LODWORD(Service[2 * v2]) )
{
if ( ++v2 == 4 )
{
buf[1] = 3;
v4 = 8;
puts("[xlcom_server] [H] Unknown request.");
goto LABEL_6;
}
}
((void (__fastcall *)(_QWORD *, int *, int *))Service[2 * (int)v2 + 1])(v1, buf, &v4);
LABEL_6:
v3 = send(*(_DWORD *)(v1[67] + 40LL), buf, v4, 64);
if ( v3 < 0 )
puts("[xlcom_server] [H] Error sending response.");
if ( v4 != v3 )
puts("[xlcom_server] [H] Message size mismatch.");
free(v1);
}
}

original_code:
void* thr_handler(void* arg) {
 client_request_t *request;
 xlcp_msg_res_t response;
 int response_size;
 size_t req_handler_id;
 int found_req_handler;
 int status;
 int i;
 mysql_thread_init();
 while(1) {
  sem_wait(&Sem_client_requests);
  request = queue_remove(Queue_client_requests);
  memset(&response, 0, sizeof(response));
  found_req_handler = 0;
  for (i=0; i<4; i++) {
   if(request->msg.type == Service[i].type) {
    found_req_handler = 1;
    req_handler_id = i;
    break;
   }
  }
  if (!found_req_handler) {
   response.status = RES_UNKNOWN;
   response_size = sizeof(response) - sizeof(response.body);
   printf("[xlcom_server] [H] Unknown request.\n");
  }
  else {
   Service[req_handler_id].handler(request, &response, &response_size);
  }
  status = send(request->client->fd, &response, response_size, MSG_DONTWAIT);
  if (status < 0) {
   printf("[xlcom_server] [H] Error sending response.\n");
  }
  if (status != response_size) {
   printf("[xlcom_server] [H] Message size mismatch.\n");
  }
  free(request);
 }
}

canonical_original_code:
void *thr_handler(void *arg) {
 struct client_request_t *request;
 struct xlcp_msg_res_t response;
 int response_size;
 unsigned long req_handler_id;
 int found_req_handler;
 int status;
 int i;
 mysql_thread_init();
 while(1) {
  sem_wait(&Sem_client_requests);
  request = queue_remove(Queue_client_requests);
  memset(&response, 0, sizeof(response));
  found_req_handler = 0;
  for (i=0; i<4; i++) {
   if(request->msg.type == Service[i].type) {
    found_req_handler = 1;
    req_handler_id = i;
    break;
   }
  }
  if (!found_req_handler) {
   response.status = RES_UNKNOWN;
   response_size = sizeof(response) - sizeof(response.body);
   printf("[xlcom_server] [H] Unknown request.\n");
  }
  else {
   Service[req_handler_id].handler(request, &response, &response_size);
  }
  status = send(request->client->fd, &response, response_size, MSG_DONTWAIT);
  if (status < 0) {
   printf("[xlcom_server] [H] Error sending response.\n");
  }
  if (status != response_size) {
   printf("[xlcom_server] [H] Message size mismatch.\n");
  }
  free(request);
 }
}

variable_types:
arg
void *

variable_types: struct client_request_t { struct xlcp_msg_req_t { enum xlcp_msg_type_t { REQ_NULL=0, REQ_PING=1, REQ_ECHO=2, REQ_AUTH=3, REQ_SEND_MESSAGE=4 } type; union { struct xlcp_msg_req_echo_t { char msg[256]; } echo; struct xlcp_msg_req_auth_t { char user[32]; char pass[40]; } auth; struct xlcp_msg_req_sendmsg_t { int target_id; int target_type; char message[512]; } sendmsg; } body; } msg; unsigned long msg_size; struct client_info_t { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; int fd; char address[16]; int is_authed; int id; char username[32]; } *client; } *

variable_types: struct xlcp_msg_res_t { enum xlcp_msg_type_t { REQ_NULL=0, REQ_PING=1, REQ_ECHO=2, REQ_AUTH=3, REQ_SEND_MESSAGE=4 } type; enum xlcp_msg_res_status_t { RES_OK=0, RES_BUSY=1, RES_ERROR=2, RES_UNKNOWN=3 } status; union { struct xlcp_msg_res_echo_t { char msg[256]; } echo; } body; }

variable_types: status int

variable_types: i int

user_defined_types: struct xlcp_msg_res_t { enum xlcp_msg_type_t type; enum xlcp_msg_res_status_t status; union { struct xlcp_msg_res_echo_t echo; } body; }

user_defined_types: struct client_request_t { struct xlcp_msg_req_t msg; unsigned long msg_size; struct client_info_t *client; }

user_defined_types: struct xlcp_msg_req_t { enum xlcp_msg_type_t type; union { struct xlcp_msg_req_echo_t echo; struct xlcp_msg_req_auth_t auth; struct xlcp_msg_req_sendmsg_t sendmsg; } body; }

user_defined_types: struct client_info_t { union pthread_mutex_t mutex; int fd; char address[16]; int is_authed; int id; char username[32]; }


decompiled_code:
void __fastcall __noreturn thr_poller(void *a1)
{
_QWORD *v1; // rbp
ssize_t v2; // rax
__int64 v3; // rdi
__int64 v4; // rax
const char *v5; // rax
int fd; // [rsp+0h] [rbp-28h] BYREF
struct epoll_event events; // [rsp+4h] [rbp-24h] BYREF

while ( 1 )
{
if ( epoll_wait(Epoll_fd, &events, 1, -1) != 1 )
printf("[xlcom_server] [P] epoll_wait returned %d, expecting 1\n", 1LL);
v1 = malloc(0x220uLL);
if ( !v1 )
puts("[xlcom_server] [P] malloc failed. No free memory?");
memset(v1, 0, 0x220uLL);
fd = events.data.fd;
v2 = recv(events.data.fd, v1, 0x20CuLL, 64);
v3 = Active_connections;
v1[66] = v2;
v4 = avl_lookup(v3, &fd);
v1[67] = v4;
if ( v4 )
{
if ( v1[66] )
{
queue_add(Queue_client_requests, v1);
sem_post(&Sem_client_requests);
}
else
{
v5 = (const char *)client_info_print_auth(v4);
printf("[xlcom_server] [P] %s disconnected.\n", v5);
avl_remove(Active_connections, &fd);
if ( epoll_ctl(Epoll_fd, 2, fd, 0LL) )
puts("[xlcom_server] [P] Error removing connection from epoll.");
close(fd);
free(v1);
}
}
else
{
puts("[xlcom_server] [P] CRITICAL ERROR: Client is connected, but no record found. Rejecting request.");
}
}
}

canonical_decompiled_code:
void __fastcall __noreturn func2(void *a1)
{
_QWORD *v1; // rbp
ssize_t v2; // rax
__int64 v3; // rdi
__int64 v4; // rax
const char *v5; // rax
int fd; // [rsp+0h] [rbp-28h] BYREF
struct epoll_event events; // [rsp+4h] [rbp-24h] BYREF

while ( 1 )
{
if ( epoll_wait(Epoll_fd, &events, 1, -1) != 1 )
printf("[xlcom_server] [P] epoll_wait returned %d, expecting 1\n", 1LL);
v1 = malloc(0x220uLL);
if ( !v1 )
puts("[xlcom_server] [P] malloc failed. No free memory?");
memset(v1, 0, 0x220uLL);
fd = events.data.fd;
v2 = recv(events.data.fd, v1, 0x20CuLL, 64);
v3 = Active_connections;
v1[66] = v2;
v4 = avl_lookup(v3, &fd);
v1[67] = v4;
if ( v4 )
{
if ( v1[66] )
{
queue_add(Queue_client_requests, v1);
sem_post(&Sem_client_requests);
}
else
{
v5 = (const char *)client_info_print_auth(v4);
printf("[xlcom_server] [P] %s disconnected.\n", v5);
avl_remove(Active_connections, &fd);
if ( epoll_ctl(Epoll_fd, 2, fd, 0LL) )
puts("[xlcom_server] [P] Error removing connection from epoll.");
close(fd);
free(v1);
}
}
else
{
puts("[xlcom_server] [P] CRITICAL ERROR: Client is connected, but no record found. Rejecting request.");
}
}
}

original_code:
void* thr_poller(void* arg) {
 int status;
 int client_fd;
 struct epoll_event epoll_ev;
 client_request_t *request;
 while(1) {
  if ((status = epoll_wait(Epoll_fd, &epoll_ev, 1, -1) != 1)) {
   printf("[xlcom_server] [P] epoll_wait returned %d, expecting 1\n", status);
  }
  if ((request = malloc(sizeof(client_request_t))) == ((void *)0)) {
   printf("[xlcom_server] [P] malloc failed. No free memory?\n");
  }
  memset(request, 0, sizeof(client_request_t));
  client_fd = epoll_ev.data.fd;
  request->msg_size = recv(client_fd, (void*)&(request->msg), sizeof(request->msg), MSG_DONTWAIT);
  if ((request->client = avl_lookup(Active_connections, &client_fd)) == ((void *)0)) {
   printf("[xlcom_server] [P] CRITICAL ERROR: Client is connected, but no record found. Rejecting request.\n");
   continue;
  }
  if (request->msg_size == 0) {
   printf("[xlcom_server] [P] %s disconnected.\n", client_info_print_auth(request->client));
   avl_remove(Active_connections, &client_fd);
   if (epoll_ctl(Epoll_fd, 2, client_fd, ((void *)0)) != 0) {
    printf("[xlcom_server] [P] Error removing connection from epoll.\n");
   }
   close(client_fd);
   free(request);
   continue;
  }
  if (request->msg_size < 0) {
   printf("[xlcom_server] [P] Error receiving request from %s.\n", request->client->address);
   free(request);
   return ((void *)0);
  }
  queue_add(Queue_client_requests, request);
  sem_post(&Sem_client_requests);
 }
}

canonical_original_code:
void *thr_poller(void *arg) {
 int status;
 int client_fd;
 struct epoll_event epoll_ev;
 struct client_request_t *request;
 while(1) {
  if ((status = epoll_wait(Epoll_fd, &epoll_ev, 1, -1) != 1)) {
   printf("[xlcom_server] [P] epoll_wait returned %d, expecting 1\n", status);
  }
  if ((request = malloc(sizeof(client_request_t))) == ((void *)0)) {
   printf("[xlcom_server] [P] malloc failed. No free memory?\n");
  }
  memset(request, 0, sizeof(client_request_t));
  client_fd = epoll_ev.data.fd;
  request->msg_size = recv(client_fd, (void *)&(request->msg), sizeof(request->msg), MSG_DONTWAIT);
  if ((request->client = avl_lookup(Active_connections, &client_fd)) == ((void *)0)) {
   printf("[xlcom_server] [P] CRITICAL ERROR: Client is connected, but no record found. Rejecting request.\n");
   continue;
  }
  if (request->msg_size == 0) {
   printf("[xlcom_server] [P] %s disconnected.\n", client_info_print_auth(request->client));
   avl_remove(Active_connections, &client_fd);
   if (epoll_ctl(Epoll_fd, 2, client_fd, ((void *)0)) != 0) {
    printf("[xlcom_server] [P] Error removing connection from epoll.\n");
   }
   close(client_fd);
   free(request);
   continue;
  }
  if (request->msg_size < 0) {
   printf("[xlcom_server] [P] Error receiving request from %s.\n", request->client->address);
   free(request);
   return ((void *)0);
  }
  queue_add(Queue_client_requests, request);
  sem_post(&Sem_client_requests);
 }
}

variable_types: struct epoll_event { unsigned int events; union epoll_data { void *ptr; int fd; unsigned int u32; unsigned long u64; } data; }

user_defined_types: struct epoll_event { unsigned int events; union epoll_data data; }

user_defined_types: enum xlcp_msg_type_t { REQ_NULL=0, REQ_PING=1, REQ_ECHO=2, REQ_AUTH=3, REQ_SEND_MESSAGE=4 }

user_defined_types: struct xlcp_msg_req_echo_t { char msg[256]; }

user_defined_types: struct xlcp_msg_req_auth_t { char user[32]; char pass[40]; }

user_defined_types: struct xlcp_msg_req_sendmsg_t { int target_id; int target_type; char message[512]; }