From 10060b091b76bee35246c5165d49ab546ebc4e37 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 9 Mar 2015 03:18:42 +0100 Subject: Bug 1134 - ProcAddressCMethodBindingEmitter: Use available 'ProcAddrTypedef' for type validation w/ local generated variant (robustness) ProcAddressCMethodBindingEmitter code regarding having the public 'ProcAddrTypedef' (from input header) was simply broken, since it always used the local generated 'ProcAddrTypedef', if 'ProcAddrTypedef' was forced. Hence the public 'ProcAddrTypedef' was ignored in most cases. ProcAddressCMethodBindingEmitter's semantic changed from: needsLocalTypedef -> hasProcAddrTypedef New Code generation: - always generated the local 'ProcAddrTypedef' - if hasProcAddrTypedef, use public 'ProcAddrTypedef' for return type variable - cast local 'ProcAddrTypedef' to public 'ProcAddrTypedef', which renders the native compiler to validate the local and public types. --- .../ProcAddressCMethodBindingEmitter.java | 63 ++++++++++++---------- .../gluegen/procaddress/ProcAddressEmitter.java | 19 +++---- 2 files changed, 43 insertions(+), 39 deletions(-) (limited to 'src/java/com') diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java index 09e6822..4707e57 100644 --- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java @@ -50,7 +50,7 @@ import com.jogamp.gluegen.cgram.types.*; public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { private boolean callThroughProcAddress; - private boolean needsLocalTypedef; + private boolean hasProcAddrTypedef; private String localTypedefCallingConvention; @@ -59,7 +59,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { public ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap, final boolean callThroughProcAddress, - final boolean needsLocalTypedef, + final boolean hasProcAddrTypedef, final String localTypedefCallingConvention, final ProcAddressEmitter emitter) { @@ -84,11 +84,6 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { methodToWrap.getMachineDataInfo(), emitter.getConfiguration() ); - - if( needsLocalTypedef && !callThroughProcAddress ) { - throw new IllegalArgumentException("needsLocalTypedef=true, but callThroughProcAddress=false for "+methodToWrap.toString()); - } - if (methodToWrap.getReturnValueCapacityExpression() != null) { setReturnValueCapacityExpression(methodToWrap.getReturnValueCapacityExpression()); } @@ -101,7 +96,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { setCommentEmitter(defaultCommentEmitter); this.callThroughProcAddress = callThroughProcAddress; - this.needsLocalTypedef = needsLocalTypedef; + this.hasProcAddrTypedef = hasProcAddrTypedef; this.localTypedefCallingConvention = localTypedefCallingConvention; this.emitter = emitter; } @@ -127,25 +122,28 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { // 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(); - String funcPointerTypedefName = - emitter.getFunctionPointerTypedefName(cSym); - - if (needsLocalTypedef) { - // We (probably) didn't get a typedef for this function - // pointer type in the header file; the user requested that we - // forcibly generate one. Here we force the emission of one. - final PointerType funcPtrType = new PointerType(null, cSym.getType(), 0); - // Just for safety, emit this name slightly differently than - // the mangling would otherwise produce - funcPointerTypedefName = "_local_" + funcPointerTypedefName; - - writer.print(" typedef "); - writer.print(funcPtrType.toString(funcPointerTypedefName, localTypedefCallingConvention)); - writer.println(";"); + + // Always emit the local typedef, based on our parsing results. + // In case we do have the public typedef from the original header, + // we use it for the local var and assign our proc-handle to it, + // cast to the local typedef. + // This allows the native C compiler to validate our types! + final String funcPointerTypedefBaseName = emitter.getFunctionPointerTypedefName(cSym); + final String funcPointerTypedefLocalName = "_local_" + funcPointerTypedefBaseName; + final String funcPointerTypedefName; + if (hasProcAddrTypedef) { + funcPointerTypedefName = funcPointerTypedefBaseName; + } else { + funcPointerTypedefName = funcPointerTypedefLocalName; } + final PointerType funcPtrType = new PointerType(null, cSym.getType(), 0); + + writer.print(" typedef "); + writer.print(funcPtrType.toString(funcPointerTypedefLocalName, localTypedefCallingConvention)); + writer.println(";"); writer.print(" "); - writer.print(funcPointerTypedefName); + writer.print(funcPointerTypedefName); // Uses public typedef if available! writer.print(" ptr_"); writer.print(cSym.getName()); writer.println(";"); @@ -161,17 +159,26 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { if (callThroughProcAddress) { // set the function pointer to the value of the passed-in procAddress final FunctionSymbol cSym = getBinding().getCSymbol(); - String funcPointerTypedefName = emitter.getFunctionPointerTypedefName(cSym); - if (needsLocalTypedef) { - funcPointerTypedefName = "_local_" + funcPointerTypedefName; + + // See above notes in emitBodyVariableDeclarations(..)! + final String funcPointerTypedefBaseName = emitter.getFunctionPointerTypedefName(cSym); + final String funcPointerTypedefLocalName = "_local_" + funcPointerTypedefBaseName; + final String funcPointerTypedefName; + if (hasProcAddrTypedef) { + funcPointerTypedefName = funcPointerTypedefBaseName; + } else { + funcPointerTypedefName = funcPointerTypedefLocalName; } final String ptrVarName = "ptr_" + cSym.getName(); + if (hasProcAddrTypedef) { + writer.println(" // implicit type validation of "+funcPointerTypedefLocalName+" -> "+funcPointerTypedefName); + } writer.print(" "); writer.print(ptrVarName); writer.print(" = ("); - writer.print(funcPointerTypedefName); + writer.print(funcPointerTypedefLocalName); writer.println(") (intptr_t) procAddress;"); writer.println(" assert(" + ptrVarName + " != NULL);"); diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java index 180c48f..51e47e9 100644 --- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java +++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressEmitter.java @@ -249,16 +249,13 @@ public class ProcAddressEmitter extends JavaEmitter { final FunctionSymbol cSymbol = baseCEmitter.getBinding().getCSymbol(); // See whether we need a proc address entry for this one - final boolean needsLocalTypedef = getProcAddressConfig().forceProcAddressGen(cSymbol) || - !hasFunctionPointerTypedef(cSymbol); - final boolean callThroughProcAddress = needsLocalTypedef || callThroughProcAddress(cSymbol); - LOG.log(Level.INFO, cSymbol.getASTLocusTag(), "genModProcAddrEmitter: needsTypedef {0}, callThrough {1}: {2}", - needsLocalTypedef, callThroughProcAddress, cSymbol.getAliasedString()); - - String forcedCallingConvention = null; - if (needsLocalTypedef) { - forcedCallingConvention = getProcAddressConfig().getLocalProcAddressCallingConvention(cSymbol); - } + final boolean hasProcAddrTypedef = hasFunctionPointerTypedef(cSymbol); + final boolean callThroughProcAddress = hasProcAddrTypedef || callThroughProcAddress(cSymbol); + final String localProcCallingConvention = getProcAddressConfig().getLocalProcAddressCallingConvention(cSymbol); + + LOG.log(Level.INFO, cSymbol.getASTLocusTag(), "genModProcAddrEmitter: callThrough {0}, hasTypedef {1}, localCallConv {2}: {3}", + callThroughProcAddress, hasProcAddrTypedef, localProcCallingConvention, cSymbol.getAliasedString()); + // Note that we don't care much about the naming of the C argument // variables so to keep things simple we ignore the buffer object // property for the binding @@ -267,7 +264,7 @@ public class ProcAddressEmitter extends JavaEmitter { // extra final argument, which is the address (the OpenGL procedure // address) of the function it needs to call final ProcAddressCMethodBindingEmitter res = new ProcAddressCMethodBindingEmitter( - baseCEmitter, callThroughProcAddress, needsLocalTypedef, forcedCallingConvention, this); + baseCEmitter, callThroughProcAddress, hasProcAddrTypedef, localProcCallingConvention, this); final MessageFormat exp = baseCEmitter.getReturnValueCapacityExpression(); if (exp != null) { -- cgit v1.2.3