From: A.Kleine <ak...@us...> - 2007-02-27 18:39:27
|
Update of /cvsroot/ming/ming/util In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv16314/ming/util Modified Files: decompile.c Log Message: Added first time support for switch(){} -statements (not quite complete and thus disabled by default). Index: decompile.c =================================================================== RCS file: /cvsroot/ming/ming/util/decompile.c,v retrieving revision 1.81 retrieving revision 1.82 diff -C2 -d -r1.81 -r1.82 *** decompile.c 26 Feb 2007 16:21:08 -0000 1.81 --- decompile.c 27 Feb 2007 18:39:16 -0000 1.82 *************** *** 22,25 **** --- 22,26 ---- #define DEBUGSTACK + //#define DECOMP_SWITCH //#define STATEMENT_CLASS // I have uncommented some buggy class recognition stuff in decompileIF() *************** *** 849,852 **** --- 850,861 ---- } + #ifdef DECOMP_SWITCH + static int + check_switch(int firstcode) + { + return (firstcode == SWFACTION_PUSH || firstcode == SWFACTION_JUMP); + } + #endif + int decompileArithmeticOp(int n, SWF_ACTION *actions,int maxn) *************** *** 1005,1008 **** --- 1014,1028 ---- break; case SWFACTION_STRICTEQUALS: + #ifdef DECOMP_SWITCH + if (actions[n+1].SWF_ACTIONRECORD.ActionCode == SWFACTION_IF) + { + if (check_switch(actions[n+1].SWF_ACTIONIF.Actions[0].SWF_ACTIONRECORD.ActionCode)) + { + push(right); // keep left and right side separated + push(left); // because it seems we have found a switch(){} and + break; // let decompileIF() once more do all the dirty work + } + } + #endif if( actions[n+1].SWF_ACTIONRECORD.ActionCode == SWFACTION_LOGICALNOT && actions[n+2].SWF_ACTIONRECORD.ActionCode != SWFACTION_IF ) { *************** *** 1698,1701 **** --- 1718,1824 ---- } // ... and let decompileIF() do all the dirty work ;-) + + #ifdef DECOMP_SWITCH + + static union SWF_ACTION * + getAllSwitchActions(union SWF_ACTION *dest,union SWF_ACTION *actions) + { + *dest++=*actions; + if (actions->SWF_ACTIONRECORD.ActionCode==SWFACTION_IF) + { + int i; + struct SWF_ACTIONIF *sactv2 = (struct SWF_ACTIONIF*)actions; + for(i=0; i< sactv2->numActions ;i++) + { + dest=getAllSwitchActions(dest,&sactv2->Actions[i]); + } + } + return dest; + } + + static int + countAllSwitchActions (union SWF_ACTION *actions) + { + int i,j=1; + if (actions->SWF_ACTIONRECORD.ActionCode==SWFACTION_IF) + { + for(i=0; i < ((struct SWF_ACTIONIF*)actions)->numActions; i++) + { + j+=countAllSwitchActions(&((struct SWF_ACTIONIF*)actions)->Actions[i]); + } + } + return j; + } + + // looks similar other decompileXXXX() but is never called by decompileAction() + // only called after some preparation by decompileIF() + // + static int + decompile_SWITCH(int n, SWF_ACTION *actions,int maxn) + { + int i,y,z; + int maxi=0; + int minimaloffset =99999999; + struct _stack *StackSave; + struct SWF_ACTIONPUSHPARAM *swcopy,*sw=pop(); + struct SWF_ACTIONPUSHPARAM *compare=pop(); + INDENT + println("switch( %s ) {",getName(sw)); + push(sw); + push(compare); + + for(i=1;i<maxn-1;i++) + { + if (actions[i].SWF_ACTIONRECORD.ActionCode==SWFACTION_IF + && actions[i-1].SWF_ACTIONRECORD.ActionCode==SWFACTION_STRICTEQUALS ) + { + struct SWF_ACTIONIF *sactv2 = (struct SWF_ACTIONIF*)&actions[i]; + INDENT + println("case %s:",getName(pop())); + swcopy=pop(); + SanityCheck(decompile_SWITCH,!strcmp(getName(swcopy),getName(sw)),"sw0 != sw"); + + z=i; + while (actions[z].SWF_ACTIONRECORD.Offset < actions[i+1].SWF_ACTIONRECORD.Offset+sactv2->BranchOffset) + { + z++; + } + if (actions[z].SWF_ACTIONRECORD.Offset<minimaloffset) + minimaloffset=actions[z].SWF_ACTIONRECORD.Offset; + y=0; + while (actions[y+z].SWF_ACTIONRECORD.ActionCode!=SWFACTION_JUMP) // fixme: could be too less + { + y++; + } + y++; + if (z+y>maxi) + { + maxi=y+z; + } + StackSave=Stack; + decompileActions( y, &actions[z],gIndent+1); + Stack=StackSave; + if (actions[i+1].SWF_ACTIONRECORD.ActionCode==SWFACTION_JUMP) + { + break; + } + y=0; + + while (actions[y+i].SWF_ACTIONRECORD.ActionCode!=SWFACTION_STRICTEQUALS + && actions[y+i].SWF_ACTIONRECORD.Offset<minimaloffset) + { + y++; + } + y--; + decompileActions( y, &actions[i+1],gIndent+1); // at least one push on stack expected + i+=y; + } + } + INDENT + println("}"); + return maxi; + } + #endif + int decompileIF(int n, SWF_ACTION *actions,int maxn) *************** *** 1917,1920 **** --- 2040,2061 ---- return 0; } + #ifdef DECOMP_SWITCH + if ( actions[n-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_STRICTEQUALS + && check_switch(sact->Actions[0].SWF_ACTIONRECORD.ActionCode) ) + { + union SWF_ACTION *xact,*xact0; + for(i=n-1,j=0; i< maxn ;i++) // n-1 due adding 1st SWFACTION_STRICTEQUALS in buffer + { + j+=countAllSwitchActions(&actions[i]); // FIRST count size of code + } + xact0=xact = (union SWF_ACTION *) calloc (j,sizeof (SWF_ACTION)); + println("/* checking %d actions for switch(){} */",j); + for(i=n-1; i< maxn ;i++) + { + xact=getAllSwitchActions(xact,&actions[i]); // SECOND copy into xtra buffer + } + return decompile_SWITCH(0,xact0,j); // THIRD decompile xtra buffer + } + #endif /* it seems we have a found the REAL 'if' statement, so it's right time to print the "if" just NOW! |