public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: cagney@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Add jnixx, a jni/c++ stub generator; use in lib.stdcpp.Demangler.
Date: Wed, 30 Apr 2008 14:29:00 -0000	[thread overview]
Message-ID: <20080430142903.28106.qmail@sourceware.org> (raw)

The branch, master has been updated
       via  3bb4b28cd96c352cb0a082348952649e00a94c01 (commit)
      from  4fc6b25036e2e78c8e0cc84c85e8f8ffcab89e12 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 3bb4b28cd96c352cb0a082348952649e00a94c01
Author: Andrew Cagney <cagney@redhat.com>
Date:   Wed Apr 30 10:27:02 2008 -0400

    Add jnixx, a jni/c++ stub generator; use in lib.stdcpp.Demangler.
    
    frysk-common/ChangeLog
    2008-04-30  Andrew Cagney  <cagney@redhat.com>
    
    	* Makefile.gen.sh (generate_jnixx_sources): New.
    	* Makefile.rules (JNIXX): New.
    	(%-jni.hxx: %.java): New.
    	(%-jni.cxx: %.java): New.
    
    frysk-sys/frysk/ChangeLog
    2008-04-30  Andrew Cagney  <cagney@redhat.com>
    
    	* jni/jnixx.java: New.
    
    frysk-sys/lib/stdcpp/ChangeLog
    2008-04-30  Andrew Cagney  <cagney@redhat.com>
    
    	* jni/Demangler.cxx (lib::stdcpp::Demangler::demangle): Replace ...
    	(Java_lib_stdcpp_Demangler_demangle): ... this.

-----------------------------------------------------------------------

Summary of changes:
 frysk-common/ChangeLog                 |    7 +
 frysk-common/Makefile.gen.sh           |   58 +++++-
 frysk-common/Makefile.rules            |   21 ++
 frysk-sys/frysk/ChangeLog              |    4 +
 frysk-sys/frysk/jni/jnixx.java         |  417 ++++++++++++++++++++++++++++++++
 frysk-sys/lib/stdcpp/ChangeLog         |    5 +
 frysk-sys/lib/stdcpp/jni/Demangler.cxx |   14 +-
 7 files changed, 520 insertions(+), 6 deletions(-)
 create mode 100644 frysk-sys/frysk/jni/jnixx.java

First 500 lines of diff:
diff --git a/frysk-common/ChangeLog b/frysk-common/ChangeLog
index af6828a..e4d9368 100644
--- a/frysk-common/ChangeLog
+++ b/frysk-common/ChangeLog
@@ -1,3 +1,10 @@
+2008-04-30  Andrew Cagney  <cagney@redhat.com>
+
+	* Makefile.gen.sh (generate_jnixx_sources): New.
+	* Makefile.rules (JNIXX): New.
+	(%-jni.hxx: %.java): New.
+	(%-jni.cxx: %.java): New.
+
 2008-04-18  Mark Wielaard  <mwielaard@redhat.com>
 
 	* Makefile.rules ($(GEN_SOURCENAME)/JUnitTests.java):
diff --git a/frysk-common/Makefile.gen.sh b/frysk-common/Makefile.gen.sh
index fbfff9e..177683c 100755
--- a/frysk-common/Makefile.gen.sh
+++ b/frysk-common/Makefile.gen.sh
@@ -653,6 +653,56 @@ generate_cni_header () {
     rm -f $$.tmp
 }
 
+# Grep the *.cxx and *.hxx files forming a list of included files.
+# Assume these are all generated from .class files found in the master
+# .jar.
+
+echo "JNIXX_BUILT ="
+echo "CLEANFILES += \$(JNIXXX_BUILT)"
+generate_jnixx_sources () {
+    local file=$1
+    local d=$2
+    local b=$3
+    local suffix=$4
+    local sources=$5
+    local _file=`echo $file | tr '[/.]' '[__]'`
+    sed -n \
+	-e 's,#include "\(.*\)-jni\.hxx".*,include - \1,p' \
+	-e 's,#include \([A-Z][A-Z0-9_]*\).*,minclude \1 -,p' \
+	-e 's,#define \([A-Z0-9_]*\) "\(.*\)-jni\.hxx".*,define \1 \2,p' \
+	< $file > $$.tmp
+    while read action m h j; do
+	echo "# file=$file action=$action m=$m h=$h"
+	if test "$action" = "minclude" ; then
+            # Assume file defining macro depends on this file
+	    automake_variable $m = \$\($_file\)
+	elif has_java_source ${h} ; then
+	    echo "JNIXX_BUILT += ${h}-jni.hxx"
+	    echo "JNIXX_BUILT += ${h}-jni.cxx"
+	    echo "${sources} += ${h}-jni.cxx"
+	    echo "${h}-jni.o: ${h}-jni.hxx"
+	    j=`echo ${h} | tr '[_]' '[/]'`
+	    echo "${h}-jni.hxx: $j.java frysk/jni/jnixx.java | ${GEN_DIRNAME}.jar"
+	    echo "${h}-jni.cxx: $j.java frysk/jni/jnixx.java | ${GEN_DIRNAME}.jar"
+	    case $action in
+		include)
+		    case "$suffix" in
+			cxx) echo "$d/$b.o: ${h}-jni.hxx" ;;
+			hxx) # remember what this file includes
+			    automake_variable $_file += ${h}-jni.hxx ;;
+		    esac
+		    ;;
+		define)
+		    echo "$d/$b.o: ${h}-jni.hxx"
+		    # Assume file using this macro is a dependency.
+		    echo "$d/$b.o: \$($m)"
+		    ;;
+	    esac
+	fi
+    done < $$.tmp
+    rm -f $$.tmp
+}
+
 # For any java file that contains "native" declarations, generate a
 # jni header.
 
@@ -891,6 +941,8 @@ print_header "bulk processing"
 
 while read file dir base suffix ; do
 
+    echo -n "." 1>&2
+
     echo ""
     echo "# file=$file"
     echo "# dir=$dir"
@@ -905,6 +957,8 @@ while read file dir base suffix ; do
 	    ;;
 	*/jni/*.cxx | */jni/*.cxx-in | */jni/*.cxx-sh)
 	    generate_jni_dependency $file $dir $base $suffix
+	    generate_jnixx_sources $file $dir $base $suffix \
+		lib${GEN_MAKENAME}_jni_a_SOURCES
 	    generate_compile $file $dir $base $suffix \
 		lib${GEN_MAKENAME}_jni_a_SOURCES
 	    ;;
@@ -919,7 +973,7 @@ while read file dir base suffix ; do
     esac
 
 done < files.base
-
+echo "" 1>&2
 
 if automake_variable_defined lib${GEN_MAKENAME}_jni_a_SOURCES ; then
     cat <<EOF
@@ -927,5 +981,7 @@ noinst_LIBRARIES += lib${GEN_DIRNAME}-jni.a
 lib${GEN_MAKENAME}_jni_so_SOURCES =
 solib_PROGRAMS += lib${GEN_DIRNAME}-jni.so
 lib${GEN_DIRNAME}-jni.so: lib${GEN_DIRNAME}-jni.a
+.PHONY: jni
+jni: lib${GEN_DIRNAME}-jni.so
 EOF
 fi
diff --git a/frysk-common/Makefile.rules b/frysk-common/Makefile.rules
index d3ebe1f..4f4aad1 100644
--- a/frysk-common/Makefile.rules
+++ b/frysk-common/Makefile.rules
@@ -390,6 +390,27 @@ $(GEN_SOURCENAME)/JUnitTests.java: files-java.list
 			$(GCJHFLAGS) $$class ; \
 	done
 \f
+# Generate one or more .hxx files, one per named class, and using
+# JNIXX, from the corresponding .java file.
+
+# This assumes that the directory's .jar file has already been built.
+
+JNIXX = \
+	set -e ; \
+	class=`echo $@ | sed -e 's/\.[ch]xx$$//' -e 's/-jni//' -e 's,/,.,g'` ; \
+	suffix=`echo $@ | sed -e 's/^.*\.\([ch]xx\)$$/\1/'` ; \
+	echo "$$class $$suffix => $@" ; \
+	rm -f $@.tmp ; \
+	CLASSPATH=$(GEN_DIRNAME).jar:$(CLASSPATH) \
+	    $(JAVA) frysk.jni.jnixx $$class $$suffix \
+		> $@.tmp ; \
+	mv $@.tmp $@
+%-jni.hxx: %.java
+	$(JNIXX)
+%-jni.cxx: %.java
+	$(JNIXX)
+
+\f
 # Shared library rule (for moment assume that .a contains PIC code).
 SUFFIXES += .so
 .a.so:
diff --git a/frysk-sys/frysk/ChangeLog b/frysk-sys/frysk/ChangeLog
index 0221e86..1464f24 100644
--- a/frysk-sys/frysk/ChangeLog
+++ b/frysk-sys/frysk/ChangeLog
@@ -1,3 +1,7 @@
+2008-04-30  Andrew Cagney  <cagney@redhat.com>
+
+	* jni/jnixx.java: New.
+
 2008-04-17  Andrew Cagney  <cagney@redhat.com>
 
 	* jni/exceptions.cxx: New.
diff --git a/frysk-sys/frysk/jni/jnixx.java b/frysk-sys/frysk/jni/jnixx.java
new file mode 100644
index 0000000..7c1d378
--- /dev/null
+++ b/frysk-sys/frysk/jni/jnixx.java
@@ -0,0 +1,417 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2008, Red Hat Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package frysk.jni;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.lang.reflect.Modifier;
+import java.io.PrintWriter;
+
+class jnixx {
+    private static PrintWriter out = new PrintWriter(System.out, true);
+    private static PrintWriter err = new PrintWriter(System.err, true);
+    static void print(char ch) {
+	out.print(ch);
+    }
+    static void print(Object o) {
+	out.print(o.toString());
+    }
+    static void println(Object o) {
+	out.println(o.toString());
+    }
+    static void println() {
+	out.println();
+    }
+
+    /**
+     * Pad with white space.
+     */
+    static void pad(int n) {
+	for (int i = 0 ; i < n; i++)
+	    print("  ");
+    }
+
+    /**
+     * Print the name in a C++ friendly form; that is "." replaced by
+     * "::".
+     */
+    static void printCxxName(Class klass) {
+	print(klass.getName().replaceAll("\\.", "::"));
+    }
+
+    /**
+     * Print the name in a C++ friendly form; that is "." replaced by
+     * "::".
+     */
+    static void printCxxName(Method method) {
+	printCxxName(method.getDeclaringClass());
+	print("::");
+	print(method.getName());
+    }
+
+    /**
+     * Print the namespace spec for the klass.
+     */
+    static void printCxxNamespace(Class klass) {
+	if (klass.isPrimitive())
+	    return;
+	if (printedNamespaces.contains(klass))
+	    return;
+	println();
+	String[] names = klass.getName().split("\\.");
+	for (int i = 0; i < names.length - 1; i++) {
+	    pad(i);
+	    print("namespace ");
+	    print(names[i]);
+	    println(" {");
+	}
+	pad(names.length - 1);
+	print("struct ");
+	print(names[names.length - 1]);
+	println(";");
+	for (int i = names.length - 2; i >= 0; i--) {
+	    pad(i);
+	    println("}");
+	}
+	printedNamespaces.add(klass);
+    }
+    private static HashSet printedNamespaces = new HashSet();
+
+    static boolean isStatic(Member member) {
+	return Modifier.isStatic(member.getModifiers());
+    }
+
+    /**
+     * Iterate over the klass printing all referenced name-space
+     * information.
+     */
+    static void printCxxNamespaces(Class klass) {
+	printCxxNamespace(klass);
+	Method[] methods = klass.getDeclaredMethods();
+	for (int i = 0; i < methods.length; i++) {
+	    Method method = methods[i];
+	    printCxxNamespace(method.getReturnType());
+	    Class[] params = method.getParameterTypes();
+	    for (int j = 0; j < params.length; j++) {
+		Class param = params[j];
+		printCxxNamespace(param);
+	    }
+	}
+    }
+
+    /**
+     * Given a method, print its JNI mangled name.
+     */
+    static void printJniName(Method method) {
+	print("Java_");
+	print(method.getDeclaringClass().getName().replaceAll("\\.", "_"));
+	print("_");
+	print(method.getName());
+    }
+
+
+    /**
+     * Given a class describing a type (class of basic), print the JNI
+     * equivalent name.  For classes, print the XX type.
+     */
+    static void printJniType(Class klass) {
+	if (klass.isPrimitive()) {
+	    if (klass == Void.TYPE) {
+		print("void");
+	    } else {
+		print("j");
+		print(klass.getName());
+	    }
+	} else if (klass == String.class) {
+	    print("jstring");
+	} else if (klass == Object.class) {
+	    print("jobject");
+	} else if (klass == Class.class) {
+	    print("jclass");
+	} else {
+	    printCxxName(klass);
+	    print("*");
+	}
+    }
+
+    /**
+     * Given a class describing a type (class of basic), print the JNI
+     * equivalent name.  For classes, print the XX type.
+     */
+    static void printCxxType(Class klass) {
+	if (klass.isPrimitive()) {
+	    if (klass == Void.TYPE) {
+		print("void");
+	    } else {
+		print("j");
+		print(klass.getName());
+	    }
+	} else if (klass == String.class) {
+	    print("jstring");
+	} else if (klass == Object.class) {
+	    print("jobject");
+	} else if (klass == Class.class) {
+	    print("jclass");
+	} else {
+	    printCxxName(klass);
+	    print("*");
+	}
+    }
+
+    /**
+     * Given an array of types, print them as a list (presumably this
+     * is a list of parameters).
+     */
+    static void printFormalCxxParameters(Method method, boolean printArgs) {
+	print("JNIEnv*");
+	if (printArgs)
+	    print(" env");
+	if (isStatic(method)) {
+	    print(", jclass");
+	    if (printArgs)
+		print(" klass");
+	} else {
+	    print(", jobject");
+	    if (printArgs)
+		print(" object");
+	}
+	Class[] params = method.getParameterTypes();
+	for (int i = 0; i < params.length; i++) {
+	    print(", ");
+	    printCxxType(params[i]);
+	    if (printArgs)
+		print(" p" + i);
+	}
+    }
+
+    static void printActualCxxParameters(Method method) {
+	print("env");
+	if (isStatic(method)) {
+	    print(", klass");
+	} else {
+	    print(", object");
+	}
+	for (int i = 0; i < method.getParameterTypes().length; i++) {
+	    print(", p" + i);
+	}
+    }
+
+    static void printActualJniParameters(Method method) {
+	if (isStatic(method))
+	    print("klass, id");
+	else
+	    print("object, id");
+	for (int i = 0; i < method.getParameterTypes().length; i++) {
+	    print(", p" + i);
+	}
+    }
+
+    static void printReturnType(Class klass) {
+	if (klass.isPrimitive()) {
+	    String name = klass.getName();
+	    print(Character.toUpperCase(name.charAt(0)));
+	    print(name.substring(1));
+	} else {
+	    print("Object");
+	}
+    }
+
+    static void printCxxMethodDeclaration(Method method) {
+	println();
+	pad(1);
+	print("static ");
+	printCxxType(method.getReturnType());
+	print(" ");
+	print(method.getName());
+	print("(");
+	printFormalCxxParameters(method, false);
+	print(");");
+	println();
+    }
+
+    static void printHxxFile(Class klass) {
+	println("#include <jni.h>");
+	printCxxNamespaces(klass);
+	println();
+	print("struct ");
+	printCxxName(klass);
+	Class parent = klass.getSuperclass();
+	if (parent == Object.class) {
+	    print(" : public __jobject");
+	} else if (parent != null) {
+	    print(" : public ");
+	    printCxxName(parent);
+	}
+	println(" {");
+	Method[] methods = klass.getDeclaredMethods();
+	for (int i = 0; i < methods.length; i++) {
+	    Method method = methods[i];
+	    printCxxMethodDeclaration(method);
+	}
+	println();
+	println("};");
+    }
+
+    static void printNativeMethodDefinition(Method method) {
+	println();
+	println("extern \"C\" {");
+	print("  JNIEXPORT ");
+	printJniType(method.getReturnType());
+	print(" JNICALL ");
+	printJniName(method);
+	print("(");
+	printFormalCxxParameters(method, false);
+	println(");");
+	println("}");
+	println();
+	printJniType(method.getReturnType());
+	println();
+	printJniName(method);
+	print("(");
+	printFormalCxxParameters(method, true);
+	println(") {");
+	println("  try {");
+	print("    ");
+	if (method.getReturnType() != Void.TYPE) {
+	    print("return ");
+	}
+	printCxxName(method);
+	print("(");
+	printActualCxxParameters(method);
+	println(");");
+	println("  } catch (const std::exception& e) {");
+	if (method.getReturnType() != Void.TYPE) {
+	    println("    return 0;");
+	}
+	println("  }");
+	println("}");
+    }
+
+    static void printSignature(Method method) {
+
+    }
+
+    static void printCxxMethodDefinition(Method method) {
+	Class returnType = method.getReturnType();
+	println();
+	printCxxType(returnType);
+	println();
+	printCxxName(method.getDeclaringClass());
+	print("::");
+	print(method.getName());


hooks/post-receive
--
frysk system monitor/debugger


                 reply	other threads:[~2008-04-30 14:29 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080430142903.28106.qmail@sourceware.org \
    --to=cagney@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).