diff options
author | Sven Gothel <[email protected]> | 2015-03-11 08:42:26 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-03-11 08:42:26 +0100 |
commit | f664f7e950ff60d73e488801cf7f37878588203d (patch) | |
tree | 1519877aea5e702b9218df8c04f47492364ee35f | |
parent | c3b2a86bb9051d6f03c3f104eff2dbe6cefc1803 (diff) |
Bug 1144 - Add 'DelegateImplementation': Cleanup MethodBinding/FunctionBinding Semantics
- Clarify name semantics: name -> [interfaceName, implName, nativeName]
- JavaMethodBindingEmitter: Refine native identity via isNativeMethod + isPrivateNativeMethod
- ProcAddressEmitter: Remove hack whether we need to wrap .. use isNativeMethod + isPrivateNativeMethod
10 files changed, 199 insertions, 120 deletions
diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh index 7aa8ab8..5d19e7f 100755 --- a/make/scripts/runtest.sh +++ b/make/scripts/runtest.sh @@ -125,12 +125,12 @@ function onetest() { #onetest com.jogamp.common.nio.TestStructAccessorEndian 2>&1 | tee -a $LOG #onetest com.jogamp.common.nio.TestByteBufferInputStream 2>&1 | tee -a $LOG #onetest com.jogamp.common.nio.TestByteBufferOutputStream 2>&1 | tee -a $LOG -onetest com.jogamp.common.nio.TestByteBufferCopyStream 2>&1 | tee -a $LOG +#onetest com.jogamp.common.nio.TestByteBufferCopyStream 2>&1 | tee -a $LOG #onetest com.jogamp.common.os.TestElfReader01 $* 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.internals.TestType 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.PCPPTest 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG -#onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG +onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p2LoadJNIAndImplLib 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen01 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen02 2>&1 | tee -a $LOG diff --git a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java index 1987668..bb95226 100644 --- a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java @@ -150,8 +150,16 @@ public class CMethodBindingEmitter extends FunctionEmitter { public final MethodBinding getBinding() { return binding; } @Override - public String getName() { - return binding.getName(); + public String getInterfaceName() { + return binding.getInterfaceName(); + } + @Override + public String getImplName() { + return binding.getImplName(); + } + @Override + public String getNativeName() { + return binding.getNativeName(); } @Override @@ -313,12 +321,8 @@ public class CMethodBindingEmitter extends FunctionEmitter { writer.print("_"); if (isOverloadedBinding) { writer.print(jniMangle(binding)); - //System.err.println("OVERLOADED MANGLING FOR " + getName() + - // " = " + jniMangle(binding)); } else { - writer.print(JavaEmitter.jniMangle(getName())); - //System.err.println(" NORMAL MANGLING FOR " + binding.getName() + - // " = " + jniMangle(getName())); + writer.print(JavaEmitter.jniMangle(getImplName())); } } @@ -990,7 +994,7 @@ public class CMethodBindingEmitter extends FunctionEmitter { // Call through function pointer writer.print(CMethodBindingEmitter.cThisArgumentName() + "->"); } - writer.print(binding.getCSymbol().getOrigName()); // use original API name + writer.print(getNativeName()); writer.print("("); emitBodyPassCArguments(writer); writer.println(");"); @@ -1166,7 +1170,7 @@ public class CMethodBindingEmitter extends FunctionEmitter { protected String jniMangle(final MethodBinding binding) { final StringBuilder buf = new StringBuilder(); - buf.append(JavaEmitter.jniMangle(getName())); + buf.append(JavaEmitter.jniMangle(getImplName())); buf.append(getImplSuffix()); buf.append("__"); if (binding.hasContainingType()) { @@ -1277,7 +1281,7 @@ public class CMethodBindingEmitter extends FunctionEmitter { writer.println(" (*env)->ThrowNew(env, (*env)->FindClass(env, \"java/lang/OutOfMemoryError\"),"); writer.print(" \"" + errorMessage); writer.print(" in native dispatcher for \\\""); - writer.print(getName()); + writer.print(getInterfaceName()); writer.println("\\\"\");"); writer.print(" return"); if (!binding.getJavaReturnType().isVoid()) { diff --git a/src/java/com/jogamp/gluegen/FunctionEmitter.java b/src/java/com/jogamp/gluegen/FunctionEmitter.java index 2009c9f..bfbb73b 100644 --- a/src/java/com/jogamp/gluegen/FunctionEmitter.java +++ b/src/java/com/jogamp/gluegen/FunctionEmitter.java @@ -49,7 +49,7 @@ public abstract class FunctionEmitter { public static final EmissionModifier STATIC = new EmissionModifier("static"); - private final boolean isInterfaceVal; + private final boolean isInterface; private final ArrayList<EmissionModifier> modifiers; private CommentEmitter commentEmitter = null; private final PrintWriter defaultOutput; @@ -61,7 +61,7 @@ public abstract class FunctionEmitter { */ public FunctionEmitter(final PrintWriter defaultOutput, final boolean isInterface, final JavaConfiguration configuration) { assert(defaultOutput != null); - this.isInterfaceVal = isInterface; + this.isInterface = isInterface; this.modifiers = new ArrayList<EmissionModifier>(); this.defaultOutput = defaultOutput; this.cfg = configuration; @@ -71,14 +71,14 @@ public abstract class FunctionEmitter { * Makes this FunctionEmitter a copy of the passed one. */ public FunctionEmitter(final FunctionEmitter arg) { - isInterfaceVal = arg.isInterfaceVal; + isInterface = arg.isInterface; modifiers = new ArrayList<EmissionModifier>(arg.modifiers); commentEmitter = arg.commentEmitter; defaultOutput = arg.defaultOutput; cfg = arg.cfg; } - public boolean isInterface() { return isInterfaceVal; } + public boolean isInterface() { return isInterface; } public PrintWriter getDefaultOutput() { return defaultOutput; } @@ -97,7 +97,9 @@ public abstract class FunctionEmitter { public Iterator<EmissionModifier> getModifiers() { return modifiers.iterator(); } - public abstract String getName(); + public abstract String getInterfaceName(); + public abstract String getImplName(); + public abstract String getNativeName(); public abstract FunctionSymbol getCSymbol(); diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java index 32fb5cd..969eaaf 100644 --- a/src/java/com/jogamp/gluegen/JavaConfiguration.java +++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java @@ -347,7 +347,7 @@ public class JavaConfiguration { } // Default access control is public return PUBLIC; - } + } /** Returns the package in which the generated glue code expects to find its run-time helper classes (Buffers, Platform, @@ -510,6 +510,14 @@ public class JavaConfiguration { public boolean returnsString(final String functionName) { return returnsString.contains(functionName); } + /** Indicates whether the given function (which returns a + <code>char*</code> in C) should be translated as returning a + <code>java.lang.String</code>. */ + public boolean returnsString(final AliasedSymbol symbol) { + return returnsString.contains( symbol.getName() ) || + oneInSet(returnsString, symbol.getAliasedNames()); + } + /** * Returns a MessageFormat string of the Java expression calculating @@ -1011,6 +1019,7 @@ public class JavaConfiguration { return false; } + /** * Return a set of aliased-name for comment in docs. * <p> diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java index c8a2da8..fa4ecab 100644 --- a/src/java/com/jogamp/gluegen/JavaEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaEmitter.java @@ -98,8 +98,10 @@ public class JavaEmitter implements GlueEmitter { private final String javaName; } - private PrintWriter javaWriter; // Emits either interface or, in AllStatic mode, everything + private String javaFileName; // of javaWriter or javaImplWriter + private PrintWriter javaWriter; // Emits either interface or, in AllStatic mode, everything private PrintWriter javaImplWriter; // Only used in non-AllStatic modes for impl class + private String cFileName; // of cWriter private PrintWriter cWriter; private final MachineDataInfo machDescJava = MachineDataInfo.StaticConfig.LP64_UNIX.md; private final MachineDataInfo.StaticConfig[] machDescTargetConfigs = MachineDataInfo.StaticConfig.values(); @@ -508,8 +510,9 @@ public class JavaEmitter implements GlueEmitter { LOG.log(INFO, cFunc.getASTLocusTag(), "Non-Ignored Intf[{0}]: {1}", i++, cFunc.getAliasedString()); } } catch (final Exception e) { - throw new RuntimeException( - "Error while emitting binding for \"" + emitter.getName() + "\"", e); + throw new GlueGenException( + "Error while emitting binding for \"" + emitter.getCSymbol().getAliasedString() + "\"", + emitter.getCSymbol().getASTLocusTag(), e); } } } @@ -571,8 +574,6 @@ public class JavaEmitter implements GlueEmitter { return; } - final PrintWriter writer = ((signatureOnly || cfg.allStatic()) ? javaWriter() : javaImplWriter()); - // It's possible we may not need a body even if signatureOnly is // set to false; for example, if the routine doesn't take any // arrays or buffers as arguments @@ -593,6 +594,10 @@ public class JavaEmitter implements GlueEmitter { } final boolean emitBody = !signatureOnly && needsBody; + final boolean isNativeMethod = !isUnimplemented && !needsBody && !signatureOnly; + + final PrintWriter writer = ((signatureOnly || cfg.allStatic()) ? javaWriter() : javaImplWriter()); + final JavaMethodBindingEmitter emitter = new JavaMethodBindingEmitter(binding, writer, @@ -607,7 +612,8 @@ public class JavaEmitter implements GlueEmitter { false, // forIndirectBufferAndArrayImplementation isUnimplemented, // isUnimplemented signatureOnly, // isInterface - false, // isNativeMethod + isNativeMethod, // isNativeMethod + false, // isPrivateNativeMethod cfg); switch (accessControl) { case PUBLIC: emitter.addModifier(JavaMethodBindingEmitter.PUBLIC); break; @@ -618,7 +624,7 @@ public class JavaEmitter implements GlueEmitter { if (cfg.allStatic()) { emitter.addModifier(FunctionEmitter.STATIC); } - if (!isUnimplemented && !needsBody && !signatureOnly) { + if (isNativeMethod) { emitter.addModifier(JavaMethodBindingEmitter.NATIVE); } emitter.setReturnedArrayLengthExpression(cfg.returnedArrayLength(binding.getName())); @@ -685,6 +691,7 @@ public class JavaEmitter implements GlueEmitter { false, // isUnimplemented false, // isInterface true, // isNativeMethod + true, // isPrivateNativeMethod cfg); emitter.addModifier(JavaMethodBindingEmitter.PRIVATE); if (cfg.allStatic()) { @@ -760,7 +767,7 @@ public class JavaEmitter implements GlueEmitter { try { // Get Java binding for the function - final MethodBinding mb = bindFunction(sym, null, null, machDescJava); + final MethodBinding mb = bindFunction(sym, machDescJava, null, null); // JavaTypes representing C pointers in the initial // MethodBinding have not been lowered yet to concrete types @@ -1401,7 +1408,7 @@ public class JavaEmitter implements GlueEmitter { final Type containingCType, final JavaType containingJType, final int i, final FunctionSymbol funcSym, final String returnSizeLookupName) { // Emit method call and associated native code - final MethodBinding mb = bindFunction(funcSym, containingJType, containingCType, machDescJava); + final MethodBinding mb = bindFunction(funcSym, machDescJava, containingJType, containingCType); mb.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis // JavaTypes representing C pointers in the initial @@ -1433,6 +1440,7 @@ public class JavaEmitter implements GlueEmitter { false, // isUnimplemented false, // isInterface false, // isNativeMethod + false, // isPrivateNativeMethod cfg); emitter.addModifier(JavaMethodBindingEmitter.PUBLIC); emitter.emit(); @@ -1452,8 +1460,8 @@ public class JavaEmitter implements GlueEmitter { false, // forIndirectBufferAndArrayImplementation false, // isUnimplemented false, // isInterface - true, // isNativeMethod - cfg); + false, // isNativeMethod + true, cfg); emitter.addModifier(JavaMethodBindingEmitter.PRIVATE); emitter.addModifier(JavaMethodBindingEmitter.NATIVE); emitter.emit(); @@ -1482,7 +1490,7 @@ public class JavaEmitter implements GlueEmitter { final int i, final FunctionSymbol funcSym, final String returnSizeLookupName, final String docArrayLenExpr, final String nativeArrayLenExpr) { // Emit method call and associated native code - final MethodBinding mb = bindFunction(funcSym, containingJType, containingCType, machDescJava); + final MethodBinding mb = bindFunction(funcSym, machDescJava, containingJType, containingCType); mb.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis // JavaTypes representing C pointers in the initial @@ -1515,6 +1523,7 @@ public class JavaEmitter implements GlueEmitter { false, // isUnimplemented true, // isInterface true, // isNativeMethod + true, // isPrivateNativeMethod cfg); if( null != docArrayLenExpr ) { emitter.setReturnedArrayLengthExpression(docArrayLenExpr, true); @@ -2367,13 +2376,16 @@ public class JavaEmitter implements GlueEmitter { } if (cfg.allStatic() || cfg.emitInterface()) { - javaWriter = openFile(jRoot + File.separator + cfg.className() + ".java", cfg.className()); + javaFileName = jRoot + File.separator + cfg.className() + ".java"; + javaWriter = openFile(javaFileName, cfg.className()); } if (!cfg.allStatic() && cfg.emitImpl()) { - javaImplWriter = openFile(jImplRoot + File.separator + cfg.implClassName() + ".java", cfg.implClassName()); + javaFileName = jImplRoot + File.separator + cfg.implClassName() + ".java"; + javaImplWriter = openFile(javaFileName, cfg.implClassName()); } if (cfg.emitImpl()) { - cWriter = openFile(nRoot + File.separator + cfg.implClassName() + "_JNI.c", cfg.implClassName()); + cFileName = nRoot + File.separator + cfg.implClassName() + "_JNI.c"; + cWriter = openFile(cFileName, cfg.implClassName()); } if (javaWriter != null) { @@ -2387,6 +2399,9 @@ public class JavaEmitter implements GlueEmitter { } } + /** For {@link #javaWriter} or {@link #javaImplWriter} */ + protected String javaFileName() { return javaFileName; } + protected PrintWriter javaWriter() { if (!cfg.allStatic() && !cfg.emitInterface()) { throw new InternalError("Should not call this"); @@ -2401,6 +2416,9 @@ public class JavaEmitter implements GlueEmitter { return javaImplWriter; } + /** For {@link #cImplWriter} */ + protected String cFileName() { return cFileName; } + protected PrintWriter cWriter() { if (!cfg.emitImpl()) { throw new InternalError("Should not call this"); @@ -2719,14 +2737,15 @@ public class JavaEmitter implements GlueEmitter { and must be lowered to concrete Java types before creating emitters for them. */ private MethodBinding bindFunction(final FunctionSymbol sym, + final MachineDataInfo curMachDesc, final JavaType containingType, - final Type containingCType, - final MachineDataInfo curMachDesc) { + final Type containingCType) { - final MethodBinding binding = new MethodBinding(sym, containingType, containingCType); // System.out.println("bindFunction(0) "+sym.getReturnType()); + final String name = sym.getName(); + final JavaType javaReturnType; - if (cfg.returnsString(binding.getName())) { + if (cfg.returnsString(sym)) { final PointerType prt = sym.getReturnType().asPointer(); if (prt == null || prt.getTargetType().asInt() == null || @@ -2736,16 +2755,15 @@ public class JavaEmitter implements GlueEmitter { "\". ReturnsString requires native method to have return type \"char *\"", sym.getASTLocusTag()); } - binding.setJavaReturnType(javaType(java.lang.String.class)); + javaReturnType = javaType(java.lang.String.class); } else { - binding.setJavaReturnType(typeToJavaType(sym.getReturnType(), curMachDesc)); + javaReturnType = typeToJavaType(sym.getReturnType(), curMachDesc); } - // System.out.println("bindFunction(1) "+binding.getJavaReturnType()); - // List of the indices of the arguments in this function that should be // converted from byte[] or short[] to String - final List<Integer> stringArgIndices = cfg.stringArguments(binding.getName()); + final List<JavaType> javaArgumentTypes = new ArrayList<JavaType>(); + final List<Integer> stringArgIndices = cfg.stringArguments(name); for (int i = 0; i < sym.getNumArguments(); i++) { final Type cArgType = sym.getArgumentType(i); @@ -2780,14 +2798,15 @@ public class JavaEmitter implements GlueEmitter { sym.getASTLocusTag()); } } - binding.addJavaArgumentType(mappedType); + javaArgumentTypes.add(mappedType); //System.out.println("During binding of [" + sym + "], added mapping from C type: " + cArgType + " to Java type: " + mappedType); } - - // System.out.println("---> " + binding); - // System.out.println(" ---> " + binding.getCSymbol()); - // System.out.println("bindFunction(3) "+binding); - return binding; + final MethodBinding mb = new MethodBinding(sym, delegationImplName, + final MethodBinding mb = new MethodBinding(sym, + javaReturnType, javaArgumentTypes, + containingType, containingCType); + mangleBinding(mb); + return mb; } private MethodBinding lowerMethodBindingPointerTypes(final MethodBinding inputBinding, @@ -2885,6 +2904,14 @@ public class JavaEmitter implements GlueEmitter { return result; } + /** + * Allow specializations to modify the given {@link MethodBinding} + * before {@link #expandMethodBinding(MethodBinding) expanding} and emission. + */ + protected void mangleBinding(final MethodBinding binding) { + // NOP + } + // Expands a MethodBinding containing C primitive pointer types into // multiple variants taking Java primitive arrays and NIO buffers, subject // to the per-function "NIO only" rule in the configuration file diff --git a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java index c570016..c145ff5 100644 --- a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java @@ -67,22 +67,22 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { protected final CommentEmitter defaultJavaCommentEmitter = new DefaultCommentEmitter(); protected final CommentEmitter defaultInterfaceCommentEmitter = new InterfaceCommentEmitter(); + protected final boolean tagNativeBinding; + protected final boolean useNIODirectOnly; + protected final MethodBinding binding; // Exception type raised in the generated code if runtime checks fail private final String runtimeExceptionType; private final String unsupportedExceptionType; + private final boolean useNIOOnly; + private final boolean isNativeMethod; + private final boolean isUnimplemented; - protected boolean emitBody; - protected boolean eraseBufferAndArrayTypes; - protected boolean useNIOOnly; - protected boolean useNIODirectOnly; - protected boolean isNativeMethod; - protected boolean forDirectBufferImplementation; - protected boolean forIndirectBufferAndArrayImplementation; - protected boolean isUnimplemented; - protected boolean tagNativeBinding; - - protected MethodBinding binding; + private boolean emitBody; + private boolean eraseBufferAndArrayTypes; + private boolean isPrivateNativeMethod; + private boolean forDirectBufferImplementation; + private boolean forIndirectBufferAndArrayImplementation; // Manually-specified prologue and epilogue code protected List<String> prologue; @@ -114,7 +114,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { final boolean isUnimplemented, final boolean isInterface, final boolean isNativeMethod, - final JavaConfiguration configuration) { + final boolean isPrivateNativeMethod, final JavaConfiguration configuration) { super(output, isInterface, configuration); this.binding = binding; this.runtimeExceptionType = runtimeExceptionType; @@ -128,7 +128,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { this.forIndirectBufferAndArrayImplementation = forIndirectBufferAndArrayImplementation; this.isUnimplemented = isUnimplemented; this.isNativeMethod = isNativeMethod; - if (isNativeMethod) { + this.isPrivateNativeMethod = isPrivateNativeMethod; + if (isPrivateNativeMethod) { setCommentEmitter(defaultJavaCommentEmitter); } else { setCommentEmitter(defaultInterfaceCommentEmitter); @@ -147,6 +148,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { useNIOOnly = arg.useNIOOnly; useNIODirectOnly = arg.useNIODirectOnly; isNativeMethod = arg.isNativeMethod; + isPrivateNativeMethod = arg.isPrivateNativeMethod; forDirectBufferImplementation = arg.forDirectBufferImplementation; forIndirectBufferAndArrayImplementation = arg.forIndirectBufferAndArrayImplementation; isUnimplemented = arg.isUnimplemented; @@ -158,13 +160,22 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { public final MethodBinding getBinding() { return binding; } - public boolean isForNativeMethod() { return isNativeMethod; } + public boolean isNativeMethod() { return isNativeMethod; } + public boolean isPrivateNativeMethod() { return isPrivateNativeMethod; } public boolean isForDirectBufferImplementation() { return forDirectBufferImplementation; } public boolean isForIndirectBufferAndArrayImplementation() { return forIndirectBufferAndArrayImplementation; } @Override - public String getName() { - return binding.getName(); + public String getInterfaceName() { + return binding.getInterfaceName(); + } + @Override + public String getImplName() { + return binding.getImplName(); + } + @Override + public String getNativeName() { + return binding.getNativeName(); } @Override @@ -237,8 +248,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { } /** Accessor for subclasses. */ - public void setForImplementingMethodCall(final boolean impl) { - this.isNativeMethod = impl; + public void setPrivateNativeMethod(final boolean v) { + this.isPrivateNativeMethod = v; } /** Accessor for subclasses. */ @@ -326,10 +337,12 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { @Override protected void emitName(final PrintWriter writer) { - if (isNativeMethod) { - writer.print(getNativeMethodName()); + if (isPrivateNativeMethod) { + writer.print(getNativeImplMethodName()); + } else if( isInterface()) { + writer.print(getInterfaceName()); } else { - writer.print(getName()); + writer.print(getImplName()); } } @@ -338,7 +351,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { boolean needComma = false; int numEmitted = 0; - if (isNativeMethod && binding.hasContainingType()) { + if (isPrivateNativeMethod && binding.hasContainingType()) { // Always emit outgoing "this" argument writer.print("ByteBuffer "); writer.print(javaThisArgumentName()); @@ -399,8 +412,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { } - protected String getNativeMethodName() { - return binding.getName() + ( useNIODirectOnly ? "0" : "1" ); + protected String getNativeImplMethodName() { + return binding.getImplName() + ( useNIODirectOnly ? "0" : "1" ); } protected String byteOffsetArgName(final int i) { @@ -548,7 +561,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { } protected void emitCall(final MethodBinding binding, final PrintWriter writer) { - writer.print(getNativeMethodName()); + writer.print(getNativeImplMethodName()); writer.print("("); emitCallArguments(binding, writer); writer.print(");"); @@ -679,9 +692,10 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { } else if(type.isIntArray()) { writer.print(", Buffers.SIZEOF_INT * "); } else { - throw new RuntimeException("Unsupported type for calculating array offset argument for " + + throw new GlueGenException("Unsupported type for calculating array offset argument for " + getArgumentName(i) + - " -- error occurred while processing Java glue code for " + getName()); + " -- error occurred while processing Java glue code for " + getCSymbol().getAliasedString(), + getCSymbol().getASTLocusTag()); } writer.print(offsetArgName(i)); } @@ -692,7 +706,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { } } else if (type.isPrimitiveArray()) { if (useNIOOnly) { - throw new RuntimeException("NIO[Direct]Only "+binding+" is set, but "+getArgumentName(i)+" is a primitive array"); + throw new GlueGenException("NIO[Direct]Only "+binding+" is set, but "+getArgumentName(i)+" is a primitive array", + getCSymbol().getASTLocusTag()); } writer.print( ", false"); } @@ -747,8 +762,9 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { } else if (returnType.isNIOLongBuffer()) { writer.println(" return _res.asLongBuffer();"); } else { - throw new RuntimeException("While emitting glue code for " + getName() + - ": can not legally make pointers opaque to anything but PointerBuffer or LongBuffer/long"); + throw new GlueGenException("While emitting glue code for " + getCSymbol().getAliasedString() + + ": can not legally make pointers opaque to anything but PointerBuffer or LongBuffer/long", + getCSymbol().getASTLocusTag()); } } else if (getBinding().getCReturnType().pointerDepth() == 1 && returnType.isNIOLongBuffer()) { writer.println(" return _res.asLongBuffer();"); diff --git a/src/java/com/jogamp/gluegen/MethodBinding.java b/src/java/com/jogamp/gluegen/MethodBinding.java index 56b4fc8..5b0290a 100644 --- a/src/java/com/jogamp/gluegen/MethodBinding.java +++ b/src/java/com/jogamp/gluegen/MethodBinding.java @@ -43,7 +43,6 @@ import com.jogamp.gluegen.cgram.types.FunctionSymbol; import com.jogamp.gluegen.cgram.types.Type; import java.util.ArrayList; -import java.util.Collection; import java.util.List; /** Represents the binding of a C function to a Java method. Also used @@ -53,6 +52,9 @@ import java.util.List; public class MethodBinding { private final FunctionSymbol sym; + private final JavaType containingType; + private final Type containingCType; + private String nativeName; private JavaType javaReturnType; private List<JavaType> javaArgumentTypes; private boolean computedSignatureProperties; @@ -66,8 +68,6 @@ public class MethodBinding { private boolean signatureUsesCArrays; private boolean signatureUsesJavaPrimitiveArrays; private boolean signatureRequiresStaticInitialization; - private JavaType containingType; - private Type containingCType; private int thisPointerIndex = -1; /** @@ -76,10 +76,11 @@ public class MethodBinding { * types. It's safe to modify this binding after construction. */ public MethodBinding(final MethodBinding bindingToCopy) { - this.sym = bindingToCopy.sym; - + this.sym = bindingToCopy.sym; this.containingType = bindingToCopy.containingType; this.containingCType = bindingToCopy.containingCType; + + this.nativeName = bindingToCopy.nativeName; this.javaReturnType = bindingToCopy.javaReturnType; this.javaArgumentTypes = ( null != bindingToCopy.javaArgumentTypes ) ? new ArrayList<JavaType>(bindingToCopy.javaArgumentTypes) : null; this.computedSignatureProperties = bindingToCopy.computedSignatureProperties; @@ -96,17 +97,25 @@ public class MethodBinding { this.thisPointerIndex = bindingToCopy.thisPointerIndex; } - /** Constructor for calling a C function. */ - public MethodBinding(final FunctionSymbol sym) { - this.sym = sym; - } - - /** Constructor for calling a function pointer contained in a - struct. */ - public MethodBinding(final FunctionSymbol sym, final JavaType containingType, final Type containingCType) { + /** + * Constructor for calling a C function or a function pointer contained in a struct. + * <p> + * In case of the latter, a struct function pointer, + * the arguments {@code containingType} and {@code containingCType} must not be {@code null}! + * </p> + */ + public MethodBinding(final FunctionSymbol sym, + final JavaType javaReturnType, + final List<JavaType> javaArgumentTypes, + final JavaType containingType, + final Type containingCType) { this.sym = sym; this.containingType = containingType; this.containingCType = containingCType; + + this.nativeName = null; + this.javaReturnType = javaReturnType; + this.javaArgumentTypes = javaArgumentTypes; } public void setJavaReturnType(final JavaType type) { @@ -142,6 +151,7 @@ public class MethodBinding { return sym.getArgumentType(i); } + /** Returns the {@link FunctionSymbol}. */ public FunctionSymbol getCSymbol() { return sym; } @@ -159,12 +169,30 @@ public class MethodBinding { return "arg" + i; } - public Collection<String> getAliasedNames() { - return sym.getAliasedNames(); - } + /** Returns the {@link FunctionSymbol}'s current {@link FunctionSymbol#getName() aliased} API name. */ public String getName() { return sym.getName(); } + /** Returns the {@link FunctionSymbol}'s current {@link FunctionSymbol#getName() aliased} API name for the interface. */ + public String getInterfaceName() { + return sym.getName(); + } + /** + * Returns the {@link FunctionSymbol}'s name for the implementation, + * which is the current {@link FunctionSymbol#getName() aliased} API name per default. + */ + public String getImplName() { + return sym.getName(); + } + /** + * Returns the {@link FunctionSymbol}'s name for the native function + * which is the {@link FunctionSymbol#getOrigName() original} C API name per default, + * but may be overriden via {@link #setNativeName(String)}. + */ + public String getNativeName() { + return null != nativeName ? nativeName : sym.getOrigName(); + } + public void setNativeName(final String s) { nativeName = s; } /** Creates a new MethodBinding replacing the specified Java argument type with a new argument type. If argumentNumber is diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java index 57a50cc..37a39e1 100644 --- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java @@ -66,11 +66,11 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { super( new MethodBinding(methodToWrap.getBinding()) { @Override - public String getName() { + public String getImplName() { if (callThroughProcAddress) { - return ProcAddressEmitter.WRAP_PREFIX + super.getName(); + return ProcAddressEmitter.WRAP_PREFIX + super.getImplName(); } else { - return super.getName(); + return super.getImplName(); } } }, @@ -121,7 +121,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { if (callThroughProcAddress) { // create variable for the function pointer with the right type, and set // it to the value of the passed-in proc address - final FunctionSymbol cSym = getBinding().getCSymbol(); + final FunctionSymbol cSym = binding.getCSymbol(); // Always emit the local typedef, based on our parsing results. // In case we do have the public typedef from the original header, @@ -145,7 +145,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { writer.print(" "); writer.print(funcPointerTypedefName); // Uses public typedef if available! writer.print(" ptr_"); - writer.print(cSym.getName()); + writer.print(getNativeName()); writer.println(";"); } @@ -158,10 +158,8 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { if (callThroughProcAddress) { // set the function pointer to the value of the passed-in procAddress - final FunctionSymbol cSym = getBinding().getCSymbol(); - // See above notes in emitBodyVariableDeclarations(..)! - final String funcPointerTypedefBaseName = emitter.getFunctionPointerTypedefName(cSym); + final String funcPointerTypedefBaseName = emitter.getFunctionPointerTypedefName(binding.getCSymbol()); final String funcPointerTypedefLocalName = "_local_" + funcPointerTypedefBaseName; final String funcPointerTypedefName; if (hasProcAddrTypedef) { @@ -170,7 +168,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { funcPointerTypedefName = funcPointerTypedefLocalName; } - final String ptrVarName = "ptr_" + cSym.getName(); + final String ptrVarName = "ptr_" + getNativeName(); if (hasProcAddrTypedef) { writer.println(" // implicit type validation of "+funcPointerTypedefLocalName+" -> "+funcPointerTypedefName); @@ -214,7 +212,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { // call throught the run-time function pointer writer.print("(* ptr_"); - writer.print(mBinding.getCSymbol().getName()); // use renamed base-name + writer.print(getNativeName()); writer.print(") "); writer.print("("); emitBodyPassCArguments(writer); diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java index 6418a53..25e5a66 100644 --- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java +++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java @@ -204,16 +204,10 @@ public class ProcAddressEmitter extends JavaEmitter { // If this emitter doesn't have a body (i.e., is a direct native // call with no intervening argument processing), we need to force - // it to emit a body, and produce another one to act as the entry - // point - // FIXME: the negative test against the PRIVATE modifier is a - // nasty hack to prevent the ProcAddressJavaMethodBindingEmitter - // from incorrectly introducing method bodies to the private - // native implementing methods; want this to work at least for - // public and package-private methods + // it to emit a body, and produce another one to act as the entry point final boolean needsJavaWrapper = baseJavaEmitter.signatureOnly() && - !baseJavaEmitter.hasModifier(JavaMethodBindingEmitter.PRIVATE) && - baseJavaEmitter.hasModifier(JavaMethodBindingEmitter.NATIVE) && + baseJavaEmitter.isNativeMethod() && + !baseJavaEmitter.isPrivateNativeMethod() && callThroughProcAddress; @@ -221,7 +215,7 @@ public class ProcAddressEmitter extends JavaEmitter { final ProcAddressJavaMethodBindingEmitter emitter = new ProcAddressJavaMethodBindingEmitter(baseJavaEmitter, callThroughProcAddress, getProcAddressConfig().getProcAddressTableExpr(), - baseJavaEmitter.isForNativeMethod(), + baseJavaEmitter.isPrivateNativeMethod(), this); if( needsJavaWrapper ) { emitter.setEmitBody(true); @@ -238,7 +232,7 @@ public class ProcAddressEmitter extends JavaEmitter { getProcAddressConfig().getProcAddressTableExpr(), true, this); - emitter.setForImplementingMethodCall(true); + emitter.setPrivateNativeMethod(true); fixSecurityModifiers(emitter); emitters.add(emitter); } diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java index f3cc8e9..3faf155 100644 --- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java @@ -41,6 +41,7 @@ package com.jogamp.gluegen.procaddress; import com.jogamp.gluegen.MethodBinding; import com.jogamp.gluegen.FunctionEmitter; import com.jogamp.gluegen.JavaMethodBindingEmitter; + import java.io.*; /** A specialization of JavaMethodBindingEmitter with knowledge of how @@ -76,12 +77,12 @@ public class ProcAddressJavaMethodBindingEmitter extends JavaMethodBindingEmitte public ProcAddressJavaMethodBindingEmitter(final ProcAddressJavaMethodBindingEmitter methodToWrap) { this(methodToWrap, methodToWrap.callThroughProcAddress, methodToWrap.getProcAddressTableExpr, - methodToWrap.changeNameAndArguments, methodToWrap.emitter); + methodToWrap.changeNameAndArguments, methodToWrap.emitter); } @Override - public String getName() { - final String res = super.getName(); + public String getImplName() { + final String res = super.getImplName(); if (changeNameAndArguments) { return ProcAddressEmitter.WRAP_PREFIX + res; } @@ -106,8 +107,8 @@ public class ProcAddressJavaMethodBindingEmitter extends JavaMethodBindingEmitte } @Override - protected String getNativeMethodName() { - final String name = super.getNativeMethodName(); + protected String getNativeImplMethodName() { + final String name = super.getNativeImplMethodName(); if (callThroughProcAddress) { return ProcAddressEmitter.WRAP_PREFIX + name; } |