aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/com/jogamp/gluegen/JavaCallbackEmitter.java')
-rw-r--r--src/java/com/jogamp/gluegen/JavaCallbackEmitter.java338
1 files changed, 237 insertions, 101 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java b/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java
index dbd38aa..01ffe8f 100644
--- a/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java
@@ -30,6 +30,8 @@ package com.jogamp.gluegen;
import com.jogamp.gluegen.JavaConfiguration.JavaCallbackInfo;
import com.jogamp.gluegen.cgram.types.Type;
+import java.nio.ByteBuffer;
+
public final class JavaCallbackEmitter {
final JavaConfiguration cfg;
final MethodBinding binding;
@@ -45,6 +47,8 @@ public final class JavaCallbackEmitter {
final JavaType cbFuncJavaReturnType;
final String jcbNextIDVarName;
+ final boolean userParamDefined;
+
final String setFuncCBArgName;
final Type setFuncUserParamCType;
final JavaType setFuncUserParamJType;
@@ -77,13 +81,24 @@ public final class JavaCallbackEmitter {
jcbNextIDVarName = "NEXT_"+capIfaceName+"_ID";
setFuncCBArgName = binding.getArgumentName(javaCallback.setFuncCBParamIdx);
- setFuncUserParamCType = mb.getCArgumentType(javaCallback.setFuncUserParamIdx);
- setFuncUserParamJType = mb.getJavaArgumentType(javaCallback.setFuncUserParamIdx);
- setFuncUserParamTypeName = setFuncUserParamJType.getName();
- setFuncUserParamArgName = binding.getArgumentName(javaCallback.setFuncUserParamIdx);
- userParamIsKey = info.setFuncKeyIndices.contains(info.setFuncUserParamIdx);
- if( !setFuncUserParamJType.isLong() ) {
+ userParamDefined = javaCallback.setFuncUserParamIdx >= 0;
+ if( !userParamDefined ) {
+ setFuncUserParamCType = null;
+ setFuncUserParamJType = null;
+ setFuncUserParamTypeName = null;
+ setFuncUserParamArgName = null;
+
+ userParamIsKey = false;
+ } else {
+ setFuncUserParamCType = mb.getCArgumentType(javaCallback.setFuncUserParamIdx);
+ setFuncUserParamJType = mb.getJavaArgumentType(javaCallback.setFuncUserParamIdx);
+ setFuncUserParamTypeName = setFuncUserParamJType.getName();
+ setFuncUserParamArgName = binding.getArgumentName(javaCallback.setFuncUserParamIdx);
+
+ userParamIsKey = info.setFuncKeyIndices.contains(info.setFuncUserParamIdx);
+ }
+ if( null != setFuncUserParamJType && !setFuncUserParamJType.isLong() ) {
if( setFuncUserParamJType.isCompoundTypeWrapper() ) {
userParamIsCompound = true;
userParamIsMappedToID = false;
@@ -99,16 +114,20 @@ public final class JavaCallbackEmitter {
userParamIDMapInstanceName = null;
}
- if( userParamIsCompound ) {
- userParamClassName = setFuncUserParamTypeName;
- } else if( null != javaCallback.userParamClassName ) {
- userParamClassName = javaCallback.userParamClassName;
+ if( userParamDefined ) {
+ if( userParamIsCompound ) {
+ userParamClassName = setFuncUserParamTypeName;
+ } else if( null != javaCallback.userParamClassName ) {
+ userParamClassName = javaCallback.userParamClassName;
+ } else {
+ userParamClassName = "Object";
+ }
} else {
- userParamClassName = "Object";
+ userParamClassName = null;
}
if( null != javaCallback.customKeyClassName ) {
- customKeyClass = true;;
+ customKeyClass = true;
KeyClassName = javaCallback.customKeyClassName;
useDataMap = true;
} else {
@@ -135,9 +154,11 @@ public final class JavaCallbackEmitter {
emitJavaBriefAPIDoc(unit, "Returns "+info.cbFuncTypeName+" callback ", "mapped to ", "", "for ");
unit.emitln(" public "+info.cbFuncTypeName+" get"+capIfaceName+"("+KeyClassName+" key);");
unit.emitln();
- emitJavaBriefAPIDoc(unit, "Returns user-param ", "mapped to ", "", "for ");
- unit.emitln(" public "+userParamClassName+" get"+capIfaceName+"UserParam("+KeyClassName+" key);");
- unit.emitln();
+ if( userParamDefined ) {
+ emitJavaBriefAPIDoc(unit, "Returns user-param ", "mapped to ", "", "for ");
+ unit.emitln(" public "+userParamClassName+" get"+capIfaceName+"UserParam("+KeyClassName+" key);");
+ unit.emitln();
+ }
emitJavaBriefAPIDoc(unit, "Releases all callback data ", "mapped via ", "", "skipping toolkit API. Favor passing `null` callback ref to ");
unit.emitln(" public int releaseAll"+capIfaceName+"();");
unit.emitln();
@@ -151,9 +172,11 @@ public final class JavaCallbackEmitter {
emitJavaBriefAPIDoc(unit, "Returns "+info.cbFuncTypeName+" callback ", "mapped to ", "", "for ");
unit.emitln(" public "+info.cbFuncTypeName+" get"+capIfaceName+"();");
unit.emitln();
- emitJavaBriefAPIDoc(unit, "Returns user-param ", "mapped to ", "", "for ");
- unit.emitln(" public "+userParamClassName+" get"+capIfaceName+"UserParam();");
- unit.emitln();
+ if( userParamDefined ) {
+ emitJavaBriefAPIDoc(unit, "Returns user-param ", "mapped to ", "", "for ");
+ unit.emitln(" public "+userParamClassName+" get"+capIfaceName+"UserParam();");
+ unit.emitln();
+ }
emitJavaBriefAPIDoc(unit, "Releases callback data ", "", "", "skipping toolkit API. Favor passing `null` callback ref to ");
unit.emitln(" public void release"+capIfaceName+"();");
unit.emitln();
@@ -189,14 +212,16 @@ public final class JavaCallbackEmitter {
unit.emitln(" }");
unit.emitln();
- emitJavaBriefAPIDoc(unit, "Returns user-param ", "mapped to ", "", "for ");
- unit.emitln(" public final "+userParamClassName+" get"+capIfaceName+"UserParam("+KeyClassName+" key) {");
- unit.emitln(" synchronized( "+lockInstanceName+" ) {");
- unit.emitln(" final "+DataClassName+" value = "+dataMapInstanceName+".get(key);");
- unit.emitln(" return null != value ? value.param : null;");
- unit.emitln(" }");
- unit.emitln(" }");
- unit.emitln();
+ if( userParamDefined ) {
+ emitJavaBriefAPIDoc(unit, "Returns user-param ", "mapped to ", "", "for ");
+ unit.emitln(" public final "+userParamClassName+" get"+capIfaceName+"UserParam("+KeyClassName+" key) {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final "+DataClassName+" value = "+dataMapInstanceName+".get(key);");
+ unit.emitln(" return null != value ? value.param : null;");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+ }
emitJavaBriefAPIDoc(unit, "Releases all callback data ", "mapped via ", "", "skipping toolkit API. Favor passing `null` callback ref to ");
unit.emitln(" public final int releaseAll"+capIfaceName+"() {");
unit.emitln(" synchronized( "+lockInstanceName+" ) {");
@@ -242,14 +267,16 @@ public final class JavaCallbackEmitter {
unit.emitln(" }");
unit.emitln();
- emitJavaBriefAPIDoc(unit, "Returns user-param ", "mapped to ", "", "for ");
- unit.emitln(" public final "+userParamClassName+" get"+capIfaceName+"UserParam() {");
- unit.emitln(" synchronized( "+lockInstanceName+" ) {");
- unit.emitln(" final "+DataClassName+" value = "+dataInstanceName+";");
- unit.emitln(" return null != value ? value.param : null;");
- unit.emitln(" }");
- unit.emitln(" }");
- unit.emitln();
+ if( userParamDefined ) {
+ emitJavaBriefAPIDoc(unit, "Returns user-param ", "mapped to ", "", "for ");
+ unit.emitln(" public final "+userParamClassName+" get"+capIfaceName+"UserParam() {");
+ unit.emitln(" synchronized( "+lockInstanceName+" ) {");
+ unit.emitln(" final "+DataClassName+" value = "+dataInstanceName+";");
+ unit.emitln(" return null != value ? value.param : null;");
+ unit.emitln(" }");
+ unit.emitln(" }");
+ unit.emitln();
+ }
emitJavaBriefAPIDoc(unit, "Releases callback data ", "", "", "skipping toolkit API. Favor passing `null` callback ref to ");
unit.emitln(" public final void release"+capIfaceName+"() {");
@@ -359,7 +386,9 @@ public final class JavaCallbackEmitter {
unit.emitln(" &&");
unit.emit (" ");
}
- if( jType.isPrimitive() || idx == info.setFuncUserParamIdx ) {
+ if( jType.isCompoundTypeWrapper() ) {
+ unit.emit(name+".getDirectBufferAddress() == o2."+name+".getDirectBufferAddress()");
+ } else if( jType.isPrimitive() || idx == info.setFuncUserParamIdx ) {
unit.emit(name+" == o2."+name);
} else {
unit.emit(name+".equals( o2."+name+" )");
@@ -392,6 +421,8 @@ public final class JavaCallbackEmitter {
} else {
unit.emitln(name+";");
}
+ } else if( jType.isCompoundTypeWrapper() ) {
+ unit.emitln("HashUtil.getAddrHash32_EqualDist( "+name+".getDirectBufferAddress() );");
} else {
if( idx == info.setFuncUserParamIdx ) {
unit.emitln("System.identityHashCode( "+name+" );");
@@ -416,23 +447,32 @@ public final class JavaCallbackEmitter {
private final void emitJavaDataClass(final CodeUnit unit) {
unit.emitln(" private static class "+DataClassName+" {");
- unit.emitln(" // userParamArgCType "+setFuncUserParamCType);
- unit.emitln(" // userParamArgJType "+setFuncUserParamJType);
- unit.emitln(" final "+info.cbFuncTypeName+" func;");
- if( userParamIsMappedToID ) {
- unit.emitln(" final long paramID;");
- }
- unit.emitln(" final "+setFuncUserParamTypeName+" param;");
- unit.emit (" "+DataClassName+"(final "+info.cbFuncTypeName+" func, ");
- if( userParamIsMappedToID ) {
- unit.emit("final long paramID, ");
- }
- unit.emitln("final "+setFuncUserParamTypeName+" param) {");
+ unit.emitln(" final " + info.cbFuncTypeName + " func;");
+ if( userParamDefined ) {
+ unit.emitln(" // userParamArgCType "+setFuncUserParamCType);
+ unit.emitln(" // userParamArgJType "+setFuncUserParamJType);
+ unit.emitln(" final "+setFuncUserParamTypeName+" param;");
+ if( userParamIsMappedToID ) {
+ unit.emitln(" final long paramID;");
+ }
+ } else {
+ unit.emitln(" // No user param defined.");
+ }
+ unit.emit (" "+DataClassName+"(final "+info.cbFuncTypeName+" func");
+ if( userParamDefined ) {
+ if( userParamIsMappedToID ) {
+ unit.emit(", final long paramID");
+ }
+ unit.emit(", final "+setFuncUserParamTypeName+" param");
+ }
+ unit.emitln(") {");
unit.emitln(" this.func = func;");
- if( userParamIsMappedToID ) {
- unit.emitln(" this.paramID = paramID;");
+ if( userParamDefined ) {
+ if( userParamIsMappedToID ) {
+ unit.emitln(" this.paramID = paramID;");
+ }
+ unit.emitln(" this.param = param;");
}
- unit.emitln(" this.param = param;");
unit.emitln(" }");
unit.emitln(" }");
}
@@ -445,7 +485,7 @@ public final class JavaCallbackEmitter {
if( idx == info.cbFuncUserParamIdx ) {
buf.append("J");
} else {
- buf.append(jType.getDescriptor());
+ buf.append(jType.getDescriptor(cfg));
}
return true;
} else {
@@ -453,45 +493,60 @@ public final class JavaCallbackEmitter {
}
} );
buf.append(")");
- buf.append(cbFuncJavaReturnType.getDescriptor());
+ buf.append(cbFuncJavaReturnType.getDescriptor(cfg));
return buf.toString();
}
public final int appendJavaAdditionalJNIParameter(final StringBuilder buf) {
- buf.append("Class<?> staticCBClazz, String callbackSignature, long nativeUserParam");
+ buf.append("Class<?> staticCBClazz, String callbackSignature");
+ if( !userParamDefined ) {
+ return 2;
+ }
+ buf.append(", long nativeUserParam");
return 3;
}
public final int appendJavaAdditionalJNIArguments(final StringBuilder buf) {
- buf.append("this.getClass(), \"" + getJavaStaticCallbackSignature()+ "\", nativeUserParam");
+ buf.append("this.getClass(), \"" + getJavaStaticCallbackSignature() + "\"");
+ if( !userParamDefined ) {
+ return 2;
+ }
+ buf.append(", nativeUserParam");
return 3;
}
public void emitJavaSetFuncPreCall(final CodeUnit unit) {
- unit.emitln(" final long nativeUserParam;");
+ if( userParamDefined ) {
+ unit.emitln(" final long nativeUserParam;");
+ }
unit.emitln(" synchronized( "+lockInstanceName+" ) {");
- if( setFuncUserParamJType.isLong() ) {
- unit.emitln(" nativeUserParam = "+setFuncUserParamArgName+";");
- } else {
- unit.emitln(" if( null != "+setFuncUserParamArgName+" ) {");
- if( setFuncUserParamJType.isCompoundTypeWrapper() ) {
- // userParamIsCompound == true
- unit.emitln(" nativeUserParam = "+setFuncUserParamArgName+".getDirectBufferAddress();");
+ if( userParamDefined ) {
+ if( setFuncUserParamJType.isLong() ) {
+ unit.emitln(" nativeUserParam = "+setFuncUserParamArgName+";");
} else {
- // userParamIsMappedToID == true
- unit.emitln(" nativeUserParam = "+jcbNextIDVarName+"++;");
- unit.emitln(" if( 0 >= "+jcbNextIDVarName+" ) { "+jcbNextIDVarName+" = 1; }");
+ unit.emitln(" if( null != "+setFuncUserParamArgName+" ) {");
+ if( setFuncUserParamJType.isCompoundTypeWrapper() ) {
+ // userParamIsCompound == true
+ unit.emitln(" nativeUserParam = "+setFuncUserParamArgName+".getDirectBufferAddress();");
+ } else {
+ // userParamIsMappedToID == true
+ unit.emitln(" nativeUserParam = "+jcbNextIDVarName+"++;");
+ unit.emitln(" if( 0 >= "+jcbNextIDVarName+" ) { "+jcbNextIDVarName+" = 1; }");
+ }
+ unit.emitln(" } else {");
+ unit.emitln(" nativeUserParam = 0;");
+ unit.emitln(" }");
}
- unit.emitln(" } else {");
- unit.emitln(" nativeUserParam = 0;");
- unit.emitln(" }");
}
unit.emitln(" if( null != "+setFuncCBArgName+" ) {");
unit.emit (" add"+capIfaceName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), info.setFuncKeyIndices, true).toString()+
- "new "+DataClassName+"("+setFuncCBArgName+", ");
- if( userParamIsMappedToID ) {
- unit.emit("nativeUserParam, ");
+ "new "+DataClassName+"("+setFuncCBArgName);
+ if( userParamDefined ) {
+ if( userParamIsMappedToID ) {
+ unit.emit(", nativeUserParam");
+ }
+ unit.emit(", "+setFuncUserParamArgName);
}
- unit.emitln(setFuncUserParamArgName+"));");
+ unit.emitln("));");
unit.emitln(" } else { ");
unit.emitln(" // release a previously mapped instance ");
if( useDataMap ) {
@@ -529,17 +584,21 @@ public final class JavaCallbackEmitter {
} );
unit.emitln(") {");
final boolean useParamLocal[] = { false };
- if( mapNativePtrToCompound[0] ) {
- unit.emitln(" final "+origUserParamJType[0]+" "+info.cbFuncUserParamName+" = "+origUserParamJType[0]+".derefPointer(nativeUserParam);");
- useParamLocal[0] = true;
- } else if( userParamIsMappedToID && userParamIsKey ) {
- unit.emitln(" final "+userParamClassName+" "+info.cbFuncUserParamName+";");
+ if( userParamDefined ) {
+ if( mapNativePtrToCompound[0] ) {
+ unit.emitln(" final "+origUserParamJType[0]+" "+info.cbFuncUserParamName+" = "+origUserParamJType[0]+".derefPointer(nativeUserParam);");
+ useParamLocal[0] = true;
+ } else if( userParamIsMappedToID && userParamIsKey ) {
+ unit.emitln(" final "+userParamClassName+" "+info.cbFuncUserParamName+";");
+ }
}
unit.emitln(" final "+DataClassName+" value;");
unit.emitln(" synchronized( "+lockInstanceName+" ) {");
- if( userParamIsMappedToID && userParamIsKey && !mapNativePtrToCompound[0] ) {
- unit.emitln(" "+info.cbFuncUserParamName+" = ("+userParamClassName+") "+userParamIDMapInstanceName+".get(nativeUserParam);");
- useParamLocal[0] = true;
+ if( userParamDefined ) {
+ if( userParamIsMappedToID && userParamIsKey && !mapNativePtrToCompound[0] ) {
+ unit.emitln(" "+info.cbFuncUserParamName+" = ("+userParamClassName+") "+userParamIDMapInstanceName+".get(nativeUserParam);");
+ useParamLocal[0] = true;
+ }
}
if( useDataMap ) {
unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+info.cbFuncBinding.getJavaCallSelectArguments(new StringBuilder(), info.cbFuncKeyIndices, false).toString()+");");
@@ -584,7 +643,11 @@ public final class JavaCallbackEmitter {
//
public int appendCAdditionalParameter(final StringBuilder buf) {
- buf.append(", jclass staticCBClazz, jstring jcallbackSignature, jlong jnativeUserParam");
+ buf.append(", jclass staticCBClazz, jstring jcallbackSignature");
+ if( !userParamDefined ) {
+ return 2;
+ }
+ buf.append(", jlong jnativeUserParam");
return 3;
}
@@ -597,7 +660,9 @@ public final class JavaCallbackEmitter {
public void appendCAdditionalJNIDescriptor(final StringBuilder buf) {
JavaType.appendJNIDescriptor(buf, Class.class, false); // to account for the additional 'jclass staticCBClazz' parameter
JavaType.appendJNIDescriptor(buf, String.class, false); // to account for the additional 'jstring jcallbackSignature' parameter
- JavaType.appendJNIDescriptor(buf, long.class, false); // to account for the additional 'long nativeUserParam' parameter
+ if( userParamDefined ) {
+ JavaType.appendJNIDescriptor(buf, long.class, false); // to account for the additional 'long nativeUserParam' parameter
+ }
}
public void emitCSetFuncPreCall(final CodeUnit unit) {
@@ -607,15 +672,22 @@ public final class JavaCallbackEmitter {
final String staticBindingClazzVarName = "staticCBClazz"+jcbNativeBasename;
final String staticBindingMethodIDVarName = "staticCBMethod"+jcbNativeBasename;
final String cbFuncArgName = binding.getArgumentName(info.setFuncCBParamIdx);
- final String userParamTypeName = info.cbFuncUserParamType.getCName();
- final String userParamArgName = binding.getArgumentName(info.setFuncUserParamIdx);
final String nativeCBFuncVarName = cbFuncArgName+"_native";
- final String nativeUserParamVarName = userParamArgName+"_native";
+ final String userParamTypeName, nativeUserParamVarName;
+ if( userParamDefined ) {
+ userParamTypeName = info.cbFuncUserParamType.getCName();
+ nativeUserParamVarName = binding.getArgumentName(info.setFuncUserParamIdx)+"_native";
+ } else {
+ userParamTypeName = null;
+ nativeUserParamVarName = null;
+ }
unit.emitln();
unit.emitln(" // JavaCallback handling");
unit.emitln(" if( NULL == staticCBClazz ) { (*env)->FatalError(env, \"NULL staticCBClazz passed to '"+jcbFriendlyBasename+"'\"); }");
unit.emitln(" "+info.cbFuncTypeName+" "+nativeCBFuncVarName+";");
- unit.emitln(" "+userParamTypeName+"* "+nativeUserParamVarName+";");
+ if( userParamDefined ) {
+ unit.emitln(" "+userParamTypeName+"* "+nativeUserParamVarName+";");
+ }
unit.emitln(" if( NULL != "+cbFuncArgName+" ) {");
unit.emitln(" if( NULL == "+staticBindingClazzVarName+" || NULL == "+staticBindingMethodIDVarName+" ) {");
unit.emitln(" jclass staticCBClazz2 = (*env)->NewGlobalRef(env, staticCBClazz);");
@@ -632,30 +704,79 @@ public final class JavaCallbackEmitter {
unit.emitln(" "+staticBindingClazzVarName+" = staticCBClazz2;");
unit.emitln(" "+staticBindingMethodIDVarName+" = cbMethodID;");
unit.emitln(" }");
+ final JavaType bbjt = JavaType.createForClass(ByteBuffer.class);
+ for (int i = 0; i < info.cbFuncBinding.getNumArguments(); i++) {
+ final String baseArgName = CodeGenUtils.capitalizeString( info.cbFuncBinding.getArgumentName(i) );
+ final JavaType currentJavaType = info.cbFuncBinding.getJavaArgumentType(i);
+ if( i != info.cbFuncUserParamIdx && currentJavaType.isCompoundTypeWrapper() ) {
+ final String staticBindingClazzArgVarName = "staticCBArg" + baseArgName + "Clazz"+jcbNativeBasename;
+ final String staticBindingMethodIDArgVarName = "staticCBArg" + baseArgName + "Method"+jcbNativeBasename;
+ unit.emitln(" if( NULL == "+staticBindingClazzArgVarName+" || NULL == "+staticBindingMethodIDArgVarName+" ) {");
+ final String argClassDescriptor = currentJavaType.getDescriptor(cfg);
+ final String argClassRef = currentJavaType.getName(cfg);
+ final String argClassLocation = argClassRef.replace(".", "/");
+ unit.emitln(" jclass "+staticBindingClazzArgVarName+"2 = (*env)->FindClass(env, \""+argClassLocation+"\");");
+ unit.emitln(" if( NULL == "+staticBindingClazzArgVarName+"2 ) { (*env)->FatalError(env, \"Failed FindClass("+argClassLocation+") in '"+jcbFriendlyBasename+"'\"); }");
+ unit.emitln(" jmethodID "+staticBindingMethodIDArgVarName+"2 = (*env)->GetStaticMethodID(env, "+staticBindingClazzArgVarName+"2, \"create\", \"("+bbjt.getDescriptor()+")"+argClassDescriptor+"\");");
+ unit.emitln(" if( NULL == "+staticBindingMethodIDArgVarName+"2 ) {");
+ unit.emitln(" char cmsg[400];");
+ unit.emitln(" snprintf(cmsg, 400, \"Failed GetStaticMethodID of '"+argClassRef+".create("+bbjt.getDescriptor()+")"+argClassDescriptor+" in "+jcbFriendlyBasename+"'\");");
+ unit.emitln(" (*env)->FatalError(env, cmsg);");
+ unit.emitln(" }");
+ unit.emitln(" "+staticBindingClazzArgVarName+" = "+staticBindingClazzArgVarName+"2;");
+ unit.emitln(" "+staticBindingMethodIDArgVarName+" = "+staticBindingMethodIDArgVarName+"2;");
+ unit.emitln(" }");
+ }
+ }
unit.emitln(" "+nativeCBFuncVarName+" = func"+jcbNativeBasename+";");
- unit.emitln(" "+nativeUserParamVarName+" = ("+userParamTypeName+"*) jnativeUserParam;");
+ if( userParamDefined ) {
+ unit.emitln(" "+nativeUserParamVarName+" = ("+userParamTypeName+"*) jnativeUserParam;");
+ }
unit.emitln(" } else {");
unit.emitln(" "+nativeCBFuncVarName+" = NULL;");
- unit.emitln(" "+nativeUserParamVarName+" = NULL;");
+ if( userParamDefined ) {
+ unit.emitln(" "+nativeUserParamVarName+" = NULL;");
+ }
unit.emitln(" }");
unit.emitln();
}
- public void emitCAdditionalCode(final CodeUnit unit, final CMethodBindingEmitter jcbCMethodEmitter) {
+ /**
+ * Emit addition C code, i.e. global varialbles and static callback invocation
+ * @param unit output C code unit
+ * @param jcbFuncCMethodEmitter only used to access {@link CMethodBindingEmitter#emitBodyMapCToJNIType(int, boolean)}, a non-ideal hack! (FIXME)
+ */
+ public void emitCAdditionalCode(final CodeUnit unit, final CMethodBindingEmitter jcbFuncCMethodEmitter) {
final String jcbNativeBasename = CodeGenUtils.capitalizeString( info.setFuncName );
final String jcbFriendlyBasename = info.setFuncName+"("+info.cbSimpleClazzName+")";
final String staticBindingClazzVarName = "staticCBClazz"+jcbNativeBasename;
final String staticBindingMethodIDVarName = "staticCBMethod"+jcbNativeBasename;
final String staticCallbackName = "func"+jcbNativeBasename;
- // final Type userParamType = javaCallback.cbFuncBinding.getCArgumentType(javaCallback.cbFuncUserParamIdx);
- final String userParamTypeName = info.cbFuncUserParamType.getCName();
- final String userParamArgName = info.cbFuncBinding.getArgumentName(info.cbFuncUserParamIdx);
+ final String userParamTypeName, userParamArgName;
+ if( userParamDefined ) {
+ // final Type userParamType = javaCallback.cbFuncBinding.getCArgumentType(javaCallback.cbFuncUserParamIdx);
+ userParamTypeName = info.cbFuncUserParamType.getCName();
+ userParamArgName = info.cbFuncBinding.getArgumentName(info.cbFuncUserParamIdx);
+ } else {
+ userParamTypeName = null;
+ userParamArgName = null;
+ }
final Type cReturnType = info.cbFuncBinding.getCReturnType();
final JavaType jretType = info.cbFuncBinding.getJavaReturnType();
unit.emitln();
unit.emitln("static jclass "+staticBindingClazzVarName+" = NULL;");
unit.emitln("static jmethodID "+staticBindingMethodIDVarName+" = NULL;");
+ for (int i = 0; i < info.cbFuncBinding.getNumArguments(); i++) {
+ final String baseArgName = CodeGenUtils.capitalizeString( info.cbFuncBinding.getArgumentName(i) );
+ final JavaType currentJavaType = info.cbFuncBinding.getJavaArgumentType(i);
+ if( i != info.cbFuncUserParamIdx && currentJavaType.isCompoundTypeWrapper() ) {
+ final String staticBindingClazzArgVarName = "staticCBArg" + baseArgName + "Clazz"+jcbNativeBasename;
+ final String staticBindingMethodIDArgVarName = "staticCBArg" + baseArgName + "Method"+jcbNativeBasename;
+ unit.emitln("static jclass "+staticBindingClazzArgVarName+" = NULL;");
+ unit.emitln("static jmethodID "+staticBindingMethodIDArgVarName+" = NULL;");
+ }
+ }
unit.emitln();
// javaCallback.cbFuncCEmitter.emitSignature();
unit.emit("static "+cReturnType.getCName()+" "+staticCallbackName+"(");
@@ -668,6 +789,16 @@ public final class JavaCallbackEmitter {
unit.emitln(" JNIEnv* env = JVMUtil_GetJNIEnv(1 /* daemon */, &detachJVM);");
unit.emitln(" jclass cbClazz = "+staticBindingClazzVarName+";");
unit.emitln(" jmethodID cbMethod = "+staticBindingMethodIDVarName+";");
+ for (int i = 0; i < info.cbFuncBinding.getNumArguments(); i++) {
+ final String baseArgName = CodeGenUtils.capitalizeString( info.cbFuncBinding.getArgumentName(i) );
+ final JavaType currentJavaType = info.cbFuncBinding.getJavaArgumentType(i);
+ if( i != info.cbFuncUserParamIdx && currentJavaType.isCompoundTypeWrapper() ) {
+ final String staticBindingClazzArgVarName = "staticCBArg" + baseArgName + "Clazz"+jcbNativeBasename;
+ final String staticBindingMethodIDArgVarName = "staticCBArg" + baseArgName + "Method"+jcbNativeBasename;
+ unit.emitln(" jclass cbClazzArg" + baseArgName+" = "+staticBindingClazzArgVarName+";");
+ unit.emitln(" jmethodID cbMethodArg" + baseArgName+" = "+staticBindingMethodIDArgVarName+";");
+ }
+ }
unit.emitln(" if( NULL == env || NULL == cbClazz || NULL == cbMethod ) {");
if( !cReturnType.isVoid() ) {
unit.emitln(" return 0;");
@@ -678,10 +809,12 @@ public final class JavaCallbackEmitter {
// javaCallback.cbFuncCEmitter.emitBodyVariableDeclarations();
// javaCallback.cbFuncCEmitter.emitBodyUserVariableDeclarations();
// javaCallback.cbFuncCEmitter.emitBodyVariablePreCallSetup();
- emitJavaCallbackBodyCToJavaPreCall(jcbCMethodEmitter);
+ emitJavaCallbackBodyCToJavaPreCall(jcbFuncCMethodEmitter);
// javaCallback.cbFuncCEmitter.emitBodyCallCFunction();
- unit.emitln(" "+userParamTypeName+"* "+userParamArgName+"_jni = ("+userParamTypeName+"*) "+userParamArgName+";");
+ if( userParamDefined ) {
+ unit.emitln(" "+userParamTypeName+"* "+userParamArgName+"_jni = ("+userParamTypeName+"*) "+userParamArgName+";");
+ }
unit.emitln(" // C Params: "+info.cbFuncBinding.getCParameterList(new StringBuilder(), false, null).toString());
unit.emitln(" // J Params: "+info.cbFuncBinding.getJavaParameterList(new StringBuilder()).toString());
@@ -699,7 +832,7 @@ public final class JavaCallbackEmitter {
}
unit.emit("(*env)->CallStatic" + CodeGenUtils.capitalizeString( jretType.getName() ) +"Method(env, cbClazz, cbMethod, ");
// javaCallback.cbFuncCEmitter.emitBodyPassCArguments();
- emitJavaCallbackBodyPassJavaArguments(unit, jcbCMethodEmitter.binding, null); //"NULL");
+ emitJavaCallbackBodyPassJavaArguments(unit);
unit.emitln(");");
unit.emitln(" if( (*env)->ExceptionCheck(env) ) {");
unit.emitln(" fprintf(stderr, \"Info: Callback '"+jcbFriendlyBasename+"': Exception in Java Callback caught:\\n\");");
@@ -717,7 +850,7 @@ public final class JavaCallbackEmitter {
unit.emitln();
}
- /* pp */ int emitJavaCallbackBodyCToJavaPreCall(final CMethodBindingEmitter ce) {
+ private int emitJavaCallbackBodyCToJavaPreCall(final CMethodBindingEmitter ce) {
int count = 0;
for (int i = 0; i < ce.binding.getNumArguments(); i++) {
if( i == info.cbFuncUserParamIdx ) {
@@ -730,18 +863,21 @@ public final class JavaCallbackEmitter {
return count;
}
- /* pp */ int emitJavaCallbackBodyPassJavaArguments(final CodeUnit unit, final MethodBinding binding, final String userParamVarName) {
+ private int emitJavaCallbackBodyPassJavaArguments(final CodeUnit unit) {
int count = 0;
boolean needsComma = false;
- for (int i = 0; i < binding.getNumArguments(); i++) {
+ for (int i = 0; i < info.cbFuncBinding.getNumArguments(); i++) {
if (needsComma) {
unit.emit(", ");
needsComma = false;
}
- if( i == info.cbFuncUserParamIdx && null != userParamVarName ) {
- unit.emit( userParamVarName );
+ final String baseArgName = info.cbFuncBinding.getArgumentName(i);
+ final JavaType currentJavaType = info.cbFuncBinding.getJavaArgumentType(i);
+ if( i != info.cbFuncUserParamIdx && currentJavaType.isCompoundTypeWrapper() ) {
+ final String cBaseArgName = CodeGenUtils.capitalizeString( baseArgName );
+ unit.emit( "(*env)->CallStaticObjectMethod(env, cbClazzArg" + cBaseArgName + ", cbMethodArg" + cBaseArgName + ", " + baseArgName + "_jni)" );
} else {
- unit.emit( binding.getArgumentName(i) + "_jni" );
+ unit.emit( baseArgName + "_jni" );
}
needsComma = true;
++count;