389 lines · 6.8 KB · Brainfuck
RawDownload
## Manage run-time resolution information.# LTLOAD:	con 6; ltload :=	array [LTLOAD] of {	"java/lang/Class",	"java/lang/Object",	"java/lang/String",	"java/lang/StringBuffer",	"inferno/vm/Array",	"java/io/Serializable"}; dortload(name: string): int{	i: int; 	if(name == nil || name == THISCLASS || name == SUPERCLASS)		return 0;	for(i = 0; i < LTLOAD; i++) {		if(name == ltload[i])			return 0;	}	return 1;} RTHash: adt {	rtc:	ref RTClass;	next:	cyclic ref RTHash;}; rttbl :=	array [Hashsize] of ref RTHash;	# hash table of ref'd classesnrtclasses:	int;				# no. of classes referenced rtappend(rtc: ref RTClass, rtr: ref RTReloc){	if(rtc.rtr == nil)		rtc.rtr = rtr;	else		rtc.tail.next = rtr;	rtc.tail = rtr;} rtprepend(rtc: ref RTClass, rtr: ref RTReloc){	if(rtc.rtr == nil)		rtc.tail = rtr;	rtr.next = rtc.rtr;	rtc.rtr = rtr;} ## Add RTReloc entry.# addRTReloc(rtc: ref RTClass, field: string, sig: string, flags: int): ref RTReloc{	rtr: ref RTReloc; 	rtr = ref RTReloc(field, sig, flags, nil, nil);	rtr.ipatch = ref Ipatch(0, 0, nil, nil);	if(field[0] == '@')	# these must go first in the list !		rtprepend(rtc, rtr);	else		rtappend(rtc, rtr);	rtc.n += 1;	return rtr;} ## Allocate a RTClass structure.# newRTClass(s: string): ref RTClass{	rtc: ref RTClass; 	rtc = ref RTClass(s, nil, nil, 0, 0);	nrtclasses += 1;	# want the order: @mp, @np, @adt, @Class	addRTReloc(rtc, RCLASS, nil, 0);	addRTReloc(rtc, RADT, nil, 0);	addRTReloc(rtc, RNP, nil, 0);	addRTReloc(rtc, RMP, nil, 0);	return rtc;} ## Add RTClass entry for classname.# addRTClass(classname: string): ref RTClass{	h: int;	he: ref RTHash; 	h = hashval(classname);	he = ref RTHash(newRTClass(classname), rttbl[h]);	rttbl[h] = he;	return he.rtc;} ## Get RTClass entry for classname.# getRTClass(classname: string): ref RTClass{	he: ref RTHash; 	for(he = rttbl[hashval(classname)]; he != nil; he = he.next) {		if(classname == he.rtc.classname)			return he.rtc;	}	return addRTClass(classname);} ## Get RTReloc entry.  Ignore signature if nil.# getRTReloc(rtc: ref RTClass, field: string, sig: string, flags: int): ref RTReloc{	rtr: ref RTReloc;	lowflags: int; 	lowflags = 0;	for(rtr = rtc.rtr; rtr != nil; rtr = rtr.next) {		if(rtr.field == field && (sig == nil || rtr.sig == sig)) {			if(rtr.flags >> 16 == 0) {				rtr.flags |= flags;				return rtr;			} else if(rtr.flags >> 16 == flags >> 16)				return rtr;			lowflags = rtr.flags & 16rffff;		}	} 	return addRTReloc(rtc, field, sig, flags|lowflags);} ## Add instruction patch information to RTReloc rtr.# RTIpatch(rtr: ref RTReloc, i: ref Inst, operand: int, patchkind: int){	addDreloc(i, operand, patchkind);	addIpatch(rtr.ipatch, i, operand, patchkind, SAVEINST);} ## Fix RTClass and RTReloc 'off' fields to prepare for instruction patch.# RTfixoff(off: int){	he: ref RTHash;	i: int; 	if(nrtclasses > 0) {		for(i = 0; i < Hashsize; i++) {			for(he = rttbl[i]; he != nil; he = he.next) {				he.rtc.off = off;				off += he.rtc.n * IBY2WD;			}		}	}} ## Patch instructions for run-time relocation.# doRTpatch(){	a: ref Addr;	he: ref RTHash;	ip: ref Ipatch;	rtr: ref RTReloc;	i, j: int;	off, ltsize: int; 	if(nrtclasses == 0)		return; 	ltsize = LTrelocsize();	for(i = 0; i < Hashsize; i++) {		for(he = rttbl[i]; he != nil; he = he.next) {			off = he.rtc.off - ltsize;			for(rtr = he.rtc.rtr; rtr != nil; rtr = rtr.next) {				ip = rtr.ipatch;				for(j = 0; j < ip.n; j++) {					case(ip.pinfo[j] & (16r3 << 2)) {					PSRC =>						a = ip.i[j].s;					PDST =>						a = ip.i[j].d;					PMID =>						a = ip.i[j].m;					}					case (ip.pinfo[j] & 16r3) {					PIMM or					PDIND1 =>						a.ival = off;					PSIND or					PDIND2 =>						a.offset = off;					}				}				off += IBY2WD;			}		}	}} ## Size of Module Data space taken by run-time relocation information.# RTrelocsize(): int{	i: int;	n: int;	he: ref RTHash; 	n = 0;	if(nrtclasses > 0) {		for(i = 0; i < Hashsize; i++) {			for(he = rttbl[i]; he != nil; he = he.next)				n += he.rtc.n;		}	}	return n * IBY2WD;} ## Fix type descriptor for run-time relocation information.# RTReloctid:	int; RTrelocdesc(map: array of byte, off: int){	i: int;	he: ref RTHash;	rtr: ref RTReloc; 	if(nrtclasses == 0)		return; 	RTReloctid = descid(3*IBY2WD, 1, array [1] of { byte 16rc0 }); 	for(i = 0; i < Hashsize; i++) {		for(he = rttbl[i]; he != nil; he = he.next) {			setbit(map, off);	# @mp cell			off += 4;			setbit(map, off);	# @np cell			off += 4;			setbit(map, off);	# @adt cell			off += 8;			rtr = he.rtc.rtr.next.next.next.next;			while(rtr != nil) {				if(rtr.flags & (Rspecialmp | Rstaticmp))					setbit(map, off);				off += 4;				rtr = rtr.next;			}		}	}} ## Write RTReloc array to .s file.# asmRTReloc(off: int, rtc: ref RTClass){	rtr: ref RTReloc;	reloff: int;		# relative offset for array elements 	if(rtc.n <= 4)		return; 	reloff = 0;	asmarray(off, RTReloctid, rtc.n - 4, reloff);	# skip @mp @np @adt @Class	rtr = rtc.rtr.next.next.next.next;	while(rtr != nil) {		asmstring(reloff, rtr.field);		reloff += IBY2WD;		if(rtr.sig != nil)			asmstring(reloff, rtr.sig);		reloff += IBY2WD;		asmint(reloff, rtr.flags);		reloff += IBY2WD;		rtr = rtr.next;	}	bout.puts("\tapop\n");} ## Write RTClass information to .s file.# asmRTClass(off: int): int{	he: ref RTHash;	i: int;	ltsize: int; 	if(nrtclasses > 0) {		ltsize = LTrelocsize();		for(i = 0; i < Hashsize; i++) {			for(he = rttbl[i]; he != nil; he = he.next) {				off += IBY2WD;	# @mp cell				asmstring(off, he.rtc.classname);				off += IBY2WD;				asmRTReloc(off, he.rtc);				off += IBY2WD;				asmint(off, he.rtc.off - ltsize);				off += IBY2WD;				# account for fields beyond @Class				off += (he.rtc.n - 4) * IBY2WD;			}		}	}	return off;} ## Write RTReloc array to .dis file.# disRTReloc(off: int, rtc: ref RTClass){	rtr: ref RTReloc;	reloff: int;		# relative offset for array elements 	if(rtc.n <= 4)		return; 	reloff = 0;	disarray(off, RTReloctid, rtc.n - 4);	# skip @mp @np @adt @Class	rtr = rtc.rtr.next.next.next.next;	while(rtr != nil) {		disstring(reloff, rtr.field);		reloff += IBY2WD;		if(rtr.sig != nil)			disstring(reloff, rtr.sig);		reloff += IBY2WD;		disint(reloff, rtr.flags);		reloff += IBY2WD;		rtr = rtr.next;	}	disapop();} ## Write RTClass information to .dis file.# disRTClass(off: int): int{	he: ref RTHash;	i: int;	ltsize: int; 	if(nrtclasses > 0) {		ltsize = LTrelocsize();		for(i = 0; i < Hashsize; i++) {			for(he = rttbl[i]; he != nil; he = he.next) {				off += IBY2WD;	# @mp cell				disstring(off, he.rtc.classname);				off += IBY2WD;				disRTReloc(off, he.rtc);				off += IBY2WD;				disint(off, he.rtc.off - ltsize);				off += IBY2WD;				# account for fields beyond @Class				off += (he.rtc.n - 4) * IBY2WD;			}		}	}	return off;}