You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/10/05 04:20:10 UTC

svn commit: r294974 [25/25] - in /incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm: ./ jchevm/ jchevm/doc/ jchevm/etc/ jchevm/include/ jchevm/java/ jchevm/java/org/ jchevm/java/org/dellroad/ jchevm/java/org/dellroad/jc/ jchevm/java/org/dellroad...

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/gen.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/gen.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/gen.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/gen.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,474 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: gen.c,v 1.3 2005/05/08 21:12:07 archiecobbs Exp $
+ */
+
+#include "javah.h"
+
+struct flag_name {
+	uint16_t	flag;
+	const char	*name;
+};
+
+struct jni_name {
+	const char	*name;
+	const char	*ctype;
+};
+
+static const struct flag_name flag_names[] = {
+	{ _JC_ACC_PUBLIC,	"public" },
+	{ _JC_ACC_PROTECTED,	"protected" },
+	{ _JC_ACC_PRIVATE,	"private" },
+	{ _JC_ACC_ABSTRACT,	"abstract" },
+	{ _JC_ACC_STATIC,	"static" },
+	{ _JC_ACC_FINAL,	"final" },
+	{ _JC_ACC_TRANSIENT,	"transient" },
+	{ _JC_ACC_VOLATILE,	"volatile" },
+	{ _JC_ACC_SYNCHRONIZED,	"synchronized" },
+	{ _JC_ACC_NATIVE,	"native" },
+	{ _JC_ACC_STRICT,	"strictfp" },
+	{ 0, NULL }
+};
+
+static const struct jni_name jni_names[] = {
+	{ "Ljava/lang/Class;",			"jclass" },
+	{ "Ljava/lang/String;",			"jstring" },
+	{ "Ljava/lang/Throwable;",		"jthrowable" },
+	{ "Ljava/lang/ref/WeakReference;",	"jweak" },
+	{ NULL, NULL }
+};
+
+static const char hexdig[] = "0123456789abcdef";
+
+static const	char *flagstr(int flags, jboolean with_class);
+static const	char *jtypestr(const char **sp);
+static const	char *ctypestr(const char **sp, jboolean jni, int pnum);
+static void	print_comment(FILE *fp, _jc_cf_method *method);
+static void	print_export(FILE *fp, _jc_cf_method *method,
+			jboolean jni, jboolean hdr);
+static void	print_name(FILE *fp, _jc_classfile *cfile,
+			_jc_cf_method *method, jboolean jni);
+static void	print_decl(FILE *fp, _jc_cf_method *method,
+			jboolean jni, jboolean with_names);
+static void	encode(const char *s, char *buf, size_t bmax);
+
+void
+javah_header(_jc_classfile *cfile, const char *dir, jboolean jni)
+{
+	char pathname[MAXPATHLEN];
+	char namebuf[MAXPATHLEN];
+	char *filename;
+	int ivs = 0;
+	FILE *fp;
+	int i;
+
+	/* Open file */
+	encode(cfile->name, namebuf, sizeof(namebuf));
+	snprintf(pathname, sizeof(pathname), "%s/%s.h", dir, namebuf);
+	filename = pathname + strlen(dir) + 1;
+	if ((fp = fopen(pathname, "w")) == NULL)
+		err(1, "%s", pathname);
+
+	/* Do header */
+	fprintf(fp, "// generated file -- do not edit\n");
+	fprintf(fp, "// %s %s\n",
+	    flagstr(cfile->access_flags, JNI_TRUE), cfile->name);
+	fprintf(fp, "\n");
+	filename[strlen(filename) - 2] = '_';
+	fprintf(fp, "#ifndef _Included_%s\n", filename);
+	fprintf(fp, "#define _Included_%s\n", filename);
+	fprintf(fp, "\n");
+	fprintf(fp, "#include <%s.h>\n", jni ? "jni" : "jc_defs");
+	fprintf(fp, "\n");
+	fprintf(fp, "#ifdef __cplusplus\n");
+	fprintf(fp, "extern \"C\" {\n");
+	fprintf(fp, "#endif\n");
+	fprintf(fp, "\n");
+
+	/* Spit out static final fields */
+	for (i = 0; i < cfile->num_fields; i++) {
+		_jc_cf_field *const field = &cfile->fields[i];
+		const u_char ptype = _jc_sig_types[(u_char)*field->descriptor];
+		_jc_cf_constant *value = field->initial_value;
+		char buf[256];
+
+		if (!_JC_ACC_TEST(field, STATIC)
+		    || ptype == _JC_TYPE_REFERENCE
+		    || value == NULL)
+			continue;
+		encode(field->name, buf, sizeof(buf));
+		fprintf(fp, "#define %s_%s ", namebuf, buf);
+		switch (ptype) {
+		case _JC_TYPE_BOOLEAN:
+		case _JC_TYPE_BYTE:
+		case _JC_TYPE_CHAR:
+		case _JC_TYPE_SHORT:
+		case _JC_TYPE_INT:
+			fprintf(fp, "%d", value->u.Integer);
+			break;
+		case _JC_TYPE_LONG:
+			fprintf(fp, "%ld", (long)value->u.Long);
+			break;
+		case _JC_TYPE_FLOAT:
+			fprintf(fp, "%g", (double)value->u.Float);
+			break;
+		case _JC_TYPE_DOUBLE:
+			fprintf(fp, "%g", (double)value->u.Double);
+			break;
+		default:
+			assert(0);
+		}
+		fprintf(fp, "\n");
+		ivs = 1;
+	}
+	if (ivs)
+		printf("\n");
+
+	/* Spit out native method declarations */
+	for (i = 0; i < cfile->num_methods; i++) {
+		_jc_cf_method *const method = &cfile->methods[i];
+
+		if ((method->access_flags & _JC_ACC_NATIVE) == 0)
+			continue;
+		print_comment(fp, method);
+		print_export(fp, method, jni, JNI_TRUE);
+		fprintf(fp, " ");
+		print_name(fp, cfile, method, jni);
+		fprintf(fp, "\n  ");
+		print_decl(fp, method, jni, JNI_FALSE);
+		if (!jni)
+			fprintf(fp, " _JC_JCNI_ATTR");
+		fprintf(fp, ";\n\n");
+	}
+	fprintf(fp, "#ifdef __cplusplus\n");
+	fprintf(fp, "}\n");
+	fprintf(fp, "#endif\n");
+	fprintf(fp, "\n");
+	fprintf(fp, "#endif\t/* _Included_%s */\n", filename);
+	fprintf(fp, "\n");
+}
+
+void
+javah_source(_jc_classfile *cfile, const char *dir, jboolean jni)
+{
+	char pathname[MAXPATHLEN];
+	char *filename;
+	char *s;
+	FILE *fp;
+	int i;
+
+	/* Open file */
+	snprintf(pathname, sizeof(pathname), "%s/%s.c", dir, cfile->name);
+	filename = pathname + strlen(dir) + 1;
+	for (s = filename; *s != '\0'; s++) {
+		if (*s == '/')
+			*s = '_';
+	}
+	if ((fp = fopen(pathname, "w")) == NULL)
+		err(1, "%s", pathname);
+
+	/* Do header */
+	fprintf(fp, "// generated file -- please edit\n");
+	fprintf(fp, "// %s %s\n",
+	    flagstr(cfile->access_flags, JNI_TRUE), cfile->name);
+	fprintf(fp, "\n");
+	filename[strlen(filename) - 1] = 'h';
+	fprintf(fp, "#include %s\n", jni ? "<jni.h>" : "\"libjc.h\"");
+	fprintf(fp, "#include \"%s\"\n", filename);
+	fprintf(fp, "\n");
+
+	/* Spit out native method declarations */
+	for (i = 0; i < cfile->num_methods; i++) {
+		_jc_cf_method *const method = &cfile->methods[i];
+
+		if ((method->access_flags & _JC_ACC_NATIVE) == 0)
+			continue;
+		print_comment(fp, method);
+		print_export(fp, method, jni, JNI_FALSE);
+		fprintf(fp, "\n");
+		print_name(fp, cfile, method, jni);
+		print_decl(fp, method, jni, JNI_TRUE);
+		fprintf(fp, "\n{\n}\n\n");
+	}
+}
+
+static void
+print_decl(FILE *fp, _jc_cf_method *method, jboolean jni, jboolean with_names)
+{
+	const char *parm = strchr(method->descriptor, '(') + 1;
+	const char *s;
+	int i;
+
+	if (jni)
+		fprintf(fp, "(JNIEnv *%s", with_names ? "jenv" : "");	/*)*/
+	else
+		fprintf(fp, "(_jc_env *%s", with_names ? "env" : "");	/*)*/
+	if ((method->access_flags & _JC_ACC_STATIC) != 0) {
+		if (jni) {
+			fprintf(fp, ", jclass");
+			if (with_names)
+				fprintf(fp, " clazz");
+		}
+	} else {
+		fprintf(fp, ", %s", jni ? "jobject" : "_jc_object *");
+		if (with_names)
+			fprintf(fp, " this");
+	}
+	for (i = 0, s = parm; *s != /*(*/ ')'; i++)
+		fprintf(fp, ", %s", ctypestr(&s, jni, with_names ? i + 1 : -1));
+	fprintf(fp, /*(*/ ")");
+}
+
+static void
+print_name(FILE *fp, _jc_classfile *cfile, _jc_cf_method *method, jboolean jni)
+{
+	char *buf;
+	char *s;
+
+	fprintf(fp, "%s_", jni ? "Java" : "JCNI");
+	if ((buf = alloca(_jc_jni_encode_length(cfile->name) + 1
+	    + _jc_jni_encode_length(method->name) + 1)) == NULL)
+		err(1, "alloca");
+	s = buf;
+	_jc_jni_encode(&s, cfile->name);
+	_jc_jni_encode(&s, "/");
+	_jc_jni_encode(&s, method->name);
+	*s = '\0';
+	fprintf(fp, "%s", buf);
+}
+
+static void
+print_export(FILE *fp, _jc_cf_method *method, jboolean jni, jboolean hdr)
+{
+	const char *ret = strchr(method->descriptor, /*(*/ ')') + 1;
+
+	if (jni)
+		fprintf(fp, "JNIEXPORT ");
+	else if (hdr)
+		fprintf(fp, "extern ");
+	fprintf(fp, "%s", ctypestr(&ret, jni, -1));
+	if (jni)
+		fprintf(fp, " JNICALL");
+}
+
+static void
+print_comment(FILE *fp, _jc_cf_method *method)
+{
+	const char *parm = strchr(method->descriptor, '(') + 1;
+	const char *ret = strchr(method->descriptor, ')') + 1;
+	_jc_cf_attr *eattr = NULL;
+	const char *s;
+	int i;
+
+	fprintf(fp, "/*\n");
+	fprintf(fp, " * %s %s %s(", /*)*/
+	    flagstr(method->access_flags, JNI_FALSE),
+	    jtypestr(&ret), method->name);
+	for (s = parm; *s != ')'; ) {
+		fprintf(fp, "%s", jtypestr(&s));
+		if (*s != /*(*/ ')')
+			fprintf(fp, ", ");
+	}
+	fprintf(fp, ")\n");
+	for (i = 0; i < method->num_attributes; i++) {
+		_jc_cf_attr *const attr = &method->attributes[i];
+
+		if (strcmp(attr->name, "Exceptions") == 0) {
+			eattr = attr;
+			break;
+		}
+	}
+	if (eattr != NULL) {
+		const int num = eattr->u.Exceptions.num_exceptions;
+		int j;
+
+		fprintf(fp, " *\tthrows ");
+		for (j = 0; j < num; j++) {
+			fprintf(fp, "%s%s", eattr->u.Exceptions.exceptions[j],
+			    j == num - 1 ? "\n" : ", ");
+		}
+	}
+	fprintf(fp, " */\n");
+}
+
+static const char *
+ctypestr(const char **sp, jboolean jni, int pnum)
+{
+	static char buf[1024];
+	const char *s = *sp;
+	jboolean star = JNI_FALSE;
+	int dims = 0;
+	u_char type;
+
+	if ((type = _jc_sig_types[(u_char)*s]) != _JC_TYPE_REFERENCE) {
+		snprintf(buf, sizeof(buf), "%s%s",
+		    (type == _JC_TYPE_VOID) ? "" : "j", _jc_prim_names[type]);
+		s++;
+		goto done;
+	}
+	while (s[dims] == '[')
+		dims++;
+	s += dims;
+	if ((type = _jc_sig_types[(u_char)*s]) == _JC_TYPE_INVALID)
+		errx(1, "bogus type \"%s\"", *sp);
+	if (type != _JC_TYPE_REFERENCE && dims == 1) {
+		if (jni) {
+			snprintf(buf, sizeof(buf),
+			    "j%sArray", _jc_prim_names[type]);
+		} else {
+			snprintf(buf, sizeof(buf),
+			    "_jc_%s_array *", _jc_prim_names[type]);
+			star = JNI_TRUE;
+		}
+		s++;
+	} else if (dims > 0) {
+		if (jni)
+			snprintf(buf, sizeof(buf), "jobjectArray");
+		else {
+			snprintf(buf, sizeof(buf), "_jc_object_array *");
+			star = JNI_TRUE;
+		}
+		while (*s != ';')
+			s++;
+		s++;
+	} else {
+		const char *semi = strchr(s, ';');
+		size_t len;
+
+		if (semi == NULL)
+			errx(1, "bogus type \"%s\"", *sp);
+		len = (semi + 1) - s;
+		if (jni) {
+			int j;
+
+			/* Check for specially named classes */
+			for (j = 0; jni_names[j].name != NULL; j++) {
+				if (strncmp(s, jni_names[j].name, len) == 0) {
+					snprintf(buf, sizeof(buf),
+					    "%s", jni_names[j].ctype);
+					goto objdone;
+				}
+			}
+		}
+		snprintf(buf, sizeof(buf), jni ? "jobject" : "_jc_object *");
+		star = !jni;
+	objdone:
+		s += len;
+	}
+done:
+	if (pnum != -1) {
+		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+		    "%sparam%d", star ? "" : " ", pnum);
+	}
+	*sp = s;
+	return buf;
+}
+
+static const char *
+jtypestr(const char **sp)
+{
+	static char buf[1024];
+	const char *s = *sp;
+	int dims = 0;
+	u_char type;
+
+again:
+	type = _jc_sig_types[(u_char)*s];
+	if (type == _JC_TYPE_INVALID)
+		goto bogus;
+	if (type != _JC_TYPE_REFERENCE) {
+		snprintf(buf, sizeof(buf), "%s", _jc_prim_names[type]);
+		s++;
+	} else if (*s == 'L') {
+		const char *t = strchr(s, ';');
+		size_t len;
+
+		if (t == NULL)
+			goto bogus;
+		for (len = 0; t > s && t[-1] != '/'; t--, len++);
+		if (len == 0)
+			goto bogus;
+		memcpy(buf, t, len);
+		buf[len] = '\0';
+		s = t + len + 1;
+	} else if (*s == '[') {
+		while (s[dims] == '[')
+			dims++;
+		s += dims;
+		goto again;
+	} else
+bogus:		errx(1, "invalid type \"%s\"", *sp);
+	while (dims-- > 0)
+		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "[]");
+	*sp = s;
+	return buf;
+}
+
+static const char *
+flagstr(int flags, jboolean with_class)
+{
+	static char buf[128];
+	int i;
+
+	*buf = '\0';
+	for (i = 0; flag_names[i].flag != 0; i++) {
+		if ((flags & flag_names[i].flag) != 0) {
+			if (with_class && flag_names[i].flag == _JC_ACC_SUPER)
+				continue;
+			if (*buf != '\0') {
+				snprintf(buf + strlen(buf),
+				    sizeof(buf) - strlen(buf), " ");
+			}
+			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+			    "%s", flag_names[i].name);
+		}
+	}
+	if (with_class) {
+		if (*buf != '\0') {
+			snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+			    " ");
+		}
+		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+		    (flags & _JC_ACC_INTERFACE) != 0 ? "interface" : "class");
+	}
+	return buf;
+}
+
+static void
+encode(const char *s, char *buf, size_t bmax)
+{
+	char ch;
+	int i;
+
+	for (i = 0; i < bmax - 3 && (ch = s[i]) != '\0'; i++) {
+		if (ch == '/' || ch == '_') {
+			*buf++ = '_';
+			continue;
+		}
+		if (isalnum(ch)) {
+			*buf++ = ch;
+			continue;
+		}
+		*buf++ = '_';
+		*buf++ = '_';
+		*buf++ = hexdig[(ch >> 4) & 0x0f];
+		*buf++ = hexdig[ch & 0x0f];
+	}
+	*buf++ = '\0';
+}
+

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/javah.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/javah.h?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/javah.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/javah.h Tue Oct  4 19:19:16 2005
@@ -0,0 +1,43 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: javah.h,v 1.1 2005/01/08 23:25:06 archiecobbs Exp $
+ */
+
+#ifndef _JAVAH_H_
+#define _JAVAH_H_
+
+#include "libjc.h"
+#include <sys/param.h>
+#include <err.h>
+#include <assert.h>
+
+#define EXCEPTION_MSG_MAX	128
+
+extern int	exception;
+extern char	exception_msg[EXCEPTION_MSG_MAX];
+
+extern _jc_env		*_jc_support_init(void);
+
+extern void		javah_header(_jc_classfile *cfile,
+				const char *dir, jboolean jni);
+extern void		javah_source(_jc_classfile *cfile,
+				const char *dir, jboolean jni);
+extern _jc_classbytes	*read_classbytes(_jc_env *env,
+				const char *dir, const char *name);
+
+#endif	/* _JAVAH_H_ */

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/main.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/main.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/main.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/tools/jcjavah/main.c Tue Oct  4 19:19:16 2005
@@ -0,0 +1,111 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ * 
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ * $Id: main.c,v 1.3 2005/03/28 15:13:09 archiecobbs Exp $
+ */
+
+#include "javah.h"
+
+int
+main(int ac, char **av)
+{
+	jboolean jni = JNI_FALSE;
+	jboolean c_files = JNI_FALSE;
+	const char *output_dir = ".";
+	const char *classpath = ".";
+	_jc_classbytes *cb;
+	_jc_classfile *cf;
+	_jc_env *env;
+	_jc_jvm *vm;
+
+	/* Initialize */
+	env = _jc_support_init();
+	vm = env->vm;
+
+	/* Parse command line */
+	for (av++, ac--; ac > 0 && **av == '-'; av++, ac--) {
+		if (strcmp(av[0], "-jni") == 0)
+			jni = JNI_TRUE;
+		else if (strcmp(*av, "-c") == 0)
+			c_files = JNI_TRUE;
+		else if (strcmp(*av, "-classpath") == 0
+		    || strcmp(*av, "-cp") == 0) {
+			av++, ac--;
+			if (ac == 0)
+				goto usage;
+			classpath = *av;
+		} else if (strcmp(*av, "-d") == 0) {
+			av++, ac--;
+			if (ac == 0)
+				goto usage;
+			output_dir = *av;
+		} else
+			goto usage;
+	}
+	if (ac == 0) {
+usage:		fprintf(stderr, "Usage: jcjavah [-classpath path]"
+		    " [-d output-dir] [-c] [-jni] class ...\n");
+		fprintf(stderr, "Options:\n"
+		    "    -classpath\tSpecify search path for class files\n"
+		    "    -cp\t\tAlias for -classpath\n"
+		    "    -d dir\tOutput directory for generated files\n"
+		    "    -c\t\tAlso generate C source file stubs\n"
+		    "    -jni\tGenerate JNI sources instead of JCNI\n");
+		exit(1);
+	}
+
+	/* Parse classpath */
+	if (_jc_parse_classpath(env, classpath,
+	    &vm->boot.class_path, &vm->boot.class_path_len) != JNI_OK)
+		errx(1, "%s: %s", _jc_vmex_names[env->ex.num], env->ex.msg);
+
+	/* Process files */
+	while (ac-- > 0) {
+		char *const classname = *av++;
+		int i;
+
+		/* Get class name */
+		for (i = 0; classname[i] != '\0'; i++) {
+			if (classname[i] == '.')
+				classname[i] = '/';
+		}
+
+		/* Read in classfile */
+		if ((cb = _jc_bootcl_find_classbytes(env,
+		   classname, NULL)) == NULL) {
+			errx(1, "can't load class `%s': %s: %s", classname,
+			    _jc_vmex_names[env->ex.num], env->ex.msg);
+		}
+
+		/* Parse classfile */
+		if ((cf = _jc_parse_classfile(env, cb, 2)) == NULL) {
+			errx(1, "can't parse class `%s': %s: %s", classname,
+			    _jc_vmex_names[env->ex.num], env->ex.msg);
+		}
+		_jc_free_classbytes(&cb);
+
+		/* Output files */
+		javah_header(cf, output_dir, jni);
+		if (c_files)
+			javah_source(cf, output_dir, jni);
+		_jc_destroy_classfile(&cf);
+	}
+
+	/* Done */
+	return 0;
+}
+