aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Criswell <criswell@uiuc.edu>2004-02-27 18:06:50 +0000
committerJohn Criswell <criswell@uiuc.edu>2004-02-27 18:06:50 +0000
commit4929390840d09806b575f1239e0ed61c592ea13d (patch)
tree3844ae57a83b06ff10faa19eeb777368bbbeb633
parent20354b6d9a8307a0a6c82f35933641f36d02697f (diff)
Initial commit of hbd.
git-svn-id: https://llvm.org/svn/llvm-project/test-suite/trunk@11918 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--MultiSource/Applications/hbd/Makefile8
-rw-r--r--MultiSource/Applications/hbd/access.cpp48
-rw-r--r--MultiSource/Applications/hbd/access.h66
-rw-r--r--MultiSource/Applications/hbd/class.cpp418
-rw-r--r--MultiSource/Applications/hbd/class.h105
-rw-r--r--MultiSource/Applications/hbd/config.h53
-rw-r--r--MultiSource/Applications/hbd/consts.h28
-rw-r--r--MultiSource/Applications/hbd/cp.cpp83
-rw-r--r--MultiSource/Applications/hbd/cp.h68
-rw-r--r--MultiSource/Applications/hbd/d1-pushc.cpp80
-rw-r--r--MultiSource/Applications/hbd/d2-pushl.cpp60
-rw-r--r--MultiSource/Applications/hbd/d3-popl.cpp116
-rw-r--r--MultiSource/Applications/hbd/d4-array.cpp68
-rw-r--r--MultiSource/Applications/hbd/d5-stack.cpp39
-rw-r--r--MultiSource/Applications/hbd/d6-arith.cpp99
-rw-r--r--MultiSource/Applications/hbd/d7-cntrl.cpp84
-rw-r--r--MultiSource/Applications/hbd/d8-ret.cpp35
-rw-r--r--MultiSource/Applications/hbd/d9-swtch.cpp43
-rw-r--r--MultiSource/Applications/hbd/da-field.cpp112
-rw-r--r--MultiSource/Applications/hbd/db-meth.cpp117
-rw-r--r--MultiSource/Applications/hbd/dc-misc.cpp32
-rw-r--r--MultiSource/Applications/hbd/decomp.cpp340
-rw-r--r--MultiSource/Applications/hbd/decomp.h85
-rw-r--r--MultiSource/Applications/hbd/err.cpp32
-rw-r--r--MultiSource/Applications/hbd/err.h29
-rw-r--r--MultiSource/Applications/hbd/exp.cpp217
-rw-r--r--MultiSource/Applications/hbd/exp.h333
-rw-r--r--MultiSource/Applications/hbd/field.h34
-rw-r--r--MultiSource/Applications/hbd/file.h51
-rw-r--r--MultiSource/Applications/hbd/general.h45
-rw-r--r--MultiSource/Applications/hbd/hbd.183
-rw-r--r--MultiSource/Applications/hbd/hbd.cpp21
-rw-r--r--MultiSource/Applications/hbd/hbd.sgml130
-rw-r--r--MultiSource/Applications/hbd/id.cpp27
-rw-r--r--MultiSource/Applications/hbd/id.h50
-rw-r--r--MultiSource/Applications/hbd/method.h148
-rw-r--r--MultiSource/Applications/hbd/op.cpp30
-rw-r--r--MultiSource/Applications/hbd/op.h36
-rw-r--r--MultiSource/Applications/hbd/options.h27
-rw-r--r--MultiSource/Applications/hbd/sig.cpp145
-rw-r--r--MultiSource/Applications/hbd/sig.h73
-rw-r--r--MultiSource/Applications/hbd/version.cpp23
-rw-r--r--MultiSource/Applications/hbd/version.h28
43 files changed, 3749 insertions, 0 deletions
diff --git a/MultiSource/Applications/hbd/Makefile b/MultiSource/Applications/hbd/Makefile
new file mode 100644
index 00000000..b796bb34
--- /dev/null
+++ b/MultiSource/Applications/hbd/Makefile
@@ -0,0 +1,8 @@
+LEVEL = ../../../../..
+PROG = hbd
+CPPFLAGS += -DHAVE_CONFIG_H
+LDFLAGS += -lstdc++
+LIBS += -lstdc++
+RUN_OPTIONS = Sort.class
+REQUIRES_EH_SUPPORT := 1
+include ../../Makefile.multisrc
diff --git a/MultiSource/Applications/hbd/access.cpp b/MultiSource/Applications/hbd/access.cpp
new file mode 100644
index 00000000..cdb1ee4e
--- /dev/null
+++ b/MultiSource/Applications/hbd/access.cpp
@@ -0,0 +1,48 @@
+/* access.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <string.h>
+#include "general.h"
+#include "access.h"
+
+char *flag2str[] = {
+ "public ", "private ", "protected ", "static ",
+ "final ", "synchronized ", "threadsafe ", "transient ",
+ "native ", "interface ", "abstract "
+};
+
+int flag2strlen[] = {
+ 7, 8, 10, 7, 6, 13, 11, 10, 7, 10, 9
+};
+
+char *AccessFlags::toString(char *buffer)
+{
+ u16 f, i;
+
+ *buffer = '\0';
+
+ for (f = flags, i = 0; f; f>>=1, i++) {
+ if (f & 1) {
+ strcat(buffer, flag2str[i]);
+ }
+ }
+ return buffer;
+}
+
+u16 AccessFlags::strlen()
+{
+ u16 buffsize = 0, f, i;
+
+ for (f = flags, i = 0; f; f>>=1, i++) {
+ if (f & 1) {
+ buffsize += flag2strlen[i];
+ }
+ }
+
+ return buffsize;
+}
diff --git a/MultiSource/Applications/hbd/access.h b/MultiSource/Applications/hbd/access.h
new file mode 100644
index 00000000..6ab46276
--- /dev/null
+++ b/MultiSource/Applications/hbd/access.h
@@ -0,0 +1,66 @@
+/* access.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef ACCESS_H
+#define ACCESS_H
+
+#include "general.h"
+
+/* The various types of Access flags Java uses */
+enum Access {
+ ACC_PUBLIC = 0x0001, /* visible to everyone */
+ ACC_PRIVATE = 0x0002, /* visible only to defining class */
+ ACC_PROTECTED = 0x0004, /* visible to subclasses */
+ ACC_STATIC = 0x0008, /* instance variable is static */
+ ACC_FINAL = 0x0010, /* no further subclassing, overriding */
+ ACC_SYNCHRONIZED = 0x0020, /* wrap method call */
+ /* in monitor lock */
+ ACC_THREADSAFE = 0x0040, /* can cache in registers */
+ ACC_TRANSIENT = 0x0080, /* not persistant */
+ ACC_NATIVE = 0x0100, /* implemented in C */
+ ACC_INTERFACE = 0x0200, /* class is an interface */
+ ACC_ABSTRACT = 0x0400 /* no definition provided */
+};
+
+/*
+ A class representing a set of access flags with
+ various useful methods.
+*/
+
+struct AccessFlags {
+ u16 flags;
+
+ AccessFlags() {
+ flags = 0;
+ }
+
+ AccessFlags(u16 inflags) {
+ flags = inflags;
+ }
+
+ void operator =(u16 inflags) {
+ flags = inflags;
+ }
+
+ void operator +=(Access a) {
+ flags |= (u16)a;
+ }
+
+ void operator -=(Access a) {
+ flags &= ~(u16)a;
+ }
+
+ int operator &(u16 intflags) {
+ return flags & intflags;
+ }
+
+ char *toString(char *buffer);
+ u16 strlen();
+};
+
+#endif
diff --git a/MultiSource/Applications/hbd/class.cpp b/MultiSource/Applications/hbd/class.cpp
new file mode 100644
index 00000000..d25a50af
--- /dev/null
+++ b/MultiSource/Applications/hbd/class.cpp
@@ -0,0 +1,418 @@
+/* class.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <string.h>
+#include <ctype.h>
+#include "general.h"
+#include "options.h"
+#include "cp.h"
+#include "access.h"
+#include "field.h"
+#include "exp.h"
+#include "method.h"
+#include "version.h"
+#include "class.h"
+#include "file.h"
+#include "err.h"
+#include "consts.h"
+
+#define JAVA_CLASSFILE_MAGIC 0xCafeBabeL
+
+char *progname;
+
+Classfile::Classfile(int argc, char **argv) {
+ functoinsert = 0;
+ outfile = stdout; infile = stdin;
+ progname = *argv++;
+ if (strcmp(progname + strlen(progname) - 3, "hbt") == 0) {
+ for (; (--argc) && (**argv == '-'); argv++) {
+ options = (CL_Options)0;
+ switch (toupper((*argv)[1])) {
+ case 'D': *(int *)&options |= (int)OPT_DEBUG; break;
+ case 'I': functoinsert = &((*argv)[2]); break;
+ default:
+ fprintf(stderr, "Unknown flag: %s\n", argv[1]);
+ fatalerror(COMMAND_LINE_ERR_HBT, progname);
+ }
+ }
+ char *tmpstr;
+ switch (argc) {
+ case 1:
+ tmpstr = new char[strlen(argv[0])+5];
+ strcpy(tmpstr, argv[0]);
+ strcat(tmpstr, ".bak");
+ rename(argv[0], tmpstr);
+ if ((infile = fopen(tmpstr, "rb"))==NULL) {
+ fprintf(stderr, "Could not open file %s\n", argv[0]);
+ goto defaultcase_hbt;
+ }
+ if ((outfile = fopen(argv[0], "wb"))==NULL) {
+ fprintf(stderr, "Could not open file %s\n", argv[1]);
+ goto defaultcase_hbt;
+ }
+ delete tmpstr;
+ break;
+ default: defaultcase_hbt:
+ fatalerror(COMMAND_LINE_ERR_HBT, progname);
+ }
+ if (functoinsert == 0)
+ fatalerror(COMMAND_LINE_ERR_HBT, progname);
+ outfile_pos = 0;
+ } else {
+ for (; (--argc) && (**argv == '-'); argv++) {
+ options = (CL_Options)0;
+ switch (toupper((*argv)[1])) {
+ case 'O': *(int *)&options |= (int)OPT_DECOMPILE_OFF; break;
+ case 'D': *(int *)&options |= (int)OPT_DEBUG; break;
+ default:
+ fprintf(stderr, "Unknown flag: %s\n", argv[1]);
+ fatalerror(COMMAND_LINE_ERR_HBD, progname);
+ }
+ }
+ switch (argc) {
+ case 2:
+ if ((outfile = fopen(argv[1], "wb"))==NULL) {
+ fprintf(stderr, "Could not open file %s\n", argv[1]);
+ goto defaultcase_hbd;
+ }
+ case 1:
+ if ((infile = fopen(argv[0], "rb"))==NULL) {
+ fprintf(stderr, "Could not open file %s\n", argv[0]);
+ goto defaultcase_hbd;
+ }
+ break;
+ default: defaultcase_hbd:
+ fatalerror(COMMAND_LINE_ERR_HBD, progname);
+ }
+ }
+ infile_pos = 0;
+}
+
+void Classfile::read() {
+ u16 numimports;
+
+ if (get32(infile, &infile_pos) != JAVA_CLASSFILE_MAGIC) fatalerror(NOT_A_CLASS_ERR);
+
+ version.read(this);
+ fprintf(stderr, "Classfile version %d.%d\n", version.major_version, version.minor_version);
+
+ imports_count = 0;
+ cp.read(this, &imports_count);
+ access_flags = get16(infile, &infile_pos);
+
+ this_class = get16(infile, &infile_pos);
+ super_class = get16(infile, &infile_pos);
+ if (((interfaces = new u16[interfaces_count = get16(infile, &infile_pos)]) == 0) && interfaces_count) memerr();
+ u16 i,j;
+ for (j = 0, i = interfaces_count; i--;) {
+ interfaces[j++] = get16(infile, &infile_pos);
+ }
+ if (((fields = new field_info_ptr[fields_count = get16(infile, &infile_pos)]) == 0) && fields_count) memerr();
+ for (j = 0, i = fields_count; i--;) {
+ field_info *fip = fields[j++] = new field_info;
+ if (!fip) memerr();
+ field_info &fi = *fip;
+ fi.isconstant = 0;
+ fi.access_flags = get16(infile, &infile_pos);
+ fi.name = cp[get16(infile, &infile_pos)]->chp;
+ fi.sig = cp[get16(infile, &infile_pos)]->chp;
+ for (int l = get16(infile, &infile_pos); l--;) {
+ u16 attribute_name_index = get16(infile, &infile_pos);
+ u32 attribute_size = get32(infile, &infile_pos);
+ char *attribute_name = cp[attribute_name_index]->chp;
+ if (!strcmp(attribute_name,"ConstantValue")) {
+ if (attribute_size != 2) {
+ fprintf(stderr, "Bad size on ConstantValue Attribute - should be 2!\n");
+ exit(1);
+ } else {
+ fi.isconstant = 1;
+ fi.constval_index = get16(infile, &infile_pos);
+ }
+ } else {
+ fprintf(stderr, "Skipping Unknown Field Attribute: %s (size %ld)\n", attribute_name, attribute_size);
+ for (u32 m = attribute_size; m--;) get8(infile, &infile_pos);
+ }
+ }
+ }
+ if (((methods = new method_info_ptr[methods_count = get16(infile, &infile_pos)]) == 0) && methods_count) memerr();
+ imports_count += methods_count;
+ numimports = 0;
+ if ((imports = new char_ptr[imports_count]) == 0) memerr();
+ char *tmpstr1, *tmpstr2, *tmpstr;
+ int package_name_length;
+ tmpstr = cp(this_class)->chp;
+ if ((tmpstr1 = strchr(tmpstr,'/')) != 0) {
+ int l;
+ while (tmpstr1) {
+ l = tmpstr1 - tmpstr;
+ tmpstr1 = strchr(tmpstr1 + 1, '/');
+ }
+ if ((package_name = new char[l+1]) == 0) memerr();
+ strncpy(package_name, tmpstr, l);
+ package_name[l] = '\0';
+ if ((this_class_name = new char[strlen(tmpstr + l + 1) + 1]) == 0) memerr();
+ strcpy(this_class_name, cp(this_class)->chp = tmpstr + l + 1);
+ tmpstr = package_name;
+ package_name_length = strlen(tmpstr);
+ while ((tmpstr = strchr(tmpstr,'/')) != 0) *tmpstr++ = '.';
+ } else {
+ package_name = 0;
+ package_name_length = 0;
+ if ((this_class_name = new char[strlen(tmpstr) + 1]) == 0) memerr();
+ strcpy(this_class_name, tmpstr);
+ }
+ for (i16 l = cp.count(); --l >= 0;) {
+ cp_info tmpcpi = *(cp[l]);
+ if (tmpcpi.tag == CONSTANT_Class) {
+ char **chap = &(cp(l)->chp);
+ tmpstr = *chap;
+ if (!strncmp(tmpstr, "java/lang/", 10)) *chap = tmpstr + 10;
+ else while ((tmpstr = strchr(tmpstr,'/')) != 0) *tmpstr++ = '.';
+ tmpstr = *chap;
+ if (package_name && !strncmp(tmpstr, package_name, package_name_length)) *chap = tmpstr += package_name_length + 1;
+ if ((numimports!=imports_count)&&(tmpstr2 = strrchr(tmpstr,'.')) != 0) {
+ imports[numimports++] = tmpstr;
+ for (int tint = numimports - 2; tint>=0; tint--) {
+ if (!strcmp(imports[tint], tmpstr)) {
+ --numimports;
+ break;
+ }
+ }
+ *chap = tmpstr2 + 1;
+ }
+ } else if(tmpcpi.tag == CONSTANT_NameAndType) {
+ // int tmpindex;
+ tmpstr = cp[/*tmpindex = */((NameAndType*)tmpcpi.p)->signature_index]->chp;
+ char *copytmpstr = tmpstr2 = strdup(tmpstr); if (!copytmpstr) memerr();
+ char *srcstr = tmpstr2, *deststr = tmpstr, *tmpstr3, *tmpstr4;
+ while ((*deststr++ = *srcstr++) != '\0') {
+ if (*(srcstr-1) == 'L') {
+ tmpstr3 = strchr(srcstr, ';'); if (!tmpstr3) fatalerror(UNKNOWN_ERR);
+ if (!strncmp(srcstr, "java/lang/", 10)) srcstr += 10;
+ else {
+ tmpstr2 = srcstr;
+ while (((tmpstr2 = strchr(tmpstr2,'/')) != 0)&&(tmpstr2 < tmpstr3)) *tmpstr2++ = '.';
+ }
+ if (package_name && !strncmp(srcstr, package_name, package_name_length)) srcstr += package_name_length + 1;
+ if (numimports!=imports_count && (tmpstr4 = strchr(srcstr, '.')) != 0 && tmpstr4 < tmpstr3) {
+ while (tmpstr4 != 0 && tmpstr4 < tmpstr3) { tmpstr2 = tmpstr4+1; tmpstr4 = strchr(tmpstr2,'.'); }
+ int tint = tmpstr3 - srcstr;
+ char *tstr = imports[numimports++] = new char[tint+1];
+ if (!tstr) memerr();
+ tstr = strncpy(tstr, srcstr, tint);
+ tstr[tint] = '\0';
+ for (tint = numimports - 2; tint>=0; tint--) {
+ if (!strcmp(imports[tint], tstr)) {
+ --numimports;
+ delete tstr;
+ break;
+ }
+ }
+ srcstr = tmpstr2;
+ }
+ while ((*deststr++ = *srcstr++) != ';') ;
+ }
+ }
+ }
+ }
+ for (j = 0, i = methods_count; i--;) {
+ method_info *mip = methods[j++] = new method_info;
+ if (!mip) memerr();
+ method_info &mi = *mip;
+ mi.access_flags = get16(infile, &infile_pos);
+ char *tmpstr;
+ mi.name = cp[get16(infile, &infile_pos)]->chp;
+ mi.sig = cp[get16(infile, &infile_pos)]->chp;
+
+ // int tmpindex;
+ tmpstr = mi.sig;
+ char *copytmpstr = tmpstr2 = strdup(tmpstr); if (!copytmpstr) memerr();
+ char *srcstr = tmpstr2, *deststr = tmpstr, *tmpstr3, *tmpstr4;
+ while ((*deststr++ = *srcstr++) != '\0') {
+ if (*(srcstr-1) == 'L') {
+ tmpstr3 = strchr(srcstr, ';'); if (!tmpstr3) fatalerror(UNKNOWN_ERR);
+ if (!strncmp(srcstr, "java/lang/", 10)) srcstr += 10;
+ else {
+ tmpstr2 = srcstr;
+ while (((tmpstr2 = strchr(tmpstr2,'/')) != 0)&&(tmpstr2 < tmpstr3)) *tmpstr2++ = '.';
+ }
+ if (package_name && !strncmp(srcstr, package_name, package_name_length)) srcstr += package_name_length + 1;
+ if (numimports!=imports_count && (tmpstr4 = strchr(srcstr, '.')) != 0 && tmpstr4 < tmpstr3) {
+ while (tmpstr4 != 0 && tmpstr4 < tmpstr3) { tmpstr2 = tmpstr4+1; tmpstr4 = strchr(tmpstr2,'.'); }
+ int tint = tmpstr3 - srcstr;
+ char *tstr = imports[numimports++] = new char[tint+1];
+ if (!tstr) memerr();
+ tstr = strncpy(tstr, srcstr, tint);
+ tstr[tint] = '\0';
+ for (tint = numimports - 2; tint>=0; tint--) {
+ if (!strcmp(imports[tint], tstr)) {
+ --numimports;
+ delete tstr;
+ break;
+ }
+ }
+ srcstr = tmpstr2;
+ }
+ }
+ }
+ mi.num_throws = 0;
+ mi.local_variable_table_length = 0;
+ mi.line_number_table_length = 0;
+ for (int l = get16(infile, &infile_pos); l--;) {
+ u16 attribute_name_index = get16(infile, &infile_pos);
+ u32 attribute_size = get32(infile, &infile_pos);
+ char *attribute_name = cp[attribute_name_index]->chp;
+ if (!strcmp(attribute_name,"Code")) {
+ mi.max_stack = (u8)get16(infile, &infile_pos);
+ mi.max_locals = (u8)get16(infile, &infile_pos);
+ if ((mi.code = new u8[mi.code_length = get32(infile, &infile_pos)]) == 0) memerr();
+ getstr(mi.code, mi.code_length, infile);
+ if (((mi.exception_table = new ExceptionTableEntry[mi.exception_table_length = get16(infile, &infile_pos)]) == 0) && mi.exception_table_length) memerr();
+ for (u16 n = 0, m = mi.exception_table_length; m--;) {
+ mi.exception_table[n].tag = TRY;
+ mi.exception_table[n].start_pc = get16(infile, &infile_pos);
+ mi.exception_table[n].end_pc = get16(infile, &infile_pos);
+ mi.exception_table[n].handler_pc = get16(infile, &infile_pos);
+ mi.exception_table[n++].catch_type = get16(infile, &infile_pos);
+ }
+ // getstr(mi.exception_table, mi.exception_table_length << 3, infile);
+ for (int l2 = get16(infile, &infile_pos); l2--;) {
+ u16 attribute_name_index2 = get16(infile, &infile_pos);
+ u32 attribute_size2 = get32(infile, &infile_pos);
+ char *attribute_name2 = cp[attribute_name_index2]->chp;
+ if (!strcmp(attribute_name2,"LineNumberTable")) {
+ if ((mi.line_number_table = new LineNumberTableEntry[mi.line_number_table_length = get16(infile, &infile_pos)]) == 0) memerr();
+ getstr(mi.line_number_table, mi.line_number_table_length << 2, infile);
+ } else if (!strcmp(attribute_name2,"LocalVariableTable")) {
+ if ((mi.local_variable_table = new LocalVariableTableEntry[mi.local_variable_table_length = get16(infile, &infile_pos)]) == 0) memerr();
+ getstr(mi.local_variable_table, mi.local_variable_table_length * 10, infile);
+ if ((mi.local_names = new char*[2*mi.local_variable_table_length]) == 0) memerr();
+ int o;
+ for (o = mi.local_variable_table_length; o--;) {
+ char *tmpstr = cp[mi.local_variable_table[o].name_index]->chp;
+ if ((mi.local_names[mi.local_variable_table[o].slot] = new char[strlen(tmpstr) + 1]) == 0) memerr();
+ strcpy(mi.local_names[mi.local_variable_table[o].slot], tmpstr);
+ }
+ if ((mi.local_sigs = new char*[2*mi.local_variable_table_length]) == 0) memerr();
+ for (o = mi.local_variable_table_length; o--;) {
+ char *tmpstr = cp[mi.local_variable_table[o].signature_index]->chp;
+ if ((mi.local_sigs[mi.local_variable_table[o].slot] = new char[strlen(tmpstr) + 1]) == 0) memerr();
+ strcpy(mi.local_sigs[mi.local_variable_table[o].slot], tmpstr);
+ }
+ } else {
+ fprintf(stderr, "Skipping Unknown Code Attribute: %s (size %ld)\n", attribute_name2, attribute_size2);
+ for (int m = attribute_size2; m--;) get8(infile, &infile_pos);
+ }
+ }
+ } else if (!strcmp(attribute_name,"Exceptions")) {
+ int *tmpintptr;
+ if ((tmpintptr = mi.throws = new int[mi.num_throws = get16(infile, &infile_pos)]) == 0) memerr();
+ for (int m = mi.num_throws;m--;) *tmpintptr++ = get16(infile, &infile_pos); //*tmpstr++ = constant_pool[constant_pool[get16(infile)].i].cp;
+ } else {
+ fprintf(stderr, "Skipping Unknown Method Attribute: %s (size %ld)\n", attribute_name, attribute_size);
+ // char *ti = new int[attribute_size], *tip = ti;
+ for (unsigned int m = 0; m++!=attribute_size;) printf("%02x%c", /**tip++ =*/ get8(infile, &infile_pos), (m%8)?' ':(m%16?'\n':'\t'));
+ printf("\n");
+ // int tc = ti[0]<<8+ti[1]
+ }
+ }
+ }
+ imports_count = numimports;
+ for (j = 0, i = get16(infile, &infile_pos); i--;) {
+ u16 attribute_name_index = get16(infile, &infile_pos);
+ u32 attribute_size = get32(infile, &infile_pos);
+ char *attribute_name = cp[attribute_name_index]->chp;
+ if (!strcmp(attribute_name,"SourceFile")) {
+ if (attribute_size != 2) {
+ fprintf(stderr, "Bad size on SourceFile Attribute - should be 2!\n");
+ exit(1);
+ } else {
+ char *tmpstr = cp[get16(infile, &infile_pos)]->chp;
+ if ((source_name = new char[strlen(tmpstr) + 1]) == 0) memerr();
+ strcpy(source_name, tmpstr);
+ }
+ } else {
+ fprintf(stderr, "Skipping Unknown Attribute: %s (size %ld)\n", attribute_name, attribute_size);
+ for (u32 k = attribute_size; k--;) get8(infile, &infile_pos);
+ }
+ }
+}
+
+void Classfile::print() {
+ int i,j;
+ fprintf(stderr, "Compiled from %s\n", source_name);
+ fprintf(outfile, "/*\n** Compiled from %s - COPYRIGHT UNKNOWN.\n**\n"
+ "** Decompiled using the HomeBrew Decompiler\n"
+ "** Copyright (c) 1994-2003 Widget (aka Pete Ryland).\n"
+ "** Available under GPL from http://pdr.cx/hbd/\n*/\n\n", source_name);
+ if (package_name) fprintf(outfile, "package %s;\n\n", package_name);
+ char **strptr = imports;
+ for (i = imports_count; i--;) {
+ fprintf(outfile, "import %s;\n", *strptr++);
+ }
+ fprintf(outfile, "\n");
+ char *tmpstr = new char[access_flags.strlen() + 1];
+ fprintf(outfile, "%sclass %s ", access_flags.toString(tmpstr), this_class_name);
+ delete tmpstr;
+ if (super_class) {
+ if (!strcmp(tmpstr = cp(super_class)->chp, "Object")) {
+ super_class_name = "Object";
+ } else {
+ if ((super_class_name = new char[strlen(tmpstr) + 1]) == 0) memerr();
+ strcpy(super_class_name, tmpstr);
+ fprintf(outfile, "extends %s ", super_class_name);
+ }
+ }
+ if (interfaces_count) {
+ fprintf(outfile, "implements ");
+ for (j = 0, i = interfaces_count - 1; i--;) {
+ fprintf(outfile, "%s, ", cp(interfaces[j])->chp);
+ }
+ fprintf(outfile, "%s ", cp(interfaces[j])->chp);
+ }
+ fprintf(outfile, "{");
+ for (j = 0, i = fields_count; i--;) {
+ field_info &fi = *(fields[j++]);
+ tmpstr = new char[fi.access_flags.strlen() + 1];
+ fprintf(outfile, "\n %s", fi.access_flags.toString(tmpstr));
+ delete tmpstr;
+ tmpstr = fi.sig;
+ printsigname(this, outfile, tmpstr, fi.name, 0);
+ if (fi.isconstant) {
+ fprintf(outfile, " = ");
+ char *chptr = fi.sig;
+ switch(*chptr++) {
+ case SIGNATURE_INT:
+ fprintf(outfile, "0x%lX", cp[fi.constval_index]->i);
+ break;
+ case SIGNATURE_LONG:
+ if(cp[fi.constval_index]->i) {
+ fprintf(outfile, "0x%lX%08lXL", cp[fi.constval_index]->i,
+ cp[(u16)((i16)fi.constval_index + 1)]->i);
+ } else {
+ fprintf(outfile, "0x%lXL", cp[(u16)((i16)fi.constval_index + 1)]->i);
+ }
+ break;
+ case SIGNATURE_FLOAT:
+ fprintf(outfile, "%#.100Gf", cp[fi.constval_index]->f);
+ break;
+ case SIGNATURE_DOUBLE:
+ fprintf(outfile, "%#.100Gd",(float)*(double*)(cp[fi.constval_index]->i));
+ break;
+ default:
+ fprintf(stderr, "Bad type for constant\n");
+ }
+ }
+ fprintf(outfile, ";");
+ }
+ for (j = 0, i = methods_count; i--;) {
+ if (decompileblock(this, methods[j++])) fprintf(outfile, "/* Decompilation Error. Continuing... */");
+ }
+ fprintf(outfile, "\n}");
+ return;
+}
diff --git a/MultiSource/Applications/hbd/class.h b/MultiSource/Applications/hbd/class.h
new file mode 100644
index 00000000..c14583e4
--- /dev/null
+++ b/MultiSource/Applications/hbd/class.h
@@ -0,0 +1,105 @@
+/* class.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef CLASS_H
+#define CLASS_H
+
+#include <stdio.h>
+#include "options.h"
+#include "version.h"
+#include "cp.h"
+#include "access.h"
+#include "general.h"
+#include "field.h"
+#include "method.h"
+
+/* The master classfile structure. */
+struct Classfile {
+ /* The input and output files */
+ FILE *infile, *outfile;
+
+ /* These keeps a tab on where in the files we are */
+ int infile_pos, outfile_pos;
+
+ /* The command-line options we are using */
+ CL_Options options;
+
+ /* The basic class file format starts from here */
+
+ /* The class version - should always be 45.3 */
+ ClassVersion version;
+
+ /* The Constant Pool */
+ ConstPool cp;
+
+ /* The access modifiers for this class */
+ AccessFlags access_flags;
+
+ /* An index into the constant pool of the name
+ of this class. */
+ u16 this_class;
+
+ /* This contains the name of the package for this class,
+ resolved from the above constant-pool reference */
+ char *package_name;
+
+ /* This contains the name of the actual class,
+ resolved from the above constant-pool reference */
+ char *this_class_name;
+
+ /* This is an index into the constant pool for the name
+ of the parent class */
+ u16 super_class;
+
+ /* The resolved string */
+ char *super_class_name;
+
+ /* This table contains indexes into the constant pool
+ for the interfaces that this class implements */
+ u16 interfaces_count;
+ u16 *interfaces;
+
+ /* This table contains the fields in this class */
+ u16 fields_count;
+ field_info_ptr *fields;
+
+ /* This table contains the methods in this class */
+ u16 methods_count;
+ method_info_ptr *methods;
+
+ /* The name of the source file from which this
+ class was compiled. This is determined from
+ the SourceFile attribute. */
+ char *source_name;
+
+ /* This table holds the import statements that this
+ class would have needed to enable it to refer to
+ all the classes it uses without referring to
+ their package name. It is determined from clues
+ the parser finds along the way. */
+ u16 imports_count;
+ char **imports;
+
+ /* The function that the translator will be inserting
+ the code for */
+ char *functoinsert;
+
+ /* The constructor, which will parse the command-line
+ arguments */
+ Classfile(int argc, char **argv);
+
+ /* The read() and print() methods are only used by the
+ decompiler */
+ /* The read() method parses the input file */
+ void read();
+ /* print() decompiles and prints the decompilation
+ of the class */
+ void print();
+};
+
+#endif
diff --git a/MultiSource/Applications/hbd/config.h b/MultiSource/Applications/hbd/config.h
new file mode 100644
index 00000000..8ac4f283
--- /dev/null
+++ b/MultiSource/Applications/hbd/config.h
@@ -0,0 +1,53 @@
+/* src/config.h. Generated by configure. */
+/* src/config-h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "hbd"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.2.3"
diff --git a/MultiSource/Applications/hbd/consts.h b/MultiSource/Applications/hbd/consts.h
new file mode 100644
index 00000000..c388f713
--- /dev/null
+++ b/MultiSource/Applications/hbd/consts.h
@@ -0,0 +1,28 @@
+/* consts.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef CONSTS_H
+#define CONSTS_H
+
+/* These are the tags that the constant pool uses. */
+enum {
+ CONSTANT_Utf8 = 1,
+ CONSTANT_Unicode, /* unused */
+ CONSTANT_Integer,
+ CONSTANT_Float,
+ CONSTANT_Long,
+ CONSTANT_Double,
+ CONSTANT_Class,
+ CONSTANT_String,
+ CONSTANT_Fieldref,
+ CONSTANT_Methodref,
+ CONSTANT_InterfaceMethodref,
+ CONSTANT_NameAndType
+};
+
+#endif
diff --git a/MultiSource/Applications/hbd/cp.cpp b/MultiSource/Applications/hbd/cp.cpp
new file mode 100644
index 00000000..6d2730c8
--- /dev/null
+++ b/MultiSource/Applications/hbd/cp.cpp
@@ -0,0 +1,83 @@
+/* cp.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "general.h"
+#include "cp.h"
+#include "file.h"
+#include "err.h"
+#include "class.h"
+#include "consts.h"
+
+void ConstPool::read(Classfile *c, u16 *imports_count) {
+ if ((constant_pool = new cp_info[(constant_pool_count = get16(c->infile, &c->infile_pos))]) == 0) memerr();
+ for (int j = 1, i = constant_pool_count - 1; i--;) {
+ cp_info *cpi = &constant_pool[j++];
+ cpi->tag = (unsigned char)get8(c->infile, &c->infile_pos);
+ unsigned short size;
+ D(fprintf(c->outfile, "\npos: 0x%05X\tindex: %4d\t",c->infile_pos,j-1))
+ switch(cpi->tag) {
+ case CONSTANT_Utf8:
+ if ((cpi->chp = new char[(size = get16(c->infile, &c->infile_pos)) + 1]) == 0) memerr();
+ getstr(cpi->chp, size, c->infile);
+ cpi->chp[size] = '\0';
+ D(fprintf(c->outfile, "UTF8: %s\t", cpi->chp))
+ break;
+ case CONSTANT_Unicode: D(fprintf(c->outfile, "Unicode\t")) /* unused */
+ break;
+ case CONSTANT_Integer:
+ cpi->i = get32(c->infile, &c->infile_pos);
+ D(fprintf(c->outfile, "32-bit int: 0x%8lX\t", cpi->i))
+ break;
+ case CONSTANT_Float:
+ cpi->i = get32(c->infile, &c->infile_pos);
+ D(fprintf(c->outfile, "32-bit float: %.25G\t", cpi->f))
+ break;
+ case CONSTANT_Long:
+ cpi->i = get32(c->infile, &c->infile_pos);
+ cpi = &constant_pool[j++];
+ cpi->tag = 0;
+ cpi->i = get32(c->infile, &c->infile_pos);
+ D(((cpi - 1)->i) ? fprintf(c->outfile, "64-bit int: 0x%lX%08lX", (cpi - 1)->i, cpi->i) : fprintf(c->outfile, "64-bit int: 0x%lX", cpi->i))
+ if (i--) continue;
+ break;
+ case CONSTANT_Double:
+ *(((unsigned long *)&cpi->i) + 1) = get32(c->infile, &c->infile_pos);
+ cpi->i = get32(c->infile, &c->infile_pos);
+ D(fprintf(c->outfile, "64-bit float: %.25G\t",(float)*(double*)(&cpi->i))) constant_pool[j++].tag = 0;
+ if (i--) continue;
+ break;
+ case CONSTANT_Class:
+ imports_count++;
+ cpi->i = get16(c->infile, &c->infile_pos);
+ D(fprintf(c->outfile, "Class: name = index %d\t", (int)cpi->i))
+ break;
+ case CONSTANT_String:
+ cpi->i = get16(c->infile, &c->infile_pos);
+ D(fprintf(c->outfile, "String: index %d\t", (int)cpi->i))
+ break;
+ case CONSTANT_Fieldref:
+ case CONSTANT_Methodref:
+ case CONSTANT_InterfaceMethodref:
+ if ((cpi->p = new Ref) == 0) memerr();
+ ((Ref*)cpi->p)->class_index = get16(c->infile, &c->infile_pos);
+ ((Ref*)cpi->p)->name_and_type = get16(c->infile, &c->infile_pos);
+ D(fprintf(c->outfile, "Ref: class_index %d, n&t_index %d\t", ((Ref*)cpi->p)->class_index, ((Ref*)cpi->p)->name_and_type))
+ break;
+ case CONSTANT_NameAndType:
+ imports_count++;
+ if ((cpi->p = new NameAndType) == 0) memerr();
+ ((NameAndType*)cpi->p)->name_index = get16(c->infile, &c->infile_pos);
+ ((NameAndType*)cpi->p)->signature_index = get16(c->infile, &c->infile_pos);
+ D(fprintf(c->outfile, "Name&Type: name_index %d, sig_index %d\t", ((NameAndType*)cpi->p)->name_index, ((NameAndType*)cpi->p)->signature_index))
+ break;
+ default:
+ fprintf(stderr, "Error reading constant pool entry %d of %d at file pos 0x%08x!\n", j, constant_pool_count, c->infile_pos);
+ fatalerror(CP_ERR);
+ }
+ }
+}
diff --git a/MultiSource/Applications/hbd/cp.h b/MultiSource/Applications/hbd/cp.h
new file mode 100644
index 00000000..548ea3d2
--- /dev/null
+++ b/MultiSource/Applications/hbd/cp.h
@@ -0,0 +1,68 @@
+/* cp.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef CP_H
+#define CP_H
+
+#include "general.h"
+
+/* These are structures that the constant pool's table
+ can contain. */
+
+typedef struct {
+ u16 class_index;
+ u16 name_and_type;
+} Ref;
+
+typedef struct {
+ u16 name_index;
+ u16 signature_index;
+} NameAndType;
+
+/* The generic structure of constants that will appear
+ in the table of constants in the constant pool */
+struct cp_info {
+ unsigned char tag;
+ union {
+ long i;
+ void *p;
+ double d;
+ float f;
+ char *chp;
+ };
+};
+
+/* Forward declaration of the Classfile struct */
+struct Classfile;
+
+/* The ConstPool struct, which contains the Constant
+ Pool. */
+struct ConstPool {
+ /* The number of entries in this Constant Pool */
+ u16 constant_pool_count;
+
+ /* The table of constants */
+ cp_info *constant_pool;
+
+ /* This will parse the input file for a constant pool */
+ void read(Classfile *c, u16 *imports_count);
+
+ /* These methods provide easy access to commonly
+ used parts of constant pool entries */
+ cp_info *operator [](u16 i) {
+ return &(constant_pool[i]);
+ }
+ cp_info *operator ()(u16 i) {
+ return &(constant_pool[constant_pool[i].i]);
+ }
+ u16 count() {
+ return constant_pool_count;
+ }
+};
+
+#endif
diff --git a/MultiSource/Applications/hbd/d1-pushc.cpp b/MultiSource/Applications/hbd/d1-pushc.cpp
new file mode 100644
index 00000000..5f217e07
--- /dev/null
+++ b/MultiSource/Applications/hbd/d1-pushc.cpp
@@ -0,0 +1,80 @@
+/* d1-pushc.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <stdio.h>
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+#include "consts.h"
+
+int pushimm(Classfile *c) /* push immediate value e.g. bipush 34 */
+{
+ int pcval = currpc - 1;
+ int val = JDNEXT8S();
+ if (ch == 0x11) { val<<=8; val+=JDNEXT8U(); }
+ char *temp_str = new char[32];
+ sprintf(temp_str, "%i", val);
+ *stkptr++ = new Exp(pcval, temp_str, INT, IM); /* id->linfo = val */
+ return 0;
+}
+
+int pushconst(Classfile *c) /* push value from cp e.g. ldc1 #3 */
+{
+ int pcval = currpc - 1;
+ int val = JDNEXT8U();
+ if (ch != 0x12) { val<<=8; val+=JDNEXT8U(); }
+ Type idtype;
+ char tmpstr[1024];
+ cp_info *cpi = c->cp[val];
+ switch (cpi->tag) {
+ case CONSTANT_Integer:
+ sprintf(tmpstr, "0x%lX", cpi->i);
+ idtype = INT;
+// id->linfo = cpi->i;
+ break;
+ case CONSTANT_Long:
+ if (cpi->i)
+ sprintf(tmpstr, "0x%lX%08lXL", cpi->i, (cpi + 1)->i);
+ else
+ sprintf(tmpstr, "0x%lXL", (cpi + 1)->i);
+ idtype = LONG;
+// id->linfo = (cpi + 1)->i;
+// id->llinfo[2] = cpi->i;
+ break;
+ case CONSTANT_Float:
+ sprintf(tmpstr, "%.25Gf", cpi->f);
+ idtype = FLOAT;
+// id->dinfo = cpi->f;
+ break;
+ case CONSTANT_Double:
+ sprintf(tmpstr, "%.25Gd", *(double *)&cpi->i);
+ idtype = DOUBLE;
+// id->dinfo = *(double*)&cpi->i;
+ break;
+ case CONSTANT_String:
+ sprintf(tmpstr, "\"%s\"", c->cp[cpi->i]->chp);
+ idtype = OBJECT; /* java.lang.String */
+// id->dinfo = (int)c->cp[cpi->i]->chp;
+ break;
+ default:
+ fprintf(stderr, "Unkown tag %d on constant\n", cpi->tag);
+ return -1;
+ }
+ char *idname = new char[strlen(tmpstr) + 1];
+ strcpy(idname, tmpstr);
+ *stkptr++ = new Exp(pcval, idname, idtype, CP, val);
+ return 0;
+}
+
+int pushimp(Classfile *c) /* push implied immediate value e.g. iconst_m1 */
+{
+ *stkptr++ = new Exp(currpc - 1, ch - 1);
+ return 0;
+}
+
diff --git a/MultiSource/Applications/hbd/d2-pushl.cpp b/MultiSource/Applications/hbd/d2-pushl.cpp
new file mode 100644
index 00000000..1e717454
--- /dev/null
+++ b/MultiSource/Applications/hbd/d2-pushl.cpp
@@ -0,0 +1,60 @@
+/* d2-pushl.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "general.h"
+#include "exp.h"
+#include "decomp.h"
+#include "method.h"
+
+int pushlocal(Classfile *c) /* push value from local (or params) */
+{
+ int pcval = currpc - 1;
+ int val;
+ Type idtype = VOID;
+ if (ch < 0x1A) {
+ val = JDNEXT8S();
+ switch (ch) {
+ case 0x15: idtype = INT; break;
+ case 0x16: idtype = LONG; break;
+ case 0x17: idtype = FLOAT; break;
+ case 0x18: idtype = DOUBLE; break;
+ case 0x19: idtype = OBJECT; break;
+ }
+ } else if (ch < 0x1E) {
+ val = ch - 0x1A;
+ idtype = INT;
+ } else if (ch < 0x22) {
+ val = ch - 0x1E;
+ idtype = LONG;
+ } else if (ch < 0x26) {
+ val = ch - 0x22;
+ idtype = FLOAT;
+ } else if (ch < 0x2A) {
+ val = ch - 0x26;
+ idtype = DOUBLE;
+ } else /* if (ch < 0x2E) */ {
+ val = ch - 0x2A;
+ idtype = OBJECT;
+ }
+ char *tmpstr = miptr->local_names[val], *idname;
+ if (tmpstr) {
+ idname = new char[strlen(tmpstr) + 1];
+ strcpy(idname, tmpstr);
+ } else {
+ fprintf(stderr, "Error in code: local used before defined.\n");
+ return 1;
+ }
+ Exp *e = new Exp(pcval, idname, idtype, LO, val);
+// if((lastaction == 16)&&(!strcmp((*(donestkptr-1))->exp1->e->id->name,id->name))) {
+// *stkptr++ = *(--donestkptr);
+ *stkptr++ = e;
+// } else {
+// *stkptr++ = e;
+// }
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/d3-popl.cpp b/MultiSource/Applications/hbd/d3-popl.cpp
new file mode 100644
index 00000000..7febaf58
--- /dev/null
+++ b/MultiSource/Applications/hbd/d3-popl.cpp
@@ -0,0 +1,116 @@
+/* d3-popl.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <stdlib.h>
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+int storelocal(Classfile *c) /* pop value to local (including params) */
+{
+ unsigned pcval = currpc - 1;
+ int val;
+ Type idtype = VOID;
+ if (ch < 0x3B) {
+ switch (ch) {
+ case 0x36: idtype = INT; break;
+ case 0x37: idtype = LONG; break;
+ case 0x38: idtype = FLOAT; break;
+ case 0x39: idtype = DOUBLE; break;
+ case 0x3A: idtype = OBJECT; break;
+ }
+ val = JDNEXT8S();
+ } else if (ch < 0x3F) {
+ val = ch - 0x3B;
+ idtype = INT;
+ } else if (ch < 0x43) {
+ val = ch - 0x3F;
+ idtype = LONG;
+ } else if (ch < 0x47) {
+ val = ch - 0x43;
+ idtype = FLOAT;
+ } else if (ch < 0x4B) {
+ val = ch - 0x47;
+ idtype = DOUBLE;
+ } else {
+ val = ch - 0x4B;
+ idtype = OBJECT;
+ }
+// if (val) {
+ char *tmpstr = miptr->local_names[val], *idname;
+ if (tmpstr) {
+ idname = new char[strlen(tmpstr) + 1];
+ strcpy(idname, tmpstr);
+ idtype = miptr->local_types[val];
+ } else {
+ idname = miptr->local_names[val] = new char[7];
+ sprintf(idname, "var%d", val);
+ if ((miptr->local_types[val] == VOID)||(miptr->local_types[val] == UNKNOWN)) {
+ if (idtype != INT)
+ miptr->local_types[val] = idtype;
+ else
+ miptr->local_types[val] = UNKNOWN;
+ }
+ }
+ Exp *e1 = new Exp(pcval, idname, idtype, LO, val);
+ Exp *e2 = *(--stkptr);
+ Exp *e = new Exp(pcval, min(pcval, e2->minpc), BINARY, idtype, ASSIGN, e1, e2);
+ if (!tmpstr) miptr->local_firstuses[val] = e->minpc;
+ if ((e2->e->type == INT) && (e1->e->type == BOOLEAN))
+ if ((e2->e == std_exps + 2)||(e2->e == std_exps + 3)) /* 0 or 1 */
+ e2->e += 13; /* false or true */
+ else
+ /* CMPEQ */;
+ *donestkptr++ = e;
+ return 0;
+}
+
+int iinclocal(Classfile *c) /* increment local by value */
+{
+ int pcval = currpc - 1;
+ int val;
+ val = JDNEXT8S();
+ char *id1name;
+ char *tmpstr = miptr->local_names[val];
+ if (tmpstr) {
+// id1name = new char[strlen(tmpstr) + 1];
+// strcpy(id1name, tmpstr);
+ id1name = tmpstr;
+ } else {
+ printf("Local int used before defined.\n");
+ return 1;
+ }
+ if (miptr->local_types[val] == UNKNOWN) miptr->local_types[val] = INT;
+// if (miptr->local_types[val] == UNKNOWN) miptr->local_types[val] = INT;
+// if (miptr->local_types[val] == VOID) miptr->local_types[val] = INT;
+ if ((miptr->local_types[val] != INT)&&(miptr->local_types[val] != SHORT)) {
+ printf("Incrementation of local var%d of type %d i.e. %s.\n", val, miptr->local_types[val], type2str[miptr->local_types[val]]);
+ return 1;
+ }
+ int incnum = JDNEXT8S();
+// id2->linfo = incnum;
+ Exp *e;
+ if ((incnum!=1)&&(incnum!=-1)) {
+ Exp *e1 = new Exp(pcval, id1name, INT, LO, val);
+ char *id2name = new char[5]; sprintf(id2name, "%ld", labs(incnum));
+ Exp *e2 = new Exp(pcval, id2name, INT, IM);
+ e = new Exp(pcval, BINARY, INT, (incnum<0)?SUBASSIGN:ADDASSIGN, e1, e2);
+ } else {
+ Exp *e1 = new Exp(pcval, id1name, INT, LO, val);
+ e = new Exp(pcval, PREUNARY, INT, (incnum<0)?DEC:INC, e1);
+ }
+
+ if ((lastaction == 4)&&(!strcmp((*(stkptr-1))->e->id->name,id1name))) {
+ e->e->et = POSTUNARY; e->minpc = min(e->minpc, (*(stkptr-1))->minpc);
+ *(stkptr-1) = e;
+ } else {
+ *donestkptr++ = e;
+ }
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/d4-array.cpp b/MultiSource/Applications/hbd/d4-array.cpp
new file mode 100644
index 00000000..931f8754
--- /dev/null
+++ b/MultiSource/Applications/hbd/d4-array.cpp
@@ -0,0 +1,68 @@
+/* d4-array.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+int anewarray(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ int val = JDNEXT16U();
+ char *class_name = c->cp(val)->chp;
+ Exp *e1 = new Exp(pcval, class_name, VOID, NO);
+ Exp *e2 = new Exp(pcval, ARRAYACCESS, VOID, ID, e1, *(stkptr-1));
+ *(stkptr-1) = new Exp(pcval, min(pcval, e2->exp2->minpc), PREUNARY, ARRAY, NEW, e2);
+ return 0;
+}
+
+int multianewarray(Classfile *c)
+{
+ printf("Multi");
+ unsigned pcval = currpc - 1;
+ /*int val = */JDNEXT16U();
+// char *class_name; // = c->constant_pool[c->constant_pool[val].i].cp;
+// for (val = JDNEXT8U(); val--;) {
+// --stkptr;
+// } stkptr++;
+ Exp *e1 = *(stkptr-1);
+ *(stkptr-1) = new Exp(pcval, min(pcval, e1->minpc), PREUNARY, ARRAY, NEW, e1);
+ return 0;
+}
+
+int doarraylength(Classfile *c) /* 190 == 0xBE */
+{
+ unsigned pcval = currpc - 1;
+ Exp *e1 = *(stkptr-1);
+ Exp *e2 = new Exp(pcval, "length", VOID, NO);
+ *(stkptr-1) = new Exp(pcval, min(pcval, e1->minpc), BINARY, INT, DOT, e1, e2);
+ return 0;
+}
+
+int doarrayget(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ Exp *e2 = *(--stkptr);
+ Exp *e1 = *(stkptr-1);
+ *(stkptr-1) = new Exp(pcval, min(min(pcval, e1->minpc), e2->minpc), ARRAYACCESS,
+ (Type)(ch - (0x2E - INT)), ID, e1, e2);
+ return 0;
+}
+
+int doarrayput(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ Exp *e4 = *(--stkptr);
+ Exp *e3 = *(--stkptr);
+ Exp *e2 = *(--stkptr);
+ unsigned minpcval = min(min(pcval, e2->minpc), e3->minpc);
+ Exp *e1 = new Exp(pcval, minpcval, ARRAYACCESS, OBJECT, ID, e2, e3);
+ *donestkptr++ = new Exp(pcval, minpcval, BINARY, OBJECT, ASSIGN, e1, e4);
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/d5-stack.cpp b/MultiSource/Applications/hbd/d5-stack.cpp
new file mode 100644
index 00000000..c38df102
--- /dev/null
+++ b/MultiSource/Applications/hbd/d5-stack.cpp
@@ -0,0 +1,39 @@
+/* d5-stack.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+int dopop(Classfile *c)
+{
+ if (stkptr != stack) *donestkptr++ = *(--stkptr);
+ return 0;
+}
+
+
+int dodup(Classfile *c)
+{
+ if ((*(stkptr-1))->e->op != NEW) {
+ *stkptr = *(stkptr-1);
+ (*stkptr)->numrefs++;
+ stkptr++;
+ }
+ return 0;
+}
+
+int dodup_x1(Classfile *c)
+{
+ *stkptr = *(stkptr-1);
+ *(stkptr-1) = *(stkptr-2);
+ *(stkptr-2) = *stkptr;
+ (*stkptr)->numrefs++;
+ stkptr++;
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/d6-arith.cpp b/MultiSource/Applications/hbd/d6-arith.cpp
new file mode 100644
index 00000000..217d17a4
--- /dev/null
+++ b/MultiSource/Applications/hbd/d6-arith.cpp
@@ -0,0 +1,99 @@
+/* d6-arith.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+extern int cond_pcend;
+extern Exp *cond_e;
+extern Exp *cond_e2;
+extern Exp **cond_donestkptr;
+extern Exp **cond_stkptr;
+
+int pushbinop(Classfile *c) /* push binary operation, popping operands e.g. lxor */
+{
+ unsigned pcval = currpc - 1;
+ Exp *e2 = *(--stkptr);
+ Exp *e1 = *(stkptr-1);
+ *(stkptr-1) = new Exp(pcval, min(min(e1->minpc, e2->minpc), pcval), BINARY,
+ e1->e->type,
+ (Op)((ch < 0x74)?
+ ((ch - 0x60) >> 2) : (0x07 + ((ch - 0x78) >> 1))),
+ e1, e2);
+ return 0;
+}
+
+int pushunop(Classfile *c) /* push unary operation, popping operand e.g. lneg */
+{
+ unsigned pcval = currpc - 1, branch_pc;
+ char *tmpstr, *buff;
+ Exp *e1 = *(stkptr-1);
+ Op eop = CAST;
+ Type etype = VOID;
+ int val;
+ switch (ch) {
+ case 0x74: case 0x75: case 0x76: case 0x77: eop = NEG; etype = e1->e->type; break;
+ case 0x88: case 0x8B: case 0x8E: etype = INT; break;
+ case 0x85: case 0x8C: case 0x8F: etype = LONG; break;
+ case 0x86: case 0x89: case 0x90: etype = FLOAT; break;
+ case 0x87: case 0x8A: case 0x8D: etype = DOUBLE; break;
+ case 0x91: etype = BYTE; break;
+ case 0x92: etype = CHAR; break;
+ case 0x93: etype = SHORT; break;
+ case 0xBF:
+ --stkptr;
+ *donestkptr++ = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, VOID, THROW, e1);
+ return 0;
+ case 0xBB:
+ val = JDNEXT16U();
+ tmpstr = c->cp(val)->chp;
+ buff = new char[strlen(tmpstr) + 1]; strcpy(buff, tmpstr);
+ e1 = new Exp(pcval, buff, VOID, CP, val);
+ *(stkptr++) = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, OBJECT, NEW, e1);
+// if ((ch = JDNEXT8()) == 0x59)
+// return actiontable[actions[ch = JDNEXT8()]]();
+// else
+// return actiontable[actions[ch]]();
+ case 0xBA: eop = NEW; break;
+ case 0xA7: /* GOTO really shouldn't be here! */
+ if (stkptr!=stack) {
+// if (stkptr!=(stack+1)) { fprintf(stderr, "Error in conditional operator!\n"); return 1; }
+ if (cond_pcend != -1) { fprintf(stderr, "Can't handle recursive conditional operators!\n"); return 1; }
+ cond_pcend = pcval + JDNEXT16S();
+ cond_stkptr = stkptr;
+ cond_e2 = *(--stkptr);
+ --donestkptr;
+ if ((*donestkptr)->e->et == BRANCH) {
+ if ((*donestkptr)->branch_pc != currpc) {
+ fprintf(stderr, "Error in conditional operator!\n"); return 1;
+ }
+ cond_e = *donestkptr;
+ } else {
+ fprintf(stderr, "Use of comma operator in conditionals not yet supported.\n");
+ return 1;
+ }
+ cond_donestkptr = donestkptr;
+ return 0;
+ }
+ branch_pc = pcval + JDNEXT16S();
+ tmpstr = new char[100];
+ sprintf(tmpstr,"label%i", branch_pc);
+ buff = new char[strlen(tmpstr) + 1]; strcpy(buff, tmpstr);
+ delete tmpstr;
+ e1 = new Exp(pcval, buff, VOID/*label*/, IM);
+ *donestkptr++ = new Exp(pcval, PREUNARY, VOID, GOTO, e1, branch_pc);
+ return 0;
+ default:
+ fprintf(stderr, "Error in pushing unary operation\n");
+ exit(-1);
+ }
+ *(stkptr-1) = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, etype, eop, e1);
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/d7-cntrl.cpp b/MultiSource/Applications/hbd/d7-cntrl.cpp
new file mode 100644
index 00000000..12b55705
--- /dev/null
+++ b/MultiSource/Applications/hbd/d7-cntrl.cpp
@@ -0,0 +1,84 @@
+/* d7-cntrl.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+int cond_pcend;
+Exp *cond_e;
+Exp *cond_e2;
+Exp **cond_donestkptr;
+Exp **cond_stkptr;
+
+int doif1(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ Exp *e = *(--stkptr), *e1, *e2;
+ switch (e->e->type) {
+ case CMPTYPE:
+ if (e->e->op != CMP) { fprintf(stderr, "doif1 error\n"); return 1; }
+ e->e->op = (Op)(EQUAL + ch - 0x99); e->e->type = BOOLEAN;
+ break;
+ case BOOLEAN:
+ if (ch == 0x99) // ifeq (ie if false)
+ if (notexp(&e)) { fprintf(stderr, "doif1 error\n"); return 1; }
+ break;
+ case INT:
+ e1 = *stkptr; e2 = new Exp(pcval, I0EXP);
+ e = new Exp(pcval, e1->minpc, BINARY, BOOLEAN, (Op)(EQUAL + ch - 0x99), e1, e2);
+ break;
+ case OBJECT:
+ e1 = *stkptr; e2 = new Exp(pcval, NULLEXP);
+ e = new Exp(pcval, e1->minpc, BINARY, BOOLEAN, (Op)(EQUAL + ch - 0xC6), e1, e2);
+ break;
+ default:
+ break;
+ }
+ *donestkptr++ = new Exp(pcval, e->minpc, IFEXP, e, pcval + JDNEXT16S());
+ return 0;
+}
+
+int doif2(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ Exp *e2 = *(--stkptr);
+ Exp *e1 = *(--stkptr);
+ Exp *e = new Exp(pcval, min(e1->minpc, e2->minpc), BINARY, BOOLEAN,
+ (Op)(EQUAL + ((ch - 0x9F) % 6)), e1, e2);
+ *donestkptr++ = new Exp(pcval, e->minpc, /*std_exp*/IFEXP, e,
+ /*branch_pc*/pcval + JDNEXT16S());
+ return 0;
+}
+
+int docmp(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ Exp *e2 = *(--stkptr);
+ Exp *e1 = *(stkptr-1);
+ *(stkptr-1) = new Exp(pcval, min(e1->minpc, e2->minpc), BINARY, CMPTYPE, CMP, e1, e2);
+ return 0;
+}
+
+int finishconditional(Classfile *c) {
+ if ((stkptr != cond_stkptr) || (donestkptr != cond_donestkptr))
+ { fprintf(stderr, "Error cond\n"); return 1; }
+ cond_e->e++;
+ if ((cond_e->exp1->e->op > LESSOREQUAL) || (cond_e->exp1->e->op < EQUAL)) {
+ if (cond_e->exp1->e->type != BOOLEAN) { fprintf(stderr, "Can't not a non-boolean\n"); return 1; }
+ Exp *e1 = cond_e->exp1;
+ cond_e->exp1 = new Exp(currpc, e1->minpc, PREUNARY, BOOLEAN, NOT_BOOL, e1);
+ } else {
+ *((int*)(&cond_e->exp1->e->op)) ^= 1;
+ }
+ cond_e->exp2 = cond_e2; cond_e->exp3 = *(stkptr-1);
+ *(stkptr-1) = cond_e;
+ cond_pcend = -1;
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/d8-ret.cpp b/MultiSource/Applications/hbd/d8-ret.cpp
new file mode 100644
index 00000000..17b4615e
--- /dev/null
+++ b/MultiSource/Applications/hbd/d8-ret.cpp
@@ -0,0 +1,35 @@
+/* d8-ret.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+int doreturn(Classfile *c) /* push return op, popping operand e.g. ireturn LO3 */
+{
+ unsigned pcval = currpc - 1;
+ if (ch == 0xB1) {
+ if (bufflength > 0) {
+ Exp *e1 = new Exp(pcval, "/* void */", VOID, IM);
+ *donestkptr++ = new Exp(pcval, PREUNARY, VOID, RETURN, e1);
+ }
+ } else {
+ Exp *e1 = *(stkptr-1);
+ if ((e1->e->type == INT) && (miptr->ret_type == BOOLEAN)) {
+ if ((e1->e == std_exps + 2)||(e1->e == std_exps + 3))
+ e1->e += 13; /* convert 0 or 1 to false or true */
+ else
+ /* CMPEQ */;
+ }
+ --stkptr;
+ *donestkptr++ = new Exp(pcval, min(pcval, e1->minpc), PREUNARY, VOID, RETURN, e1);
+ }
+ return 0;
+}
+
diff --git a/MultiSource/Applications/hbd/d9-swtch.cpp b/MultiSource/Applications/hbd/d9-swtch.cpp
new file mode 100644
index 00000000..36fac620
--- /dev/null
+++ b/MultiSource/Applications/hbd/d9-swtch.cpp
@@ -0,0 +1,43 @@
+/* d9-swtch.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+int dotableswitch(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ while(currpc%4) JDNEXT8U();
+ Exp *e1 = *(--stkptr);
+ unsigned defaultpc = JDNEXT32S();
+ unsigned low = JDNEXT32S(), high = JDNEXT32S(), numcases = high - low + 1;
+ Case *tcase = new Case[numcases];
+ *donestkptr++ = new Exp(pcval, e1->minpc, SWITCH, VOID, ID, e1, defaultpc, numcases, tcase);
+ for (unsigned m = low; m <= high;) {
+ tcase->caseval = m++;
+ (tcase++)->branch_pc = JDNEXT32S();
+ }
+ return 0;
+}
+
+int doluswitch(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ while(currpc%4) JDNEXT8U();
+ Exp *e1 = *(--stkptr);
+ unsigned defaultpc = JDNEXT32U(), numcases = JDNEXT32U();
+ Case *tcase = new Case[numcases];
+ *donestkptr++ = new Exp(pcval, e1->minpc, SWITCH, VOID, ID, e1, defaultpc, numcases, tcase);
+ for (unsigned m = numcases; m--;) {
+ tcase->caseval = JDNEXT32U();
+ (tcase++)->branch_pc = JDNEXT32U();
+ }
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/da-field.cpp b/MultiSource/Applications/hbd/da-field.cpp
new file mode 100644
index 00000000..2279a472
--- /dev/null
+++ b/MultiSource/Applications/hbd/da-field.cpp
@@ -0,0 +1,112 @@
+/* da-field.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+#include "field.h"
+
+int doget(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ int val = JDNEXT16S();
+ Ref *mr = (Ref*)c->cp[val]->p;
+ NameAndType *nt = (NameAndType*)c->cp[mr->name_and_type]->p;
+ char *tmpstr = c->cp[nt->name_index]->chp;
+ Exp *e = new Exp(pcval, tmpstr, sig2type(c->cp[nt->signature_index]->chp), CP, val);
+ if (ch == 0xB2) { /* getstatic */
+ Exp *e1;
+ tmpstr = c->cp(mr->class_index)->chp;
+// int tmpint = strlen(c->package_name);
+ if (strcmp(tmpstr, c->this_class_name)) {
+ Exp *e2 = new Exp(pcval, tmpstr, VOID, NO);
+ e1 = new Exp(pcval, BINARY, e->e->type, DOT, e2, e);
+ e->e->type = VOID;
+ } else {
+ e1 = e;
+ }
+ *stkptr++ = e1;
+ return 0;
+ } else { /* getfield */
+ if (((*(stkptr-1))->e->et == IDENT) && !strcmp((*(stkptr-1))->e->id->name,"this")) {
+ /* this.bar == bar */
+ e->minpc = min(pcval, (*(stkptr-1))->minpc);
+ *(stkptr-1) = e; return 0;
+ } else {
+ /* foo.bar */
+ *(stkptr-1) = new Exp(pcval, min(pcval, (*(stkptr-1))->minpc), BINARY,
+ e->e->type, DOT, *(stkptr-1), e);
+ e->e->type = VOID;
+ return 0;
+ }
+ }
+}
+
+int doput(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ int val = JDNEXT16S();
+ Ref *mr = (Ref*)c->cp[val]->p;
+ NameAndType *nt = (NameAndType*)c->cp[mr->name_and_type]->p;
+ char *tmpstr = c->cp[nt->name_index]->chp;
+ Exp *e = new Exp(pcval, tmpstr, sig2type(c->cp[nt->signature_index]->chp), NO);
+ if (ch == 0xB3) { /* putstatic */
+ Exp *e1;
+ tmpstr = c->cp(mr->class_index)->chp;
+ if (strcmp(tmpstr, c->this_class_name)) {
+ Exp *e2 = new Exp(pcval, tmpstr, VOID, NO);
+ e1 = new Exp(pcval, BINARY, e->e->type, DOT, e2, e);
+ e->e->type = VOID;
+ } else {
+ e1 = e;
+ }
+ Exp *e3 = *(--stkptr);
+ if ((e3->e->type == INT) && (e1->e->type == BOOLEAN)) {
+ if ((e3->e == std_exps + 2)||(e3->e == std_exps + 3))
+ e3->e += 13;
+ else
+ /* CMPEQ */;
+ }
+ *donestkptr++ = new Exp(pcval, min(pcval, e3->minpc), BINARY,
+ e1->e->type, ASSIGN, e1, e3);
+ return 0;
+ } else { /* putfield */
+ Exp *e3 = *(stkptr-2);
+ if ((e3->e->et == IDENT) && !strcmp(e3->e->id->name,"this")) {
+ /* this.bar == bar */
+ e3 = *(--stkptr);
+ if ((e3->e->type == INT) && (e->e->type == BOOLEAN)) {
+ if ((e3->e == std_exps + 2)||(e3->e == std_exps + 3))
+ e3->e += 13;
+ else
+ /* CMPEQ */;
+ }
+ stkptr--;
+ *donestkptr++ = new Exp(pcval, min(min(pcval, (*stkptr)->minpc),
+ (*stkptr)->minpc),
+ BINARY, e->e->type, ASSIGN, e, e3);
+ return 0;
+ } else {
+ /* foo.bar */
+ Exp *e1 = new Exp(pcval, min((*(stkptr-1))->minpc, pcval), BINARY,
+ e->e->type, DOT, e3, e);
+ e->e->type = VOID;
+ e3 = *(--stkptr);
+ if ((e3->e->type == INT) && (e1->e->type == BOOLEAN)) {
+ if ((e3->e == std_exps + 2)||(e3->e == std_exps + 3))
+ e3->e += 13;
+ else
+ /* CMPEQ */;
+ }
+ *donestkptr++ = new Exp(pcval, min(e3->minpc, e1->minpc), BINARY,
+ e1->e->type, ASSIGN, e1, e3);
+ return 0;
+ }
+ }
+}
diff --git a/MultiSource/Applications/hbd/db-meth.cpp b/MultiSource/Applications/hbd/db-meth.cpp
new file mode 100644
index 00000000..494d8aa4
--- /dev/null
+++ b/MultiSource/Applications/hbd/db-meth.cpp
@@ -0,0 +1,117 @@
+/* db-meth.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+int invokefunc(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ unsigned minpcval = pcval;
+ int i;
+ Type exptypes[256];
+ int val = JDNEXT16S();
+ Ref *mr = (Ref*)c->cp[val]->p;
+ NameAndType *nt = (NameAndType*)c->cp[mr->name_and_type]->p;
+ char *classname = c->cp(mr->class_index)->chp;
+ char *tmpstr = c->cp[nt->signature_index]->chp;
+ char *name = c->cp[nt->name_index]->chp;
+ Exp **el = new Exp*[strlen(tmpstr)-2];
+ Exp *e1 = new Exp(pcval, name, VOID, NO);
+ unsigned numexps = 0;
+ while (*(++tmpstr) != ')') {
+ exptypes[numexps++] = sig2type(tmpstr);
+ if (*tmpstr == '[') tmpstr++;
+ if (*tmpstr == 'L') while (*(++tmpstr) != ';') /* do nothing */;
+ }
+ Type etype = sig2type(tmpstr + 1);
+ Exp **elp = el;
+ for (i = numexps; i--;) {
+ if (((*(--stkptr))->e->type == INT) && (exptypes[i] == BOOLEAN)) {
+ if (((*stkptr)->e == std_exps + 2)||((*stkptr)->e == std_exps + 3))
+ (*stkptr)->e += 13;
+ else
+ /* CMPEQ */;
+ }
+ *elp++ = *stkptr;
+ minpcval = min(minpcval, (*stkptr)->minpc);
+ }
+ if (ch == 0xB9) { /* invokeinterface */
+ if (numexps != (unsigned)(JDNEXT8U() - 1)) {
+ fprintf(stderr,"Error in interface method invocation - nargs doesn't match.\n");
+ return 1;
+ }
+ JDNEXT8U(); /* reserved byte */
+ }
+ if (ch != 0xB8) { /* invokevirtual OR invokenonvirtual OR invokeinterface */
+ if (((*(stkptr-1))->e->et == IDENT) && !strcmp((*(stkptr-1))->e->id->name,"this")) {
+ /* this.bar(...) == bar(...) */
+ if (strcmp(classname,c->this_class_name)) { /* super.bar(...) */
+ if (!strcmp(name,"<init>")) { /* super() */
+ e1->e->id->name = "super";
+ minpcval = min(minpcval, (*(stkptr-1))->minpc);
+ Exp *e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e1, numexps, el);
+ if (etype == VOID) {
+ --stkptr; *donestkptr++ = e;
+ } else *(stkptr-1) = e;
+ return 0;
+ }
+ minpcval = min(minpcval, (*(stkptr-1))->minpc);
+ Exp *e2 = new Exp(pcval, "super", VOID, NO);
+ Exp *e3 = new Exp(pcval, minpcval, BINARY, FUNC, DOT, e2, e1);
+ Exp *e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e3, numexps, el);
+ if (etype == VOID) {
+ --stkptr; *donestkptr++ = e;
+ } else *(stkptr-1) = e;
+ return 0;
+ } else {
+ if (!strcmp(name,"<init>")) {
+ minpcval = min(minpcval, (*(stkptr-1))->minpc);
+ e1->e->id->name = "this";
+ }
+ Exp *e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e1, numexps, el);
+ if (e->e->type == VOID) {
+ --stkptr; *donestkptr++ = e;
+ } else *(stkptr-1) = e;
+ return 0;
+ }
+ } else {
+ /* foo.bar(...) */
+ Exp *e;
+ if (!strcmp(name,"<init>")) {
+ /* killexp(e1)? */
+ minpcval = min(minpcval, (*(stkptr-1))->minpc);
+ e = new Exp(pcval, minpcval, FUNCTIONCALL, OBJECT, ID, *(stkptr-1), numexps, el);
+ } else {
+ minpcval = min(minpcval, (*(stkptr-1))->minpc);
+ Exp *e3 = new Exp(pcval, minpcval, BINARY, FUNC, DOT, *(stkptr-1), e1);
+ e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e3, numexps, el);
+ }
+ if ((e->exp1->e->op != NEW) && (etype == VOID)) {
+ --stkptr; *donestkptr++ = e;
+ } else *(stkptr-1) = e;
+ return 0;
+ }
+ } else { /* invokestatic */
+ Exp *e;
+ tmpstr = c->cp(mr->class_index)->chp;
+ if (strcmp(tmpstr, c->this_class_name)) {
+ Exp *e2 = new Exp(pcval, tmpstr, VOID, NO);
+ Exp *e3 = new Exp(pcval, minpcval, BINARY, FUNC, DOT, e2, e1);
+ e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e3, numexps, el);
+ } else
+ e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e1, numexps, el);
+ if (etype == VOID)
+ *donestkptr++ = e;
+ else
+ *stkptr++ = e;
+ return 0;
+ }
+}
diff --git a/MultiSource/Applications/hbd/dc-misc.cpp b/MultiSource/Applications/hbd/dc-misc.cpp
new file mode 100644
index 00000000..d3ec176e
--- /dev/null
+++ b/MultiSource/Applications/hbd/dc-misc.cpp
@@ -0,0 +1,32 @@
+/* dc-misc.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "exp.h"
+#include "class.h"
+#include "decomp.h"
+#include "cp.h"
+
+int docheckcast(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ unsigned val = JDNEXT16U();
+ Exp *e1 = *(stkptr-1);
+ Exp *e2 = new Exp(pcval, c->cp(val)->chp, OBJECT, CP, val);
+ *(stkptr-1) = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, OBJECT, CAST, e1, e2);
+ return 0;
+}
+
+int doinstanceof(Classfile *c)
+{
+ unsigned pcval = currpc - 1;
+ unsigned val = JDNEXT16U();
+ Exp *e1 = *(stkptr-1);
+ Exp *e2 = new Exp(pcval, c->cp(val)->chp, OBJECT, CP, val);
+ *(stkptr-1) = new Exp(pcval, e1->minpc, BINARY, BOOLEAN, INSTANCEOF, e1, e2);
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/decomp.cpp b/MultiSource/Applications/hbd/decomp.cpp
new file mode 100644
index 00000000..faa4d00f
--- /dev/null
+++ b/MultiSource/Applications/hbd/decomp.cpp
@@ -0,0 +1,340 @@
+/* decomp.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "general.h"
+#include "options.h"
+#include "version.h"
+#include "cp.h"
+#include "access.h"
+#include "field.h"
+#include "exp.h"
+#include "method.h"
+#include "consts.h"
+#include "class.h"
+#include "file.h"
+#include "sig.h"
+#include "decomp.h"
+
+void printintlist(intlist *t) {
+ fprintf(stderr, "[");
+ intnode *n = t->head;
+ while (n) {
+ fprintf(stderr, "%d", n->node);
+ n = n->next;
+ if (!n)
+ break;
+ fprintf(stderr, ", ");
+ }
+ fprintf(stderr, "]\n");
+}
+
+int ch;
+unsigned char *inbuff;
+int bufflength;
+unsigned currpc;
+int lastaction;
+method_info *miptr;
+
+Exp *stack[8];
+Exp **stkptr;
+Exp *donestack[256];
+Exp **donestkptr;
+
+//Block *blocks[16];
+//int numblocks;
+//int currblock;
+
+int indentlevel;
+
+/*
+char pass1size[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 3, 2, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 1, 0, 0, 0, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+*/// 1,1,1,1,/*C*/1,1,1,1,1,/*.*/-1,-1,-1,-1,-1,-1,-1, // cmps
+// -1,-1,-1,-1,-1,-1,-1,-2,-3,-4,-5,-6,/*R*/1,1,1,1, // returns
+// 1,1/*.*/,3,3,3,3, 3, 3, 5, 3, 3, 3, 0, 3, 1, 1,
+/* 3, 0, 0, 0, 0, 3,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+int addifblock(void)
+{
+ unsigned pcval = currpc - 1;
+ Block *b = blocks[currblock++] = new Block;
+ b->tag = IF;
+ b->start_pc = pcval + 3;
+ b->end_pc = pcval + (signed)(((unsigned)JDNEXT8() << 8) + (unsigned)JDNEXT8());
+ b->else_pc = 0;
+ b->exp = 0;
+ fprintf(stderr, "if(?) goto %d else %d\n", b->end_pc, b->start_pc);
+ return 0;
+}
+
+int addgotoblock(void)
+{
+ unsigned pcval = currpc - 1;
+ Block *b = blocks[currblock++] = new Block;
+ b->tag = GOTOLABEL;
+ b->start_pc = pcval + 3;
+ b->end_pc = pcval + (signed)(((unsigned)JDNEXT8() << 8) + (unsigned)JDNEXT8());
+ b->else_pc = 0;
+ b->exp = 0;
+ fprintf(stderr, "goto %d instead of %d\n", b->end_pc, b->start_pc);
+ return 0;
+}
+
+int (*pass1actions[])(void) = {
+ 0, addifblock, addgotoblock, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+*/
+char actions[] = {
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,15, 0,
+ 0, 0,15, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
+ 0, 0, 0,18, 0, 0, 0,21, 0,13,25, 0, 0, 0, 0, 0,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6,
+
+ 6, 6, 6, 6,16, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 0,22,22,22,22, 22,12,12,12,12,12,12,23,
+ 23,23,23,23,23,23,23, 7, 0, 0,27,24,10,10,10,10,
+ 10,10, 8, 9, 8, 9,11,11, 11,11, 7, 7, 0,19,14, 7,
+ 17,26, 0, 0, 0,20/*?(multianewarray)*/,12,12, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+int (*actiontable[])(Classfile *c) = {
+ 0, pushimp, pushimm, pushconst, pushlocal, storelocal, pushbinop, pushunop,
+ doget, doput, doreturn, invokefunc, doif1, dodup, doarraylength, doarrayget,
+ iinclocal, docheckcast, doarrayput, anewarray, multianewarray, dopop, docmp, doif2,
+ doluswitch, dodup_x1, doinstanceof, dotableswitch
+};
+
+int decompileblock(Classfile *c, method_info_ptr mi) {
+ char *str;
+// int i;
+ miptr = mi;
+ cond_pcend = -1;
+ char *strptr;
+ int dodecompile = ((int)(c->options)) ^ 2;
+
+ if (mi->name == "<init>") {
+ }
+
+ strptr = new char[mi->access_flags.strlen() + 1];
+ fprintf(c->outfile, "\n %s", mi->access_flags.toString(strptr));
+ delete strptr;
+ char *tmp = mi->sig;
+ if (printsigname(c, c->outfile, tmp, mi->name, mi)) return 1;
+ for (int m = 0; m != mi->num_throws;) {
+ fprintf(c->outfile, " throws %s", c->cp(mi->throws[m++])->chp);
+ }
+ if ((mi->access_flags & (ACC_NATIVE | ACC_ABSTRACT))) dodecompile = 0;
+ if (dodecompile) {
+
+/**********************************************************************/
+/** PASS1 - input stage, analyse opcodes, create stack of statements **/
+/**********************************************************************/
+ int action = 0;
+ inbuff = mi->code;
+ bufflength = mi->code_length;
+ currpc = 0;
+ stkptr = stack;
+ donestkptr = donestack;
+
+ indentlevel = 0;
+// indents_end = indents_begin = (intlist *)0;
+
+ while (bufflength > 0) {
+ if (((int)currpc == cond_pcend)) if (finishconditional(c)) return 1;
+ ch = JDNEXT8U();
+ lastaction = action;
+ action = actions[ch];
+ if (action) {
+ if(actiontable[action](c)) return 1;
+ } else {
+ fprintf(c->outfile, "// unknown opcode 0x%02X\n", ch);
+ }
+ }
+
+ fprintf(c->outfile, " {\n");
+
+/**********************************************************************/
+/** PASS2 - lazy conditionals (&& and ||), note backward jump refs **/
+/**********************************************************************/
+ looplist *branchbacklist = new looplist();
+ Exp **p = donestack;
+ for (;p < (donestkptr-1);p++) {
+ Exp *pptr = *p, *pptr1 = *(p+1), *pptr2 = *(p+2);
+ if (pptr->e->op == GOTO)
+ goto here;
+ if (pptr->e->et == BRANCH) {
+ if (pptr1->e->et == BRANCH || pptr1->e->op == COND) {
+ unsigned minpc = min(pptr->minpc, pptr1->minpc);
+ Exp *e;
+ if (pptr->branch_pc == pptr1->branch_pc) {
+ e = new Exp(minpc, BINARY, BOOLEAN, OR_BOOL,
+ pptr->exp1, pptr1->exp1);
+ } else {
+ if (pptr->branch_pc == pptr2->minpc) {
+ e = new Exp(minpc, BINARY, BOOLEAN, AND_BOOL,
+ pptr->exp1, pptr1->exp1);
+ if (notexp(&(e->exp1))) return 1;
+ } else {
+ goto here;
+ }
+ }
+ killexp(pptr);
+ pptr1->exp1 = e;
+ pptr1->minpc = minpc;
+ *p = pptr1; *(++p) = 0;
+ pptr = pptr1; pptr1 = pptr2;
+ }
+here:
+ if (pptr->minpc >= pptr->branch_pc) {
+ branchbacklist->add(new Loop(pptr->minpc, pptr->branch_pc,
+ pptr1->minpc, pptr->exp1, LOOP_DOWHILE));
+ }
+ }
+ }
+
+/**********************************************************************/
+/** PASS3 - analyse control flow, recursively print statement stack **/
+/**********************************************************************/
+ intlist *iflist = new intlist();
+ intlist *elselist = new intlist();
+ looplist *branchbacklist2 = new looplist();
+
+ p = donestack;
+ while (p != donestkptr) {
+ Exp *pptr = *p++;
+ if (pptr) {
+ if (!branchbacklist->isempty()) {
+ Loop *l = branchbacklist->top();
+ if (l->jumpto_pc == pptr->minpc) {
+ l->type = LOOP_DOWHILE;
+ fprintf(c->outfile, " do {\n", str);
+ indentlevel++;
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ branchbacklist2->push(branchbacklist->pop());
+ }
+ }
+ if (!branchbacklist->isempty()) {
+ Loop *l = branchbacklist->top();
+ if (pptr->e->op == GOTO && pptr->branch_pc == l->jumpfrom_pc) {
+ l->type = LOOP_WHILE;
+ str = l->condition->toString(0);
+ fprintf(c->outfile, " while (%s) {\n", str);
+ delete str;
+ indentlevel++;
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ branchbacklist2->push(branchbacklist->pop());
+ continue;
+ }
+ }
+ if (!iflist->isempty() && iflist->top() == pptr->minpc) {
+ iflist->pop();
+ fprintf(c->outfile, " }\n");
+ indentlevel--;
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ }
+ if (pptr->e->op == GOTO || pptr->e->et == BRANCH) {
+ if (!branchbacklist2->isempty()) {
+ Loop *l = branchbacklist2->top();
+ if (l->jumpfrom_pc == pptr->minpc) {
+ if (l->type == LOOP_DOWHILE) {
+ if (pptr->e->op == GOTO) {
+ fprintf(c->outfile, " } while(true);\t/*%d*/\n", pptr->minpc);
+ } else {
+ char *str = l->condition->toString(0);
+ fprintf(c->outfile, " } while(%s);\t/*%d*/\n", str,
+ pptr->minpc);
+ delete str;
+ }
+ } else {
+ fprintf(c->outfile, " }\t/*%d*/\n", pptr->minpc);
+ }
+ branchbacklist2->pop();
+ indentlevel--;
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ continue;
+ }
+ if (branchbacklist2->containsPast(pptr->branch_pc)) {
+ fprintf(c->outfile, " break;\t/*%d*/\n", (*(p-1))->minpc);
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ continue;
+ }
+ }
+ if (!iflist->isempty() && iflist->top() == ((*p)?(*p)->minpc:0)) {
+ elselist->push(pptr->branch_pc);
+ iflist->pop();
+ fprintf(c->outfile, " } else {\t/*%d*/\n", (*(p-1))->minpc);
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ continue;
+ }
+ if (pptr->e->et == BRANCH && pptr->branch_pc > pptr->minpc) {
+ iflist->push(pptr->branch_pc);
+ indentlevel++;
+ }
+ } else {
+ if (pptr->e->op == RETURN && !iflist->isempty()
+ && iflist->top() == ((*p)?(*p)->minpc:0)) {
+ iflist->pop();
+ str = pptr->toString(0);
+ if (str) {
+ fprintf(c->outfile, " %s;\t/*%d*/\n", str, (*(p-1))->minpc);
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ }
+ delete str;
+ fprintf(c->outfile, " }\n");
+ indentlevel--;
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ continue;
+ } else {
+ if (!elselist->isempty() && elselist->top() == pptr->minpc) {
+ elselist->pop();
+ fprintf(c->outfile, " }\n");
+ indentlevel--;
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ }
+ }
+ }
+ str = pptr->toString(0);
+ if (str) {
+ fprintf(c->outfile, strrchr(str,'{')?" %s":" %s;", str);
+ fprintf(c->outfile, "\t/*%d*/",(*(p-1))->minpc);
+ fprintf(c->outfile, "\n");
+ for (int i=indentlevel; i--;) fprintf(c->outfile, " ");
+ }
+ delete str;
+ }
+ }
+ fprintf(c->outfile, " }");
+ } else {
+ fprintf(c->outfile, ";");
+ }
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/decomp.h b/MultiSource/Applications/hbd/decomp.h
new file mode 100644
index 00000000..aa5c01c9
--- /dev/null
+++ b/MultiSource/Applications/hbd/decomp.h
@@ -0,0 +1,85 @@
+/* decomp.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef DECOMP_H
+#define DECOMP_H
+
+#include "general.h"
+
+/* These all need to be global for various reasons */
+extern int ch;
+extern char actions[];
+extern int (*actiontable[])(Classfile *c);
+extern unsigned char *inbuff;
+extern int bufflength;
+extern unsigned currpc;
+
+/* Various macros to read the bytecodes and keep track of
+ where we are in the code */
+#define JDNEXT8S() (i8)(currpc++,bufflength--,*inbuff++)
+#define JDNEXT8U() (u8)(currpc++,bufflength--,*inbuff++)
+#define JDNEXT16S() (i16)(currpc+=2,bufflength-=2,inbuff+=2, \
+ (((u16)*(inbuff-2))<<8)+((u16)*(inbuff-1)))
+#define JDNEXT16U() (u16)(currpc+=2,bufflength-=2,inbuff+=2, \
+ (((u16)*(inbuff-2))<<8)+((u16)*(inbuff-1)))
+#define JDNEXT32S() (i32)(currpc+=4,bufflength-=4,inbuff+=4, \
+ (((u32)*(inbuff-4))<<24)+(((u32)*(inbuff-3))<<16) \
+ +(((u32)*(inbuff-2))<<8)+((u32)*(inbuff-1)))
+#define JDNEXT32U() (u32)(currpc+=4,bufflength-=4,inbuff+=4, \
+ (((u32)*(inbuff-4))<<24)+(((u32)*(inbuff-3))<<16) \
+ +(((u32)*(inbuff-2))<<8)+((u32)*(inbuff-1)))
+//#define JDLAST(num) (*(inbuff-(num)-1))
+#define JDLAST8S() (i8)(*(inbuff-1))
+#define JDLAST8U() (u8)(*(inbuff-1))
+#define JDPEEK8S() (i8)(*inbuff)
+#define JDPEEK8U() (u8)(*inbuff)
+
+/* These are all the prototypes for the actions that are used
+ by the decompiler */
+int pushimp(Classfile *c);
+int pushimm(Classfile *c);
+int pushconst(Classfile *c);
+int pushlocal(Classfile *c);
+int storelocal(Classfile *c);
+int pushbinop(Classfile *c);
+int pushunop(Classfile *c);
+int finishconditional(Classfile *c);
+int doget(Classfile *c);
+int doput(Classfile *c);
+int doreturn(Classfile *c);
+int invokefunc(Classfile *c);
+int doif1(Classfile *c);
+int dodup(Classfile *c);
+int doarraylength(Classfile *c);
+int doarrayget(Classfile *c);
+int iinclocal(Classfile *c);
+int docheckcast(Classfile *c);
+int doarrayput(Classfile *c);
+int anewarray(Classfile *c);
+int multianewarray(Classfile *c);
+int dopop(Classfile *c);
+int docmp(Classfile *c);
+int doif2(Classfile *c);
+int doluswitch(Classfile *c);
+int dodup_x1(Classfile *c);
+int doinstanceof(Classfile *c);
+int dotableswitch(Classfile *c);
+
+/* These are the globals which contain the
+ various stacks used by the decompiler. */
+extern Exp *stack[];
+extern Exp **stkptr;
+extern Exp *donestack[];
+extern Exp **donestkptr;
+extern int lastaction;
+extern int cond_pcend;
+extern Exp *cond_e1;
+extern Exp *cond_e1;
+extern Exp **cond_donestkptr;
+
+#endif
diff --git a/MultiSource/Applications/hbd/err.cpp b/MultiSource/Applications/hbd/err.cpp
new file mode 100644
index 00000000..0c920824
--- /dev/null
+++ b/MultiSource/Applications/hbd/err.cpp
@@ -0,0 +1,32 @@
+/* err.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "general.h"
+#include "options.h"
+
+char *errmsgs[] = {
+ "Unknown error.",
+ "Out of memory error.",
+ DEBUG_ON? "Usage: %s [-O] [-D] InFile.class [OutFile.java]\n"
+ :"Usage: %s [-O] InFile.class [OutFile.java]\n",
+ DEBUG_ON? "Usage: %s [-D] -Ifuncname InFile.class\n"
+ :"Usage: %s -Ifuncname InFile.class\n",
+ "Not a class.",
+ "Unsupported Class Version.",
+ "3"
+};
+void fatalerror(int msgid,...)
+{
+ va_list ap;
+ va_start(ap, msgid);
+ vfprintf(stderr, errmsgs[msgid], ap);
+ va_end(ap);
+ exit(msgid);
+}
diff --git a/MultiSource/Applications/hbd/err.h b/MultiSource/Applications/hbd/err.h
new file mode 100644
index 00000000..f86f2557
--- /dev/null
+++ b/MultiSource/Applications/hbd/err.h
@@ -0,0 +1,29 @@
+/* errhandl.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef ERRHANDL_H
+#define ERRHANDL_H
+
+/* The various errors that can occur in the programs.
+ These are passed to the fatalerror() function
+ below. */
+enum errorids {
+ UNKNOWN_ERR, OUT_OF_MEM_ERR,
+ COMMAND_LINE_ERR_HBD, COMMAND_LINE_ERR_HBT,
+ NOT_A_CLASS_ERR, BAD_VERSION_ERR, CP_ERR
+};
+
+/* This function will exit the program giving
+ an appropriate error. The msgid should be
+ from the enum above */
+void fatalerror(int msgid,...);
+
+/* Since this is commonly used, we have a macro for it */
+#define memerr() fatalerror(OUT_OF_MEM_ERR)
+
+#endif
diff --git a/MultiSource/Applications/hbd/exp.cpp b/MultiSource/Applications/hbd/exp.cpp
new file mode 100644
index 00000000..e4d88a1e
--- /dev/null
+++ b/MultiSource/Applications/hbd/exp.cpp
@@ -0,0 +1,217 @@
+/* exp.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "exp.h"
+
+Exp_ std_exps[] = {
+ Exp_(&idnull), Exp_(&idneg1), Exp_(&id0i), Exp_(&id1i), Exp_(&id2i), Exp_(&id3i),
+ Exp_(&id4i), Exp_(&id5i), Exp_(&id0L), Exp_(&id1L), Exp_(&id0f), Exp_(&id1f),
+ Exp_(&id2f), Exp_(&id0d), Exp_(&id1d), Exp_(&idfalse), Exp_(&idtrue),
+ Exp_(1, BRANCH, VOID, ID, 0), Exp_(1, TERNARY, BOOLEAN, COND, 0)
+};
+
+void killexp(Exp *e) {
+ if (!(--e->numrefs)) {
+ if (!e->e->isstd) {
+ if (e->e->et == IDENT) {
+// delete e->e->id->name;
+// delete e->e->id;
+ }
+// delete e->e;
+ }
+// delete e;
+ }
+}
+
+int notexp(Exp **e_ptr) {
+ Exp *e = *e_ptr;
+ switch (e->e->op) {
+ case NOT_BOOL:
+ *e_ptr = e->exp1;
+ killexp(e);
+ break;
+ case OR_BOOL:
+ e->e->op = AND_BOOL;
+ notexp(&(e->exp1));
+ notexp(&(e->exp2));
+ break;
+ case AND_BOOL:
+ e->e->op = OR_BOOL;
+ notexp(&(e->exp1));
+ notexp(&(e->exp2));
+ break;
+ case OR: case AND:
+ notexp(&(e->exp1));
+ notexp(&(e->exp2));
+ case EQUAL: case NOTEQUAL: case LESS: case GREATEROREQUAL:
+ case GREATER: case LESSOREQUAL:
+ *((int*)(&e->e->op)) ^= 1;
+ break;
+ default:
+ if (e->e->type != BOOLEAN) {
+ fprintf(stderr, "Can't not a non-boolean\n");
+ return 1;
+ }
+ *e_ptr = new Exp(e->pc, e->minpc, PREUNARY, BOOLEAN, NOT_BOOL, e);
+ }
+ return 0;
+}
+
+/*
+Exp::Exp(int pcval, char *idname, Type idtype) {
+ numrefs = 1;
+ minpc = pc = pcval;
+ e = new Exp_;
+ e->isstd = 0;
+ e->et = IDENT;
+ e->op = ID;
+ e->type = idtype;
+ e->id = new Id;
+ e->id->name = idname;
+}
+*/
+
+char *Exp::toString(unsigned nextpc) {
+ char *e1, *e2, *e3, *o, *o2, *s, *t1;
+ int sizestr, i;
+ switch (e->et) {
+ case IDENT:
+ s = new char[strlen(e->id->name) + 1];
+ strcpy(s, e->id->name);
+ return s;
+ case PREUNARY:
+ exp1->numrefs += numrefs-1;
+ e1 = exp1->toString(0);
+ if (e->op == CAST) {
+ if (e->type == OBJECT) {
+ exp2->numrefs += numrefs-1;
+ e2 = exp2->toString(0);
+ killexp(exp2);
+ o = new char[strlen(e2) + 3];
+ sprintf(o, "(%s)", e2);
+ delete e2;
+ } else {
+ o = new char[strlen(type2str[e->type]) + 3];
+ sprintf(o, "(%s)", type2str[e->type]);
+ }
+ } else {
+ o = strdup(op2str[e->op]);
+ }
+ s = new char[5 + strlen(o) + strlen(e1)];
+ if (op_prec[exp1->e->op] < (op_prec[e->op] + 0))
+ sprintf(s, "%s(%s)", o, e1);
+ else
+ sprintf(s, "%s%s", o, e1);
+ killexp(exp1); delete e1; delete o;
+ return s;
+ case POSTUNARY:
+ exp1->numrefs += numrefs-1;
+ e1 = exp1->toString(0); o = op2str[e->op];
+ s = new char[5 + strlen(o) + strlen(e1)];
+ sprintf(s, (op_prec[exp1->e->op] < (op_prec[e->op] + 0))?"(%s)%s":"%s%s", e1, o);
+ killexp(exp1); delete e1;
+ return s;
+ case BINARY:
+ exp1->numrefs += numrefs-1;
+ exp2->numrefs += numrefs-1;
+ e1 = exp1->toString(0); e2 = exp2->toString(0);
+ o = op2str[e->op];
+ t1 = new char[9 + strlen(o)];
+ sprintf(t1, "%s%s%s",
+ (op_prec[exp1->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s",
+ o, (op_prec[exp2->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s");
+ s = new char[strlen(t1) + strlen(e1) + strlen(e2) - 3];
+ sprintf(s, t1, e1, e2); delete t1;
+ killexp(exp1); killexp(exp2); delete e1; delete e2;
+ return s;
+ case TERNARY:
+ exp1->numrefs += numrefs-1; exp2->numrefs += numrefs-1; exp3->numrefs += numrefs-1;
+ e1 = exp1->toString(0); e2 = exp2->toString(0); e3 = exp3->toString(0);
+ o = op2str[e->op]; o2 = op2str[e->op + 1];
+ t1 = new char[19];
+ sprintf(t1, "%s%s%s%s%s",
+ (op_prec[exp1->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s",
+ o, (op_prec[exp2->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s",
+ o2, (op_prec[exp3->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s");
+ s = new char[strlen(t1) + strlen(e1) + strlen(e2) + strlen(e3) - 5];
+ sprintf(s, t1, e1, e2, e3); delete t1;
+ killexp(exp1); killexp(exp2); killexp(exp3);
+ delete e1; delete e2; delete e3;
+ return s;
+ case FUNCTIONCALL:
+ t1 = new char[256];
+ exp1->numrefs += numrefs-1;
+ e1 = exp1->toString(0); sizestr = strlen(e1) + 3;
+ sprintf(t1, "%s(", e1);
+ killexp(exp1); delete e1;
+ i = numexps;
+ if (i) {
+ while (--i) {
+ explist[i]->numrefs += numrefs-1;
+ e1 = explist[i]->toString(0); strcat(t1, e1); sizestr += strlen(e1) + 2;
+ killexp(explist[i]); delete e1; strcat(t1, ", ");
+ }
+ explist[0]->numrefs += numrefs-1;
+ e1 = explist[0]->toString(0); strcat(t1, e1); sizestr += strlen(e1);
+ killexp(explist[0]); delete e1;
+ }
+ strcat(t1,")");
+ s = new char[sizestr];
+ strcpy(s, t1);
+ delete t1;
+ return s;
+ case ARRAYACCESS:
+ exp1->numrefs += numrefs-1; exp2->numrefs += numrefs-1;
+ e1 = exp1->toString(0); e2 = exp2->toString(0);
+ s = new char[strlen(e1) + strlen(e2) + 3];
+ sprintf(s, "%s[%s]", e1, e2);
+ killexp(exp1); killexp(exp2); delete e1; delete e2;
+ return s;
+ case BRANCH:
+// if ((unsigned)e->op > minpc) {
+// {
+// intlist *i = indents_end, *j;
+// if ((!i) || (i->node >= branch_pc)) {
+// indents_end = new intlist;
+// indents_end->node = branch_pc;
+// indents_end->next = i;
+// } else {
+// while ((i->next) && (i->next->node < branch_pc)) i = i->next;
+// j = i->next; i = i->next = new intlist; i->next = j;
+// i->node = branch_pc;
+// }
+// indentlevel++;
+ notexp(&exp1);
+ exp1->numrefs += numrefs-1;
+ e1 = exp1->toString(0);
+ s = new char[strlen(e1) + 8];
+ sprintf(s, "if (%s) {", e1);
+// } else {
+// exp1->numrefs += numrefs-1;
+// e1 = exp1->toString(0);
+// s = new char[strlen(e1) + 21];
+// sprintf(s, "if (%s) goto label%d", e1, branch_pc);
+// }
+ killexp(exp1); delete e1;
+ return s;
+ case SWITCH:
+ exp1->numrefs += numrefs-1;
+ e1 = exp1->toString(0);
+ s = new char[strlen(e1) + 29];
+ sprintf(s, "switch (%s) default: label%d", e1, default_pc);
+ killexp(exp1); delete e1;
+ return s;
+ default:
+ fprintf(stderr, "Error converting expressions to strings. %d\n", e->et);
+ exit(-1);
+ return 0;
+ }
+}
diff --git a/MultiSource/Applications/hbd/exp.h b/MultiSource/Applications/hbd/exp.h
new file mode 100644
index 00000000..0802bf14
--- /dev/null
+++ b/MultiSource/Applications/hbd/exp.h
@@ -0,0 +1,333 @@
+/* exp.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef EXP_H
+#define EXP_H
+
+#include "id.h"
+#include "op.h"
+
+/* The various types of expressions */
+enum Exptype {
+ NOEXP, IDENT, PREUNARY, POSTUNARY,
+ BINARY, TERNARY, FUNCTIONCALL, ARRAYACCESS,
+ BRANCH, SWITCH
+};
+
+/*
+ This structure is a secondary structure to
+ the actual Exp struct. It is used to allow
+ us to have a set of "standard" Expressions
+ for things like an integer constant "1" which
+ is often used. This saves both time and memory.
+*/
+struct Exp_ {
+ int isstd; /* 1 if this is one of the standard Exp_'s */
+ Exptype et; /* The tpye of expression this is */
+ Type type; /* The Java type of the result of this Exp_ */
+ Op op; /* The operation performed in this Exp_ */
+ Id *id; /* A reference to an Id if this Exp_
+ is simply an identifier */
+
+ /* This constructor creates an expression for the
+ given identifier */
+ Exp_(Id *idptr) {
+ isstd = 1; et = IDENT; type = idptr->type;
+ op = ID; id = idptr;
+ }
+
+ /* These constructors will create more general Exp_'s */
+ Exp_(Exptype _et, Type _type, Op _op) {
+ isstd = 0; et = _et; type = _type; op = _op;
+ }
+ Exp_(Exptype _et, Type _type, Op _op, Id *_id) {
+ isstd = 0; et = _et; type = _type; op = _op; id = _id;
+ }
+ Exp_(int _isstd, Exptype _et, Type _type, Op _op, Id *_id) {
+ isstd = _isstd; et = _et; type = _type; op = _op; id = _id;
+ }
+};
+
+/* This is the table of commonly-used Exp_'s */
+extern Exp_ std_exps[];
+
+struct Case { long caseval; long branch_pc; };
+
+/* The main Exp struct */
+struct Exp {
+ /* The secondary Exp_ structure for this Exp */
+ Exp_ *e;
+
+ /* A reference count */
+ unsigned numrefs;
+
+ unsigned pc;
+ unsigned minpc;
+ Exp *exp1, *exp2;
+
+ union {
+ Exp *exp3;
+ unsigned default_pc;
+ };
+ union {
+ unsigned numexps;
+ unsigned branch_pc;
+ unsigned numcases;
+ };
+ union {
+ Exp **explist;
+ Case *cases;
+ };
+
+ /* Constructors for "standard" Exp_'s */
+ Exp(unsigned pcval, unsigned stdexpnum) {
+ numrefs = 1; pc = minpc = pcval; e = std_exps + stdexpnum;
+ }
+ Exp(unsigned pcval, unsigned minpcval,
+ unsigned stdexpnum, Exp *_exp1, unsigned branchpcval) {
+ numrefs = 1; pc = pcval; minpc = minpcval;
+ e = std_exps + stdexpnum;
+ exp1 = _exp1; branch_pc = branchpcval;
+ }
+
+ /* A constructor for Identifiers */
+ Exp(unsigned pcval, Exptype et, Type type, Op op, Id *id) {
+ numrefs = 1; pc = minpc = pcval;
+ e = new Exp_(et, type, op, id);
+ }
+
+ /* A fairly general constructor */
+ Exp(unsigned pcval, Exptype et,
+ Type type, Op op, Exp *_exp1 = 0, Exp *_exp2 = 0) {
+ numrefs = 1; pc = minpc = pcval;
+ e = new Exp_(et, type, op);
+ exp1 = _exp1; exp2 = _exp2;
+ }
+
+ /* A constructor for case "expressions" */
+ Exp(unsigned pcval, unsigned minpcval, Exptype et,
+ Type type, Op op, Exp *_exp1, unsigned defaultpcval,
+ unsigned _numcases, Case *_cases) {
+ numrefs = 1; pc = pcval; minpc = minpcval;
+ e = new Exp_(et, type, op);
+ exp1 = _exp1; default_pc = defaultpcval;
+ numcases = _numcases; cases = _cases;
+ }
+
+ /* A constructor for method calls */
+ Exp(unsigned pcval, unsigned minpcval, Exptype et,
+ Type type, Op op, Exp *_exp1,
+ unsigned _numexps, Exp** _explist) {
+ numrefs = 1; pc = pcval; minpc = minpcval;
+ e = new Exp_(et, type, op);
+ exp1 = _exp1; numexps = _numexps;
+ explist = _explist;
+ }
+
+ /* A constructor for conditionals */
+ Exp(unsigned pcval, Exptype et, Type type,
+ Op op, Exp *_exp1, unsigned branchpcval) {
+ numrefs = 1; pc = minpc = pcval;
+ e = new Exp_(et, type, op);
+ exp1 = _exp1; branch_pc = branchpcval;
+ }
+
+ /* Another general constructor */
+ Exp(unsigned pcval, int minpcval, Exptype et,
+ Type type, Op op, Exp *_exp1, Exp *_exp2 = 0) {
+ numrefs = 1; pc = pcval; minpc = minpcval;
+ e = new Exp_(et, type, op);
+ exp1 = _exp1; exp2 = _exp2;
+ }
+
+ /* Another constructor for identifiers */
+ Exp(unsigned pcval, char *idname,
+ Type idtype, Loc idloc, int idlocinfo = 0) {
+ Id *id = new Id; id->name = idname; id->type = idtype;
+ id->loc = idloc; id->locinfo = idlocinfo;
+ numrefs = 1; pc = minpc = pcval;
+ e = new Exp_(IDENT, idtype, ID, id);
+ }
+
+ /* Provides a string representation of this Expression */
+ char *toString(unsigned nextpc);
+};
+
+/* This enum provides an easier way to look up the table of
+ "standard" Exp_'s */
+enum stdexp_vals {
+ NULLEXP, INEG1EXP, I0EXP, I1EXP, I2EXP, I3EXP, I4EXP, I5EXP,
+ L0EXP, L1EXP, F0EXP, F1EXP, F2EXP, D0EXP, D1EXP, FALSEEXP,
+ TRUEEXP, IFEXP
+};
+
+/* This recursively deletes an expression and it's children */
+void killexp(Exp *e);
+
+/* This will negate a boolean expression. It will cause an
+ error if called on a non-boolean expression */
+int notexp(Exp **e);
+
+/* These handle the indent level during the print phase */
+
+struct intnode {
+ unsigned node;
+ intnode *next;
+
+ intnode(unsigned i) {
+ node = i;
+ next = 0;
+ }
+
+ intnode(unsigned i, intnode *n) {
+ node = i;
+ next = n;
+ }
+};
+
+struct intlist {
+ intnode *head;
+ intnode *tail;
+
+ intlist() {
+ head = 0;
+ tail = 0;
+ }
+
+ void push(unsigned i) {
+ intnode *n = new intnode(i, head);
+ head = n;
+ if (tail == 0)
+ tail = head;
+ }
+
+ void add(unsigned i) {
+ intnode *n = new intnode(i);
+ if (tail == 0) {
+ head = tail = n;
+ } else {
+ tail->next = n;
+ tail = n;
+ }
+ }
+
+ unsigned top() {
+ return head?head->node:0;
+ }
+
+ int isempty() {
+ return head==0;
+ }
+
+ unsigned pop() {
+ intnode *n = head;
+ unsigned i = n->node;
+ head = n->next;
+ delete n;
+ if (head == 0)
+ tail = 0;
+ return i;
+ }
+
+ int contains(unsigned i) {
+ intnode *n = head;
+ while (n) {
+ if (n->node == i)
+ return 1;
+ n = n->next;
+ }
+ return 0;
+ }
+};
+
+typedef enum { LOOP_WHILE, LOOP_DOWHILE, LOOP_FOR } LoopType;
+
+struct Loop {
+ unsigned jumpfrom_pc, jumpto_pc, jumppast_pc;
+ Exp *condition;
+ LoopType type;
+
+ Loop(unsigned from, unsigned to, unsigned past, Exp *cond, LoopType lt) {
+ jumpfrom_pc = from; jumpto_pc = to; jumppast_pc = past;
+ condition = cond; type = lt;
+ }
+};
+
+struct loopnode {
+ Loop *node;
+ loopnode *next;
+
+ loopnode(Loop *e) {
+ node = e;
+ next = 0;
+ }
+
+ loopnode(Loop *e, loopnode *n) {
+ node = e;
+ next = n;
+ }
+};
+
+struct looplist {
+ loopnode *head;
+ loopnode *tail;
+
+ looplist() {
+ head = 0;
+ tail = 0;
+ }
+
+ void push(Loop *e) {
+ loopnode *n = new loopnode(e, head);
+ head = n;
+ if (tail == 0)
+ tail = head;
+ }
+
+ void add(Loop *e) {
+ loopnode *n = new loopnode(e);
+ if (tail == 0) {
+ head = tail = n;
+ } else {
+ tail->next = n;
+ tail = n;
+ }
+ }
+
+ Loop *top() {
+ return head?head->node:0;
+ }
+
+ int isempty() {
+ return head==0;
+ }
+
+ Loop *pop() {
+ loopnode *n = head;
+ Loop *e = n->node;
+ head = n->next;
+ delete n;
+ if (head == 0)
+ tail = 0;
+ return e;
+ }
+
+ int containsPast(unsigned i) {
+ loopnode *n = head;
+ while (n) {
+ if (n->node->jumppast_pc == i)
+ return 1;
+ n = n->next;
+ }
+ return 0;
+ }
+};
+
+extern int indentlevel;
+
+#endif
diff --git a/MultiSource/Applications/hbd/field.h b/MultiSource/Applications/hbd/field.h
new file mode 100644
index 00000000..f9840c1b
--- /dev/null
+++ b/MultiSource/Applications/hbd/field.h
@@ -0,0 +1,34 @@
+/* field.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef FIELD_H
+#define FIELD_H
+
+#include "access.h"
+
+/* This struct contains the info for one field */
+typedef struct {
+ /* The access flags for this field */
+ AccessFlags access_flags;
+
+ /* The name of this field.
+ Resolved from the constant pool */
+ char *name;
+
+ /* The signature of this field.
+ Also, resolved from the constant pool */
+ char *sig;
+
+ /* 1 if this is a constant */
+ int isconstant;
+
+ /* If it is a constant, its index to the constant pool */
+ u16 constval_index;
+} field_info, *field_info_ptr;
+
+#endif
diff --git a/MultiSource/Applications/hbd/file.h b/MultiSource/Applications/hbd/file.h
new file mode 100644
index 00000000..fd8cf97d
--- /dev/null
+++ b/MultiSource/Applications/hbd/file.h
@@ -0,0 +1,51 @@
+/* file.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef FILE_H
+#define FILE_H
+
+/* Various macros to read and copy from the files,
+ and maintain tabs on where in the files we are at. */
+
+inline u8 get8(FILE *f, int *f_pos) {
+ *f_pos++;
+ return getc(f);
+}
+
+inline u16 get16(FILE *f, int *f_pos) {
+ u16 t1 = get8(f, f_pos); u16 t2 = get8(f, f_pos);
+ return (u16)((t1 << 8) | t2);
+}
+
+inline u32 get32(FILE *f, int *f_pos) {
+ u32 t1 = get16(f, f_pos); u32 t2 = get16(f, f_pos);
+ return (u32)((t1 << 16) | t2);
+}
+
+#define getstr(str, size, f) ((f##_pos+=size), \
+ fread(str,size,1,f))
+
+#define put8(f, v) ((f##_pos++),(putc((v), f)))
+#define put16(f, v) (put8(f, (v) >> 8), put8(f, (v)))
+#define putstr(outf, size, str) ((outf##_pos+=size), \
+ fwrite(str,size,1,outf))
+
+#define copy8(inf, outf) ((outf##_pos++),(inf##_pos++), \
+ putc(getc(inf), outf))
+#define copy16(inf, outf) (u16)( \
+ (((u16)copy8(inf,outf)) << 8) \
+ | (u16)copy8(inf,outf))
+#define copy32(inf, outf) (u32)( \
+ (((u32)copy16(inf,outf)) << 16) \
+ | (u32)copy16(inf,outf))
+#define copystr(str, size, inf, outf) ((outf##_pos+=size), \
+ (inf##_pos+=size), \
+ fread(str,size,1,inf), \
+ fwrite(str,size,1,outf))
+
+#endif
diff --git a/MultiSource/Applications/hbd/general.h b/MultiSource/Applications/hbd/general.h
new file mode 100644
index 00000000..5abb4877
--- /dev/null
+++ b/MultiSource/Applications/hbd/general.h
@@ -0,0 +1,45 @@
+/* general.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef _GENERAL_H_
+#define _GENERAL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* These allow us to set debugging mode on at
+ compile-time or make it an option at run-time. */
+//#define debug
+#define debug_optional
+
+/* The D macro */
+#if defined(debug)
+# define D(x) x
+#elif defined(debug_optional)
+extern int debugon;
+# define D(x) if(debugon){ x; } else {}
+#else
+# define D(x)
+#endif /* debug */
+
+/* The min macro */
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+/* Miscellaneous typedefs for specific-sized quantities.
+ These should be in a machine-dependant file. */
+typedef unsigned char u8;
+typedef signed char i8;
+typedef unsigned short u16;
+typedef signed short i16;
+typedef unsigned long u32;
+typedef signed long i32;
+
+typedef char *char_ptr;
+
+#endif
diff --git a/MultiSource/Applications/hbd/hbd.1 b/MultiSource/Applications/hbd/hbd.1
new file mode 100644
index 00000000..07ae0c56
--- /dev/null
+++ b/MultiSource/Applications/hbd/hbd.1
@@ -0,0 +1,83 @@
+.\" This -*- nroff -*- file has been generated from
+.\" DocBook SGML with docbook-to-man on Debian GNU/Linux.
+...\"
+...\" transcript compatibility for postscript use.
+...\"
+...\" synopsis: .P! <file.ps>
+...\"
+.de P!
+\\&.
+.fl \" force out current output buffer
+\\!%PB
+\\!/showpage{}def
+...\" the following is from Ken Flowers -- it prevents dictionary overflows
+\\!/tempdict 200 dict def tempdict begin
+.fl \" prolog
+.sy cat \\$1\" bring in postscript file
+...\" the following line matches the tempdict above
+\\!end % tempdict %
+\\!PE
+\\!.
+.sp \\$2u \" move below the image
+..
+.de pF
+.ie \\*(f1 .ds f1 \\n(.f
+.el .ie \\*(f2 .ds f2 \\n(.f
+.el .ie \\*(f3 .ds f3 \\n(.f
+.el .ie \\*(f4 .ds f4 \\n(.f
+.el .tm ? font overflow
+.ft \\$1
+..
+.de fP
+.ie !\\*(f4 \{\
+. ft \\*(f4
+. ds f4\"
+' br \}
+.el .ie !\\*(f3 \{\
+. ft \\*(f3
+. ds f3\"
+' br \}
+.el .ie !\\*(f2 \{\
+. ft \\*(f2
+. ds f2\"
+' br \}
+.el .ie !\\*(f1 \{\
+. ft \\*(f1
+. ds f1\"
+' br \}
+.el .tm ? font underflow
+..
+.ds f1\"
+.ds f2\"
+.ds f3\"
+.ds f4\"
+'\" t
+.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n
+.TH "HBD" "1"
+.SH "NAME"
+hbd \(em Decompiles Java .class files.
+.SH "SYNOPSIS"
+.PP
+\fBhbd\fP [\fB-O \fIdon't decompile\fP\fP] [\fB-D \fIdebug mode\fP\fP] [Inputfile.class]
+.SH "DESCRIPTION"
+.PP
+The HomeBrew Decompiler, \fBhbd\fP, can
+be used to decompile Java .class files.
+.PP
+The class file to be decompiled is passed on the command
+line and the resulting decompilation goes to stdout. Any
+errors can be seen on stderr.
+.SH "OPTIONS"
+.IP "\fB-D\fP " 10
+Debug mode.
+.IP "\fB-O\fP " 10
+Do not decompile.
+.SH "AUTHOR"
+.PP
+This manual page was written by Pete Ryland pdr@pdr.cx.
+Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation
+License, Version 1.1 or any later version published by the Free
+Software Foundation; with no Invariant Sections, no Front-Cover
+Texts and no Back-Cover Texts.
+...\" created by instant / docbook-to-man, Sat 15 Feb 2003, 20:06
diff --git a/MultiSource/Applications/hbd/hbd.cpp b/MultiSource/Applications/hbd/hbd.cpp
new file mode 100644
index 00000000..074cc68d
--- /dev/null
+++ b/MultiSource/Applications/hbd/hbd.cpp
@@ -0,0 +1,21 @@
+/* hbd.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <stdio.h>
+#include "class.h"
+
+int debugon = 0;
+
+int main(int argc, char **argv)
+{
+ fprintf(stderr, "HomeBrew Decompiler. Copyright (c) 1994-2003 Pete Ryland.\n");
+ Classfile c(argc, argv);
+ c.read();
+ c.print();
+ return 0;
+}
diff --git a/MultiSource/Applications/hbd/hbd.sgml b/MultiSource/Applications/hbd/hbd.sgml
new file mode 100644
index 00000000..70180b96
--- /dev/null
+++ b/MultiSource/Applications/hbd/hbd.sgml
@@ -0,0 +1,130 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+
+<!-- Process this file with docbook-to-man to generate an nroff manual
+ page: `docbook-to-man manpage.sgml > manpage.1'. You may view
+ the manual page with: `docbook-to-man manpage.sgml | nroff -man |
+ less'. A typical entry in a Makefile or Makefile.am is:
+
+manpage.1: manpage.sgml
+ docbook-to-man $< > $@
+
+
+ The docbook-to-man binary is found in the docbook-to-man package.
+ Please remember that if you create the nroff version in one of the
+ debian/rules file targets (such as build), you will need to include
+ docbook-to-man in your Build-Depends control field.
+
+ -->
+
+ <!-- Fill in your name for FIRSTNAME and SURNAME. -->
+ <!ENTITY dhfirstname "<firstname>Pete</firstname>">
+ <!ENTITY dhsurname "<surname>Ryland</surname>">
+ <!-- Please adjust the date whenever revising the manpage. -->
+ <!ENTITY dhdate "<date>February 15, 2003</date>">
+ <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+ allowed: see man(7), man(1). -->
+ <!ENTITY dhsection "<manvolnum>1</manvolnum>">
+ <!ENTITY dhemail "<email>pdr@pdr.cx</email>">
+ <!ENTITY dhusername "Pete Ryland">
+ <!ENTITY dhucpackage "<refentrytitle>HBD</refentrytitle>">
+ <!ENTITY dhpackage "hbd">
+
+ <!ENTITY debian "<productname>Debian</productname>">
+ <!ENTITY gnu "<acronym>GNU</acronym>">
+ <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+ <refentryinfo>
+ <address>
+ &dhemail;
+ </address>
+ <author>
+ &dhfirstname;
+ &dhsurname;
+ </author>
+ <copyright>
+ <year>1994-2003</year>
+ <holder>&dhusername;</holder>
+ </copyright>
+ &dhdate;
+ </refentryinfo>
+ <refmeta>
+ &dhucpackage;
+
+ &dhsection;
+ </refmeta>
+ <refnamediv>
+ <refname>&dhpackage;</refname>
+
+ <refpurpose>Decompiles Java .class files.</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&dhpackage;</command>
+ <arg><option>-O <replaceable>don't decompile</replaceable></option></arg>
+ <arg><option>-D <replaceable>debug mode</replaceable></option></arg>
+ <arg>Inputfile.class</arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>The HomeBrew Decompiler, <command>&dhpackage;</command>, can
+ be used to decompile Java .class files.</para>
+
+ <para>The class file to be decompiled is passed on the command
+ line and the resulting decompilation goes to stdout. Any
+ errors can be seen on stderr.</para>
+
+ </refsect1>
+ <refsect1>
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term><option>-D</option>
+ </term>
+ <listitem>
+ <para>Debug mode.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-O</option>
+ </term>
+ <listitem>
+ <para>Do not decompile.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>AUTHOR</title>
+
+ <para>This manual page was written by &dhusername; &dhemail;.
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the &gnu; Free Documentation
+ License, Version 1.1 or any later version published by the Free
+ Software Foundation; with no Invariant Sections, no Front-Cover
+ Texts and no Back-Cover Texts.</para>
+
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
+
+
diff --git a/MultiSource/Applications/hbd/id.cpp b/MultiSource/Applications/hbd/id.cpp
new file mode 100644
index 00000000..4420dac4
--- /dev/null
+++ b/MultiSource/Applications/hbd/id.cpp
@@ -0,0 +1,27 @@
+/* id.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include "id.h"
+
+Id idnull = {"null", OBJECT, IM, 0},
+ idneg1 = {"-1", INT, IM, 0},
+ id0i = {"0", INT, IM, 0},
+ id1i = {"1", INT, IM, 0},
+ id2i = {"2", INT, IM, 0},
+ id3i = {"3", INT, IM, 0},
+ id4i = {"4", INT, IM, 0},
+ id5i = {"5", INT, IM, 0},
+ id0L = {"0L", LONG, IM, 0},
+ id1L = {"1L", LONG, IM, 0},
+ id0f = {"0.0f", FLOAT, IM, 0},
+ id1f = {"1.0f", FLOAT, IM, 0},
+ id2f = {"2.0f", FLOAT, IM, 0},
+ id0d = {"0.0d", DOUBLE, IM, 0},
+ id1d = {"1.0d", DOUBLE, IM, 0},
+ idfalse = {"false", BOOLEAN, IM, 0},
+ idtrue = {"true", BOOLEAN, IM, 0};
diff --git a/MultiSource/Applications/hbd/id.h b/MultiSource/Applications/hbd/id.h
new file mode 100644
index 00000000..a4ba4e83
--- /dev/null
+++ b/MultiSource/Applications/hbd/id.h
@@ -0,0 +1,50 @@
+/* id.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef ID_H
+#define ID_H
+
+#include "sig.h"
+
+/* The location of an identifier */
+enum Loc {
+ NO /* Not Applicable */, IM /* Immediate */,
+ CP /* Const Pool */, LO /* Local */
+}; /* Id location */
+
+/* The Id structure, which contains information
+ about one identifier. */
+struct Id {
+ /* Its name */
+ char *name;
+
+ /* Its Java type */
+ Type type;
+
+ /* Where this ident is located */
+ Loc loc;
+
+ /* An index into the "loc" of where this ident is */
+ int locinfo;
+
+ union {
+ long linfo;
+ double dinfo;
+ long llinfo[2];
+ };
+};
+
+/* "Standard" identifiers used by the standard Exp_'s */
+extern Id idnull, idneg1,
+ id0i, id1i, id2i, id3i, id4i, id5i,
+ id0L, id1L,
+ id0f, id1f, id2f,
+ id0d, id1d,
+ idfalse, idtrue;
+
+#endif
diff --git a/MultiSource/Applications/hbd/method.h b/MultiSource/Applications/hbd/method.h
new file mode 100644
index 00000000..4329661e
--- /dev/null
+++ b/MultiSource/Applications/hbd/method.h
@@ -0,0 +1,148 @@
+/* method.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef METHOD_H
+#define METHOD_H
+
+#include "access.h"
+#include "exp.h"
+
+/* These are used by our table of blocks */
+typedef enum { TRY, IF, DOWHILE, WHILE, GOTOLABEL } Blocktype;
+
+typedef struct {
+ /* The type of block this is */
+ Blocktype tag;
+
+ /* Its starting and ending code offsets */
+ unsigned short start_pc;
+ unsigned short end_pc;
+
+ /* Other offset, depending on the block type */
+ union {
+ unsigned else_pc;
+ unsigned short handler_pc;
+ };
+
+ /* An index into the constant pool
+ of the class we're catching */
+ unsigned short catch_type;
+
+ /* The list of expressions within this block */
+ Exp *exp;
+} Block, ExceptionTableEntry;
+
+/* The line number table has these as entries.
+ They are currently parsed from the input file,
+ but not used */
+typedef struct {
+ unsigned short start_pc;
+ unsigned short line_number;
+} LineNumberTableEntry;
+
+/* This table stores the local table information.
+ This is parsed from the input file in the
+ optional LocalVariableTable attribute */
+typedef struct {
+ /* The first code offset where this var is used */
+ unsigned short start_pc;
+
+ /* The length of the scope of this local */
+ unsigned short length;
+
+ /* The constant pool index to its name */
+ unsigned short name_index;
+
+ /* The constant pool index to its type signature */
+ unsigned short signature_index;
+
+ /* Which local we are talking about */
+ unsigned short slot;
+} LocalVariableTableEntry;
+
+/* The main method structure */
+typedef struct {
+ /* The access flags for this method */
+ AccessFlags access_flags;
+
+ /* The name of the method */
+ char *name;
+
+ /* Its type signature */
+ char *sig;
+
+ /* The maximum stack size the JVM code can use */
+ unsigned char max_stack;
+
+ /* The maximium number of locals in scope at any one time */
+ unsigned char max_locals;
+
+ /* The length of the code in bytes */
+ unsigned code_length;
+
+ /* The code */
+ unsigned char *code;
+
+ /* The exception table */
+ unsigned short exception_table_length;
+ ExceptionTableEntry *exception_table;
+
+ /* The line number table */
+ unsigned short line_number_table_length;
+ LineNumberTableEntry *line_number_table;
+
+ /* The local variable table */
+ unsigned short local_variable_table_length;
+ LocalVariableTableEntry *local_variable_table;
+
+ /* A table of the names of the locals.
+ These are potentially created
+ as each local is encountered. */
+ char **local_names;
+
+ /* The type signatures of the locals.
+ These need to be guessed if there is no
+ LocalVariableTable attribute in the method. */
+ char **local_sigs;
+
+ /* The first code offset where each local is used.
+ Again, these need to be guessed if there is no
+ LocalVariableTable attribute in the method. */
+ unsigned *local_firstuses;
+
+ /* The types of the locals,
+ corresponding to the local_sigs above */
+ Type *local_types;
+
+ /* The type signature of the
+ return value of the method */
+ char *ret_sig;
+
+ /* The type of the return value
+ corresponding to the signature above */
+ Type ret_type;
+
+ /* The number of different exceptions that
+ this method is able to throw and not catch */
+ int num_throws;
+
+ /* A table of constant-pool entries to the classes
+ that this method throws */
+ int *throws;
+} method_info, *method_info_ptr;
+
+/* This global contains the method
+ we are currently working on */
+extern method_info *miptr;
+
+/* Forward declaration */
+typedef struct Classfile Classfile;
+/* Decompiles the given method's code */
+int decompileblock(Classfile *c, method_info_ptr mi);
+
+#endif
diff --git a/MultiSource/Applications/hbd/op.cpp b/MultiSource/Applications/hbd/op.cpp
new file mode 100644
index 00000000..6bb24f76
--- /dev/null
+++ b/MultiSource/Applications/hbd/op.cpp
@@ -0,0 +1,30 @@
+/* op.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+char *op2str[] = {
+ " + ", " - ", " * ", " / ", " %% ", ".", " = ", " << ",
+ " >> ", " >>> ", " & ", " | ", " ^ ", "~", "-", "(cast)",
+ "return ", "throw ", "new ", "goto ", " += ", " -= ", "++", "--",
+ " ? ", " : ", " error ", " cmp ", " == ", " != ", " < ", " >= ",
+ " > ", " <= ", "!", " && ", " || ", " instanceof ", ", ",
+ ""
+};
+int op_prec[] = {
+ 27, 27, 29, 29, 29, 39, 2, 26,
+ 26, 26, 19, 17, 18, 32, 32, 39,
+ 38, 38, 38, 38, 2, 2, 32, 32,
+ 14, 14, 39, 20, 20, 20, 22, 22,
+ 22, 22, 32, 16, 15, 32, 1,
+ 39
+};
+int op_assoc[] = {
+ 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0,
+ 0,0,1,1,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,
+ 0
+};
diff --git a/MultiSource/Applications/hbd/op.h b/MultiSource/Applications/hbd/op.h
new file mode 100644
index 00000000..78317c3e
--- /dev/null
+++ b/MultiSource/Applications/hbd/op.h
@@ -0,0 +1,36 @@
+/* op.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef _OP_H_
+#define _OP_H_
+
+/* The operations that can go in
+ the op field of the Exp struct */
+enum Op {
+ ADD, SUB, MUL, DIV,
+ MOD, DOT, ASSIGN, SHL,
+ SHR, USHR, AND, OR,
+ XOR, NOT, NEG, CAST,
+ RETURN, THROW, NEW, GOTO,
+ ADDASSIGN, SUBASSIGN, INC, DEC,
+ COND, COND_, CMP, DUMMY,
+ EQUAL, NOTEQUAL, LESS, GREATEROREQUAL,
+ GREATER, LESSOREQUAL, NOT_BOOL, AND_BOOL,
+ OR_BOOL, INSTANCEOF, COMMA, ID
+};
+
+/* The Java string representation of the operations */
+extern char *op2str[];
+
+/* The precedence of the ops */
+extern int op_prec[];
+
+/* The accociativity of the ops */
+extern int op_assoc[];
+
+#endif
diff --git a/MultiSource/Applications/hbd/options.h b/MultiSource/Applications/hbd/options.h
new file mode 100644
index 00000000..c6a2656d
--- /dev/null
+++ b/MultiSource/Applications/hbd/options.h
@@ -0,0 +1,27 @@
+/* options.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef _OPTIONS_H_
+#define _OPTIONS_H_
+
+#ifdef debug_optional
+#define DEBUG_ON 1
+#else
+#define DEBUG_ON 0
+#endif
+
+/* The command-line options */
+enum CL_Options {
+ OPT_DEBUG = DEBUG_ON,
+ OPT_DECOMPILE_OFF = 2
+};
+
+//void parse_cmdline(FILE **infile_ptr, FILE **outfile_ptr,
+// CL_Options *options, int argc, char **argv);
+
+#endif
diff --git a/MultiSource/Applications/hbd/sig.cpp b/MultiSource/Applications/hbd/sig.cpp
new file mode 100644
index 00000000..d1c69b51
--- /dev/null
+++ b/MultiSource/Applications/hbd/sig.cpp
@@ -0,0 +1,145 @@
+/* sig.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "general.h"
+#include "class.h"
+#include "method.h"
+#include "sig.h"
+#include "err.h"
+
+char *type2str[] = {
+ "void", "byte", "char", "short", "int", "long", "float", "double", "object"
+};
+
+Type sig2type(char* sig)
+{
+ switch (*sig) {
+ case SIGNATURE_BYTE: return BYTE;
+ case SIGNATURE_CHAR: return CHAR;
+ case SIGNATURE_DOUBLE: return DOUBLE;
+ case SIGNATURE_FLOAT: return FLOAT;
+ case SIGNATURE_INT: return INT;
+ case SIGNATURE_LONG: return LONG;
+ case SIGNATURE_CLASS: return OBJECT;
+ case SIGNATURE_SHORT: return SHORT;
+ case SIGNATURE_BOOLEAN: return BOOLEAN;
+ case SIGNATURE_ARRAY: return OBJECT;
+ case SIGNATURE_FUNC: return FUNC;
+ case SIGNATURE_VOID: return VOID;
+ default:
+ fprintf(stderr, "Error converting signature to a type.\n");
+ exit(1);
+ }
+ return VOID;
+}
+
+int printsigname(Classfile *c, FILE* outfile, char *&sig, char *name, void *mip)
+{
+ method_info_ptr mi = (method_info_ptr)mip;
+ int i;
+ char *t, *t2;
+ switch(*sig++) {
+ case SIGNATURE_BYTE: fprintf(outfile, "byte %s", name); return 0;
+ case SIGNATURE_CHAR: fprintf(outfile, "char %s", name); return 0;
+ case SIGNATURE_DOUBLE: fprintf(outfile, "double %s", name); return 0;
+ case SIGNATURE_FLOAT: fprintf(outfile, "float %s", name); return 0;
+ case SIGNATURE_INT: fprintf(outfile, "int %s", name); return 0;
+ case SIGNATURE_LONG: fprintf(outfile, "long %s", name); return 0;
+ case SIGNATURE_CLASS:
+ t = sig;
+ while (*sig++ != ';') ;
+ if ((t2 = new char[sig - t]) == 0) memerr();
+ strncpy(t2, t, sig - t - 1);
+ t2[sig - t - 1] = '\0';
+ t = t2;
+ if (!strncmp(t, "java/lang/", 10)) t += 10;
+ else while ((t2 = strchr(t2, '/')) != 0) *t2 = '.';
+ i = c->package_name?strlen(c->package_name):0;
+ if (c->package_name && !strncmp(t, c->package_name, i)) t += i + 1;
+ fprintf(outfile, "%s %s", t, name);
+ return 0;
+ case SIGNATURE_SHORT: fprintf(outfile, "short %s", name); return 0;
+ case SIGNATURE_BOOLEAN: fprintf(outfile, "boolean %s", name); return 0;
+ case SIGNATURE_ARRAY:
+ i = 0;
+ while ((*sig >= '0') && (*sig <= '9')) i = (i * 10) + *sig++ - '0';
+ printsigname(c, outfile, sig, name, mi);
+ if (i) fprintf(outfile, "[%d]", i); else fprintf(outfile, "[]");
+ return 0;
+ case SIGNATURE_FUNC:
+ if (!mi) {
+ fprintf(stderr, "Non-function with function sig!\n");
+ return 0;
+ }
+ t = sig;
+ while (*sig++ != SIGNATURE_ENDFUNC) /* skip for now */;
+ if (!strcmp(name, "<clinit>")) {
+// fprintf(outfile, "\b");
+ return 0;
+ }
+ if ((mi->ret_sig = new char[strlen(sig) + 1]) == 0) memerr();
+ strcpy(mi->ret_sig, sig);
+ mi->ret_type = sig2type(mi->ret_sig);
+ if (strcmp(name, "<init>"))
+ printsigname(c, outfile, sig, name, mi); /* return type and name */
+ else
+ fprintf(outfile, "%s", c->this_class_name);
+ fprintf(outfile, "(");
+ mi->max_locals++;
+ if (!mi->local_variable_table_length) {
+ if (((mi->local_names = new char_ptr[mi->max_locals]) == 0) ||
+ ((mi->local_sigs = new char_ptr[mi->max_locals]) == 0) ||
+ ((mi->local_types = new Type[mi->max_locals]) == 0) ||
+ ((mi->local_firstuses = new unsigned[mi->max_locals]) == 0)) memerr();
+ for (int it = mi->max_locals; it--; ) {
+ mi->local_firstuses[it] = 0;
+ mi->local_names[it] = mi->local_sigs[it] = 0;
+ mi->local_types[it] = VOID;
+ }
+ if ((mi->access_flags & ACC_STATIC) == 0) {
+ mi->local_names[0] = "this";
+ mi->local_sigs[0] = "L";
+ mi->local_types[0] = OBJECT;
+ mi->local_firstuses[0] = 0;
+ }
+ }
+ i = ((mi->access_flags & ACC_STATIC) == 0) ? 1 : 0;
+ while (*t != SIGNATURE_ENDFUNC) {
+ if (mi->local_variable_table_length) {
+ if (strcmp(t,mi->local_sigs[i])) {
+ fprintf(stderr, "Function Parameter type mismatch\n");
+ return 1;
+ }
+ printsigname(c, outfile, t,mi->local_names[i],mi);
+ } else {
+ if ((mi->local_names[i] = new char[6]) == 0) memerr();
+ sprintf(mi->local_names[i], "var%d", i);
+ char *t2 = t;
+ printsigname(c, outfile, t,mi->local_names[i],mi);
+ if ((mi->local_sigs[i] = new char[t - t2 + 1]) == 0) memerr();
+ strncpy(mi->local_sigs[i], t2, t-t2);
+ mi->local_sigs[i][t-t2] = '\0';
+ mi->local_types[i] = sig2type(mi->local_sigs[i]);
+ mi->local_firstuses[i] = 0;
+ }
+ if ((*(t-1) == 'D') || (*(t-1) == 'J')) i++;
+ i++;
+ if (*t != SIGNATURE_ENDFUNC) fprintf(outfile, ", ");
+ }
+ fprintf(outfile, ")");
+ return 0;
+ case SIGNATURE_VOID: fprintf(outfile, "void %s", name); return 0;
+// case 0: fprintf(outfile, "%s", name); return 0;
+ default:
+ fprintf(stderr, "Error reading type signature!\n");
+ return 1;
+ }
+}
+
diff --git a/MultiSource/Applications/hbd/sig.h b/MultiSource/Applications/hbd/sig.h
new file mode 100644
index 00000000..d479fa4d
--- /dev/null
+++ b/MultiSource/Applications/hbd/sig.h
@@ -0,0 +1,73 @@
+/* sig.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef SIG_H
+#define SIG_H
+
+#include <stdio.h>
+
+/* The Java types */
+typedef enum {
+ VOID, BYTE, CHAR, SHORT,
+ INT, LONG, FLOAT, DOUBLE,
+ OBJECT, ARRAY, BOOLEAN, FUNC,
+ CMPTYPE, /* -1, 0, or 1 */
+ UNKNOWN, UNKNOWN_1, UNKNOWN_4,
+ UNKNOWN_8
+} Type;
+
+/* This converts a signature string to a type */
+Type sig2type(char* sig);
+
+/* This contains string representations of the types */
+extern char *type2str[];
+
+/* These defines are used for converting sigs */
+#define SIGNATURE_ANY 'A'
+#define SIGNATURE_ARRAY '['
+#define SIGNATURE_BYTE 'B'
+#define SIGNATURE_CHAR 'C'
+#define SIGNATURE_CLASS 'L'
+#define SIGNATURE_ENDCLASS ';'
+#define SIGNATURE_ENUM 'E'
+#define SIGNATURE_FLOAT 'F'
+#define SIGNATURE_DOUBLE 'D'
+#define SIGNATURE_FUNC '('
+#define SIGNATURE_ENDFUNC ')'
+#define SIGNATURE_INT 'I'
+#define SIGNATURE_LONG 'J'
+#define SIGNATURE_SHORT 'S'
+#define SIGNATURE_VOID 'V'
+#define SIGNATURE_BOOLEAN 'Z'
+
+#define SIGNATURE_ANY_STRING "A"
+#define SIGNATURE_ARRAY_STRING "["
+#define SIGNATURE_BYTE_STRING "B"
+#define SIGNATURE_CHAR_STRING "C"
+#define SIGNATURE_CLASS_STRING "L"
+#define SIGNATURE_ENDCLASS_STRING ";"
+#define SIGNATURE_ENUM_STRING "E"
+#define SIGNATURE_FLOAT_STRING "F"
+#define SIGNATURE_DOUBLE_STRING "D"
+#define SIGNATURE_FUNC_STRING "("
+#define SIGNATURE_ENDFUNC_STRING ")"
+#define SIGNATURE_INT_STRING "I"
+#define SIGNATURE_LONG_STRING "J"
+#define SIGNATURE_SHORT_STRING "S"
+#define SIGNATURE_VOID_STRING "V"
+#define SIGNATURE_BOOLEAN_STRING "Z"
+
+/* Forward declaration */
+struct Classfile;
+
+/* This prints the method name with return type
+ and parameters in the format used in Java source files */
+int printsigname(Classfile *c, FILE *outfile,
+ char *&sig, char *name, void *mi);
+
+#endif
diff --git a/MultiSource/Applications/hbd/version.cpp b/MultiSource/Applications/hbd/version.cpp
new file mode 100644
index 00000000..c8e16acf
--- /dev/null
+++ b/MultiSource/Applications/hbd/version.cpp
@@ -0,0 +1,23 @@
+/* version.cpp */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#include <stdio.h>
+#include "general.h"
+#include "version.h"
+#include "file.h"
+#include "err.h"
+#include "class.h"
+
+void ClassVersion::read(Classfile *c) {
+ minor_version = get16(c->infile, &c->infile_pos);
+ if ((major_version = get16(c->infile, &c->infile_pos)) != 45)
+ fatalerror(BAD_VERSION_ERR);
+ else if (minor_version != 3) {
+ fprintf(stderr, "Warning: Class Version 45.%d. (Program designed for ver 45.3)\n", minor_version);
+ }
+}
diff --git a/MultiSource/Applications/hbd/version.h b/MultiSource/Applications/hbd/version.h
new file mode 100644
index 00000000..63db3200
--- /dev/null
+++ b/MultiSource/Applications/hbd/version.h
@@ -0,0 +1,28 @@
+/* version.h */
+/*
+ Java Decompiler
+ Copyright (c) 1994-2003, Pete Ryland.
+ Distributed under the GNU GPL Version 2.
+ This package is available from http://pdr.cx/hbd/
+*/
+
+#ifndef VERSION_H
+#define VERSION_H
+
+#include "general.h"
+
+/* Forward declaration */
+struct Classfile;
+
+/* This struct is for the class file version */
+struct ClassVersion {
+ u16 minor_version;
+ u16 major_version;
+
+ /* read() is used by the decompiler to read
+ the version of the input class file and
+ make sure it is a version that we support */
+ void read(Classfile *c);
+};
+
+#endif