diff options
author | Sven Gothel <[email protected]> | 2010-11-06 23:37:00 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-11-06 23:37:00 +0100 |
commit | f1d31c8f4435b84e4adf19ed11b175365e943a34 (patch) | |
tree | 35889d32bb7a3de8e5c44755433cb2753d540284 /src/java/com/jogamp/gluegen/nativesig/NativeSignatureEmitter.java | |
parent | 09626a68ebdd093d732adf66d74fa446e7427e79 (diff) | |
parent | 40495c4e04ab8b15e17ec6bdc6b6c35f4144c34e (diff) |
Relocation: GlueGen GL Parts to Jogl
Diffstat (limited to 'src/java/com/jogamp/gluegen/nativesig/NativeSignatureEmitter.java')
-rwxr-xr-x | src/java/com/jogamp/gluegen/nativesig/NativeSignatureEmitter.java | 190 |
1 files changed, 190 insertions, 0 deletions
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<? extends FunctionEmitter> generateMethodBindingEmitters(Set<MethodBinding> methodBindingSet, FunctionSymbol sym) throws Exception { + + // Allow superclass to do most of the work for us + List<? extends FunctionEmitter> res = super.generateMethodBindingEmitters(methodBindingSet, sym); + + // Filter out all non-JavaMethodBindingEmitters + for (Iterator<? extends FunctionEmitter> 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<FunctionEmitter> processed = new ArrayList<FunctionEmitter>(); + + // First, filter out all emitters going to the "other" (public) writer + for (Iterator<? extends FunctionEmitter> 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<JavaMethodBindingEmitter> emittersForBinding = new ArrayList<JavaMethodBindingEmitter>(); + JavaMethodBindingEmitter emitter = (JavaMethodBindingEmitter) res.remove(0); + emittersForBinding.add(emitter); + MethodBinding binding = emitter.getBinding(); + for (Iterator<? extends FunctionEmitter> 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<JavaMethodBindingEmitter> 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<JavaMethodBindingEmitter> newEmitters = new ArrayList<JavaMethodBindingEmitter>(); + 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<JavaMethodBindingEmitter> allEmitters) { + for (JavaMethodBindingEmitter emitter : allEmitters) { + if (!emitter.signatureOnly()) { + return true; + } + } + return false; + } + + protected NativeSignatureJavaMethodBindingEmitter findEmitterWithWriter(List<JavaMethodBindingEmitter> 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"); + } +} |