From 40495c4e04ab8b15e17ec6bdc6b6c35f4144c34e Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 6 Nov 2010 23:13:39 +0100 Subject: Renamed com.sun.gluegen -> com.jogamp.gluegen --- .../com/jogamp/gluegen/ant/StaticGLGenTask.java | 304 +++++++++++++ .../gluegen/nativesig/NativeSignatureEmitter.java | 190 ++++++++ .../NativeSignatureJavaMethodBindingEmitter.java | 487 +++++++++++++++++++++ src/java/com/sun/gluegen/ant/StaticGLGenTask.java | 304 ------------- .../gluegen/nativesig/NativeSignatureEmitter.java | 186 -------- .../NativeSignatureJavaMethodBindingEmitter.java | 484 -------------------- 6 files changed, 981 insertions(+), 974 deletions(-) create mode 100644 src/java/com/jogamp/gluegen/ant/StaticGLGenTask.java create mode 100755 src/java/com/jogamp/gluegen/nativesig/NativeSignatureEmitter.java create mode 100755 src/java/com/jogamp/gluegen/nativesig/NativeSignatureJavaMethodBindingEmitter.java delete mode 100644 src/java/com/sun/gluegen/ant/StaticGLGenTask.java delete mode 100755 src/java/com/sun/gluegen/nativesig/NativeSignatureEmitter.java delete mode 100755 src/java/com/sun/gluegen/nativesig/NativeSignatureJavaMethodBindingEmitter.java (limited to 'src/java/com') diff --git a/src/java/com/jogamp/gluegen/ant/StaticGLGenTask.java b/src/java/com/jogamp/gluegen/ant/StaticGLGenTask.java new file mode 100644 index 000000000..2785344a5 --- /dev/null +++ b/src/java/com/jogamp/gluegen/ant/StaticGLGenTask.java @@ -0,0 +1,304 @@ +package com.jogamp.gluegen.ant; + +/* + * StaticGLGenTask.java + * Copyright (C) 2003 Rob Grzywinski (rgrzywinski@realityinteractive.com) + * + * Copying, distribution and use of this software in source and binary + * forms, with or without modification, is permitted provided that the + * following conditions are met: + * + * Distributions of source code must reproduce the copyright notice, + * this list of conditions and the following disclaimer in the source + * code header files; and Distributions of binary code must reproduce + * the copyright notice, this list of conditions and the following + * disclaimer in the documentation, Read me file, license file and/or + * other materials provided with the software distribution. + * + * The names of Sun Microsystems, Inc. ("Sun") and/or the copyright + * holder may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT A WARRANTY OF ANY + * KIND. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, NON-INTERFERENCE, ACCURACY OF + * INFORMATIONAL CONTENT OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. THE + * COPYRIGHT HOLDER, SUN AND SUN'S LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL THE + * COPYRIGHT HOLDER, SUN OR SUN'S LICENSORS BE LIABLE FOR ANY LOST + * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGES. YOU ACKNOWLEDGE THAT THIS SOFTWARE IS NOT + * DESIGNED, LICENSED OR INTENDED FOR USE IN THE DESIGN, CONSTRUCTION, + * OPERATION OR MAINTENANCE OF ANY NUCLEAR FACILITY. THE COPYRIGHT + * HOLDER, SUN AND SUN'S LICENSORS DISCLAIM ANY EXPRESS OR IMPLIED + * WARRANTY OF FITNESS FOR SUCH USES. + */ + +import java.io.IOException; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.Execute; +import org.apache.tools.ant.taskdefs.LogStreamHandler; +import org.apache.tools.ant.types.CommandlineJava; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.PatternSet; +import org.apache.tools.ant.util.JavaEnvUtils; + +/** + *

An ANT {@link org.apache.tools.ant.Task} + * for using {@link com.jogamp.gluegen.opengl.BuildStaticGLInfo}.

+ * + *

Usage:

+ *
+    <staticglgen package="[generated files package]" 
+                    headers="[file pattern of GL headers]"
+                    outputdir="[directory to output the generated files]" />
+ * 
+ * + * @author Rob Grzywinski rgrzywinski@yahoo.com + */ +// FIXME: blow out javadoc +public class StaticGLGenTask extends Task +{ + /** + *

The {@link com.jogamp.gluegen.opengl.BuildStaticGLInfo} classname.

+ */ + private static final String GL_GEN = "com.jogamp.gluegen.opengl.BuildStaticGLInfo"; + + // ========================================================================= + /** + *

The {@link org.apache.tools.ant.types.CommandlineJava} that is used + * to execute {@link com.jogamp.gluegen.opengl.BuildStaticGLInfo}.

+ */ + private CommandlineJava glgenCommandline; + + // ========================================================================= + /** + *

The package name for the generated files.

+ */ + private String packageName; + + /** + *

The output directory.

+ */ + private String outputDirectory; + + /** + *

The {@link org.apache.tools.ant.types.FileSet} of GL headers.

+ */ + private FileSet headerSet = new FileSet(); + + // ========================================================================= + /** + *

Create and add the VM and classname to {@link org.apache.tools.ant.types.CommandlineJava}.

+ */ + public StaticGLGenTask() + { + // create the CommandlineJava that will be used to call BuildStaticGLInfo + glgenCommandline = new CommandlineJava(); + + // set the VM and classname in the commandline + glgenCommandline.setVm(JavaEnvUtils.getJreExecutable("java")); + glgenCommandline.setClassname(GL_GEN); + } + + // ========================================================================= + // ANT getters and setters + /** + *

Set the package name for the generated files. This is called by ANT.

+ * + * @param packageName the name of the package for the generated files + */ + public void setPackage(String packageName) + { + log( ("Setting package name to: " + packageName), Project.MSG_VERBOSE); + this.packageName = packageName; + } + + /** + *

Set the output directory. This is called by ANT.

+ * + * @param directory the output directory + */ + public void setOutputDir(String directory) + { + log( ("Setting output directory to: " + directory), + Project.MSG_VERBOSE); + this.outputDirectory = directory; + } + + /** + *

Add a header file to the list. This is called by ANT for a nested + * element.

+ * + * @return {@link org.apache.tools.ant.types.PatternSet.NameEntry} + */ + public PatternSet.NameEntry createHeader() + { + return headerSet.createInclude(); + } + + /** + *

Add a header file to the list. This is called by ANT for a nested + * element.

+ * + * @return {@link org.apache.tools.ant.types.PatternSet.NameEntry} + */ + public PatternSet.NameEntry createHeadersFile() + { + return headerSet.createIncludesFile(); + } + + /** + *

Set the set of header patterns. Patterns may be separated by a comma + * or a space. This is called by ANT.

+ * + * @param headers the string containing the header patterns + */ + public void setHeaders(String headers) + { + headerSet.setIncludes(headers); + } + + /** + *

Add an optional classpath that defines the location of {@link com.jogamp.gluegen.opengl.BuildStaticGLInfo} + * and BuildStaticGLInfo's dependencies.

+ * + * @returns {@link org.apache.tools.ant.types.Path} + */ + public Path createClasspath() + { + return glgenCommandline.createClasspath(project).createPath(); + } + + // ========================================================================= + /** + *

Run the task. This involves validating the set attributes, creating + * the command line to be executed and finally executing the command.

+ * + * @see org.apache.tools.ant.Task#execute() + */ + public void execute() + throws BuildException + { + // validate that all of the required attributes have been set + validateAttributes(); + + // TODO: add logic to determine if the generated file needs to be + // regenerated + + // add the attributes to the CommandlineJava + addAttributes(); + + log(glgenCommandline.describeCommand(), Project.MSG_VERBOSE); + + // execute the command and throw on error + final int error = execute(glgenCommandline.getCommandline()); + if(error == 1) + throw new BuildException( ("BuildStaticGLInfo returned: " + error), location); + } + + /** + *

Ensure that the user specified all required arguments.

+ * + * @throws BuildException if there are required arguments that are not + * present or not valid + */ + private void validateAttributes() + throws BuildException + { + // validate that the package name is set + if(!isValid(packageName)) + throw new BuildException("Invalid package name: " + packageName); + + // validate that the output directory is set + // TODO: switch to file and ensure that it exists + if(!isValid(outputDirectory)) + throw new BuildException("Invalid output directory name: " + outputDirectory); + + // TODO: validate that there are headers set + } + + /** + *

Is the specified string valid? A valid string is non-null + * and has a non-zero length.

+ * + * @param string the string to be tested for validity + * @return true if the string is valid. false + * otherwise. + */ + private boolean isValid(String string) + { + // check for null + if(string == null) + return false; + + // ensure that the string has a non-zero length + // NOTE: must trim() to remove leading and trailing whitespace + if(string.trim().length() < 1) + return false; + + // the string is valid + return true; + } + + /** + *

Add all of the attributes to the command line. They have already + * been validated.

+ */ + private void addAttributes() + { + // add the package name + glgenCommandline.createArgument().setValue(packageName); + + // add the output directory name + glgenCommandline.createArgument().setValue(outputDirectory); + + // add the header -files- from the FileSet + headerSet.setDir(getProject().getBaseDir()); + DirectoryScanner directoryScanner = headerSet.getDirectoryScanner(getProject()); + String[] directoryFiles = directoryScanner.getIncludedFiles(); + for(int i=0; iExecute {@link com.jogamp.gluegen.opengl.BuildStaticGLInfo} in a + * forked JVM.

+ * + * @throws BuildException + */ + private int execute(String[] command) + throws BuildException + { + // create the object that will perform the command execution + Execute execute = new Execute(new LogStreamHandler(this, Project.MSG_INFO, + Project.MSG_WARN), + null); + + // set the project and command line + execute.setAntRun(project); + execute.setCommandline(command); + execute.setWorkingDirectory( project.getBaseDir() ); + + // execute the command + try + { + return execute.execute(); + } catch(IOException ioe) + { + throw new BuildException(ioe, location); + } + } +} diff --git a/src/java/com/jogamp/gluegen/nativesig/NativeSignatureEmitter.java b/src/java/com/jogamp/gluegen/nativesig/NativeSignatureEmitter.java new file mode 100755 index 000000000..bbc33d706 --- /dev/null +++ b/src/java/com/jogamp/gluegen/nativesig/NativeSignatureEmitter.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ +package com.jogamp.gluegen.nativesig; + +import com.jogamp.gluegen.MethodBinding; +import com.jogamp.gluegen.FunctionEmitter; +import com.jogamp.gluegen.JavaMethodBindingEmitter; +import com.jogamp.gluegen.JavaType; +import java.io.*; +import java.util.*; + +import com.jogamp.gluegen.*; +import com.jogamp.gluegen.cgram.types.*; +import com.jogamp.gluegen.opengl.*; +import com.jogamp.gluegen.procaddress.*; + +/** + * Emitter producing NativeSignature attributes. + */ +public class NativeSignatureEmitter extends GLEmitter { + + @Override + protected List generateMethodBindingEmitters(Set methodBindingSet, FunctionSymbol sym) throws Exception { + + // Allow superclass to do most of the work for us + List res = super.generateMethodBindingEmitters(methodBindingSet, sym); + + // Filter out all non-JavaMethodBindingEmitters + for (Iterator iter = res.iterator(); iter.hasNext();) { + FunctionEmitter emitter = iter.next(); + if (!(emitter instanceof JavaMethodBindingEmitter)) { + iter.remove(); + } + } + + if (res.isEmpty()) { + return res; + } + + PrintWriter writer = (getConfig().allStatic() ? javaWriter() : javaImplWriter()); + + List processed = new ArrayList(); + + // First, filter out all emitters going to the "other" (public) writer + for (Iterator iter = res.iterator(); iter.hasNext();) { + FunctionEmitter emitter = iter.next(); + if (emitter.getDefaultOutput() != writer) { + processed.add(emitter); + iter.remove(); + } + } + + // Now process all of the remaining emitters sorted by MethodBinding + while (!res.isEmpty()) { + List emittersForBinding = new ArrayList(); + JavaMethodBindingEmitter emitter = (JavaMethodBindingEmitter) res.remove(0); + emittersForBinding.add(emitter); + MethodBinding binding = emitter.getBinding(); + for (Iterator iter = res.iterator(); iter.hasNext();) { + JavaMethodBindingEmitter emitter2 = (JavaMethodBindingEmitter) iter.next(); + if (emitter2.getBinding() == binding) { + emittersForBinding.add(emitter2); + iter.remove(); + } + } + generateNativeSignatureEmitters(binding, emittersForBinding); + processed.addAll(emittersForBinding); + } + + return processed; + } + + protected void generateNativeSignatureEmitters(MethodBinding binding, List allEmitters) { + + if (allEmitters.isEmpty()) { + return; + } + + PrintWriter writer = (getConfig().allStatic() ? javaWriter() : javaImplWriter()); + + // Give ourselves the chance to interpose on the generation of all code to keep things simple + List newEmitters = new ArrayList(); + for (JavaMethodBindingEmitter javaEmitter : allEmitters) { + NativeSignatureJavaMethodBindingEmitter newEmitter = null; + if (javaEmitter instanceof GLJavaMethodBindingEmitter) { + newEmitter = new NativeSignatureJavaMethodBindingEmitter((GLJavaMethodBindingEmitter) javaEmitter); + } else if (javaEmitter instanceof ProcAddressJavaMethodBindingEmitter) { + newEmitter = new NativeSignatureJavaMethodBindingEmitter((ProcAddressJavaMethodBindingEmitter) javaEmitter); + } else { + newEmitter = new NativeSignatureJavaMethodBindingEmitter(javaEmitter, this); + } + newEmitters.add(newEmitter); + } + allEmitters.clear(); + allEmitters.addAll(newEmitters); + + // Detect whether we need to produce more or modify some of these emitters. + // Note that at this point we are assuming that generatePublicEmitters has + // been called with signatureOnly both true and false. + if (signatureContainsStrings(binding) && !haveEmitterWithBody(allEmitters)) { + // This basically handles glGetString but also any similar methods + NativeSignatureJavaMethodBindingEmitter javaEmitter = findEmitterWithWriter(allEmitters, writer); + + // First, we need to clone this emitter to produce the native + // entry point + NativeSignatureJavaMethodBindingEmitter emitter = new NativeSignatureJavaMethodBindingEmitter(javaEmitter); + emitter.removeModifier(JavaMethodBindingEmitter.PUBLIC); + emitter.addModifier(JavaMethodBindingEmitter.PRIVATE); + emitter.setForImplementingMethodCall(true); + // Note: this is chosen so we don't have to change the logic in + // emitReturnVariableSetupAndCall which decides which variant + // (direct / indirect) to call + emitter.setForDirectBufferImplementation(true); + allEmitters.add(emitter); + + // Now make the original emitter non-native and cause it to emit a body + javaEmitter.removeModifier(JavaMethodBindingEmitter.NATIVE); + javaEmitter.setEmitBody(true); + } + } + + protected boolean signatureContainsStrings(MethodBinding binding) { + for (int i = 0; i < binding.getNumArguments(); i++) { + JavaType type = binding.getJavaArgumentType(i); + if (type.isString() || type.isStringArray()) { + return true; + } + } + JavaType retType = binding.getJavaReturnType(); + if (retType.isString() || retType.isStringArray()) { + return true; + } + return false; + } + + protected boolean haveEmitterWithBody(List allEmitters) { + for (JavaMethodBindingEmitter emitter : allEmitters) { + if (!emitter.signatureOnly()) { + return true; + } + } + return false; + } + + protected NativeSignatureJavaMethodBindingEmitter findEmitterWithWriter(List allEmitters, PrintWriter writer) { + for (JavaMethodBindingEmitter jemitter : allEmitters) { + NativeSignatureJavaMethodBindingEmitter emitter = (NativeSignatureJavaMethodBindingEmitter)jemitter; + if (emitter.getDefaultOutput() == writer) { + return emitter; + } + } + throw new RuntimeException("Unexpectedly failed to find an emitter with the given writer"); + } +} diff --git a/src/java/com/jogamp/gluegen/nativesig/NativeSignatureJavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/nativesig/NativeSignatureJavaMethodBindingEmitter.java new file mode 100755 index 000000000..060d00861 --- /dev/null +++ b/src/java/com/jogamp/gluegen/nativesig/NativeSignatureJavaMethodBindingEmitter.java @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.gluegen.nativesig; + +import com.jogamp.gluegen.MethodBinding; +import com.jogamp.gluegen.JavaMethodBindingEmitter; +import com.jogamp.gluegen.JavaType; +import java.io.*; + +import com.jogamp.gluegen.*; +import com.jogamp.gluegen.cgram.types.*; +import com.jogamp.gluegen.opengl.*; +import com.jogamp.gluegen.procaddress.*; + +public class NativeSignatureJavaMethodBindingEmitter extends GLJavaMethodBindingEmitter { + + public NativeSignatureJavaMethodBindingEmitter(GLJavaMethodBindingEmitter methodToWrap) { + super(methodToWrap); + } + + public NativeSignatureJavaMethodBindingEmitter(ProcAddressJavaMethodBindingEmitter methodToWrap) { + super(methodToWrap, false); + } + + public NativeSignatureJavaMethodBindingEmitter(JavaMethodBindingEmitter methodToWrap, NativeSignatureEmitter emitter) { + super(methodToWrap, false, null, false, false, emitter); + } + + @Override + protected void emitSignature(PrintWriter writer) { + writer.print(getBaseIndentString()); + emitNativeSignatureAnnotation(writer); + super.emitSignature(writer); + } + + protected void emitNativeSignatureAnnotation(PrintWriter writer) { + if (hasModifier(JavaMethodBindingEmitter.NATIVE)) { + // Emit everything as a leaf for now + // FIXME: make this configurable + writer.print("@NativeSignature(\"l"); + MethodBinding binding = getBinding(); + if (callThroughProcAddress) { + writer.print("p"); + } + writer.print("("); + if (callThroughProcAddress) { + writer.print("P"); + } + for (int i = 0; i < binding.getNumArguments(); i++) { + emitNativeSignatureElement(writer, binding.getJavaArgumentType(i), binding.getCArgumentType(i), i); + } + writer.print(")"); + emitNativeSignatureElement(writer, binding.getJavaReturnType(), binding.getCReturnType(), -1); + writer.println("\")"); + } + } + + protected void emitNativeSignatureElement(PrintWriter writer, JavaType type, Type cType, int index) { + if (type.isVoid()) { + if (index > 0) { + throw new InternalError("Error parsing arguments -- void should not be seen aside from argument 0"); + } + return; + } + + if (type.isNIOBuffer()) { + writer.print("A"); + } else if (type.isPrimitiveArray()) { + writer.print("MO"); + } else if (type.isPrimitive()) { + Class clazz = type.getJavaClass(); + if (clazz == Byte.TYPE) { writer.print("B"); } + else if (clazz == Character.TYPE) { writer.print("C"); } + else if (clazz == Double.TYPE) { writer.print("D"); } + else if (clazz == Float.TYPE) { writer.print("F"); } + else if (clazz == Integer.TYPE) { writer.print("I"); } + else if (clazz == Long.TYPE) { + // See if this is intended to be a pointer at the C level + if (cType.isPointer()) { + writer.print("A"); + } else { + writer.print("J"); + } + } + else if (clazz == Short.TYPE) { writer.print("S"); } + else if (clazz == Boolean.TYPE) { writer.print("Z"); } + else throw new InternalError("Unhandled primitive type " + clazz); + } else if (type.isString()) { + writer.print("A"); + } else { + throw new RuntimeException("Type not yet handled: " + type); + } + } + + protected String getReturnTypeString(boolean skipArray) { + if (isForImplementingMethodCall()) { + JavaType returnType = getBinding().getJavaReturnType(); + if (returnType.isString() || returnType.isNIOByteBuffer()) { + // Treat these as addresses + return "long"; + } + } + return super.getReturnTypeString(skipArray); + } + + protected void emitPreCallSetup(MethodBinding binding, PrintWriter writer) { + super.emitPreCallSetup(binding, writer); + for (int i = 0; i < binding.getNumArguments(); i++) { + JavaType type = binding.getJavaArgumentType(i); + if (type.isNIOBuffer() && !directNIOOnly) { + // Emit declarations for variables holding primitive arrays as type Object + // We don't know 100% sure we're going to use these at this point in the code, though + writer.println(" Object " + getNIOBufferArrayName(i) + " = (_direct ? null : Buffers.getArray(" + + getArgumentName(i) + "));"); + } else if (type.isString()) { + writer.println(" long " + binding.getArgumentName(i) + "_c_str = BuffersInternal.newCString(" + binding.getArgumentName(i) + ");"); + } + // FIXME: going to need more of these for Buffer[] and String[], at least + } + } + + protected String getNIOBufferArrayName(int argNumber) { + return "__buffer_array_" + argNumber; + } + + protected int emitArguments(PrintWriter writer) + { + boolean needComma = false; + int numEmitted = 0; + + if (callThroughProcAddress) { + if (changeNameAndArguments) { + writer.print("long procAddress"); + ++numEmitted; + needComma = true; + } + } + + if (forImplementingMethodCall && binding.hasContainingType()) { + if (needComma) { + writer.print(", "); + } + + // Always emit outgoing "this" argument + writer.print("long "); + writer.print(javaThisArgumentName()); + ++numEmitted; + needComma = true; + } + + for (int i = 0; i < binding.getNumArguments(); i++) { + JavaType type = binding.getJavaArgumentType(i); + if (type.isVoid()) { + // Make sure this is the only param to the method; if it isn't, + // there's something wrong with our parsing of the headers. + if (binding.getNumArguments() != 1) { + throw new InternalError( + "\"void\" argument type found in " + + "multi-argument function \"" + binding + "\""); + } + continue; + } + + if (type.isJNIEnv() || binding.isArgumentThisPointer(i)) { + // Don't need to expose these at the Java level + continue; + } + + if (needComma) { + writer.print(", "); + } + + if (forImplementingMethodCall && + (forDirectBufferImplementation && type.isNIOBuffer() || + type.isString())) { + // Direct Buffers and Strings go out as longs + writer.print("long"); + // FIXME: will need more tests here to handle other constructs like String and direct Buffer arrays + } else { + writer.print(erasedTypeString(type, false)); + } + writer.print(" "); + writer.print(getArgumentName(i)); + + ++numEmitted; + needComma = true; + + // Add Buffer and array index offset arguments after each associated argument + if (forIndirectBufferAndArrayImplementation) { + if (type.isNIOBuffer()) { + writer.print(", int " + byteOffsetArgName(i)); + } else if (type.isNIOBufferArray()) { + writer.print(", int[] " + + byteOffsetArrayArgName(i)); + } + } + + // Add offset argument after each primitive array + if (type.isPrimitiveArray()) { + writer.print(", int " + offsetArgName(i)); + } + } + return numEmitted; + } + + protected void emitReturnVariableSetupAndCall(MethodBinding binding, PrintWriter writer) { + writer.print(" "); + JavaType returnType = binding.getJavaReturnType(); + boolean needsResultAssignment = false; + + if (!returnType.isVoid()) { + if (returnType.isCompoundTypeWrapper() || + returnType.isNIOByteBuffer()) { + writer.println("java.nio.ByteBuffer _res;"); + needsResultAssignment = true; + } else if (returnType.isArrayOfCompoundTypeWrappers()) { + writer.println("java.nio.ByteBuffer[] _res;"); + needsResultAssignment = true; + } else if (returnType.isString() || returnType.isNIOByteBuffer()) { + writer.print(returnType); + writer.println(" _res;"); + needsResultAssignment = true; + } else { + // Always assign to "_res" variable so we can clean up + // outgoing String arguments, for example + emitReturnType(writer); + writer.println(" _res;"); + needsResultAssignment = true; + } + } + + if (binding.signatureCanUseIndirectNIO() && !directNIOOnly) { + // Must generate two calls for this gated on whether the NIO + // buffers coming in are all direct or indirect + writer.println("if (_direct) {"); + writer.print (" "); + } + + if (needsResultAssignment) { + writer.print(" _res = "); + if (returnType.isString()) { + writer.print("BuffersInternal.newJavaString("); + } else if (returnType.isNIOByteBuffer()) { + writer.print("BuffersInternal.newDirectByteBuffer("); + } + } else { + writer.print(" "); + if (!returnType.isVoid()) { + writer.print("return "); + } + } + + if (binding.signatureUsesJavaPrimitiveArrays() && + !binding.signatureCanUseIndirectNIO()) { + // FIXME: what happens with a C function of the form + // void foo(int* arg0, void* arg1); + // ? + + // Only one call being made in this body, going to indirect + // buffer / array entry point + emitCall(binding, writer, false); + if (returnType.isString() || returnType.isNIOByteBuffer()) { + writer.print(")"); + } + writer.print(";"); + writer.println(); + } else { + emitCall(binding, writer, true); + if (returnType.isString() || returnType.isNIOByteBuffer()) { + writer.print(")"); + } + writer.print(";"); + } + + if (binding.signatureCanUseIndirectNIO() && !directNIOOnly) { + // Must generate two calls for this gated on whether the NIO + // buffers coming in are all direct or indirect + writer.println(); + writer.println(" } else {"); + writer.print (" "); + if (needsResultAssignment) { + writer.print(" _res = "); + } else { + writer.print(" "); + if (!returnType.isVoid()) { + writer.print("return "); + } + } + emitCall(binding, writer, false); + writer.print(";"); + writer.println(); + writer.println(" }"); + } else { + writer.println(); + } + emitPrologueOrEpilogue(epilogue, writer); + if (needsResultAssignment) { + emitCallResultReturn(binding, writer); + } + } + + protected int emitCallArguments(MethodBinding binding, PrintWriter writer, boolean direct) { + // Note that we override this completely because we both need to + // move the potential location of the outgoing proc address as + // well as change the way we pass out Buffers, arrays, Strings, etc. + + boolean needComma = false; + int numArgsEmitted = 0; + + if (callThroughProcAddress) { + writer.print("__addr_"); + needComma = true; + ++numArgsEmitted; + } + + if (binding.hasContainingType()) { + // Emit this pointer + assert(binding.getContainingType().isCompoundTypeWrapper()); + writer.print("BuffersInternal.getDirectBufferAddress("); + writer.print("getBuffer()"); + writer.print(")"); + needComma = true; + ++numArgsEmitted; + } + for (int i = 0; i < binding.getNumArguments(); i++) { + JavaType type = binding.getJavaArgumentType(i); + if (type.isJNIEnv() || binding.isArgumentThisPointer(i)) { + // Don't need to expose these at the Java level + continue; + } + + if (type.isVoid()) { + // Make sure this is the only param to the method; if it isn't, + // there's something wrong with our parsing of the headers. + assert(binding.getNumArguments() == 1); + continue; + } + + if (needComma) { + writer.print(", "); + } + + if (type.isCompoundTypeWrapper()) { + writer.print("BuffersInternal.getDirectBufferAddress("); + writer.print("(("); + } + + if (type.isNIOBuffer()) { + if (!direct) { + writer.print(getNIOBufferArrayName(i)); + } else { + writer.print("BuffersInternal.getDirectBufferAddress("); + writer.print(getArgumentName(i)); + writer.print(")"); + } + } else { + writer.print(getArgumentName(i)); + } + + if (type.isCompoundTypeWrapper()) { + writer.print(" == null) ? null : "); + writer.print(getArgumentName(i)); + writer.print(".getBuffer())"); + writer.print(")"); + } + + if (type.isNIOBuffer()) { + if (direct) { + writer.print("+ Buffers.getDirectBufferByteOffset(" + getArgumentName(i) + ")"); + } else { + writer.print(", BuffersInternal.arrayBaseOffset(" + + getNIOBufferArrayName(i) + + ") + Buffers.getIndirectBufferByteOffset(" + getArgumentName(i) + ")"); + } + } else if (type.isNIOBufferArray()) { + writer.print(", " + byteOffsetArrayArgName(i)); + } + + // Add Array offset parameter for primitive arrays + if (type.isPrimitiveArray()) { + writer.print(", "); + writer.print("BuffersInternal.arrayBaseOffset(" + getArgumentName(i) + ") + "); + if(type.isFloatArray()) { + writer.print("Buffers.SIZEOF_FLOAT * "); + } else if(type.isDoubleArray()) { + writer.print("Buffers.SIZEOF_DOUBLE * "); + } else if(type.isByteArray()) { + writer.print("1 * "); + } else if(type.isLongArray()) { + writer.print("Buffers.SIZEOF_LONG * "); + } else if(type.isShortArray()) { + writer.print("Buffers.SIZEOF_SHORT * "); + } else if(type.isIntArray()) { + writer.print("Buffers.SIZEOF_INT * "); + } else { + throw new RuntimeException("Unsupported type for calculating array offset argument for " + + getArgumentName(i) + + "-- error occurred while processing Java glue code for " + getName()); + } + writer.print(offsetArgName(i)); + } + + if (type.isString()) { + writer.print("_c_str"); + } + + if (type.isCompoundTypeWrapper()) { + writer.print(")"); + } + + needComma = true; + ++numArgsEmitted; + } + return numArgsEmitted; + } + + protected void emitCallResultReturn(MethodBinding binding, PrintWriter writer) { + for (int i = 0; i < binding.getNumArguments(); i++) { + JavaType type = binding.getJavaArgumentType(i); + if (type.isString()) { + writer.println(";"); + writer.println(" BuffersInternal.freeCString(" + binding.getArgumentName(i) + "_c_str);"); + } + // FIXME: will need more of these cleanups for things like Buffer[] and String[] (see above) + } + + super.emitCallResultReturn(binding, writer); + } + + public String getName() { + String res = super.getName(); + if (forImplementingMethodCall && bufferObjectVariant) { + return res + "BufObj"; + } + return res; + } + + protected String getImplMethodName(boolean direct) { + String name = null; + if (direct) { + name = binding.getName() + "$0"; + } else { + name = binding.getName() + "$1"; + } + if (bufferObjectVariant) { + return name + "BufObj"; + } + return name; + } +} diff --git a/src/java/com/sun/gluegen/ant/StaticGLGenTask.java b/src/java/com/sun/gluegen/ant/StaticGLGenTask.java deleted file mode 100644 index 87619422c..000000000 --- a/src/java/com/sun/gluegen/ant/StaticGLGenTask.java +++ /dev/null @@ -1,304 +0,0 @@ -package com.sun.gluegen.ant; - -/* - * StaticGLGenTask.java - * Copyright (C) 2003 Rob Grzywinski (rgrzywinski@realityinteractive.com) - * - * Copying, distribution and use of this software in source and binary - * forms, with or without modification, is permitted provided that the - * following conditions are met: - * - * Distributions of source code must reproduce the copyright notice, - * this list of conditions and the following disclaimer in the source - * code header files; and Distributions of binary code must reproduce - * the copyright notice, this list of conditions and the following - * disclaimer in the documentation, Read me file, license file and/or - * other materials provided with the software distribution. - * - * The names of Sun Microsystems, Inc. ("Sun") and/or the copyright - * holder may not be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT A WARRANTY OF ANY - * KIND. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, NON-INTERFERENCE, ACCURACY OF - * INFORMATIONAL CONTENT OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. THE - * COPYRIGHT HOLDER, SUN AND SUN'S LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL THE - * COPYRIGHT HOLDER, SUN OR SUN'S LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, - * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND - * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR - * INABILITY TO USE THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGES. YOU ACKNOWLEDGE THAT THIS SOFTWARE IS NOT - * DESIGNED, LICENSED OR INTENDED FOR USE IN THE DESIGN, CONSTRUCTION, - * OPERATION OR MAINTENANCE OF ANY NUCLEAR FACILITY. THE COPYRIGHT - * HOLDER, SUN AND SUN'S LICENSORS DISCLAIM ANY EXPRESS OR IMPLIED - * WARRANTY OF FITNESS FOR SUCH USES. - */ - -import java.io.IOException; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.taskdefs.Execute; -import org.apache.tools.ant.taskdefs.LogStreamHandler; -import org.apache.tools.ant.types.CommandlineJava; -import org.apache.tools.ant.types.FileSet; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.types.PatternSet; -import org.apache.tools.ant.util.JavaEnvUtils; - -/** - *

An ANT {@link org.apache.tools.ant.Task} - * for using {@link com.sun.gluegen.opengl.BuildStaticGLInfo}.

- * - *

Usage:

- *
-    <staticglgen package="[generated files package]" 
-                    headers="[file pattern of GL headers]"
-                    outputdir="[directory to output the generated files]" />
- * 
- * - * @author Rob Grzywinski rgrzywinski@yahoo.com - */ -// FIXME: blow out javadoc -public class StaticGLGenTask extends Task -{ - /** - *

The {@link com.sun.gluegen.opengl.BuildStaticGLInfo} classname.

- */ - private static final String GL_GEN = "com.sun.gluegen.opengl.BuildStaticGLInfo"; - - // ========================================================================= - /** - *

The {@link org.apache.tools.ant.types.CommandlineJava} that is used - * to execute {@link com.sun.gluegen.opengl.BuildStaticGLInfo}.

- */ - private CommandlineJava glgenCommandline; - - // ========================================================================= - /** - *

The package name for the generated files.

- */ - private String packageName; - - /** - *

The output directory.

- */ - private String outputDirectory; - - /** - *

The {@link org.apache.tools.ant.types.FileSet} of GL headers.

- */ - private FileSet headerSet = new FileSet(); - - // ========================================================================= - /** - *

Create and add the VM and classname to {@link org.apache.tools.ant.types.CommandlineJava}.

- */ - public StaticGLGenTask() - { - // create the CommandlineJava that will be used to call BuildStaticGLInfo - glgenCommandline = new CommandlineJava(); - - // set the VM and classname in the commandline - glgenCommandline.setVm(JavaEnvUtils.getJreExecutable("java")); - glgenCommandline.setClassname(GL_GEN); - } - - // ========================================================================= - // ANT getters and setters - /** - *

Set the package name for the generated files. This is called by ANT.

- * - * @param packageName the name of the package for the generated files - */ - public void setPackage(String packageName) - { - log( ("Setting package name to: " + packageName), Project.MSG_VERBOSE); - this.packageName = packageName; - } - - /** - *

Set the output directory. This is called by ANT.

- * - * @param directory the output directory - */ - public void setOutputDir(String directory) - { - log( ("Setting output directory to: " + directory), - Project.MSG_VERBOSE); - this.outputDirectory = directory; - } - - /** - *

Add a header file to the list. This is called by ANT for a nested - * element.

- * - * @return {@link org.apache.tools.ant.types.PatternSet.NameEntry} - */ - public PatternSet.NameEntry createHeader() - { - return headerSet.createInclude(); - } - - /** - *

Add a header file to the list. This is called by ANT for a nested - * element.

- * - * @return {@link org.apache.tools.ant.types.PatternSet.NameEntry} - */ - public PatternSet.NameEntry createHeadersFile() - { - return headerSet.createIncludesFile(); - } - - /** - *

Set the set of header patterns. Patterns may be separated by a comma - * or a space. This is called by ANT.

- * - * @param headers the string containing the header patterns - */ - public void setHeaders(String headers) - { - headerSet.setIncludes(headers); - } - - /** - *

Add an optional classpath that defines the location of {@link com.sun.gluegen.opengl.BuildStaticGLInfo} - * and BuildStaticGLInfo's dependencies.

- * - * @returns {@link org.apache.tools.ant.types.Path} - */ - public Path createClasspath() - { - return glgenCommandline.createClasspath(project).createPath(); - } - - // ========================================================================= - /** - *

Run the task. This involves validating the set attributes, creating - * the command line to be executed and finally executing the command.

- * - * @see org.apache.tools.ant.Task#execute() - */ - public void execute() - throws BuildException - { - // validate that all of the required attributes have been set - validateAttributes(); - - // TODO: add logic to determine if the generated file needs to be - // regenerated - - // add the attributes to the CommandlineJava - addAttributes(); - - log(glgenCommandline.describeCommand(), Project.MSG_VERBOSE); - - // execute the command and throw on error - final int error = execute(glgenCommandline.getCommandline()); - if(error == 1) - throw new BuildException( ("BuildStaticGLInfo returned: " + error), location); - } - - /** - *

Ensure that the user specified all required arguments.

- * - * @throws BuildException if there are required arguments that are not - * present or not valid - */ - private void validateAttributes() - throws BuildException - { - // validate that the package name is set - if(!isValid(packageName)) - throw new BuildException("Invalid package name: " + packageName); - - // validate that the output directory is set - // TODO: switch to file and ensure that it exists - if(!isValid(outputDirectory)) - throw new BuildException("Invalid output directory name: " + outputDirectory); - - // TODO: validate that there are headers set - } - - /** - *

Is the specified string valid? A valid string is non-null - * and has a non-zero length.

- * - * @param string the string to be tested for validity - * @return true if the string is valid. false - * otherwise. - */ - private boolean isValid(String string) - { - // check for null - if(string == null) - return false; - - // ensure that the string has a non-zero length - // NOTE: must trim() to remove leading and trailing whitespace - if(string.trim().length() < 1) - return false; - - // the string is valid - return true; - } - - /** - *

Add all of the attributes to the command line. They have already - * been validated.

- */ - private void addAttributes() - { - // add the package name - glgenCommandline.createArgument().setValue(packageName); - - // add the output directory name - glgenCommandline.createArgument().setValue(outputDirectory); - - // add the header -files- from the FileSet - headerSet.setDir(getProject().getBaseDir()); - DirectoryScanner directoryScanner = headerSet.getDirectoryScanner(getProject()); - String[] directoryFiles = directoryScanner.getIncludedFiles(); - for(int i=0; iExecute {@link com.sun.gluegen.opengl.BuildStaticGLInfo} in a - * forked JVM.

- * - * @throws BuildException - */ - private int execute(String[] command) - throws BuildException - { - // create the object that will perform the command execution - Execute execute = new Execute(new LogStreamHandler(this, Project.MSG_INFO, - Project.MSG_WARN), - null); - - // set the project and command line - execute.setAntRun(project); - execute.setCommandline(command); - execute.setWorkingDirectory( project.getBaseDir() ); - - // execute the command - try - { - return execute.execute(); - } catch(IOException ioe) - { - throw new BuildException(ioe, location); - } - } -} diff --git a/src/java/com/sun/gluegen/nativesig/NativeSignatureEmitter.java b/src/java/com/sun/gluegen/nativesig/NativeSignatureEmitter.java deleted file mode 100755 index f20495b65..000000000 --- a/src/java/com/sun/gluegen/nativesig/NativeSignatureEmitter.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ -package com.sun.gluegen.nativesig; - -import java.io.*; -import java.util.*; - -import com.sun.gluegen.*; -import com.sun.gluegen.cgram.types.*; -import com.sun.gluegen.opengl.*; -import com.sun.gluegen.procaddress.*; - -/** - * Emitter producing NativeSignature attributes. - */ -public class NativeSignatureEmitter extends GLEmitter { - - @Override - protected List generateMethodBindingEmitters(Set methodBindingSet, FunctionSymbol sym) throws Exception { - - // Allow superclass to do most of the work for us - List res = super.generateMethodBindingEmitters(methodBindingSet, sym); - - // Filter out all non-JavaMethodBindingEmitters - for (Iterator iter = res.iterator(); iter.hasNext();) { - FunctionEmitter emitter = iter.next(); - if (!(emitter instanceof JavaMethodBindingEmitter)) { - iter.remove(); - } - } - - if (res.isEmpty()) { - return res; - } - - PrintWriter writer = (getConfig().allStatic() ? javaWriter() : javaImplWriter()); - - List processed = new ArrayList(); - - // First, filter out all emitters going to the "other" (public) writer - for (Iterator iter = res.iterator(); iter.hasNext();) { - FunctionEmitter emitter = iter.next(); - if (emitter.getDefaultOutput() != writer) { - processed.add(emitter); - iter.remove(); - } - } - - // Now process all of the remaining emitters sorted by MethodBinding - while (!res.isEmpty()) { - List emittersForBinding = new ArrayList(); - JavaMethodBindingEmitter emitter = (JavaMethodBindingEmitter) res.remove(0); - emittersForBinding.add(emitter); - MethodBinding binding = emitter.getBinding(); - for (Iterator iter = res.iterator(); iter.hasNext();) { - JavaMethodBindingEmitter emitter2 = (JavaMethodBindingEmitter) iter.next(); - if (emitter2.getBinding() == binding) { - emittersForBinding.add(emitter2); - iter.remove(); - } - } - generateNativeSignatureEmitters(binding, emittersForBinding); - processed.addAll(emittersForBinding); - } - - return processed; - } - - protected void generateNativeSignatureEmitters(MethodBinding binding, List allEmitters) { - - if (allEmitters.isEmpty()) { - return; - } - - PrintWriter writer = (getConfig().allStatic() ? javaWriter() : javaImplWriter()); - - // Give ourselves the chance to interpose on the generation of all code to keep things simple - List newEmitters = new ArrayList(); - for (JavaMethodBindingEmitter javaEmitter : allEmitters) { - NativeSignatureJavaMethodBindingEmitter newEmitter = null; - if (javaEmitter instanceof GLJavaMethodBindingEmitter) { - newEmitter = new NativeSignatureJavaMethodBindingEmitter((GLJavaMethodBindingEmitter) javaEmitter); - } else if (javaEmitter instanceof ProcAddressJavaMethodBindingEmitter) { - newEmitter = new NativeSignatureJavaMethodBindingEmitter((ProcAddressJavaMethodBindingEmitter) javaEmitter); - } else { - newEmitter = new NativeSignatureJavaMethodBindingEmitter(javaEmitter, this); - } - newEmitters.add(newEmitter); - } - allEmitters.clear(); - allEmitters.addAll(newEmitters); - - // Detect whether we need to produce more or modify some of these emitters. - // Note that at this point we are assuming that generatePublicEmitters has - // been called with signatureOnly both true and false. - if (signatureContainsStrings(binding) && !haveEmitterWithBody(allEmitters)) { - // This basically handles glGetString but also any similar methods - NativeSignatureJavaMethodBindingEmitter javaEmitter = findEmitterWithWriter(allEmitters, writer); - - // First, we need to clone this emitter to produce the native - // entry point - NativeSignatureJavaMethodBindingEmitter emitter = new NativeSignatureJavaMethodBindingEmitter(javaEmitter); - emitter.removeModifier(JavaMethodBindingEmitter.PUBLIC); - emitter.addModifier(JavaMethodBindingEmitter.PRIVATE); - emitter.setForImplementingMethodCall(true); - // Note: this is chosen so we don't have to change the logic in - // emitReturnVariableSetupAndCall which decides which variant - // (direct / indirect) to call - emitter.setForDirectBufferImplementation(true); - allEmitters.add(emitter); - - // Now make the original emitter non-native and cause it to emit a body - javaEmitter.removeModifier(JavaMethodBindingEmitter.NATIVE); - javaEmitter.setEmitBody(true); - } - } - - protected boolean signatureContainsStrings(MethodBinding binding) { - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType type = binding.getJavaArgumentType(i); - if (type.isString() || type.isStringArray()) { - return true; - } - } - JavaType retType = binding.getJavaReturnType(); - if (retType.isString() || retType.isStringArray()) { - return true; - } - return false; - } - - protected boolean haveEmitterWithBody(List allEmitters) { - for (JavaMethodBindingEmitter emitter : allEmitters) { - if (!emitter.signatureOnly()) { - return true; - } - } - return false; - } - - protected NativeSignatureJavaMethodBindingEmitter findEmitterWithWriter(List allEmitters, PrintWriter writer) { - for (JavaMethodBindingEmitter jemitter : allEmitters) { - NativeSignatureJavaMethodBindingEmitter emitter = (NativeSignatureJavaMethodBindingEmitter)jemitter; - if (emitter.getDefaultOutput() == writer) { - return emitter; - } - } - throw new RuntimeException("Unexpectedly failed to find an emitter with the given writer"); - } -} diff --git a/src/java/com/sun/gluegen/nativesig/NativeSignatureJavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/nativesig/NativeSignatureJavaMethodBindingEmitter.java deleted file mode 100755 index 379eccf1f..000000000 --- a/src/java/com/sun/gluegen/nativesig/NativeSignatureJavaMethodBindingEmitter.java +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -package com.sun.gluegen.nativesig; - -import java.io.*; - -import com.sun.gluegen.*; -import com.sun.gluegen.cgram.types.*; -import com.sun.gluegen.opengl.*; -import com.sun.gluegen.procaddress.*; - -public class NativeSignatureJavaMethodBindingEmitter extends GLJavaMethodBindingEmitter { - - public NativeSignatureJavaMethodBindingEmitter(GLJavaMethodBindingEmitter methodToWrap) { - super(methodToWrap); - } - - public NativeSignatureJavaMethodBindingEmitter(ProcAddressJavaMethodBindingEmitter methodToWrap) { - super(methodToWrap, false); - } - - public NativeSignatureJavaMethodBindingEmitter(JavaMethodBindingEmitter methodToWrap, NativeSignatureEmitter emitter) { - super(methodToWrap, false, null, false, false, emitter); - } - - @Override - protected void emitSignature(PrintWriter writer) { - writer.print(getBaseIndentString()); - emitNativeSignatureAnnotation(writer); - super.emitSignature(writer); - } - - protected void emitNativeSignatureAnnotation(PrintWriter writer) { - if (hasModifier(JavaMethodBindingEmitter.NATIVE)) { - // Emit everything as a leaf for now - // FIXME: make this configurable - writer.print("@NativeSignature(\"l"); - MethodBinding binding = getBinding(); - if (callThroughProcAddress) { - writer.print("p"); - } - writer.print("("); - if (callThroughProcAddress) { - writer.print("P"); - } - for (int i = 0; i < binding.getNumArguments(); i++) { - emitNativeSignatureElement(writer, binding.getJavaArgumentType(i), binding.getCArgumentType(i), i); - } - writer.print(")"); - emitNativeSignatureElement(writer, binding.getJavaReturnType(), binding.getCReturnType(), -1); - writer.println("\")"); - } - } - - protected void emitNativeSignatureElement(PrintWriter writer, JavaType type, Type cType, int index) { - if (type.isVoid()) { - if (index > 0) { - throw new InternalError("Error parsing arguments -- void should not be seen aside from argument 0"); - } - return; - } - - if (type.isNIOBuffer()) { - writer.print("A"); - } else if (type.isPrimitiveArray()) { - writer.print("MO"); - } else if (type.isPrimitive()) { - Class clazz = type.getJavaClass(); - if (clazz == Byte.TYPE) { writer.print("B"); } - else if (clazz == Character.TYPE) { writer.print("C"); } - else if (clazz == Double.TYPE) { writer.print("D"); } - else if (clazz == Float.TYPE) { writer.print("F"); } - else if (clazz == Integer.TYPE) { writer.print("I"); } - else if (clazz == Long.TYPE) { - // See if this is intended to be a pointer at the C level - if (cType.isPointer()) { - writer.print("A"); - } else { - writer.print("J"); - } - } - else if (clazz == Short.TYPE) { writer.print("S"); } - else if (clazz == Boolean.TYPE) { writer.print("Z"); } - else throw new InternalError("Unhandled primitive type " + clazz); - } else if (type.isString()) { - writer.print("A"); - } else { - throw new RuntimeException("Type not yet handled: " + type); - } - } - - protected String getReturnTypeString(boolean skipArray) { - if (isForImplementingMethodCall()) { - JavaType returnType = getBinding().getJavaReturnType(); - if (returnType.isString() || returnType.isNIOByteBuffer()) { - // Treat these as addresses - return "long"; - } - } - return super.getReturnTypeString(skipArray); - } - - protected void emitPreCallSetup(MethodBinding binding, PrintWriter writer) { - super.emitPreCallSetup(binding, writer); - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType type = binding.getJavaArgumentType(i); - if (type.isNIOBuffer() && !directNIOOnly) { - // Emit declarations for variables holding primitive arrays as type Object - // We don't know 100% sure we're going to use these at this point in the code, though - writer.println(" Object " + getNIOBufferArrayName(i) + " = (_direct ? null : Buffers.getArray(" + - getArgumentName(i) + "));"); - } else if (type.isString()) { - writer.println(" long " + binding.getArgumentName(i) + "_c_str = BuffersInternal.newCString(" + binding.getArgumentName(i) + ");"); - } - // FIXME: going to need more of these for Buffer[] and String[], at least - } - } - - protected String getNIOBufferArrayName(int argNumber) { - return "__buffer_array_" + argNumber; - } - - protected int emitArguments(PrintWriter writer) - { - boolean needComma = false; - int numEmitted = 0; - - if (callThroughProcAddress) { - if (changeNameAndArguments) { - writer.print("long procAddress"); - ++numEmitted; - needComma = true; - } - } - - if (forImplementingMethodCall && binding.hasContainingType()) { - if (needComma) { - writer.print(", "); - } - - // Always emit outgoing "this" argument - writer.print("long "); - writer.print(javaThisArgumentName()); - ++numEmitted; - needComma = true; - } - - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType type = binding.getJavaArgumentType(i); - if (type.isVoid()) { - // Make sure this is the only param to the method; if it isn't, - // there's something wrong with our parsing of the headers. - if (binding.getNumArguments() != 1) { - throw new InternalError( - "\"void\" argument type found in " + - "multi-argument function \"" + binding + "\""); - } - continue; - } - - if (type.isJNIEnv() || binding.isArgumentThisPointer(i)) { - // Don't need to expose these at the Java level - continue; - } - - if (needComma) { - writer.print(", "); - } - - if (forImplementingMethodCall && - (forDirectBufferImplementation && type.isNIOBuffer() || - type.isString())) { - // Direct Buffers and Strings go out as longs - writer.print("long"); - // FIXME: will need more tests here to handle other constructs like String and direct Buffer arrays - } else { - writer.print(erasedTypeString(type, false)); - } - writer.print(" "); - writer.print(getArgumentName(i)); - - ++numEmitted; - needComma = true; - - // Add Buffer and array index offset arguments after each associated argument - if (forIndirectBufferAndArrayImplementation) { - if (type.isNIOBuffer()) { - writer.print(", int " + byteOffsetArgName(i)); - } else if (type.isNIOBufferArray()) { - writer.print(", int[] " + - byteOffsetArrayArgName(i)); - } - } - - // Add offset argument after each primitive array - if (type.isPrimitiveArray()) { - writer.print(", int " + offsetArgName(i)); - } - } - return numEmitted; - } - - protected void emitReturnVariableSetupAndCall(MethodBinding binding, PrintWriter writer) { - writer.print(" "); - JavaType returnType = binding.getJavaReturnType(); - boolean needsResultAssignment = false; - - if (!returnType.isVoid()) { - if (returnType.isCompoundTypeWrapper() || - returnType.isNIOByteBuffer()) { - writer.println("java.nio.ByteBuffer _res;"); - needsResultAssignment = true; - } else if (returnType.isArrayOfCompoundTypeWrappers()) { - writer.println("java.nio.ByteBuffer[] _res;"); - needsResultAssignment = true; - } else if (returnType.isString() || returnType.isNIOByteBuffer()) { - writer.print(returnType); - writer.println(" _res;"); - needsResultAssignment = true; - } else { - // Always assign to "_res" variable so we can clean up - // outgoing String arguments, for example - emitReturnType(writer); - writer.println(" _res;"); - needsResultAssignment = true; - } - } - - if (binding.signatureCanUseIndirectNIO() && !directNIOOnly) { - // Must generate two calls for this gated on whether the NIO - // buffers coming in are all direct or indirect - writer.println("if (_direct) {"); - writer.print (" "); - } - - if (needsResultAssignment) { - writer.print(" _res = "); - if (returnType.isString()) { - writer.print("BuffersInternal.newJavaString("); - } else if (returnType.isNIOByteBuffer()) { - writer.print("BuffersInternal.newDirectByteBuffer("); - } - } else { - writer.print(" "); - if (!returnType.isVoid()) { - writer.print("return "); - } - } - - if (binding.signatureUsesJavaPrimitiveArrays() && - !binding.signatureCanUseIndirectNIO()) { - // FIXME: what happens with a C function of the form - // void foo(int* arg0, void* arg1); - // ? - - // Only one call being made in this body, going to indirect - // buffer / array entry point - emitCall(binding, writer, false); - if (returnType.isString() || returnType.isNIOByteBuffer()) { - writer.print(")"); - } - writer.print(";"); - writer.println(); - } else { - emitCall(binding, writer, true); - if (returnType.isString() || returnType.isNIOByteBuffer()) { - writer.print(")"); - } - writer.print(";"); - } - - if (binding.signatureCanUseIndirectNIO() && !directNIOOnly) { - // Must generate two calls for this gated on whether the NIO - // buffers coming in are all direct or indirect - writer.println(); - writer.println(" } else {"); - writer.print (" "); - if (needsResultAssignment) { - writer.print(" _res = "); - } else { - writer.print(" "); - if (!returnType.isVoid()) { - writer.print("return "); - } - } - emitCall(binding, writer, false); - writer.print(";"); - writer.println(); - writer.println(" }"); - } else { - writer.println(); - } - emitPrologueOrEpilogue(epilogue, writer); - if (needsResultAssignment) { - emitCallResultReturn(binding, writer); - } - } - - protected int emitCallArguments(MethodBinding binding, PrintWriter writer, boolean direct) { - // Note that we override this completely because we both need to - // move the potential location of the outgoing proc address as - // well as change the way we pass out Buffers, arrays, Strings, etc. - - boolean needComma = false; - int numArgsEmitted = 0; - - if (callThroughProcAddress) { - writer.print("__addr_"); - needComma = true; - ++numArgsEmitted; - } - - if (binding.hasContainingType()) { - // Emit this pointer - assert(binding.getContainingType().isCompoundTypeWrapper()); - writer.print("BuffersInternal.getDirectBufferAddress("); - writer.print("getBuffer()"); - writer.print(")"); - needComma = true; - ++numArgsEmitted; - } - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType type = binding.getJavaArgumentType(i); - if (type.isJNIEnv() || binding.isArgumentThisPointer(i)) { - // Don't need to expose these at the Java level - continue; - } - - if (type.isVoid()) { - // Make sure this is the only param to the method; if it isn't, - // there's something wrong with our parsing of the headers. - assert(binding.getNumArguments() == 1); - continue; - } - - if (needComma) { - writer.print(", "); - } - - if (type.isCompoundTypeWrapper()) { - writer.print("BuffersInternal.getDirectBufferAddress("); - writer.print("(("); - } - - if (type.isNIOBuffer()) { - if (!direct) { - writer.print(getNIOBufferArrayName(i)); - } else { - writer.print("BuffersInternal.getDirectBufferAddress("); - writer.print(getArgumentName(i)); - writer.print(")"); - } - } else { - writer.print(getArgumentName(i)); - } - - if (type.isCompoundTypeWrapper()) { - writer.print(" == null) ? null : "); - writer.print(getArgumentName(i)); - writer.print(".getBuffer())"); - writer.print(")"); - } - - if (type.isNIOBuffer()) { - if (direct) { - writer.print("+ Buffers.getDirectBufferByteOffset(" + getArgumentName(i) + ")"); - } else { - writer.print(", BuffersInternal.arrayBaseOffset(" + - getNIOBufferArrayName(i) + - ") + Buffers.getIndirectBufferByteOffset(" + getArgumentName(i) + ")"); - } - } else if (type.isNIOBufferArray()) { - writer.print(", " + byteOffsetArrayArgName(i)); - } - - // Add Array offset parameter for primitive arrays - if (type.isPrimitiveArray()) { - writer.print(", "); - writer.print("BuffersInternal.arrayBaseOffset(" + getArgumentName(i) + ") + "); - if(type.isFloatArray()) { - writer.print("Buffers.SIZEOF_FLOAT * "); - } else if(type.isDoubleArray()) { - writer.print("Buffers.SIZEOF_DOUBLE * "); - } else if(type.isByteArray()) { - writer.print("1 * "); - } else if(type.isLongArray()) { - writer.print("Buffers.SIZEOF_LONG * "); - } else if(type.isShortArray()) { - writer.print("Buffers.SIZEOF_SHORT * "); - } else if(type.isIntArray()) { - writer.print("Buffers.SIZEOF_INT * "); - } else { - throw new RuntimeException("Unsupported type for calculating array offset argument for " + - getArgumentName(i) + - "-- error occurred while processing Java glue code for " + getName()); - } - writer.print(offsetArgName(i)); - } - - if (type.isString()) { - writer.print("_c_str"); - } - - if (type.isCompoundTypeWrapper()) { - writer.print(")"); - } - - needComma = true; - ++numArgsEmitted; - } - return numArgsEmitted; - } - - protected void emitCallResultReturn(MethodBinding binding, PrintWriter writer) { - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType type = binding.getJavaArgumentType(i); - if (type.isString()) { - writer.println(";"); - writer.println(" BuffersInternal.freeCString(" + binding.getArgumentName(i) + "_c_str);"); - } - // FIXME: will need more of these cleanups for things like Buffer[] and String[] (see above) - } - - super.emitCallResultReturn(binding, writer); - } - - public String getName() { - String res = super.getName(); - if (forImplementingMethodCall && bufferObjectVariant) { - return res + "BufObj"; - } - return res; - } - - protected String getImplMethodName(boolean direct) { - String name = null; - if (direct) { - name = binding.getName() + "$0"; - } else { - name = binding.getName() + "$1"; - } - if (bufferObjectVariant) { - return name + "BufObj"; - } - return name; - } -} -- cgit v1.2.3