Charles.Forsyth20061220965a0ca19 years agoHistory
609 lines · 9.4 KB · Brainfuck
RawDownload
implement Dis; ## Derived by Vita Nuova Limited 1998 from /appl/wm/rt.b, which is# Copyright © 1996-1999 Lucent Technologies Inc.  All rights reserved.# include "sys.m";	sys: Sys;	sprint: import sys; include "math.m";	math: Math; include "dis.m"; disptr: int;disobj: array of byte; optab := array[] of {	"nop",	"alt",	"nbalt",	"goto",	"call",	"frame",	"spawn",	"runt",	"load",	"mcall",	"mspawn",	"mframe",	"ret",	"jmp",	"case",	"exit",	"new",	"newa",	"newcb",	"newcw",	"newcf",	"newcp",	"newcm",	"newcmp",	"send",	"recv",	"consb",	"consw",	"consp",	"consf",	"consm",	"consmp",	"headb",	"headw",	"headp",	"headf",	"headm",	"headmp",	"tail",	"lea",	"indx",	"movp",	"movm",	"movmp",	"movb",	"movw",	"movf",	"cvtbw",	"cvtwb",	"cvtfw",	"cvtwf",	"cvtca",	"cvtac",	"cvtwc",	"cvtcw",	"cvtfc",	"cvtcf",	"addb",	"addw",	"addf",	"subb",	"subw",	"subf",	"mulb",	"mulw",	"mulf",	"divb",	"divw",	"divf",	"modw",	"modb",	"andb",	"andw",	"orb",	"orw",	"xorb",	"xorw",	"shlb",	"shlw",	"shrb",	"shrw",	"insc",	"indc",	"addc",	"lenc",	"lena",	"lenl",	"beqb",	"bneb",	"bltb",	"bleb",	"bgtb",	"bgeb",	"beqw",	"bnew",	"bltw",	"blew",	"bgtw",	"bgew",	"beqf",	"bnef",	"bltf",	"blef",	"bgtf",	"bgef",	"beqc",	"bnec",	"bltc",	"blec",	"bgtc",	"bgec",	"slicea",	"slicela",	"slicec",	"indw",	"indf",	"indb",	"negf",	"movl",	"addl",	"subl",	"divl",	"modl",	"mull",	"andl",	"orl",	"xorl",	"shll",	"shrl",	"bnel",	"bltl",	"blel",	"bgtl",	"bgel",	"beql",	"cvtlf",	"cvtfl",	"cvtlw",	"cvtwl",	"cvtlc",	"cvtcl",	"headl",	"consl",	"newcl",	"casec",	"indl",	"movpc",	"tcmp",	"mnewz",	"cvtrf",	"cvtfr",	"cvtws",	"cvtsw",	"lsrw",	"lsrl",	"eclr",	"newz",	"newaz",	"raise",	"casel",	"mulx",	"divx",	"cvtxx",	"mulx0",	"divx0",	"cvtxx0",	"mulx1",	"divx1",	"cvtxx1",	"cvtfx",	"cvtxf",	"expw",	"expl",	"expf",	"self",}; init(){	sys = load Sys  Sys->PATH;	math = load Math Math->PATH;	# optional} loadobj(disfile: string): (ref Mod, string){	fd := sys->open(disfile, sys->OREAD);	if(fd == nil)		return (nil, "open failed: "+sprint("%r")); 	(ok, d) := sys->fstat(fd);	if(ok < 0)		return (nil, "stat failed: "+sprint("%r")); 	objlen := int d.length;	disobj = array[objlen] of byte; 	if(sys->read(fd, disobj, objlen) != objlen){		disobj = nil;		return (nil, "read failed: "+sprint("%r"));	} 	disptr = 0;	m := ref Mod;	m.magic = operand();	if(m.magic == SMAGIC) {		n := operand();		m.sign = disobj[disptr:disptr+n];		disptr += n;		m.magic = operand();	}	if(m.magic != XMAGIC){		disobj = nil;		return (nil, "bad magic number");	} 	m.rt = operand();	m.ssize = operand();	m.isize = operand();	m.dsize = operand();	m.tsize = operand();	m.lsize = operand();	m.entry = operand();	m.entryt = operand(); 	m.inst = array[m.isize] of ref Inst;	for(i := 0; i < m.isize; i++) {		o := ref Inst;		o.op = int disobj[disptr++];		o.addr = int disobj[disptr++];		case o.addr & ARM {		AXIMM or		AXINF or		AXINM =>			o.mid = operand();		} 		case (o.addr>>3) & 7 {		AFP or		AMP or		AIMM =>			o.src = operand();		AIND|AFP or		AIND|AMP =>			o.src = operand()<<16;			o.src |= operand();		} 		case o.addr & 7	 {		AFP or		AMP or		AIMM =>			o.dst = operand();		AIND|AFP or		AIND|AMP =>			o.dst = operand()<<16;			o.dst |= operand();		}		m.inst[i] = o;	} 	m.types = array[m.tsize] of ref Type;	for(i = 0; i < m.tsize; i++) {		h := ref Type;		id := operand();		h.size = operand();		h.np = operand();		h.map = disobj[disptr:disptr+h.np];		disptr += h.np;		m.types[i] = h;	} 	for(;;) {		op := int disobj[disptr++];		if(op == 0)			break; 		n := op & (DMAX-1);		if(n == 0)			n = operand(); 		offset := operand(); 		dat: ref Data;		case op>>4 {		DEFB =>			dat = ref Data.Bytes(op, n, offset, disobj[disptr:disptr+n]);			disptr += n;		DEFW =>			words := array[n] of int;			for(i = 0; i < n; i++)				words[i] = getw();			dat = ref Data.Words(op, n, offset, words);		DEFS =>			dat = ref Data.String(op, n, offset, string disobj[disptr:disptr+n]);			disptr += n;		DEFF =>			if(math != nil){				reals := array[n] of real;				for(i = 0; i < n; i++)					reals[i] = math->bits64real(getl());				dat = ref Data.Reals(op, n, offset, reals);			} else {				disptr += 8*n;	# skip it				dat = ref Data.Reals(op, n, offset, nil);			}			break;		DEFA =>			typex := getw();			length := getw();			dat = ref Data.Array(op, n, offset, typex, length);		DIND =>			dat = ref Data.Aindex(op, n, offset, getw());		DAPOP =>			dat = ref Data.Arestore(op, n, offset);		DEFL =>			bigs := array[n] of big;			for(i = 0; i < n; i++)				bigs[i] = getl();			dat = ref Data.Bigs(op, n, offset, bigs);		* =>			dat = ref Data.Zero(op, n, offset);		}		m.data = dat :: m.data;	} 	m.data = revdat(m.data); 	m.name = gets(); 	m.links = array[m.lsize] of ref Link;	for(i = 0; i < m.lsize; i++) {		l := ref Link;		l.pc = operand();		l.desc = operand();		l.sig = getw();		l.name = gets(); 		m.links[i] = l;	} 	if(m.rt & Dis->HASLDT0)		raise "obsolete dis"; 	if(m.rt & Dis->HASLDT){		nl := operand();		imps := array[nl] of array of ref Import;		for(i = 0; i < nl; i++){			n := operand();			imps[i] = array[n] of ref Import;			for(j := 0; j < n; j++){				imps[i][j] = im := ref Import;				im.sig = getw();				im.name = gets();			}		}		disptr++;		m.imports = imps;	} 	if(m.rt & Dis->HASEXCEPT){		nh := operand();	# number of handlers		hs := array[nh] of ref Handler;		for(i = 0; i < nh; i++){			h := hs[i] = ref Handler;			h.eoff = operand();			h.pc1 = operand();			h.pc2 = operand();			t := operand();			if(t >= 0)				h.t = m.types[t];			n := operand();				h.ne = n>>16;			n &= 16rffff;	# number of cases			h.etab = array[n+1] of ref Except;			for(j := 0; j < n; j++){				e := h.etab[j] = ref Except;				k := disptr;				while(int disobj[disptr++])	# pattern					;				e.s = string disobj[k: disptr-1];				e.pc = operand();			}			e := h.etab[j] = ref Except;			e.pc = operand();	# * pc		}		disptr++;	# 0 byte		m.handlers = hs;	} 	m.srcpath = gets(); 	disobj = nil;	return (m, nil);} operand(): int{	if(disptr >= len disobj)		return -1; 	b := int disobj[disptr++]; 	case b & 16rC0 {	16r00 =>		return b;	16r40 =>		return b | ~16r7F;	16r80 =>		if(disptr >= len disobj)			return -1;		if(b & 16r20)			b |= ~16r3F;		else			b &= 16r3F;		return (b<<8) | int disobj[disptr++];	16rC0 =>		if(disptr+2 >= len disobj)			return -1;		if(b & 16r20)			b |= ~16r3F;		else			b &= 16r3F;		b = b<<24 |			(int disobj[disptr]<<16) |		    	(int disobj[disptr+1]<<8)|		    	int disobj[disptr+2];		disptr += 3;		return b;	}	return 0;} get4(a: array of byte, i: int): int{	return (int a[i+0] << 24) | (int a[i+1] << 16) | (int a[i+2] << 8) | int a[i+3];} getw(): int{	if(disptr+3 >= len disobj)		return -1;	i := (int disobj[disptr+0]<<24) |	     (int disobj[disptr+1]<<16) |	     (int disobj[disptr+2]<<8) |	      int disobj[disptr+3]; 	disptr += 4;	return i;} getl(): big{	if(disptr+7 >= len disobj)		return big -1;	i := (big disobj[disptr+0]<<56) |	     (big disobj[disptr+1]<<48) |	     (big disobj[disptr+2]<<40) |	     (big disobj[disptr+3]<<32) |	     (big disobj[disptr+4]<<24) |	     (big disobj[disptr+5]<<16) |	     (big disobj[disptr+6]<<8) |	      big disobj[disptr+7]; 	disptr += 8;	return i;} gets(): string{	s := disptr;	while(disptr < len disobj && disobj[disptr] != byte 0)		disptr++; 	v := string disobj[s:disptr];	disptr++;	return v;} revdat(d: list of ref Data): list of ref Data{

Lines 1–500 of 609.