372 lines · 4.6 KB · C
RawDownload
#include "java.h" /* * Utility functions. */ static uchar *codeix; voiduSet(uchar *x){	codeix = x;} char*uPtr(void){	return (char*)codeix;} voiduN(int i){	codeix += i;} ucharu1(void){	return *codeix++;} ushortu2(void){	ushort l; 	l = (codeix[0]<<8) | codeix[1];	codeix += 2;	return l;} uintu4(void){	uint l; 	l = (codeix[0]<<24) | (codeix[1]<<16) | (codeix[2]<<8) | codeix[3];	codeix += 4;	return l;} voidgetattr(Attr *a){	a->name = u2();	verifycpindex(nil, a->name, 1 << CON_Utf8);	a->ln = u4();	a->info = Malloc(a->ln);	memmove(a->info, codeix, a->ln);	codeix += a->ln;} /* * Get the constantvalue_index of a ConstantValue attribute. */ intCVattrindex(Field *fp){	int i;	Attr *a; 	for(i = 0, a = fp->attr_info; i < fp->attr_count; i++, a++) {		if(strcmp(STRING(a->name), "ConstantValue") != 0)			continue;		if(a->ln != 2)			verifyerrormess("ConstantValue attribute");		return (a->info[0]<<8) | a->info[1];	}	return 0;} /* * Align 'off' on an 'align'-byte boundary ('align' is a power of 2). */ intalign(int off, int align){	align--;	return (off + align) & ~align;} /* * Set 'offset' bit in type descriptor 'map'. */ voidsetbit(uchar *map, int offset){	uchar *m; 	m = &map[offset / (8*IBY2WD)];	*m |= 1 << (7 - (offset / IBY2WD % 8));} /* * Trivial hash function from asm. */ inthashval(char *s){	int h; 	h = 0;	while(*s)		h = h*3 + *s++;	if(h < 0)		h = -h;	return h % Hashsize;} /* * Advance to the next Java type in a method descriptor. */ char*nextjavatype(char *s){	int nlb; 	nlb = 0;	for(;;) {		switch(s[0]) {		case 'L':			s = strchr(s, ';');		case 'V':		case 'Z':		case 'B':		case 'C':		case 'S':		case 'I':		case 'J':		case 'F':		case 'D':			return s+1;		case '[':			if(++nlb < 256) {				s++;				break;			}		default:			verifyerrormess("field/method descriptor");		}	}	return nil;	/* for compiler */} ucharj2dtype(uchar jtype){	uchar dtype; 	switch(jtype) {	case 'Z':	case 'B':	case 'C':	case 'S':	case 'I':		dtype = DIS_W;		break;	case 'J':	case 'F':	case 'D':		dtype = DIS_L;		break;	case 'L':	case '[':		dtype = DIS_P;		break;	default:		verifyerrormess("java data type");		return -1;	}	return dtype;} /* * $i operands */ voidaddrimm(Addr *a, int ival){	a->mode = Aimm;	a->u.ival = ival;} /* * Is an int too big to be an immediate operand? */ intnotimmable(int val){	return val < 0 && ((val >> 29) & 7) != 7 || val > 0 && (val >> 29) != 0;} /* * i(fp) and i(mp) operands */ voidaddrsind(Addr *a, uchar mode, int off){	a->mode = mode;	a->u.offset = off;} /* * i(j(fp)) and i(j(mp)) operands */ voidaddrdind(Addr *a, uchar mode, uint fi, uint si){	a->mode = mode;	a->u.b.fi = fi;	a->u.b.si = si;} /* * Assign a register to a destination operand if not already done so. */ voiddstreg(Addr *a, uchar dtype){	if(a->mode == Afp && a->u.offset == -1)		a->u.offset = getreg(dtype);} /* * Print a string. */ voidpstring(char *s){	int slen;	char *se;	char c; 	slen = strlen(s);	se = s + slen;	for(; s < se; s++) {		/* null char represented as 0xC080 in String literals */		c = s[0];		if(s+1 < se && (uchar)c == 0xC0 && (uchar)s[1] == 0x80) {			c = '\0';			s++;		}		if(c == '\n')			Bwrite(bout, "\\n", 2);		else if(c == '\t')			Bwrite(bout, "\\t", 2);		else if(c == '"')			Bwrite(bout, "\\\"", 2);		else if(c == '\\')			Bwrite(bout, "\\\\", 2);		else			Bputc(bout, c);	}} void*Malloc(uint n){	void *p; 	p = malloc(n);	if(p == nil)		fatal("out of memory\n");	return p;} void*Mallocz(uint n){	void *p; 	p = Malloc(n);	memset(p, 0, n);	return p;} void*Realloc(void *p, uint n){	if(p == nil)		p = malloc(n);	else		p = realloc(p, n);	if(p == nil)		fatal("out of memory\n");	return p;} /* * Die. */ voidfatal(char *fmt, ...){	va_list s;	char buf[1024], *out; 	va_start(s, fmt);	write(2, "fatal j2d error: ", 17);	out = doprint(buf, buf+sizeof(buf), fmt, s);	va_end(s);	write(2, buf, (int)(out-buf));	if(bout != nil)		remove(ofile);	exits("fatal");} /* * Bytecode verification. */ /* * Verify a constant pool index. */ voidverifycpindex(Jinst *j, int ix, int CON_bits){	if(ix > 0 && ix < class->cp_count && ((1 << class->cts[ix]) & CON_bits))		return; 	if(j != nil)		verifyerror(j);	else		verifyerrormess("constant pool index");} voidverifyerror(Jinst *j){	fatal("VerifyError: %J\n", j);} voidverifyerrormess(char *mess){	fatal("VerifyError: %s\n", mess);} /* * Size of frame cell of given type. */ int cellsize[DIS_P+1] = {	0,	/* DIS_X */	IBY2WD,	/* DIS_W */	IBY2LG,	/* DIS_L */	IBY2WD,	/* DIS_P */};