sourcemod/sourcepawn/decompiler/code_analyzer.h
David Anderson 5cb4acf590 Added some notion of def-use to unfold copy propagation across registers and the eval stack.
At some point we will need to walk the expr tree to fold this back where appropriate, i.e. single use for calls.
2008-09-23 22:00:47 -07:00

152 lines
2.8 KiB
C

#ifndef _INCLUDE_SP_DECOMP_CODE_ANALYZER_H_
#define _INCLUDE_SP_DECOMP_CODE_ANALYZER_H_
#include <sp_vm_types.h>
enum Opcode
{
_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"
#undef OPDEF
};
struct sp_opdef_t
{
const char *name;
int params;
};
struct FuncVar;
struct BaseNode
{
BaseNode(cell_t _op) : op(_op)
{
}
cell_t op;
};
struct ConstNode : public BaseNode
{
ConstNode(cell_t _val) : BaseNode(_OP_CONST), val(_val)
{
}
cell_t val;
};
struct StmtNode : public BaseNode
{
StmtNode(cell_t _op, BaseNode *_node, StmtNode *_next) : BaseNode(_op)
, node(_node)
, next(_next)
{
}
BaseNode *node;
StmtNode *next;
};
struct FunctionInfo;
struct CallNode : public BaseNode
{
CallNode(FunctionInfo *f, BaseNode **t, unsigned int c) : BaseNode(OP_CALL)
, func(f)
, args(t)
, argc(c)
{
}
FunctionInfo *func;
BaseNode **args;
unsigned int argc;
};
struct DefineNode : public BaseNode
{
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
{
UnaryNode(cell_t _op, BaseNode *_node) : BaseNode(_op), node(_node)
{
}
BaseNode *node;
};
struct VarNode : public BaseNode
{
VarNode(FuncVar *_var) : BaseNode(_OP_VAR), var(_var)
{
}
FuncVar *var;
};
struct BinOpNode : public BaseNode
{
BinOpNode(cell_t _op, BaseNode *_left, BaseNode *_right) : BaseNode(_op)
,left(_left)
,right(_right)
{
}
BaseNode *left;
BaseNode *right;
};
struct DeclNode : public BaseNode
{
DeclNode(VarNode *_var, BaseNode *_expr) : BaseNode(_OP_NEW), var(_var), expr(_expr)
{
}
VarNode *var;
BaseNode *expr;
};
struct FuncVar
{
sp_fdbg_symbol_t *sym;
sp_fdbg_arraydim_t *dims;
sp_tag_t *tag;
const char *name;
DeclNode *new_stmt;
};
struct FunctionInfo
{
char name[64];
sp_fdbg_symbol_t *sym;
FuncVar known_args[SP_MAX_EXEC_PARAMS];
unsigned int num_known_args;
sp_tag_t *tag;
uint32_t code_addr;
uint32_t code_end;
bool is_public;
FunctionInfo *next;
FuncVar *known_vars;
unsigned int num_known_vars;
};
struct sp_decomp_t;
int Sp_DecompFunction(sp_decomp_t *dc, uint32_t code_addr, bool is_public);
#endif //_INCLUDE_SP_DECOMP_CODE_ANALYZER_H_