180 lines · 3.5 KB · Brainfuck
RawDownload
bufio:	Bufio;math:	Math;sys:	Sys;str:	String; Iobuf: import bufio;fprint, print, sprint: import sys; gendis:		int = 1;	# generate .dis rather than .s (default)fabort:		int;		# -f: cause broken thread on fatal erroremitcpool:	int;		# -p: emit constant pool (with -S only)gensbl:		int;		# -g: generate .sbl filecompileflag:	int;		# -c (MUSTCOMPILE) & -C (DONTCOMPILE)verbose:	int;		# -v: emit Java instructions (with -S only)bout:		ref Bufio->Iobuf;ofile:		string; usage(){	print("usage: j2d [-cgpvCS] [-o outfile] file.class\n");	exit;} ## Translate .class file (in) into .s or .dis (out).# translate(in: string, out: string){	ClassLoader(in); 	bout = bufio->create(out, Bufio->OWRITE, 8r644);	if(bout == nil)		fatal("can't open " + out + ": " + sprint("%r")); 	if(emitcpool != 0)		dumpcpool(); 	thisCreloc();	xlate();	mpdesc();	# Patch frame/call for invokespecial/invokestatic.	dofcpatch();	# Patch instructions for run-time resolution.	doRTpatch(); 	if(gendis == 0) {	# generate .s file		asminst();		asmentry();		asmdesc();		asmvar();		asmmod();		asmlinks();		asmhandlers();	} else		disout();	# generate .dis file 	if(gensbl)		#  generate .sbl file		sblout(out); 	bout.close();} MAXUNENCODED:	con Sys->NAMEMAX - 7;ENCODEDLEN:	con 21; encoding :=	array [] of {	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',	'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',	'o', 'p', 'q', 'r', 's', 't', 'u', 'v',	'w', 'x', 'y', 'z', '0', '1', '2', '3',	'4', '5', '6', '7', '8', '9', '+', '-',}; encodename(name: string): string{	d := array [Keyring->MD5dlen] of byte;	kr := load Keyring Keyring->PATH;	kr->md5(array of byte name, len name, d, nil);	e := array[ENCODEDLEN] of byte;	v := 0;	n := 0;	r := 0;	for(i := 0; i < ENCODEDLEN; i++) {		if(r < 6) {			v |=  int d[n++] << r;			r += 8;		}		e[i] = byte encoding[v & 16r3F];		v >>= 6;		r -= 6;	}	return string e;} ## Construct output filename.# mkfileext(file: string, ext: string): string{	n := len file;	if(n <= 6 || file[n-6:] != ".class")		usage();	else		n -= 6;	if(n > MAXUNENCODED) {		file = encodename(file);		n = ENCODEDLEN;	}	return file[:n] + ext;} init(nil: ref Draw->Context, argv: list of string){	ext, s: string; 	sys = load Sys Sys->PATH;	math = load Math Math->PATH;	bufio = load Bufio Bufio->PATH;	if(bufio == nil)		fatal("can't load " + Bufio->PATH + ": " + sprint("%r"));	str = load String String->PATH;	if(str == nil)		fatal("can't load " + String->PATH + ": " + sprint("%r")); 	arg := Arg.init(argv);	while(c := arg.opt()) {		case c {		'C' =>			compileflag |= _DONTCOMPILE;		'S' =>			gendis = 0;		'c' =>			compileflag |= _MUSTCOMPILE;		'g' =>			gensbl = 1;		'f' =>			fabort = 1;		'p' =>			emitcpool = 1;		'o' =>			ofile = arg.arg();		'v' =>			verbose = 1;		* =>			usage();		}	}	argv = arg.argv;	arg = nil; 	if(len argv != 1)		usage();	ifile := hd argv;	if(compileflag == (_MUSTCOMPILE|_DONTCOMPILE)) {		print("j2d: warning: -c and -C are mutually exclusive, ignoring\n");		compileflag = 0;	}	if((verbose != 0 || emitcpool != 0) && gendis != 0) {		print("j2d: warning: -p/-v only allowed with -S, ignoring\n");		emitcpool = 0;		verbose = 0;	}	if(ofile != nil)		translate(ifile, ofile);	else {		if(gendis == 0)			ext = ".s";		else			ext = ".dis";		(nil, s) = str->splitr(ifile, "/");		ofile = mkfileext(s, ext);		translate(ifile, ofile);	}	reset();}