/* luadec, based on luac */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#define DEBUG_PRINT
#ifndef LUA_OPNAMES
#define LUA_OPNAMES
#endif
#include "ldebug.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lundump.h"
#include "lstring.h"
#include "StringBuffer.h"
#include "proto.h"
#include "print.h"
#include "structs.h"
#define stddebug stdout
extern int locals;
extern int localdeclare[255][255];
extern int functionnum;
extern lua_State* glstate;
extern int guess_locals;
char* error_nil = "ERROR_nil";
char* nilstr = "nil";
char* upvalue = "upvaluexxxxxxxxx";
StringBuffer *errorStr;
/*
* -------------------------------------------------------------------------
*/
char* getupval(Function * F, int r) {
if (F->f->upvalues && r < F->f->sizeupvalues) {
return (char*)getstr(F->f->upvalues[r]);
} else {
char* s = malloc(20);
sprintf(s,"upvalue_%d",r);
return s;
}
}
#define GLOBAL(r) (char*)svalue(&f->k[r])
#define UPVALUE(r) ( getupval(F,r) )
#define REGISTER(r) F->R[r]
#define PRIORITY(r) (r>=MAXSTACK ? 0 : F->Rprio[r])
#define LOCAL(r) (F->f->locvars ? ((char*)getstr(F->f->locvars[r].varname)) : error_nil)
#define LOCAL_STARTPC(r) F->f->locvars[r].startpc
#define PENDING(r) F->Rpend[r]
#define CALL(r) F->Rcall[r]
#define IS_TABLE(r) F->Rtabl[r]
#define IS_VARIABLE(r) F->Rvar[r]
#define IS_CONSTANT(r) (r >= 256) // TODO: Lua5.1 specific. Should use MSR!!!!
#define SET_CTR(s) s->ctr
#define SET(s,y) s->values[y]
#define SET_IS_EMPTY(s) (s->ctr == 0)
#define opstr(o) ((o)==OP_EQ?"==":(o)==OP_LE?"<=":(o)==OP_LT?"<":(((o)==OP_TEST)||((o)==OP_TESTSET))?NULL:"?") // Lua5.1 specific
#define invopstr(o) ((o)==OP_EQ?"~=":(o)==OP_LE?">":(o)==OP_LT?">=":(((o)==OP_TEST)||((o)==OP_TESTSET))?"not":"?") // Lua5.1 specific
#define IsMain(f) (f->linedefined==0)
#define fb2int(x) (((x) & 7) << ((x) >> 3))
#define SET_ERROR(F,e) { StringBuffer_printf(errorStr," -- DECOMPILER ERROR: %s\n", (e)); RawAddStatement((F),errorStr); }
/* error = e; errorCode = __LINE__; */ /*if (debug) { printf("DECOMPILER ERROR: %s\n", e); }*/
static int debug;
static char* error;
static int errorCode;
void RawAddStatement(Function * F, StringBuffer * str);
void DeclareLocal(Function * F, int ixx, char* value);
Statement *NewStatement(char *code, int line, int indent) {
Statement *self;
self = calloc(sizeof(Statement), 1);
cast(ListItem*, self)->next = NULL;
self->code = code;
self->line = line;
self->indent = indent;
return self;
}
void DeleteStatement(Statement * self, void* dummy) {
free(self->code);
}
void PrintStatement(Statement * self, void* F_) {
int i;
Function* F = cast(Function*, F_);
for (i = 0; i < self->indent; i++) {
StringBuffer_add(F->decompiledCode, " ");
}
StringBuffer_addPrintf(F->decompiledCode, "%s\n", self->code);
}
LogicExp* MakeExpNode(BoolOp* boolOp) {
LogicExp* node = cast(LogicExp*, malloc(sizeof(LogicExp)));
node->parent = NULL;
node->subexp = NULL;
node->next = NULL;
node->prev = NULL;
node->op1 = boolOp->op1;
node->op2 = boolOp->op2;
node->op = boolOp->op;
node->dest = boolOp->dest;
node->neg = boolOp->neg;
node->is_chain = 0;
return node;
}
LogicExp* MakeExpChain(int dest) {
LogicExp* node = cast(LogicExp*, malloc(sizeof(LogicExp)));
node->parent = NULL;
node->subexp = NULL;
node->next = NULL;
node->prev = NULL;
node->dest = dest;
node->is_chain = 1;
return node;
}
StringBuffer* PrintLogicItem(StringBuffer* str, LogicExp* exp, int inv, int rev) {
if (exp->subexp) {
StringBuffer_addChar(str, '(');
str = PrintLogicExp(str, exp->dest, exp->subexp, inv, rev);
StringBuffer_addChar(str, ')');
} else {
char *op;
int cond = exp->neg;
if (inv) cond = !cond;
if (rev) cond = !cond;
if (cond)
op = invopstr(exp->op);
else
op = opstr(exp->op);
if ((exp->op != OP_TEST) && (exp->op != OP_TESTSET)) {
StringBuffer_addPrintf(str, "%s %s %s", exp->op1, op, exp->op2);
} else {
if (op)
StringBuffer_addPrintf(str, "%s %s", op, exp->op2);
else
StringBuffer_addPrintf(str, "%s", exp->op2);
}
}
return str;
}
StringBuffer* PrintLogicExp(StringBuffer* str, int dest, LogicExp* exp, int inv_, int rev) {
int inv = inv_;
if (!str)
str = StringBuffer_new(NULL);
while (exp->next) {
char* op;
int cond = exp->dest > dest;
inv = cond ? inv_ : !inv_;
str = PrintLogicItem(str, exp, inv, rev);
exp = exp->next;
if (inv_) cond = !cond;
if (rev) cond = !cond;
op = cond ? "and" : "or";
StringBuffer_addPrintf(str, " %s ", op);
}
return PrintLogicItem(str, exp, inv_, rev);
}
void TieAsNext(LogicExp* curr, LogicExp* item) {
curr->next = item;
item->prev = curr;
item->parent = curr->parent;
}
void Untie(LogicExp* curr, int* thenaddr) {
LogicExp* previous = curr->prev;
if (previous)
previous->next = NULL;
curr->prev = NULL;
curr->parent = NULL;
}
void TieAsSubExp(LogicExp* parent, LogicExp* item) {
parent->subexp = item;
while (item) {
item->parent = parent;
item = item->next;
}
}
LogicExp* MakeBoolean(Function * F, int* endif, int* thenaddr)
{
int i;
int firstaddr, elseaddr, last, realLast;
LogicExp *curr, *first;
int dest;
if (endif)
*endif = 0;
if (F->nextBool == 0) {
SET_ERROR(F,"Attempted to build a boolean expression without a pending context");
return NULL;
}
realLast = F->nextBool - 1;
last = realLast;
firstaddr = F->bools[0]->pc + 2;
*thenaddr = F->bools[last]->pc + 2;
elseaddr = F->bools[last]->dest;
for (i = realLast; i >= 0; i--) {
int dest = F->bools[i]->dest;
if ((elseaddr > *thenaddr) &&
( ((F->bools[i]->op == OP_TEST) || (F->bools[i]->op == OP_TESTSET)) ? (dest > elseaddr+1) :
(dest > elseaddr))) {
last = i;
*thenaddr = F->bools[i]->pc + 2;
elseaddr = dest;
}
}
{
int tmpLast = last;
for (i = 0; i < tmpLast; i++) {
int dest = F->bools[i]->dest;
if (elseaddr > firstaddr) {
if (dest < firstaddr) {
last = i;
*thenaddr = F->bools[i]->pc + 2;
elseaddr = dest;
}
} else {
if (dest == firstaddr) {
last = i;
*thenaddr = F->bools[i]->pc + 2;
elseaddr = dest;
} else {
break;
}
}
}
}
dest = F->bools[0]->dest;
curr = MakeExpNode(F->bools[0]);
if (dest > firstaddr && dest <= *thenaddr) {
first = MakeExpChain(dest);
TieAsSubExp(first, curr);
} else {
first = curr;
if (endif)
*endif = dest;
}
if (debug) {
printf("\n");
for (i = 0; i <= last; i++) {
BoolOp* op = F->bools[i];
if (debug) {
printf("Exps(%d): at %d\tdest %d\tneg %d\t(%s %s %s) cpd %d \n", i,
op->pc, op->dest, op->neg, op->op1, opstr(op->op), op->op2, curr->parent ? curr->parent->dest : -1);
}
}
printf("\n");
}
for (i = 1; i <= last; i++) {
BoolOp* op = F->bools[i];
int at = op->pc;
int dest = op->dest;
LogicExp* exp = MakeExpNode(op);
if (dest < firstaddr) {
/* jump to loop in a while */
TieAsNext(curr, exp);
curr = exp;
if (endif)
*endif = dest;
} else if (dest > *thenaddr) {
/* jump to "else" */
TieAsNext(curr, exp);
curr = exp;
if (endif) {
if ((op->op != OP_TEST) && (op->op != OP_TESTSET)) {
if (*endif != 0 && *endif != dest) {
SET_ERROR(F,"unhandled construct in 'if'");
//return NULL;
}
许吴倩
- 粉丝: 28
- 资源: 4547
最新资源
- 技术资料分享wav音频格式很好的技术资料.zip
- 技术资料分享WAV文件格式分析与应用很好的技术资料.zip
- 技术资料分享wav文件格式分析详解很好的技术资料.zip
- 技术资料分享VS1053-cn很好的技术资料.zip
- 技术资料分享VS1003-cn很好的技术资料.zip
- 技术资料分享UM0424-STM32F10xxx-USB-development-kit-en很好的技术资料.zip
- 网络管理与维护:Windows故障转移群集实现高可用文件服务器实训指南
- 技术资料分享uip在单片机上的移植精讲很好的技术资料.zip
- 技术资料分享uip-中文资料很好的技术资料.zip
- 技术资料分享ucos教程很好的技术资料.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈