367 lines · 7.0 KB · Brainfuck
RawDownload
## Manage load-time resolution information.# LTHash: adt {	cr:	ref Creloc;	next:	cyclic ref LTHash;}; doclinitinits:	int;lttbl :=	array [Hashsize] of ref LTHash;	# hash table of ref'd classesthisclass:	ref Creloc;			# class under translationnltclasses:	int;				# no. of classes referenced ## Allocate a Creloc structure.# newCreloc(s: string): ref Creloc{	nltclasses += 1;	return ref Creloc(s, nil, nil, 0);} ltappend(cr: ref Creloc, fr: ref Freloc){	if(cr.fr == nil)		cr.fr = fr;	else		cr.tail.next = fr;	cr.tail = fr;} ltprepend(cr: ref Creloc, fr: ref Freloc){	if(cr.fr == nil)		cr.tail = fr;	fr.next = cr.fr;	cr.fr = fr;} ## Add Freloc entry.# addFreloc(cr: ref Creloc, field: string, sig: string, flags: int): ref Freloc{	fr: ref Freloc; 	fr = ref Freloc(field, sig, flags, nil, nil);	fr.ipatch = ref Ipatch(0, 0, nil, nil);	if(field[0] == '@')	# these must go first in the list !		ltprepend(cr, fr);	else		ltappend(cr, fr);	cr.n += 1;	return fr;} ## Add Creloc entry for classname.# addCreloc(classname: string): ref Creloc{	h: int;	he: ref LTHash; 	h = hashval(classname);	he = ref LTHash(newCreloc(classname), lttbl[h]);	lttbl[h] = he;	return he.cr;} ## Get Creloc entry for classname.# getCreloc(classname: string): ref Creloc{	he: ref LTHash; 	for(he = lttbl[hashval(classname)]; he != nil; he = he.next) {		if(classname == he.cr.classname)			return he.cr;	}	return addCreloc(classname);} ## Get Freloc entry.  Ignore signature if nil.# getFreloc(cr: ref Creloc, field: string, sig: string, flags: int): ref Freloc{	fr: ref Freloc;	lowflags: int; 	lowflags = 0;	for(fr = cr.fr; fr != nil; fr = fr.next) {		if(fr.field == field && (sig == nil || fr.sig == sig)) {			if(fr.flags >> 16 == 0) {				fr.flags |= flags;				return fr;			} else if(fr.flags >> 16 == flags >> 16)				return fr;			lowflags = fr.flags & 16rffff;		}	} 	return addFreloc(cr, field, sig, flags|lowflags);} ## Seed Creloc for this class.# thisCreloc(){	i, haveclinit: int;	fp: ref Field;	mp: ref Method; 	thisclass = addCreloc(THISCLASS); 	# class access_flags here for the benefit of interfaces	addFreloc(thisclass, RCLASS, nil, class.access_flags|compileflag); 	# data	for(i = 0; i < class.fields_count; i++) {		fp = class.fields[i];		addFreloc(thisclass, STRING(fp.name_index),			STRING(fp.sig_index), fp.access_flags);		if((fp.access_flags & ACC_STATIC) && CVattrindex(fp))			doclinitinits = 1;	} 	# methods	haveclinit = 0;	for(i = 0; i < class.methods_count; i++) {		mp = class.methods[i];		addFreloc(thisclass, STRING(mp.name_index),			STRING(mp.sig_index), mp.access_flags);		if(STRING(mp.name_index) == "<clinit>")			haveclinit = 1;	}	if(doclinitinits && haveclinit == 0)		addFreloc(thisclass, "<clinit>", "()V", ACC_STATIC);	if((class.access_flags & (ACC_INTERFACE | ACC_ABSTRACT)) == 0)		addFreloc(thisclass, "<clone>", "()V", ACC_STATIC);} ## Add instruction patch information to Freloc fr.# LTIpatch(fr: ref Freloc, i: ref Inst, operand: int, patchkind: int){	addIpatch(fr.ipatch, i, operand, patchkind, !SAVEINST);} ## Size of Module Data space taken by load-time relocation information.# Includes nil terminator.# LTrelocsize(): int{	return align((9 + 2*(nltclasses-1)) * IBY2WD, 32);} ## Fix type descriptor for relocation information.# Freloctid, Ifacetid:	int; LTrelocdesc(map: array of byte){	i, bit: int; 	Freloctid = descid(4*IBY2WD, 1, array [1] of { byte 16rd0 });	setIpatchtid();		# force type id for patch info	Ifacetid = descid(IBY2WD, 1, array [1] of { byte 16r80 }); 	setbit(map, 8);		# Class name	setbit(map, 12);	# Superclass name	setbit(map, 16);	# Interfaces	setbit(map, 20);	# Class relocation	setbit(map, 28);	# Data relocation	#	# even i: Class name	# odd i:  Class relocation	#	bit = 32;	for(i = 0; i < (nltclasses-1)*2; i++) {		setbit(map, bit);		bit += 4;	}	setbit(map, bit);	# nil} ## Write Freloc array to .s file.# asmFreloc(off: int, cr: ref Creloc){	fr: ref Freloc;	reloff: int;		# relative offset for array elements 	reloff = 0;	asmarray(off, Freloctid, cr.n, reloff);	# cr.n != 0, always	for(fr = cr.fr; fr != nil; fr = fr.next) {		asmstring(reloff, fr.field);		reloff += IBY2WD;		if(fr.sig != nil)			asmstring(reloff, fr.sig);		reloff += IBY2WD;		asmint(reloff, fr.flags);		reloff += IBY2WD;		asmIpatch(reloff, fr.ipatch);		reloff += IBY2WD;	}	bout.puts("\tapop\n");} ## Write Creloc's (except for this_class) to .s file.# asmCreloc(off: int): int{	he: ref LTHash;	i: int; 	for(i = 0; i < Hashsize; i++) {		for(he = lttbl[i]; he != nil; he = he.next) {			if(he.cr == thisclass)				continue;			asmstring(off, he.cr.classname);			off += IBY2WD;			asmFreloc(off, he.cr);			off += IBY2WD;		}	}	off += IBY2WD;	# skip past nil	return off;} JVNO:		con '4';JMAGIC:		con ('J'<<24)|('a'<<16)|('v'<<8)|'a';JVERSION:	con ('S'<<24)|('u'<<16)|('x'<<8)|JVNO; ## Write Creloc for this_class to .s file.# asmthisCreloc(off: int): int{	i: int;	reloff: int;		# relative offset for array elements 	asmint(off, JMAGIC);	off += IBY2WD;	asmint(off, JVERSION);	off += IBY2WD;	asmstring(off, THISCLASS);	off += IBY2WD;	if(SUPERCLASS != nil)	# Object has no superclass		asmstring(off, SUPERCLASS);	off += IBY2WD;	if(class.interfaces_count > 0) {		reloff = 0;		asmarray(off, Ifacetid, class.interfaces_count, reloff);		for(i = 0; i < class.interfaces_count; i++) {			asmstring(reloff, CLASSNAME(class.interfaces[i]));			reloff += IBY2WD;		}		bout.puts("\tapop\n");	}	off += IBY2WD;	asmFreloc(off, thisclass);	off += IBY2WD;	return off;} ## Write Freloc array to .dis file.# disFreloc(off: int, cr: ref Creloc){	fr: ref Freloc;	reloff: int;		# relative offset for array elements 	reloff = 0;	disarray(off, Freloctid, cr.n);	for(fr = cr.fr; fr != nil; fr = fr.next) {		disstring(reloff, fr.field);		reloff += IBY2WD;		if(fr.sig != nil)			disstring(reloff, fr.sig);		reloff += IBY2WD;		disint(reloff, fr.flags);		reloff += IBY2WD;		disIpatch(reloff, fr.ipatch);		reloff += IBY2WD;	}	disapop();} ## Write Creloc's (except for this_class) to .dis file.# disCreloc(off: int): int{	he: ref LTHash;	i: int; 	for(i = 0; i < Hashsize; i++) {		for(he = lttbl[i]; he != nil; he = he.next) {			if(he.cr == thisclass)				continue;			disstring(off, he.cr.classname);			off += IBY2WD;			disFreloc(off, he.cr);			off += IBY2WD;		}	}	off += IBY2WD;	# skip past nil	return off;} ## Write Creloc for this_class to .dis file.# disthisCreloc(off: int): int{	i: int;	reloff: int;		# relative offset for array elements 	disint(off, JMAGIC);	off += IBY2WD;	disint(off, JVERSION);	off += IBY2WD;	disstring(off, THISCLASS);	off += IBY2WD;	if(SUPERCLASS != nil)	# Object has no superclass		disstring(off, SUPERCLASS);	off += IBY2WD;	if(class.interfaces_count > 0) {		reloff = 0;		disarray(off, Ifacetid, class.interfaces_count);		for(i = 0; i < class.interfaces_count; i++) {			disstring(reloff, CLASSNAME(class.interfaces[i]));			reloff += IBY2WD;		}		disapop();	}	off += IBY2WD;	disFreloc(off, thisclass);	off += IBY2WD;	return off;}