| /* d6-arith.cpp */ |
| /* |
| Java Decompiler |
| Copyright (c) 1994-2003, Pete Ryland. |
| Distributed under the GNU GPL Version 2. |
| This package is available from http://pdr.cx/hbd/ |
| */ |
| |
| #include "exp.h" |
| #include "class.h" |
| #include "decomp.h" |
| #include "cp.h" |
| |
| extern int cond_pcend; |
| extern Exp *cond_e; |
| extern Exp *cond_e2; |
| extern Exp **cond_donestkptr; |
| extern Exp **cond_stkptr; |
| |
| int pushbinop(Classfile *c) /* push binary operation, popping operands e.g. lxor */ |
| { |
| unsigned pcval = currpc - 1; |
| Exp *e2 = *(--stkptr); |
| Exp *e1 = *(stkptr-1); |
| *(stkptr-1) = new Exp(pcval, min(min(e1->minpc, e2->minpc), pcval), BINARY, |
| e1->e->type, |
| (Op)((ch < 0x74)? |
| ((ch - 0x60) >> 2) : (0x07 + ((ch - 0x78) >> 1))), |
| e1, e2); |
| return 0; |
| } |
| |
| int pushunop(Classfile *c) /* push unary operation, popping operand e.g. lneg */ |
| { |
| unsigned pcval = currpc - 1, branch_pc; |
| char *tmpstr, *buff; |
| Exp *e1 = *(stkptr-1); |
| Op eop = CAST; |
| Type etype = VOID; |
| int val; |
| switch (ch) { |
| case 0x74: case 0x75: case 0x76: case 0x77: eop = NEG; etype = e1->e->type; break; |
| case 0x88: case 0x8B: case 0x8E: etype = INT; break; |
| case 0x85: case 0x8C: case 0x8F: etype = LONG; break; |
| case 0x86: case 0x89: case 0x90: etype = FLOAT; break; |
| case 0x87: case 0x8A: case 0x8D: etype = DOUBLE; break; |
| case 0x91: etype = BYTE; break; |
| case 0x92: etype = CHAR; break; |
| case 0x93: etype = SHORT; break; |
| case 0xBF: |
| --stkptr; |
| *donestkptr++ = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, VOID, THROW, e1); |
| return 0; |
| case 0xBB: |
| val = JDNEXT16U(); |
| tmpstr = c->cp(val)->chp; |
| buff = new char[strlen(tmpstr) + 1]; strcpy(buff, tmpstr); |
| e1 = new Exp(pcval, buff, VOID, CP, val); |
| *(stkptr++) = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, OBJECT, NEW, e1); |
| // if ((ch = JDNEXT8()) == 0x59) |
| // return actiontable[actions[ch = JDNEXT8()]](); |
| // else |
| // return actiontable[actions[ch]](); |
| case 0xBA: eop = NEW; break; |
| case 0xA7: /* GOTO really shouldn't be here! */ |
| if (stkptr!=stack) { |
| // if (stkptr!=(stack+1)) { fprintf(stderr, "Error in conditional operator!\n"); return 1; } |
| if (cond_pcend != -1) { fprintf(stderr, "Can't handle recursive conditional operators!\n"); return 1; } |
| cond_pcend = pcval + JDNEXT16S(); |
| cond_stkptr = stkptr; |
| cond_e2 = *(--stkptr); |
| --donestkptr; |
| if ((*donestkptr)->e->et == BRANCH) { |
| if ((*donestkptr)->branch_pc != currpc) { |
| fprintf(stderr, "Error in conditional operator!\n"); return 1; |
| } |
| cond_e = *donestkptr; |
| } else { |
| fprintf(stderr, "Use of comma operator in conditionals not yet supported.\n"); |
| return 1; |
| } |
| cond_donestkptr = donestkptr; |
| return 0; |
| } |
| branch_pc = pcval + JDNEXT16S(); |
| tmpstr = new char[100]; |
| sprintf(tmpstr,"label%i", branch_pc); |
| buff = new char[strlen(tmpstr) + 1]; strcpy(buff, tmpstr); |
| delete [] tmpstr; |
| e1 = new Exp(pcval, buff, VOID/*label*/, IM); |
| *donestkptr++ = new Exp(pcval, PREUNARY, VOID, GOTO, e1, branch_pc); |
| return 0; |
| default: |
| fprintf(stderr, "Error in pushing unary operation\n"); |
| exit(-1); |
| } |
| *(stkptr-1) = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, etype, eop, e1); |
| return 0; |
| } |