diff options
Diffstat (limited to 'src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java')
-rw-r--r-- | src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java | 90 |
1 files changed, 55 insertions, 35 deletions
diff --git a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java index 5c059c9..37a39e1 100644 --- a/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java @@ -42,30 +42,35 @@ package com.jogamp.gluegen.procaddress; import com.jogamp.gluegen.CMethodBindingEmitter; import com.jogamp.gluegen.MethodBinding; import com.jogamp.gluegen.JavaType; + import java.io.*; + import com.jogamp.gluegen.cgram.types.*; public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { private boolean callThroughProcAddress; - private boolean needsLocalTypedef; + private boolean hasProcAddrTypedef; private String localTypedefCallingConvention; private static final String procAddressJavaTypeName = JavaType.createForClass(Long.TYPE).jniTypeName(); private ProcAddressEmitter emitter; - public ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap, final boolean callThroughProcAddress, - final boolean needsLocalTypedef, final String localTypedefCallingConvention, final ProcAddressEmitter emitter) { + public ProcAddressCMethodBindingEmitter(final CMethodBindingEmitter methodToWrap, + final boolean callThroughProcAddress, + final boolean hasProcAddrTypedef, + final String localTypedefCallingConvention, + final ProcAddressEmitter emitter) { 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(); } } }, @@ -76,9 +81,9 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { methodToWrap.getIsJavaMethodStatic(), true, methodToWrap.forIndirectBufferAndArrayImplementation(), - methodToWrap.getMachineDataInfo() + methodToWrap.getMachineDataInfo(), + emitter.getConfiguration() ); - if (methodToWrap.getReturnValueCapacityExpression() != null) { setReturnValueCapacityExpression(methodToWrap.getReturnValueCapacityExpression()); } @@ -91,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; } @@ -116,28 +121,31 @@ 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(); - 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(";"); + 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, + // 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.print(getNativeName()); writer.println(";"); } @@ -150,18 +158,25 @@ 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(binding.getCSymbol()); + final String funcPointerTypedefLocalName = "_local_" + funcPointerTypedefBaseName; + final String funcPointerTypedefName; + if (hasProcAddrTypedef) { + funcPointerTypedefName = funcPointerTypedefBaseName; + } else { + funcPointerTypedefName = funcPointerTypedefLocalName; } - final String ptrVarName = "ptr_" + cSym.getName(); + final String ptrVarName = "ptr_" + getNativeName(); + 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);"); @@ -181,7 +196,12 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { final Type cReturnType = binding.getCReturnType(); if (!cReturnType.isVoid()) { - writer.print("_res = "); + // Note we respect const/volatile in the function return type. + // However, we cannot have it 'const' for our local variable. + // See return type in CMethodBindingEmitter.emitBodyVariableDeclarations(..)! + writer.print("_res = ("); + writer.print(cReturnType.getCName(false)); + writer.print(") "); } final MethodBinding mBinding = getBinding(); if (mBinding.hasContainingType()) { @@ -192,7 +212,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { // call throught the run-time function pointer writer.print("(* ptr_"); - writer.print(mBinding.getCSymbol().getName()); + writer.print(getNativeName()); writer.print(") "); writer.print("("); emitBodyPassCArguments(writer); |