blob: a38645379f192f045597d5551c30415b99914046 [file] [log] [blame]
/* 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;
}