diff --git a/sourcepawn/decompiler/code_analyzer.cpp b/sourcepawn/decompiler/code_analyzer.cpp index 24f2eeaa..6e41d159 100644 --- a/sourcepawn/decompiler/code_analyzer.cpp +++ b/sourcepawn/decompiler/code_analyzer.cpp @@ -43,6 +43,15 @@ struct ControlFlowGraph FunctionInfo *func; }; +DefineNode::DefineNode(BaseNode *o, const char *fmt, ...) : BaseNode(_OP_DEFINE), other(o) +{ + va_list ap; + + va_start(ap, fmt); + Sp_FormatArgs(name, sizeof(name), fmt, ap); + va_end(ap); +} + static FunctionInfo *sp_InferFuncPrototype(sp_decomp_t *dc, uint32_t code_addr, bool is_public) { sp_tag_t *pTag; @@ -333,6 +342,14 @@ void sp_DebugExprTree(PrintBuffer *buffer, BaseNode *node, bool is_stmt=false) { switch (node->op) { + case _OP_DEFINE: + { + DefineNode *def = (DefineNode *)node; + + buffer->Append("new %s = ", def->name); + sp_DebugExprTree(buffer, def->other, is_stmt); + break; + } case OP_CALL: { CallNode *call = (CallNode *)node; @@ -345,6 +362,13 @@ void sp_DebugExprTree(PrintBuffer *buffer, BaseNode *node, bool is_stmt=false) buffer->Append(")"); break; } + case _OP_USE: + { + UseNode *unode = (UseNode *)node; + + buffer->Append("%s", unode->def->name); + break; + } case _OP_VAR: { VarNode *var_node = (VarNode *)node; @@ -577,6 +601,7 @@ int sp_AnalyzeGraph(sp_decomp_t *dc, ControlFlowGraph *graph) FunctionInfo *func, *tfunc; cell_t p1, p2, op; FuncVar *v1, *v2; + unsigned int callnumber = 0; unsigned int stack_entries = 0; StackEntry eval_stack[MAX_STACK_ENTRIES]; @@ -637,6 +662,11 @@ int sp_AnalyzeGraph(sp_decomp_t *dc, ControlFlowGraph *graph) assert(sp <= 0); pri = new (graph) CallNode(tfunc, nodes, cnode->val); + pri = new (graph) DefineNode(pri, "call%03x", ++callnumber); + rtemp = new (graph) StmtNode(_OP_STMT, pri, NULL); + root_tail->next = rtemp; + root_tail = rtemp; + pri = new (graph) UseNode((DefineNode *)pri); break; } diff --git a/sourcepawn/decompiler/code_analyzer.h b/sourcepawn/decompiler/code_analyzer.h index 7182338b..ebec22e4 100644 --- a/sourcepawn/decompiler/code_analyzer.h +++ b/sourcepawn/decompiler/code_analyzer.h @@ -5,13 +5,14 @@ enum Opcode { - _OP_VAR = -1, - _OP_STMT = -2, - _OP_CONST = -3, - _OP_STORE = -4, - _OP_NEW = -5, - _OP_MODULO = -6, - _OP_EMPTY = -7, + _OP_VAR = -1, /* Variable container */ + _OP_STMT = -2, /* Statement contained */ + _OP_CONST = -3, /* Constant value */ + _OP_STORE = -4, /* Store operation (binary assignment) */ + _OP_NEW = -5, /* Variable declaration */ + _OP_MODULO = -6, /* Binary modulo operator */ + _OP_DEFINE = -7, /* "define" node for SSA */ + _OP_USE = -8, /* "use" node for SSA */ #define OPDEF(num,name,str,params) \ OP_##name = num, #include "opcodes.tbl" @@ -70,8 +71,17 @@ struct CallNode : public BaseNode struct DefineNode : public BaseNode { - TempNode(const char *name + DefineNode(BaseNode *o, const char *fmt, ...); char name[32]; + BaseNode *other; +}; + +struct UseNode : public BaseNode +{ + UseNode(DefineNode *n) : BaseNode(_OP_USE), def(n) + { + } + DefineNode *def; }; struct UnaryNode : public BaseNode