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 char** strings2chars(String) and String chars2strings(char**). Date: Fri, 09 May 2008 13:40:00 -0000 [thread overview] Message-ID: <20080509134020.29754.qmail@sourceware.org> (raw) The branch, master has been updated via dcceec6534cd5e28eca8dccc095f4c44113d9160 (commit) from 776b3cd28bc6c5bfecf4fec01b1d0a7d53445d48 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit dcceec6534cd5e28eca8dccc095f4c44113d9160 Author: Andrew Cagney <cagney@redhat.com> Date: Fri May 9 09:29:38 2008 -0400 Add char** strings2chars(String) and String chars2strings(char**). frysk-sys/frysk/jnixx/ChangeLog 2008-05-09 Andrew Cagney <cagney@redhat.com> * Main.java (treatAsNative(Method)): New. (treatAsPrivate(Member)): New. * PrintDeclarations.java: Use. * PrintHxxDefinitions.java: Use. * PrintCxxDefinitions.java: Use; Extend ClassWalker. * TestJnixx.java (testCharsConversion()): New. * chars.hxx: New. * chars.cxx: .New. * jni/Native.cxx (Native::copy): New. * cni/Native.cxx (Native::copy): New. ----------------------------------------------------------------------- Summary of changes: frysk-sys/frysk/jnixx/ChangeLog | 13 ++ frysk-sys/frysk/jnixx/ClassVisitor.java | 4 + frysk-sys/frysk/jnixx/Main.java | 45 +++++- frysk-sys/frysk/jnixx/Native.java | 1 + frysk-sys/frysk/jnixx/PrintCxxDefinitions.java | 168 ++++++++++++---------- frysk-sys/frysk/jnixx/PrintDeclarations.java | 2 +- frysk-sys/frysk/jnixx/PrintHxxDefinitions.java | 2 +- frysk-sys/frysk/jnixx/TestJnixx.java | 6 + frysk-sys/frysk/jnixx/{Main.java => chars.cxx} | 87 ++++++----- frysk-sys/frysk/jnixx/{Native.java => chars.hxx} | 10 +- frysk-sys/frysk/jnixx/cni/Native.cxx | 5 + frysk-sys/frysk/jnixx/jni/Native.cxx | 13 ++ 12 files changed, 228 insertions(+), 128 deletions(-) copy frysk-sys/frysk/jnixx/{Main.java => chars.cxx} (56%) copy frysk-sys/frysk/jnixx/{Native.java => chars.hxx} (92%) First 500 lines of diff: diff --git a/frysk-sys/frysk/jnixx/ChangeLog b/frysk-sys/frysk/jnixx/ChangeLog index d3758c1..c527462 100644 --- a/frysk-sys/frysk/jnixx/ChangeLog +++ b/frysk-sys/frysk/jnixx/ChangeLog @@ -1,3 +1,16 @@ +2008-05-09 Andrew Cagney <cagney@redhat.com> + + * Main.java (treatAsNative(Method)): New. + (treatAsPrivate(Member)): New. + * PrintDeclarations.java: Use. + * PrintHxxDefinitions.java: Use. + * PrintCxxDefinitions.java: Use; Extend ClassWalker. + * TestJnixx.java (testCharsConversion()): New. + * chars.hxx: New. + * chars.cxx: .New. + * jni/Native.cxx (Native::copy): New. + * cni/Native.cxx (Native::copy): New. + 2008-05-08 Andrew Cagney <cagney@redhat.com> * jnixx.hxx (jnixx::env): Fill in missing JNI bindings; match JNI diff --git a/frysk-sys/frysk/jnixx/ClassVisitor.java b/frysk-sys/frysk/jnixx/ClassVisitor.java index 20f34e2..6520b2d 100644 --- a/frysk-sys/frysk/jnixx/ClassVisitor.java +++ b/frysk-sys/frysk/jnixx/ClassVisitor.java @@ -67,6 +67,8 @@ abstract class ClassVisitor { Field field = fields[i]; if (field.isSynthetic()) continue; + if (Main.treatAsInvisible(field)) + continue; acceptField(field); } Method[] methods = klass.getDeclaredMethods(); @@ -74,6 +76,8 @@ abstract class ClassVisitor { Method method = methods[i]; if (method.isSynthetic()) continue; + if (Main.treatAsInvisible(method)) + continue; acceptMethod(method); } Class[] classes = klass.getClasses(); diff --git a/frysk-sys/frysk/jnixx/Main.java b/frysk-sys/frysk/jnixx/Main.java index 97ccadc..aeb1b19 100644 --- a/frysk-sys/frysk/jnixx/Main.java +++ b/frysk-sys/frysk/jnixx/Main.java @@ -40,9 +40,45 @@ package frysk.jnixx; import java.io.PrintWriter; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Member; class Main { + /** + * Does this method require native bindings? Methods that are not + * part of this JNI library, that are native, must be treated as + * virtual. + */ + static boolean treatAsNative(Method method) { + // FIXME: Should be filtering based on something smarter than + // this. + if (method.getDeclaringClass().getName().startsWith("java.")) + return false; + if (method.getDeclaringClass().getName().startsWith("gnu.")) + return false; + if (Modifier.isNative(method.getModifiers())) + return true; + return false; + } + + /** + * Is the member visible to this generated JNI code. Private + * methods and fileds and the java package are not visible. + */ + static boolean treatAsInvisible(Member member) { + if (Modifier.isPrivate(member.getModifiers())) { + // FIXME: Should be filtering based on something smarter + // than is. + if (member.getDeclaringClass().getName().startsWith("java.")) + return true; + if (member.getDeclaringClass().getName().startsWith("gnu.")) + return true; + } + return false; + } + private static void printHxxFile(Printer p, Class[] classes) { p.println("#include \"frysk/jnixx/jnixx.hxx\""); new PrintNamespaces(p).walk(classes); @@ -53,12 +89,9 @@ class Main { private static void printCxxFile(Printer p, Class[] classes) { printHxxFile(p, classes); // #include p.println(); - for (int i = 0; i < classes.length; i++) { - p.print("jclass "); - p.printQualifiedCxxName(classes[i]); - p.println("::_class;"); - } - new PrintCxxDefinitions(p).visit(classes); + p.println("\f"); + p.println(); + new PrintCxxDefinitions(p).walk(classes); } public static void main(String[] args) throws ClassNotFoundException { diff --git a/frysk-sys/frysk/jnixx/Native.java b/frysk-sys/frysk/jnixx/Native.java index 49614bd..066470b 100644 --- a/frysk-sys/frysk/jnixx/Native.java +++ b/frysk-sys/frysk/jnixx/Native.java @@ -43,4 +43,5 @@ class Native { static native boolean isJni(); static native int sizeOfJnixxEnv(); static native int sizeOfJnixxObject(); + static native String[] copy(String[] strings); } diff --git a/frysk-sys/frysk/jnixx/PrintCxxDefinitions.java b/frysk-sys/frysk/jnixx/PrintCxxDefinitions.java index 0958db6..1e8be54 100644 --- a/frysk-sys/frysk/jnixx/PrintCxxDefinitions.java +++ b/frysk-sys/frysk/jnixx/PrintCxxDefinitions.java @@ -44,103 +44,123 @@ import java.lang.reflect.Field; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; -class PrintCxxDefinitions extends ClassVisitor { +class PrintCxxDefinitions extends ClassWalker { private final Printer p; PrintCxxDefinitions(Printer p) { this.p = p; } + private ClassVisitor printer = new ClassVisitor() { - private void printNativeMethodDefinition(Method method) { - boolean isStatic = Modifier.isStatic(method.getModifiers()); - p.println(); - while (p.dent(0, "extern \"C\" {", "};")) { - p.print("JNIEXPORT "); - p.printJniType(method.getReturnType()); - p.print(" JNICALL "); - p.printJniName(method); - p.print("("); - p.printFormalJniParameters(method, false); - p.println(");"); - } - p.println(); - p.printJniType(method.getReturnType()); - p.println(); - p.printJniName(method); - p.print("("); - p.printFormalJniParameters(method, true); - p.print(")"); - while (p.dent(0, "{", "};")) { - p.println("try {"); - { - p.indent(); - p.println("::jnixx::env _env = ::jnixx::env(_jni);"); - Class returnType = method.getReturnType(); - if (returnType != Void.TYPE) { - p.printCxxType(returnType); - p.print(" ret = "); - } - if (isStatic) { - p.printQualifiedCxxName(method); - } else { - p.printCxxType(method.getDeclaringClass()); - p.print("(object)."); - p.print(method.getName()); + private void printNativeMethodDefinition(Method method) { + boolean isStatic = Modifier.isStatic(method.getModifiers()); + p.println(); + while (p.dent(0, "extern \"C\" {", "};")) { + p.print("JNIEXPORT "); + p.printJniType(method.getReturnType()); + p.print(" JNICALL "); + p.printJniName(method); + p.print("("); + p.printFormalJniParameters(method, false); + p.println(");"); } + p.println(); + p.printJniType(method.getReturnType()); + p.println(); + p.printJniName(method); p.print("("); - p.printActualCxxParameters(method); - p.println(");"); - if (returnType != Void.TYPE) { - p.print("return "); - if (returnType.isPrimitive()) { - p.print("ret"); - } else if (returnType == String.class) { - p.print("(jstring) ret._object"); - } else if (returnType.isArray()) { - if (returnType.getComponentType().isPrimitive()) { - p.print("ret"); + p.printFormalJniParameters(method, true); + p.print(")"); + while (p.dent(0, "{", "};")) { + p.println("try {"); + { + p.indent(); + p.println("::jnixx::env _env = ::jnixx::env(_jni);"); + Class returnType = method.getReturnType(); + if (returnType != Void.TYPE) { + p.printCxxType(returnType); + p.print(" ret = "); + } + if (isStatic) { + p.printQualifiedCxxName(method); } else { - p.print("(jobjectArray) ret._object"); + p.printCxxType(method.getDeclaringClass()); + p.print("(object)."); + p.print(method.getName()); + } + p.print("("); + p.printActualCxxParameters(method); + p.println(");"); + if (returnType != Void.TYPE) { + p.print("return "); + if (returnType.isPrimitive()) { + p.print("ret"); + } else if (returnType == String.class) { + p.print("(jstring) ret._object"); + } else if (returnType.isArray()) { + if (returnType.getComponentType().isPrimitive()) { + p.print("ret"); + } else { + p.print("(jobjectArray) ret._object"); + } + } else { + p.print("ret._object"); + } + p.println(";"); } - } else { - p.print("ret._object"); + p.outdent(); } - p.println(";"); + p.println("} catch (jnixx::exception) {"); + { + p.indent(); + if (method.getReturnType() != Void.TYPE) { + p.println("return 0;"); + } else { + p.println("return;"); + } + p.outdent(); + } + p.println("}"); } - p.outdent(); } - p.println("} catch (jnixx::exception) {"); - { - p.indent(); - if (method.getReturnType() != Void.TYPE) { - p.println("return 0;"); - } else { - p.println("return;"); + + public void acceptMethod(Method method) { + if (Main.treatAsNative(method)) { + printNativeMethodDefinition(method); } - p.outdent(); } - p.println("}"); - } - } + void acceptInterface(Class constructor) { + } + void acceptConstructor(Constructor constructor) { + } + void acceptField(Field field) { + } + void acceptComponent(Class klass) { + } + void acceptClass(Class klass) { + } + }; - public void acceptMethod(Method method) { - if (Modifier.isNative(method.getModifiers())) { - printNativeMethodDefinition(method); - } + void acceptArray(Class klass) { + acceptClass(klass); } - void acceptInterface(Class constructor) { - } - void acceptConstructor(Constructor constructor) { - } - void acceptField(Field field) { - } - void acceptComponent(Class klass) { + void acceptPrimitive(Class klass) { + acceptClass(klass); } void acceptClass(Class klass) { + if (klass.isPrimitive()) + return; + if (klass.isArray()) + return; p.println(); p.print("jclass "); p.printQualifiedCxxName(klass); p.println("::_class;"); + printer.visit(klass); + } + void acceptInterface(Class klass) { + acceptClass(klass); } } + diff --git a/frysk-sys/frysk/jnixx/PrintDeclarations.java b/frysk-sys/frysk/jnixx/PrintDeclarations.java index 86b57d3..32c9b34 100644 --- a/frysk-sys/frysk/jnixx/PrintDeclarations.java +++ b/frysk-sys/frysk/jnixx/PrintDeclarations.java @@ -105,7 +105,7 @@ class PrintDeclarations extends ClassWalker { if (Modifier.isStatic(method.getModifiers())) { p.print("static "); } - if (!Modifier.isNative(method.getModifiers())) { + if (!Main.treatAsNative(method)) { p.print("inline "); } p.printCxxType(method.getReturnType()); diff --git a/frysk-sys/frysk/jnixx/PrintHxxDefinitions.java b/frysk-sys/frysk/jnixx/PrintHxxDefinitions.java index fc7a7c6..8ae9bea 100644 --- a/frysk-sys/frysk/jnixx/PrintHxxDefinitions.java +++ b/frysk-sys/frysk/jnixx/PrintHxxDefinitions.java @@ -225,7 +225,7 @@ class PrintHxxDefinitions extends ClassWalker { } public void acceptMethod(Method method) { - if (!Modifier.isNative(method.getModifiers())) { + if (!Main.treatAsNative(method)) { printCxxMethodDefinition(method); } } diff --git a/frysk-sys/frysk/jnixx/TestJnixx.java b/frysk-sys/frysk/jnixx/TestJnixx.java index 5b15f0d..ca08e0b 100644 --- a/frysk-sys/frysk/jnixx/TestJnixx.java +++ b/frysk-sys/frysk/jnixx/TestJnixx.java @@ -55,4 +55,10 @@ public class TestJnixx extends TestCase { assertEquals("word-size", Host.wordSize(), Native.sizeOfJnixxObject() * 8); } + public void testCharsConversion() { + if (unsupported("CNI", !Native.isJni())) + return; + String[] strings = new String[] { "arg1", "arg2", "arg3" }; + assertEquals("converted", strings, Native.copy(strings)); + } } diff --git a/frysk-sys/frysk/jnixx/Main.java b/frysk-sys/frysk/jnixx/chars.cxx similarity index 56% copy from frysk-sys/frysk/jnixx/Main.java copy to frysk-sys/frysk/jnixx/chars.cxx index 97ccadc..f81b6e6 100644 --- a/frysk-sys/frysk/jnixx/Main.java +++ b/frysk-sys/frysk/jnixx/chars.cxx @@ -37,46 +37,53 @@ // version and license this file solely under the GPL without // exception. -package frysk.jnixx; +#include "jni.hxx" +#include <malloc.h> -import java.io.PrintWriter; - -class Main { - - private static void printHxxFile(Printer p, Class[] classes) { - p.println("#include \"frysk/jnixx/jnixx.hxx\""); - new PrintNamespaces(p).walk(classes); - new PrintDeclarations(p).walk(classes); - new PrintHxxDefinitions(p).walk(classes); - } - - private static void printCxxFile(Printer p, Class[] classes) { - printHxxFile(p, classes); // #include - p.println(); - for (int i = 0; i < classes.length; i++) { - p.print("jclass "); - p.printQualifiedCxxName(classes[i]); - p.println("::_class;"); - } - new PrintCxxDefinitions(p).visit(classes); - } - - public static void main(String[] args) throws ClassNotFoundException { - if (args.length < 2) { - throw new RuntimeException("Usage: jnixx cxx}hxx <class-name> ..."); - } - - Class[] classes = new Class[args.length - 1]; - for (int i = 0; i < classes.length; i++) { - classes[i] = Class.forName(args[i + 1], false, - Main.class.getClassLoader()); - } +char** +strings2chars(jnixx::env env, ::java::lang::StringArray strings) { + jsize arrayLength = env.GetArrayLength((jobjectArray)strings._object); + // compute the allocated size. + size_t size = 0; + size += sizeof(void*); // NULL + for (int i = 0; i < arrayLength; i++) { + size += sizeof(void*); // pointer + jstring string = (jstring) env.GetObjectArrayElement((jobjectArray)strings._object, i); + size += env.GetStringUTFLength(string); // chars + size += 1; // NUL + env.DeleteLocalRef(string); + } + // Create the array. + char **elements = (char**) ::malloc(size); + char **argv = elements; + // Store strings after the array + char *arg = (char*) (argv + arrayLength + 1); + // Copy + for (int i = 0; i < arrayLength; i++) { + *argv++ = arg; + jstring string = (jstring)env.GetObjectArrayElement((jobjectArray)strings._object, i); + int utfLength = env.GetStringUTFLength(string); + env.GetStringUTFRegion(string, 0, env.GetStringLength(string), arg); + arg += utfLength; + env.DeleteLocalRef(string); + *arg++ = '\0'; + } + *argv = NULL; + return elements; +} - Printer p = new Printer(new PrintWriter(System.out)); - if (args[0].equals("hxx")) - printHxxFile(p, classes); - else - printCxxFile(p, classes); - p.flush(); - } +::java::lang::StringArray +chars2strings(::jnixx::env env, char** argv) { + int length = 0; + for (char **p = argv; *p != NULL; p++) { + length++; + } + jclass stringClass = ::java::lang::String::_class_(env); + jobjectArray strings = env.NewObjectArray(length, stringClass, NULL); + for (int i = 0; i < length; i++) { + jstring string = env.NewStringUTF(argv[i]); + env.SetObjectArrayElement(strings, i, string); + env.DeleteLocalRef(string); + } + return strings; } diff --git a/frysk-sys/frysk/jnixx/Native.java b/frysk-sys/frysk/jnixx/chars.hxx similarity index 92% copy from frysk-sys/frysk/jnixx/Native.java copy to frysk-sys/frysk/jnixx/chars.hxx index 49614bd..a0e5deb 100644 --- a/frysk-sys/frysk/jnixx/Native.java +++ b/frysk-sys/frysk/jnixx/chars.hxx @@ -37,10 +37,8 @@ // version and license this file solely under the GPL without // exception. -package frysk.jnixx; +extern char** strings2chars(jnixx::env env, + ::java::lang::StringArray strings); -class Native { - static native boolean isJni(); - static native int sizeOfJnixxEnv(); - static native int sizeOfJnixxObject(); -} +extern ::java::lang::StringArray chars2strings(::jnixx::env env, + char** argv); diff --git a/frysk-sys/frysk/jnixx/cni/Native.cxx b/frysk-sys/frysk/jnixx/cni/Native.cxx index 4388148..a8a0852 100644 --- a/frysk-sys/frysk/jnixx/cni/Native.cxx +++ b/frysk-sys/frysk/jnixx/cni/Native.cxx @@ -55,3 +55,8 @@ jint frysk::jnixx::Native::sizeOfJnixxObject() { return -1; } + +JArray<jstring>* +frysk::jnixx::Native::copy(JArray<jstring>* strings) { + return NULL; +} diff --git a/frysk-sys/frysk/jnixx/jni/Native.cxx b/frysk-sys/frysk/jnixx/jni/Native.cxx index f397aaa..471d4ad 100644 hooks/post-receive -- frysk system monitor/debugger
reply other threads:[~2008-05-09 13:40 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=20080509134020.29754.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).