From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29796 invoked by alias); 9 May 2008 13:40:20 -0000 Received: (qmail 29769 invoked by uid 367); 9 May 2008 13:40:20 -0000 Date: Fri, 09 May 2008 13:40:00 -0000 Message-ID: <20080509134020.29754.qmail@sourceware.org> From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Add char** strings2chars(String) and String chars2strings(char**). X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 776b3cd28bc6c5bfecf4fec01b1d0a7d53445d48 X-Git-Newrev: dcceec6534cd5e28eca8dccc095f4c44113d9160 Mailing-List: contact frysk-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-cvs-owner@sourceware.org Reply-To: frysk@sourceware.org X-SW-Source: 2008-q2/txt/msg00208.txt.bz2 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 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 * 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 + + * 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 * 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 -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[] 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* +frysk::jnixx::Native::copy(JArray* 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