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: linkBe 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).