Dmitry Kabak (userdimaRemoved some obsolete debug outputbfe96f613 years agoHistory
2960 lines · 52.7 KB · Brainfuck
RawDownload
pcdis:		int;callunrescue:	int;J:		ref Jinst;M:		ref Method;code:		ref Code;		# method under translation trylevel:	fn(pc: int): int;unrescue:	fn(n: int); ## Allocate a Dis instruction.# newi(op: int): ref Inst{	i: ref Inst; 	i = ref Inst(byte op, nil, nil, nil, pcdis, J, nil);	i.s = ref Addr(byte 0, 0, 0);	i.m = ref Addr(byte 0, 0, 0);	i.d = ref Addr(byte 0, 0, 0);	pcdis += 1;	if(J != nil && J.dis == nil)		J.dis = i;	if(ihead == nil)		ihead = i;	if(itail != nil)		itail.next = i;	itail = i;	return i;} ## Allocate a Dis instruction and record for branch-address patching.# newibap(op: int): ref Inst{	i: ref Inst; 	i = newi(op);	patchop(i);	return i;} ## Turn single indirection off fp into double indirection.# sind2dind(a: ref Addr, s: int){	if(a.mode == byte Afp) {		a.mode = byte Afpind;		a.ival = a.offset;		a.offset = s;	} else if(a.mode == byte Amp && a.offset == 0)		;	# verifyerror(J); # can't reject prior to runtime	else		fatal("sind2dind: " + string a.mode + " not Afp");} ## Middle operands that match destination operands are redundant.# middstcmp(i: ref Inst){	m, d: ref Addr; 	m = i.m;	d = i.d;	if(m.mode == Afp && m.mode == d.mode && m.offset == d.offset) {		m.mode = Anone;		m.offset = 0;	}} ## For instructions that may reference Module Data.# datareloc(i: ref Inst){	if(i.op == byte IMOVP && i.s.mode == byte Amp && i.s.offset == 0)		return;		# don't relocate reference to nil	if(i.s.mode == byte Amp)		addDreloc(i, PSRC, PSIND);	if(i.m.mode == byte Amp)		addDreloc(i, PMID, PSIND);} movinst(jtype: int): int{	movi: int; 	case jtype {	'Z' or	'B' =>		if(J.op == byte Jgetfield || J.op == byte Jgetstatic)			movi = ICVTBW;		else if(J.op == byte Jputfield || J.op == byte Jputstatic)			movi = ICVTWB;		else			movi = IMOVW;	'C' or	'S' or	'I' =>		movi = IMOVW;	'J' =>		movi = IMOVL;	'F' or	'D' =>		movi = IMOVF;	'L' or	'[' =>		movi = IMOVP;	}	return movi;} FieldInfo: adt {	classname:	string;	fieldname:	string;	sig:		string;	flags:		int;}; getfldinfo(): ref FieldInfo{	i: int;	m: ref Method;	fi: ref FieldInfo = ref FieldInfo(nil, nil, nil, 0);	ix: int; 	pick jp := J {	Pi =>		ix = jp.i;	Px2c0 =>		ix = jp.x2c0.ix;	* =>		badpick("getfldinfo[Pi|Px2c0]");	} 	pick c := class.cps[ix] {	Pfmiref =>		fi.classname = CLASSNAME(c.fmiref.class_index);		pick n := class.cps[c.fmiref.name_type_index] {		Pnat =>			fi.fieldname = STRING(n.nat.name_index);			fi.sig = STRING(n.nat.sig_index);		* =>			badpick("getfldinfo[Pnat]");		}	* =>		badpick("getfldinfo[Pfmiref]");	}	fi.flags = 0;	if(fi.classname != THISCLASS)		return fi;	for(i = 0; i < class.methods_count; i++) {		m = class.methods[i];		if(fi.fieldname == STRING(m.name_index)		&& fi.sig == STRING(m.sig_index)) {			fi.flags = m.access_flags;			break;		}	}	return fi;} ## mframe instruction for a call to a Loader entry point.# loadermframe(frm: ref Freloc, frf: ref Freloc): ref Inst{	imframe: ref Inst; 	imframe = newi(IMFRAME);	addrsind(imframe.s, Amp, 0);	addrimm(imframe.m, 0);	addrsind(imframe.d, Afp, getreg(DIS_W));	LTIpatch(frm, imframe, PSRC, PSIND);	LTIpatch(frf, imframe, PMID, PIMM); 	return imframe;} ## mcall instruction for a call to a Loader entry point.# loadermcall(imframe: ref Inst, frf: ref Freloc, frm: ref Freloc): ref Inst{	imcall: ref Inst; 	imcall = newi(IMCALL);	*imcall.s = *imframe.d;	*imcall.m = *imframe.m;	*imcall.d = *imframe.s;	LTIpatch(frf, imcall, PMID, PIMM);	LTIpatch(frm, imcall, PDST, PSIND); 	return imcall;} ## Call "rtload" for run-time resolution.# rtcache:	array of string;rtncache:	int;rtnmax:		int; callrtload(rtc: ref RTClass, classname: string){	j: int;	imframe, i: ref Inst;	cr: ref Creloc;	frm, frf: ref Freloc;	rtr: ref RTReloc; 	# rtload() already called for classname in this basic block ?	for(j = 0; j < rtncache; j++) {		if(rtcache[j] == classname)			return;	}	if(rtncache >= rtnmax) {		oldrtnmax := rtnmax;		rtnmax += ALLOCINCR;		newrtcache := array [rtnmax] of string;		for(k := 0; k < oldrtnmax; k++)			newrtcache[k] = rtcache[k];		rtcache = newrtcache;	}	rtcache[rtncache++] = classname; 	rtr = getRTReloc(rtc, RMP, nil, 0);	cr = getCreloc(RLOADER);	frm = getFreloc(cr, RMP, nil, 0);	frf = getFreloc(cr, "rtload", nil, 0); 	i = newi(IBNEW);	addrsind(i.s, Amp, 0);	addrsind(i.m, Amp, 0);	addrimm(i.d, i.pc+4);	RTIpatch(rtr, i, PSRC, PSIND); 	imframe = loadermframe(frm, frf); 	i = newi(ILEA);	addrsind(i.s, Amp, 0);	addrdind(i.d, Afpind, imframe.d.offset, REGSIZE);	RTIpatch(rtr, i, PSRC, PSIND); 	loadermcall(imframe, frf, frm);	relreg(imframe.d);} ## Sign-extend an 8-bit unsigned char (Dis byte) to a 32-bit int.# signextend(dst: ref Addr){	i: ref Inst; 	i = newi(ISHLW);	addrimm(i.s, 24);	# *i.m = *dst; # redundant	*i.d = *dst; 	i = newi(ISHRW);	addrimm(i.s, 24);	# *i.m = *dst; # redundant	*i.d = *dst;} ## addw instruction for run-time relocated getstatic & putstatic.# rtstaticadd(fi: ref FieldInfo, rtc: ref RTClass): ref Addr{	i: ref Inst; 	i = newi(IADDW);	addrdind(i.s, Ampind, 0, 0);	addrsind(i.m, Amp, 0);	addrsind(i.d, Afp, getreg(DIS_W)); 	RTIpatch(getRTReloc(rtc, RMP, nil, 0), i, PSRC, PDIND1);	RTIpatch(getRTReloc(rtc, fi.fieldname, fi.sig, Rgetputstatic),		i, PMID, PSIND); 	return i.d;} ## Run-time relocated getstatic.# rtgetstatic(fi: ref FieldInfo){	a: ref Addr;	i: ref Inst;	rtc: ref RTClass; 	rtc = getRTClass(fi.classname);	callrtload(rtc, fi.classname);	a = rtstaticadd(fi, rtc); 	i = newi(movinst(fi.sig[0]));	*i.s = *a;	sind2dind(i.s, 0);	relreg(a);	dstreg(J.dst, j2dtype(J.jtype));	*i.d = *J.dst; 	if(fi.sig[0] == 'B')		signextend(i.d);} ## Run-time relocated putstatic.# rtputstatic(fi: ref FieldInfo){	a: ref Addr;	i: ref Inst;	rtc: ref RTClass; 	rtc = getRTClass(fi.classname);	callrtload(rtc, fi.classname);	a = rtstaticadd(fi, rtc); 	i = newi(movinst(fi.sig[0]));	*i.s = *code.j[J.src[0]].dst;	relreg(code.j[J.src[0]].dst);	*i.d = *a;	sind2dind(i.d, 0);	relreg(a);	datareloc(i);} ## addw instruction for load-time relocated getstatic & putstatic.# ltstaticadd(fi: ref FieldInfo): ref Addr{	i: ref Inst;	cr: ref Creloc; 	i = newi(IADDW);	addrdind(i.s, Ampind, 0, 0);	addrimm(i.m, 0);	addrsind(i.d, Afp, getreg(DIS_W)); 	cr = getCreloc(fi.classname);	LTIpatch(getFreloc(cr, RMP, nil, 0), i, PSRC, PDIND1);	LTIpatch(getFreloc(cr, fi.fieldname, fi.sig, Rgetputstatic),		i, PMID, PIMM); 	return i.d;} ## Load-time relocated getstatic.# getstatic(){	i: ref Inst;	a: ref Addr;	fi: ref FieldInfo; 	fi = getfldinfo();	if(dortload(fi.classname)) {		rtgetstatic(fi);		return;	} 	a = ltstaticadd(fi); 	i = newi(movinst(fi.sig[0]));	*i.s = *a;	sind2dind(i.s, 0);	relreg(a);	dstreg(J.dst, j2dtype(J.jtype));	*i.d = *J.dst; 	if(fi.sig[0] == 'B')		signextend(i.d);} ## Load-time relocated putstatic.# putstatic(){	i: ref Inst;	a: ref Addr;	fi: ref FieldInfo; 	fi = getfldinfo();	if(dortload(fi.classname)) {		rtputstatic(fi);		return;	} 	a = ltstaticadd(fi); 	i = newi(movinst(fi.sig[0]));	*i.s = *code.j[J.src[0]].dst;	relreg(code.j[J.src[0]].dst);	*i.d = *a;	sind2dind(i.d, 0);	relreg(a);	datareloc(i);} ## addw instruction for run-time relocated getfield & putfield.# rtfieldadd(fi: ref FieldInfo, rtc: ref RTClass, a: ref Addr): ref Addr{	i: ref Inst; 	i = newi(IADDW);	*i.s = *a;	addrsind(i.m, Amp, 0);	addrsind(i.d, Afp, getreg(DIS_W)); 	RTIpatch(getRTReloc(rtc, fi.fieldname, fi.sig, Rgetputfield),		i, PMID, PSIND); 	return i.d;} ## Run-time relocated getfield.# rtgetfield(fi: ref FieldInfo){	a: ref Addr;	i: ref Inst;	rtc: ref RTClass; 	rtc = getRTClass(fi.classname);	callrtload(rtc, fi.classname);	a = rtfieldadd(fi, rtc, code.j[J.src[0]].dst);	relreg(code.j[J.src[0]].dst); 	i = newi(movinst(fi.sig[0]));	*i.s = *a;	sind2dind(i.s, 0);	relreg(a);	dstreg(J.dst, j2dtype(J.jtype));	*i.d = *J.dst; 	if(fi.sig[0] == 'B')		signextend(i.d);} ## Run-time relocated putfield.# rtputfield(fi: ref FieldInfo){	a: ref Addr;	i: ref Inst;	rtc: ref RTClass; 	rtc = getRTClass(fi.classname);	callrtload(rtc, fi.classname);	a = rtfieldadd(fi, rtc, code.j[J.src[0]].dst);	relreg(code.j[J.src[0]].dst); 	i = newi(movinst(fi.sig[0]));	*i.s = *code.j[J.src[1]].dst;	relreg(code.j[J.src[1]].dst);	*i.d = *a;	relreg(a);	sind2dind(i.d, 0);	datareloc(i);} ## Load-time relocated getfield.# getfield(){	i: ref Inst;

Lines 1–500 of 2960.