forsyth20121205-174063a80cc13 years agoHistory
701 lines · 15.2 KB · Brainfuck
RawDownload
implement WmRt; include "sys.m";	sys: Sys;	sprint: import sys; include "bufio.m";	bufio: Bufio;	Iobuf: import bufio; include "draw.m"; include "tk.m";	tk: Tk;	Toplevel: import tk; include "tkclient.m";	tkclient: Tkclient; include "dialog.m";	dialog: Dialog; include "selectfile.m";	selectfile: Selectfile; include "dis.m";	dis: Dis;	Inst, Type, Data, Link, Mod: import dis;	XMAGIC: import Dis;	MUSTCOMPILE, DONTCOMPILE: import Dis;	AMP, AFP, AIMM, AXXX, AIND, AMASK: import Dis;	ARM, AXNON, AXIMM, AXINF, AXINM: import Dis;	DEFB, DEFW, DEFS, DEFF, DEFA, DIND, DAPOP, DEFL: import Dis; WmRt: module{	init:	fn(ctxt: ref Draw->Context, argv: list of string);}; gctxt: ref Draw->Context;t: ref Toplevel;disfile: string; TK:	con 1; m: ref Mod;rt := 0;ss := -1; rt_cfg := array[] of {	"frame .m",	"menubutton .m.open -text File -menu .file",	"menubutton .m.prop -text Properties -menu .prop",	"menubutton .m.view -text View -menu .view",	"label .m.l",	"pack .m.open .m.view .m.prop -side left",	"pack .m.l -side right",	"frame .b",	"text .b.t -width 12c -height 7c -yscrollcommand {.b.s set} -bg white",	"scrollbar .b.s -command {.b.t yview}",	"pack .b.s -fill y -side left",	"pack .b.t -fill both -expand 1",	"pack .m -anchor w -fill x",	"pack .b -fill both -expand 1",	"pack propagate . 0",	"update", 	"menu .prop",	".prop add checkbutton -text {Must compile} -command {send cmd must}",	".prop add checkbutton -text {Don't compile} -command {send cmd dont}",	".prop add separator",	".prop add command -text {Set stack extent} -command {send cmd stack}",	".prop add command -text {Sign module} -command {send cmd sign}", 	"menu .view",	".view add command -text {Header} -command {send cmd hdr}",	".view add command -text {Code segment} -command {send cmd code}",	".view add command -text {Data segment} -command {send cmd data}",	".view add command -text {Type descriptors} -command {send cmd type}",	".view add command -text {Link descriptors} -command {send cmd link}",	".view add command -text {Import descriptors} -command {send cmd imports}",	".view add command -text {Exception handlers} -command {send cmd handlers}", 	"menu .file",	".file add command -text {Open module} -command {send cmd open}",	".file add separator",	".file add command -text {Write .dis module} -command {send cmd save}",	".file add command -text {Write .s file} -command {send cmd list}",}; init(ctxt: ref Draw->Context, nil: list of string){	sys = load Sys Sys->PATH;	if (ctxt == nil) {		sys->fprint(sys->fildes(2), "rt: no window context\n");		raise "fail:bad context";	}	tk = load Tk Tk->PATH;	tkclient = load Tkclient Tkclient->PATH;	dialog = load Dialog Dialog->PATH;	selectfile = load Selectfile Selectfile->PATH; 	sys->pctl(Sys->NEWPGRP, nil); 	tkclient->init();	dialog->init();	selectfile->init(); 	gctxt = ctxt; 	menubut: chan of string;	(t, menubut) = tkclient->toplevel(ctxt, "", "Dis Module Manager", Tkclient->Appl); 	cmd := chan of string; 	tk->namechan(t, cmd, "cmd");	tkcmds(t, rt_cfg);	tkclient->onscreen(t, nil);	tkclient->startinput(t, "kbd"::"ptr"::nil); 	dis = load Dis Dis->PATH;	if(dis == nil) {		dialog->prompt(ctxt, t.image, "error -fg red", "Load Module",				"wmrt requires Dis",				0, "Exit"::nil);		return;	}	dis->init(); 	for(;;) alt {	s := <-t.ctxt.kbd =>		tk->keyboard(t, s);	s := <-t.ctxt.ptr =>		tk->pointer(t, *s);	s := <-t.ctxt.ctl or	s = <-t.wreq =>		tkclient->wmctl(t, s);	menu := <-menubut =>		if(menu == "exit")			return;		tkclient->wmctl(t, menu);	s := <-cmd =>		case s {		"open" =>			openfile(ctxt);		"save" =>			writedis();		"list" =>			writeasm();		"hdr" =>			hdr();		"code" =>			das(TK);		"data" =>			dat(TK);		"type" =>			desc(TK);		"link" =>			link(TK);		"imports" =>			imports(TK);		"handlers" =>			handlers(TK);		"must" =>			rt ^= MUSTCOMPILE;		"dont" =>			rt ^= DONTCOMPILE;		"stack" =>			spawn stack(ctxt);		"sign" =>			dialog->prompt(ctxt, t.image, "error -fg red", "Signed Modules",				"not implemented",				0, "Continue"::nil);		}	}} stack_cfg := array[] of {	"scale .s -length 200 -to 32768 -resolution 128 -orient horizontal",	"frame .f",	"pack .s .f -pady 5 -fill x -expand 1",}; stack(ctxt: ref Draw->Context){	# (s, sbut) := tkclient->toplevel(ctxt, tkclient->geom(t), "Dis Stack", 0);	(s, sbut) := tkclient->toplevel(ctxt, "", "Dis Stack", 0); 	cmd := chan of string;	tk->namechan(s, cmd, "cmd");	tkcmds(s, stack_cfg);	tk->cmd(s, ".s set " + string ss);	tk->cmd(s, "update");	tkclient->onscreen(s, nil);	tkclient->startinput(s, "kbd"::"ptr"::nil); 	for(;;) alt {	c := <-s.ctxt.kbd =>		tk->keyboard(s, c);	c := <-s.ctxt.ptr =>		tk->pointer(s, *c);	c := <-s.ctxt.ctl or	c = <-s.wreq =>		tkclient->wmctl(s, c);	wmctl := <-sbut =>		if(wmctl == "exit") {			ss = int tk->cmd(s, ".s get");			return;		}		tkclient->wmctl(s, wmctl);	}	} openfile(ctxt: ref Draw->Context){	pattern := list of {		"*.dis (Dis VM module)",		"* (All files)"	}; 	for(;;) {		disfile = selectfile->filename(ctxt, t.image, "Dis file", pattern, nil);		if(disfile == "")			break; 		s: string;		(m, s) = dis->loadobj(disfile);		if(s == nil) {			ss = m.ssize;			rt = m.rt;			tk->cmd(t, ".m.l configure -text {"+m.name+"}");			das(TK);			return;		} 		r := dialog->prompt(ctxt, t.image, "error -fg red", "Open Dis File",				s,				0, "Retry" :: "Abort" :: nil);		if(r == 1)			return;	}} writedis(){	if(m == nil || m.magic == 0) {		dialog->prompt(gctxt, t.image, "error -fg red", "Write .dis",				"no module loaded",				0, "Continue"::nil);		return;	}	if(rt < 0)		rt = m.rt;	if(ss < 0)		ss = m.ssize;	if(rt == m.rt && ss == m.ssize)		return;	while((fd := sys->open(disfile, Sys->OREAD)) == nil){		if(dialog->prompt(gctxt, t.image, "error -fg red", "Open Dis File", "open failed: "+sprint("%r"),		     0, "Retry" :: "Abort" :: nil))			return;	}	if(len discona(rt) == len discona(m.rt) && len discona(ss) == len discona(m.ssize)){		sys->seek(fd, big 4, Sys->SEEKSTART);	# skip magic		discon(fd, rt);		discon(fd, ss);		m.rt = rt;		m.ssize = ss;		return;	}	# rt and ss representations changed in length: read the file in,	# make a copy and update rt and ss when copying	(ok, d) := sys->fstat(fd);	if(ok < 0){		ioerror("Reading Dis file "+disfile, "can't find file length: "+sprint("%r"));		return;	}	length := int d.length;	disbuf := array[length] of byte;	if(sys->read(fd, disbuf, length) != length){		ioerror("Reading Dis file "+disfile, "read error: "+sprint("%r"));		return;	}	outbuf := array[length+2*4] of byte;	# could avoid this buffer if required, by writing portions of disbuf	(magic, i) := operand(disbuf, 0);	o := putoperand(outbuf, magic);	if(magic == Dis->SMAGIC){		ns: int;		(ns, i) = operand(disbuf, i);		o += putoperand(outbuf[o:], ns);		sign := disbuf[i:i+ns];		i += ns;		outbuf[o:] = sign;		o += ns;	}	(nil, i) = operand(disbuf, i);	(nil, i) = operand(disbuf, i);	if(i < 0){		ioerror("Reading Dis file "+disfile, "Dis header too short");		return;	}	o += putoperand(outbuf[o:], rt);	o += putoperand(outbuf[o:], ss);	outbuf[o:] = disbuf[i:];	o += len disbuf - i;	fd = sys->create(disfile, Sys->OWRITE, 8r666);	if(fd == nil){		ioerror("Rewriting "+disfile, sys->sprint("can't create %s: %r",disfile));		return;	}	if(sys->write(fd, outbuf, o) != o)		ioerror("Rewriting "+disfile, "write error: "+sprint("%r"));	m.rt = rt;	m.ssize = ss;} ioerror(title: string, err: string){	dialog->prompt(gctxt, t.image, "error -fg red", title, err, 0, "Dismiss" :: nil);} putoperand(out: array of byte, v: int): int{	a := discona(v);	out[0:] = a;	return len a;} discona(val: int): array of byte{	if(val >= -64 && val <= 63)		return array[] of { byte(val & ~16r80) };	else if(val >= -8192 && val <= 8191)		return array[] of { byte((val>>8) & ~16rC0 | 16r80), byte val };	else		return array[] of { byte(val>>24 | 16rC0), byte(val>>16), byte(val>>8), byte val };} discon(fd: ref Sys->FD, val: int){	a := discona(val);	sys->write(fd, a, len a);} operand(disobj: array of byte, o: int): (int, int){	if(o >= len disobj)		return (-1, -1);	b := int disobj[o++];	case b & 16rC0 {	16r00 =>		return (b, o);	16r40 =>		return (b | ~16r7F, o);	16r80 =>		if(o >= len disobj)			return (-1, -1);		if(b & 16r20)			b |= ~16r3F;		else			b &= 16r3F;		b = (b<<8) | int disobj[o++];		return (b, o);	16rC0 =>		if(o+2 >= len disobj)			return (-1, -1);		if(b & 16r20)			b |= ~16r3F;		else			b &= 16r3F;		b = b<<24 |			(int disobj[o]<<16) |		    	(int disobj[o+1]<<8)|		    	int disobj[o+2];		o += 3;		return (b, o);	}	return (0, -1);	# can't happen} fasm: ref Iobuf; writeasm(){	if(m == nil || m.magic == 0) {		dialog->prompt(gctxt, t.image, "error -fg red", "Write .s",				"no module loaded",				0, "Continue"::nil);		return;	} 	bufio = load Bufio Bufio->PATH;	if(bufio == nil) {		dialog->prompt(gctxt, t.image, "error -fg red", "Write .s",				"Bufio load failed: "+sprint("%r"),				0, "Exit"::nil);		return;	} 	for(;;) {		asmfile: string;		if(len disfile > 4 && disfile[len disfile-4:] == ".dis")			asmfile = disfile[0:len disfile-3] + "s";		else			asmfile = disfile + ".s";		fasm = bufio->create(asmfile, Sys->OWRITE|Sys->OTRUNC, 8r666);		if(fasm != nil)			break;		r := dialog->prompt(gctxt, t.image, "error -fg red", "Create .s file",			"open failed: "+sprint("%r"),			0, "Retry" :: "Abort" :: nil);		if(r == 0)			continue;		else			return;	}	das(!TK);	fasm.puts("\tentry\t" + string m.entry + "," + string m.entryt + "\n");	desc(!TK);	dat(!TK);	fasm.puts("\tmodule\t" + m.name + "\n");	link(!TK);	imports(!TK);	handlers(!TK);	fasm.close();} link(flag: int){	if(m == nil || m.magic == 0) {		dialog->prompt(gctxt, t.image, "error -fg red", "Link Descriptors",				"no module loaded",				0, "Continue"::nil);		return;	} 	if(flag == TK)		tk->cmd(t, ".b.t delete 1.0 end"); 	for(i := 0; i < m.lsize; i++) {		l := m.links[i];		s := sprint("	link %d,%d, 0x%ux, \"%s\"\n",					l.desc, l.pc, l.sig, l.name);		if(flag == TK)			tk->cmd(t, ".b.t insert end '"+s);		else			fasm.puts(s);	}	if(flag == TK)		tk->cmd(t, ".b.t see 1.0; update");} imports(flag: int){	if(m == nil || m.magic == 0) {		dialog->prompt(gctxt, t.image, "error -fg red", "Import Descriptors",				"no module loaded",				0, "Continue"::nil);		return;	} 	if(flag == TK)		tk->cmd(t, ".b.t delete 1.0 end"); 	mi := m.imports;	for(i := 0; i < len mi; i++) {		a := mi[i];		for(j := 0; j < len a; j++) {			ai := a[j];			s := sprint("	import 0x%ux, \"%s\"\n", ai.sig, ai.name);			if(flag == TK)				tk->cmd(t, ".b.t insert end '"+s);			else				fasm.puts(s);		}	}	if(flag == TK)		tk->cmd(t, ".b.t see 1.0; update");} handlers(flag: int){	if(m == nil || m.magic == 0) {		dialog->prompt(gctxt, t.image, "error -fg red", "Exception Handlers",				"no module loaded",				0, "Continue"::nil);		return;	} 	if(flag == TK)		tk->cmd(t, ".b.t delete 1.0 end"); 	hs := m.handlers;	for(i := 0; i < len hs; i++) {		h := hs[i];		tt := -1;		for(j := 0; j < len m.types; j++) {			if(h.t == m.types[j]) {				tt = j;				break;

Lines 1–500 of 701.