1509 lines · 23.5 KB · C
RawDownload
#include "java.h"#include "javaisa.h" /* * "Simulate" the Java VM on a method. */ typedef struct Result	Result; struct Result {	uchar	jtype;	int	pc;}; static	Result	*jvmstack;	/* simulated JVM stack */static	int	jvmtos;		/* number of items in jvmstack */static	int	jvmwords;	/* number of words that would be on JVM stack */static	uchar	rettype;	/* return type of simulated method */ static Resultjvmpop(void){	Result r; 	if(jvmtos == 0)		goto bad;	r = jvmstack[--jvmtos];	if(r.jtype == 'J' || r.jtype == 'D')		jvmwords -= 2;	else		jvmwords -= 1;	if(jvmwords < 0)bad:		verifyerrormess("stack underflow");	return r;} static voidjvmpush(Result r){	if(r.jtype == 'J' || r.jtype == 'D')		jvmwords += 2;	else		jvmwords += 1;	if(jvmwords > code->max_stack)		verifyerrormess("stack overflow");	jvmstack[jvmtos++] = r;} /* * Initialize jvmstack to process basic block bb. */ static voidjvminit(BB *bb){	int i;	Result r;	StkSnap *s; 	jvmtos = 0;	jvmwords = 0;	if(bb->flags & (BB_FINALLY | BB_HANDLER)) {		r.jtype = 'L';		r.pc = code->code_length;		jvmpush(r);	/* push a dummy */		return;	} 	/* set jvmstack to bb->entrystk */	s = bb->entrystk;	for(i = 0; i < bb->entrysz; i++) {		r.jtype = s[i].jtype;		r.pc = s[i].pc[0];		jvmpush(r);	}} static voidtypecheck(Result *r, uchar jtype){	/* assumes 'L' and '[' are interchangeable */	if(r->jtype != jtype && r->jtype + jtype != 'L' + '[')		verifyerror(&code->j[r->pc]);} static ucharjvmtype(uchar jtype){	switch(jtype) {	case 'Z':	case 'B':	case 'C':	case 'S':		jtype = 'I';		break;	}	return jtype;} static voidsetresult(Result *r, uchar jtype, Jinst *j){	r->jtype = jtype;	r->pc = j->pc;	j->jtype = jtype;} static voidsrcalloc(Jinst *j, int n){	j->nsrc = n;	j->src = Malloc(n*sizeof(int));} static voidiconst(Jinst *j, int ival){	Result r; 	addrimm(&j->dst, ival);	setresult(&r, 'I', j);	jvmpush(r);} static voidmpconst(Jinst *j, uchar jtype, int off){	Result r; 	addrsind(&j->dst, Amp, off);	setresult(&r, jtype, j);	jvmpush(r);} static voidverifyindex(Jinst *j, uchar jtype, int ix){	int n; 	switch(jtype) {	case 'I':	case 'F':	case 'L':		n = code->max_locals-1;		break;	case 'J':	case 'D':		n = code->max_locals-2;		break;	default:		fatal("verifyindex: invalid jtype");		return;	}	if(ix > n)		verifyerror(j);} static intgetfpoff(uchar jtype, int ix){	int off; 	switch(jtype) {	case 'I':		off = localix(DIS_W, ix);		break;	case 'J':	case 'F':	case 'D':		off = localix(DIS_L, ix);		break;	case 'L':		off = localix(DIS_P, ix);		break;	default:		fatal("getfpoff: invalid jtype");		return -1;	}	return off;} static voidjavaload(Jinst *j, uchar jtype, int ix){	Result r; 	verifyindex(j, jtype, ix);	addrsind(&j->dst, Afp, getfpoff(jtype, ix));	setresult(&r, jtype, j);	jvmpush(r);} static voidjavastore(Jinst *j, uchar jtype, int ix){	Result r; 	verifyindex(j, jtype, ix); 	srcalloc(j, 1); 	r = jvmpop();	typecheck(&r, jtype);	j->src[0] = r.pc; 	addrsind(&j->dst, Afp, getfpoff(jtype, ix));} static voidarrayload(Jinst *j, uchar jtype){	Result r; 	srcalloc(j, 2); 	r = jvmpop();	typecheck(&r, 'I');	j->src[1] = r.pc; 	r = jvmpop();	typecheck(&r, '[');	j->src[0] = r.pc; 	addrsind(&j->dst, Afp, -1);	setresult(&r, jtype, j);	jvmpush(r);} static voidarraystore(Jinst *j, uchar jtype){	Result r; 	srcalloc(j, 3); 	r = jvmpop();	typecheck(&r, jtype);	j->src[2] = r.pc; 	r = jvmpop();	typecheck(&r, 'I');	j->src[1] = r.pc; 	r = jvmpop();	typecheck(&r, '[');	j->src[0] = r.pc; } static voidbinop(Jinst *j, uchar loptype, uchar roptype, uchar dsttype){	Result r; 	srcalloc(j, 2); 	r = jvmpop();	typecheck(&r, roptype);	j->src[1] = r.pc; 	r = jvmpop();	typecheck(&r, loptype);	j->src[0] = r.pc; 	addrsind(&j->dst, Afp, -1);	setresult(&r, dsttype, j);	jvmpush(r);} static voidunop(Jinst *j, uchar srctype, uchar dsttype){	Result r; 	srcalloc(j, 1); 	r = jvmpop();	typecheck(&r, srctype);	j->src[0] = r.pc; 	addrsind(&j->dst, Afp, -1);	setresult(&r, dsttype, j);	jvmpush(r);} /* * If the local variable being stored into corresponds to a local * that is on the stack, then an explicit mov_ MUST be generated * for the load instruction that put it on the stack. */ static voidstorechk(int six, uchar stype){	int i, lix;	uchar ltype;	Jinst *j; 	for(i = 0; i < jvmtos; i++) {		j = &code->j[jvmstack[i].pc];		lix = -1;		switch(j->op) {		case Jiload:		case Jlload:		case Jfload:		case Jdload:		case Jaload:			lix = j->u.i;			break;		case Jiload_0:		case Jlload_0:		case Jfload_0:		case Jdload_0:		case Jaload_0:			lix = 0;			break;		case Jiload_1:		case Jlload_1:		case Jfload_1:		case Jdload_1:		case Jaload_1:			lix = 1;			break;		case Jiload_2:		case Jlload_2:		case Jfload_2:		case Jdload_2:		case Jaload_2:			lix = 2;			break;		case Jiload_3:		case Jlload_3:		case Jfload_3:		case Jdload_3:		case Jaload_3:			lix = 3;			break;		case Jwide:			switch(j->u.w.op) {			case Jiload:			case Jlload:			case Jfload:			case Jdload:			case Jaload:				lix = j->u.w.ix;			}			break;		}		ltype = '-';		switch(j->op) {		case Jiload:		case Jiload_0:		case Jiload_1:		case Jiload_2:		case Jiload_3:			ltype = 'I';			break;		case Jlload:		case Jlload_0:		case Jlload_1:		case Jlload_2:		case Jlload_3:			ltype = 'J';			break;		case Jfload:		case Jfload_0:		case Jfload_1:		case Jfload_2:		case Jfload_3:			ltype = 'F';			break;		case Jdload:		case Jdload_0:		case Jdload_1:		case Jdload_2:		case Jdload_3:			ltype = 'D';			break;		case Jaload:		case Jaload_0:		case Jaload_1:		case Jaload_2:		case Jaload_3:			ltype = 'L';			break;		case Jwide:			switch(j->u.w.op) {			case Jiload:				ltype = 'I';				break;			case Jlload:				ltype = 'J';				break;			case Jfload:				ltype = 'F';				break;			case Jdload:				ltype = 'D';				break;			case Jaload:				ltype = 'L';				break;			}			break;		}		if(lix == six && ltype == stype && j->movsrc.mode == Anone) {			j->movsrc = j->dst;			addrsind(&j->dst, Afp, -1);		}	}} static voiduseone(Jinst *j, uchar jtype){	Result r; 	srcalloc(j, 1); 	r = jvmpop();	typecheck(&r, jtype);	j->src[0] = r.pc;} static voidusetwo(Jinst *j, uchar loptype, uchar roptype){	Result r; 	srcalloc(j, 2); 	r = jvmpop();	typecheck(&r, roptype);	j->src[1] = r.pc; 	r = jvmpop();	typecheck(&r, loptype);	j->src[0] = r.pc;} static voidjavanew(Jinst *j){	Result r;	char *name; 	name = CLASSNAME(j->u.i);	if(name[0] == '[')		verifyerror(j); 	addrsind(&j->dst, Afp, -1);	setresult(&r, 'L', j);	jvmpush(r);	crefenter(name, j->bb);} static intcheckdim(Jinst *j, int ix){	int ndim;	char *name; 	ndim = 0;	name = CLASSNAME(ix);	while(name[0] == '[') {		ndim++;		name++;	}	if(ndim > 255)		verifyerror(j);	crefenter(name, j->bb);	return ndim;} static voidanewarray(Jinst *j){	checkdim(j, j->u.i);	unop(j, 'I', '[');} static voidmultianewarray(Jinst *j){	Result r;	int i, ndim; 	ndim = checkdim(j, j->u.x2d.ix);	if(ndim == 0 || j->u.x2d.dim > ndim)		verifyerror(j); 	srcalloc(j, j->u.x2d.dim); 	for(i = j->u.x2d.dim-1; i >= 0; i--) {		r = jvmpop();		typecheck(&r, 'I');		j->src[i] = r.pc;	} 	addrsind(&j->dst, Afp, -1);

Lines 1–500 of 1509.