summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/gluegen/JavaEmitter.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-07-21 11:06:52 +0200
committerSven Gothel <[email protected]>2011-07-21 11:06:52 +0200
commitdc4b259b6651bdc0cec0895bc74e26e504870c8e (patch)
treeafd356aa28e4091ce12c8c6bc5e3a6b9edf48a58 /src/java/com/jogamp/gluegen/JavaEmitter.java
parent8e0d7f00c69d79bcdac4be508e5b5999b423e904 (diff)
GlueGen proper size / alignment of primitive and compound types usage [2/2] - Fin
MachineDesction == MD MD.StaticConfig: - enum for all supported static configs (ID -> MD) - verified at runtime: test runtime queried-MD versus static-MD, hard fail if not compatible (size/alignment) SizeThunk primitive sizes: - Add notion of fixed native size (eg. int64_t) and otherwise (eg. long) java struct 'wrappers' code generation: - single class using size/offset arrays of all MachineDescription configurations - at runtime the array idx is queried in static block - type aligment for not fixed-native-size types (SizeThunk, undef long/int) via StructAccessor junit test: - add float test - fix native code - add java (create, write) -> native (verify) test works (tested) on: linux 32/64 and windows 32/64
Diffstat (limited to 'src/java/com/jogamp/gluegen/JavaEmitter.java')
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java378
1 files changed, 172 insertions, 206 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index dfa7594..c68fae8 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -60,6 +60,8 @@ import com.jogamp.gluegen.runtime.types.Type;
import java.nio.Buffer;
import java.util.logging.Logger;
+import jogamp.common.os.MachineDescriptionRuntime;
+
import static java.util.logging.Level.*;
import static com.jogamp.gluegen.JavaEmitter.MethodAccess.*;
@@ -97,9 +99,9 @@ public class JavaEmitter implements GlueEmitter {
private PrintWriter javaWriter; // Emits either interface or, in AllStatic mode, everything
private PrintWriter javaImplWriter; // Only used in non-AllStatic modes for impl class
private PrintWriter cWriter;
- private MachineDescription machDesc32;
- private MachineDescription machDesc64;
-
+ private final MachineDescription machDescJava = MachineDescription.StaticConfig.X86_64_UNIX.md;
+ private final MachineDescription.StaticConfig[] machDescTargetConfigs = MachineDescription.StaticConfig.values();
+
protected final static Logger LOG = Logger.getLogger(JavaEmitter.class.getPackage().getName());
public void readConfigurationFile(String filename) throws Exception {
@@ -107,16 +109,6 @@ public class JavaEmitter implements GlueEmitter {
cfg.read(filename);
}
- public void setMachineDescription(MachineDescription md32, MachineDescription md64) {
-
- if ((md32 == null) && (md64 == null)) {
- throw new RuntimeException("Must specify at least one MachineDescription");
- }
-
- machDesc32 = md32;
- machDesc64 = md64;
- }
-
class ConstantRenamer implements SymbolFilter {
private List<ConstantDefinition> constants;
@@ -615,7 +607,7 @@ public class JavaEmitter implements GlueEmitter {
cfg.allStatic(),
(binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue),
!cfg.nioDirectOnly(binding.getName()),
- machDesc64);
+ machDescJava);
prepCEmitter(binding, cEmitter);
allEmitters.add(cEmitter);
}
@@ -663,7 +655,7 @@ public class JavaEmitter implements GlueEmitter {
try {
// Get Java binding for the function
- MethodBinding mb = bindFunction(sym, null, null, machDesc64);
+ MethodBinding mb = bindFunction(sym, null, null, machDescJava);
// JavaTypes representing C pointers in the initial
// MethodBinding have not been lowered yet to concrete types
@@ -771,19 +763,6 @@ public class JavaEmitter implements GlueEmitter {
}
public void emitStruct(CompoundType structType, String alternateName) throws Exception {
- // Emit abstract base class delegating to 32-bit or 64-bit implementations
- emitStructImpl(structType, alternateName, machDesc32, machDesc64, true, false);
- // Emit concrete implementing class for each variant
- emitStructImpl(structType, alternateName, machDesc32, machDesc64, false, true);
- emitStructImpl(structType, alternateName, machDesc32, machDesc64, false, false);
- }
-
- public void emitStructImpl(CompoundType structType,
- String alternateName,
- MachineDescription md32,
- MachineDescription md64,
- boolean doBaseClass,
- boolean do32Bit) throws Exception {
String name = structType.getName();
if (name == null && alternateName != null) {
name = alternateName;
@@ -805,50 +784,31 @@ public class JavaEmitter implements GlueEmitter {
}
String containingTypeName = containingType.getName();
- if ((md32 == null) || (md64 == null)) {
- throw new RuntimeException("Must supply both 32- and 64-bit MachineDescriptions to emitStructImpl");
- }
- String suffix = "";
-
- // The "external" MachineDescription is the one used to determine
- // the sizes of the primitive types seen in the public API. For
- // example, if a C long is an element of a struct, it is the size
+ // machDescJava global MachineDescription is the one used to determine
+ // the sizes of the primitive types seen in the public API in Java.
+ // For example, if a C long is an element of a struct, it is the size
// of a Java int on a 32-bit machine but the size of a Java long
// on a 64-bit machine. To support both of these sizes with the
// same API, the abstract base class must take and return a Java
// long from the setter and getter for this field. However the
// implementation on a 32-bit platform must downcast this to an
- // int and set only an int's worth of data in the struct. The
- // "internal" MachineDescription is the one used to determine how
+ // int and set only an int's worth of data in the struct.
+ //
+ // The machDescTarget MachineDescription is the one used to determine how
// much data to set in or get from the struct and exactly from
// where it comes.
//
- // Note that the 64-bit MachineDescription is always used as the
- // external MachineDescription.
-
- MachineDescription extMachDesc = md64;
- MachineDescription intMachDesc = null;
-
- if (!doBaseClass) {
- if (do32Bit) {
- intMachDesc = md32;
- suffix = "32";
- } else {
- intMachDesc = md64;
- suffix = "64";
- }
- }
+ // Note that machDescJava MachineDescription is always 64bit unix,
+ // which complies w/ Java types.
boolean needsNativeCode = false;
// Native code for calls through function pointers gets emitted
// into the abstract base class; Java code which accesses fields
// gets emitted into the concrete classes
- if (doBaseClass) {
- for (int i = 0; i < structType.getNumFields(); i++) {
- if (structType.getField(i).getType().isFunctionPointer()) {
- needsNativeCode = true;
- break;
- }
+ for (int i = 0; i < structType.getNumFields(); i++) {
+ if (structType.getField(i).getType().isFunctionPointer()) {
+ needsNativeCode = true;
+ break;
}
}
@@ -859,7 +819,7 @@ public class JavaEmitter implements GlueEmitter {
writer = openFile(
cfg.javaOutputDir() + File.separator +
CodeGenUtils.packageAsPath(structClassPkg) +
- File.separator + containingTypeName + suffix + ".java");
+ File.separator + containingTypeName + ".java");
CodeGenUtils.emitAutogeneratedWarning(writer, this);
if (needsNativeCode) {
String nRoot = cfg.nativeOutputDir();
@@ -883,6 +843,7 @@ public class JavaEmitter implements GlueEmitter {
writer.println("import " + cfg.gluegenRuntimePackage() + ".*;");
writer.println("import " + DynamicLookupHelper.class.getPackage().getName() + ".*;");
writer.println("import " + Buffers.class.getPackage().getName() + ".*;");
+ writer.println("import " + MachineDescriptionRuntime.class.getName() + ";");
writer.println();
List<String> imports = cfg.imports();
for (String str : imports) {
@@ -895,10 +856,7 @@ public class JavaEmitter implements GlueEmitter {
for (String doc : javadoc) {
writer.println(doc);
}
- writer.print((doBaseClass ? "public " : "") + (doBaseClass ? "abstract " : "") + "class " + containingTypeName + suffix + " ");
- if (!doBaseClass) {
- writer.print("extends " + containingTypeName + " ");
- }
+ writer.print("public class " + containingTypeName + " ");
boolean firstIteration = true;
List<String> userSpecifiedInterfaces = cfg.implementedInterfaces(containingTypeName);
for (String userInterface : userSpecifiedInterfaces) {
@@ -911,67 +869,95 @@ public class JavaEmitter implements GlueEmitter {
}
writer.println("{");
writer.println();
- if (doBaseClass) {
- writer.println(" StructAccessor accessor;");
- writer.println();
- }
+ writer.println(" StructAccessor accessor;");
+ writer.println();
+ writer.println(" private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();");
+ writer.println();
+ // generate all offset and size arrays
+ generateOffsetAndSizeArrays(writer, containingTypeName, structType, null); /* w/o offset */
+ for (int i = 0; i < structType.getNumFields(); i++) {
+ final Field field = structType.getField(i);
+ final Type fieldType = field.getType();
+
+ if (!cfg.shouldIgnoreInInterface(name + " " + field.getName())) {
+ final String renamed = cfg.getJavaSymbolRename(field.getName());
+ final String fieldName = renamed==null ? field.getName() : renamed;
+ if (fieldType.isFunctionPointer()) {
+ // no offset/size for function pointer ..
+ } else if (fieldType.isCompound()) {
+ // FIXME: will need to support this at least in order to
+ // handle the union in jawt_Win32DrawingSurfaceInfo (fabricate
+ // a name?)
+ if (fieldType.getName() == null) {
+ throw new RuntimeException("Anonymous structs as fields not supported yet (field \"" +
+ field + "\" in type \"" + name + "\")");
+ }
+
+ generateOffsetAndSizeArrays(writer, fieldName, fieldType, field);
+ } else if (fieldType.isArray()) {
+ Type baseElementType = field.getType().asArray().getBaseElementType();
+
+ if(!baseElementType.isPrimitive())
+ break;
+
+ generateOffsetAndSizeArrays(writer, fieldName, null, field); /* w/o size */
+ } else {
+ JavaType externalJavaType = null;
+ try {
+ externalJavaType = typeToJavaType(fieldType, false, machDescJava);
+ } catch (Exception e) {
+ System.err.println("Error occurred while creating accessor for field \"" +
+ field.getName() + "\" in type \"" + name + "\"");
+ throw(e);
+ }
+ if (externalJavaType.isPrimitive()) {
+ // Primitive type
+ generateOffsetAndSizeArrays(writer, fieldName, null, field); /* w/o size */
+ } else {
+ // FIXME
+ LOG.log(WARNING, "Complicated fields (field \"{0}\" of type \"{1}\") not implemented yet", new Object[]{field, name});
+ // throw new RuntimeException("Complicated fields (field \"" + field + "\" of type \"" + t +
+ // "\") not implemented yet");
+ }
+ }
+ }
+ }
+ writer.println();
writer.println(" public static int size() {");
- if (doBaseClass) {
- writer.println(" if (Platform.is32Bit()) {");
- writer.println(" return " + containingTypeName + "32" + ".size();");
- writer.println(" } else {");
- writer.println(" return " + containingTypeName + "64" + ".size();");
- writer.println(" }");
- } else {
- writer.println(" return " + structType.getSize(intMachDesc) + ";");
- }
+ writer.println(" return "+containingTypeName+"_size[mdIdx];");
writer.println(" }");
writer.println();
- if (doBaseClass) {
- writer.println(" public static " + containingTypeName + " create() {");
- writer.println(" return create(Buffers.newDirectByteBuffer(size()));");
- writer.println(" }");
- writer.println();
- writer.println(" public static " + containingTypeName + " create(java.nio.ByteBuffer buf) {");
- writer.println(" if (Platform.is32Bit()) {");
- writer.println(" return new " + containingTypeName + "32(buf);");
- writer.println(" } else {");
- writer.println(" return new " + containingTypeName + "64(buf);");
- writer.println(" }");
- writer.println(" }");
- writer.println();
- writer.println(" " + containingTypeName + "(java.nio.ByteBuffer buf) {");
- writer.println(" accessor = new StructAccessor(buf);");
- writer.println(" }");
- writer.println();
- writer.println(" public java.nio.ByteBuffer getBuffer() {");
- writer.println(" return accessor.getBuffer();");
- writer.println(" }");
- } else {
- writer.println(" " + containingTypeName + suffix + "(java.nio.ByteBuffer buf) {");
- writer.println(" super(buf);");
- writer.println(" }");
- writer.println();
- }
- for (int i = 0; i < structType.getNumFields(); i++) {
+ writer.println(" public static " + containingTypeName + " create() {");
+ writer.println(" return create(Buffers.newDirectByteBuffer(size()));");
+ writer.println(" }");
+ writer.println();
+ writer.println(" public static " + containingTypeName + " create(java.nio.ByteBuffer buf) {");
+ writer.println(" return new " + containingTypeName + "(buf);");
+ writer.println(" }");
+ writer.println();
+ writer.println(" " + containingTypeName + "(java.nio.ByteBuffer buf) {");
+ writer.println(" accessor = new StructAccessor(buf);");
+ writer.println(" }");
+ writer.println();
+ writer.println(" public java.nio.ByteBuffer getBuffer() {");
+ writer.println(" return accessor.getBuffer();");
+ writer.println(" }");
- Field field = structType.getField(i);
- Type fieldType = field.getType();
+ for (int i = 0; i < structType.getNumFields(); i++) {
+ final Field field = structType.getField(i);
+ final Type fieldType = field.getType();
if (!cfg.shouldIgnoreInInterface(name + " " + field.getName())) {
-
- String renamed = cfg.getJavaSymbolRename(field.getName());
- String fieldName = renamed==null ? field.getName() : renamed;
+ final String renamed = cfg.getJavaSymbolRename(field.getName());
+ final String fieldName = renamed==null ? field.getName() : renamed;
if (fieldType.isFunctionPointer()) {
-
- if (doBaseClass) {
try {
// Emit method call and associated native code
FunctionType funcType = fieldType.asPointer().getTargetType().asFunction();
FunctionSymbol funcSym = new FunctionSymbol(fieldName, funcType);
- MethodBinding binding = bindFunction(funcSym, containingType, containingCType, machDesc64);
+ MethodBinding binding = bindFunction(funcSym, containingType, containingCType, machDescJava);
binding.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis
writer.println();
@@ -1024,14 +1010,13 @@ public class JavaEmitter implements GlueEmitter {
false,
true,
false, // FIXME: should unify this with the general emission code
- machDesc64);
+ machDescJava);
prepCEmitter(binding, cEmitter);
cEmitter.emit();
} catch (Exception e) {
System.err.println("While processing field " + field + " of type " + name + ":");
throw(e);
}
- }
} else if (fieldType.isCompound()) {
// FIXME: will need to support this at least in order to
// handle the union in jawt_Win32DrawingSurfaceInfo (fabricate
@@ -1042,15 +1027,11 @@ public class JavaEmitter implements GlueEmitter {
}
writer.println();
- generateGetterSignature(writer, doBaseClass, fieldType.getName(), capitalizeString(fieldName));
- if (doBaseClass) {
- writer.println(";");
- } else {
- writer.println(" {");
- writer.println(" return " + fieldType.getName() + ".create(accessor.slice(" +
- field.getOffset(intMachDesc) + ", " + fieldType.getSize(intMachDesc) + "));");
- writer.println(" }");
- }
+ generateGetterSignature(writer, false, fieldType.getName(), capitalizeString(fieldName));
+ writer.println(" {");
+ writer.println(" return " + fieldType.getName() + ".create( accessor.slice( " +
+ fieldName+"_offset[mdIdx], "+fieldName+"_size[mdIdx] ) );");
+ writer.println(" }");
} else if (fieldType.isArray()) {
@@ -1059,110 +1040,70 @@ public class JavaEmitter implements GlueEmitter {
if(!baseElementType.isPrimitive())
break;
- String paramType = typeToJavaType(baseElementType, false, extMachDesc).getName();
+ String paramType = typeToJavaType(baseElementType, false, machDescJava).getName();
String capitalized = capitalizeString(fieldName);
- final int byteOffset = doBaseClass ? -1 : (int) field.getOffset(intMachDesc);
-
// Setter
writer.println();
- generateSetterSignature(writer, doBaseClass, containingTypeName, capitalized, paramType+"[]");
- if (doBaseClass) {
- writer.println(";");
- } else {
- writer.println(" {");
- writer.print (" accessor.set" + capitalizeString(paramType) + "sAt(" + byteOffset + ", ");
- writer.println("val);");
- writer.println(" return this;");
- writer.println(" }");
- }
+ generateSetterSignature(writer, false, containingTypeName, capitalized, paramType+"[]");
+ writer.println(" {");
+ writer.print (" accessor.set" + capitalizeString(paramType) + "sAt(" + fieldName+"_offset[mdIdx], val);");
+ writer.println(" return this;");
+ writer.println(" }");
writer.println();
// Getter
- generateGetterSignature(writer, doBaseClass, paramType+"[]", capitalized);
- if (doBaseClass) {
- writer.println(";");
- } else {
- writer.println(" {");
- writer.print (" return ");
- writer.println("accessor.get" + capitalizeString(paramType) + "sAt(" + byteOffset + ", new " +paramType+"["+fieldType.asArray().getLength()+"]);");
- writer.println(" }");
- }
-
+ generateGetterSignature(writer, false, paramType+"[]", capitalized);
+ writer.println(" {");
+ writer.print (" return accessor.get" + capitalizeString(paramType) + "sAt(" + fieldName+"_offset[mdIdx], new " +paramType+"["+fieldType.asArray().getLength()+"]);");
+ writer.println(" }");
} else {
- JavaType internalJavaType = null;
- JavaType externalJavaType = null;
-
+ JavaType javaType = null;
+
try {
- externalJavaType = typeToJavaType(fieldType, false, extMachDesc);
- if (!doBaseClass) {
- internalJavaType = typeToJavaType(fieldType, false, intMachDesc);
- }
+ javaType = typeToJavaType(fieldType, false, machDescJava);
} catch (Exception e) {
System.err.println("Error occurred while creating accessor for field \"" +
field.getName() + "\" in type \"" + name + "\"");
throw(e);
}
- if (externalJavaType.isPrimitive()) {
+ if (javaType.isPrimitive()) {
// Primitive type
- String externalJavaTypeName = null;
- String internalJavaTypeName = null;
- externalJavaTypeName = externalJavaType.getName();
- if (!doBaseClass) {
- internalJavaTypeName = internalJavaType.getName();
- }
+ final boolean fieldTypeNativeSizeFixed = fieldType.getSize().hasFixedNativeSize() || isOpaque(fieldType) ;
+ String javaTypeName = javaType.getName();
if (isOpaque(fieldType)) {
- externalJavaTypeName = compatiblePrimitiveJavaTypeName(fieldType, externalJavaType, extMachDesc);
- if (!doBaseClass) {
- internalJavaTypeName = compatiblePrimitiveJavaTypeName(fieldType, internalJavaType, intMachDesc);
- }
- }
- String capitalized = null;
- if (!doBaseClass) {
- capitalized = capitalizeString(internalJavaTypeName);
+ javaTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava);
}
- final int byteOffset = doBaseClass ? -1 : (int) field.getOffset(intMachDesc);
+ String capJavaTypeName = capitalizeString(javaTypeName);
+
writer.println();
- String capitalizedFieldName = capitalizeString(fieldName);
+ String capFieldName = capitalizeString(fieldName);
// Setter
- generateSetterSignature(writer, doBaseClass, containingTypeName, capitalizedFieldName, externalJavaTypeName);
- if (doBaseClass) {
- writer.println(";");
+ generateSetterSignature(writer, false, containingTypeName, capFieldName, javaTypeName);
+ writer.println(" {");
+ if( fieldTypeNativeSizeFixed ) {
+ writer.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);");
} else {
- writer.println(" {");
- writer.print (" accessor.set" + capitalized + "At(" + byteOffset + ", ");
- if (!externalJavaTypeName.equals(internalJavaTypeName)) {
- writer.print("(" + internalJavaTypeName + ") ");
- }
- writer.println("val);");
- writer.println(" return this;");
- writer.println(" }");
+ writer.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+javaTypeName+"SizeInBytes());");
}
+ writer.println(" return this;");
+ writer.println(" }");
writer.println();
+
// Getter
- generateGetterSignature(writer, doBaseClass, externalJavaTypeName, capitalizedFieldName);
- if (doBaseClass) {
- writer.println(";");
+ generateGetterSignature(writer, false, javaTypeName, capFieldName);
+ writer.println(" {");
+ writer.print (" return ");
+ if( fieldTypeNativeSizeFixed ) {
+ writer.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx]);");
} else {
- writer.println(" {");
- writer.print (" return ");
- if (!externalJavaTypeName.equals(internalJavaTypeName)) {
- writer.print("(" + externalJavaTypeName + ") ");
- }
- writer.println("accessor.get" + capitalized + "At(" + byteOffset + ");");
- writer.println(" }");
- }
- } else {
- // FIXME
- LOG.log(WARNING, "Complicated fields (field \"{0}\" of type \"{1}\") not implemented yet", new Object[]{field, name});
- // throw new RuntimeException("Complicated fields (field \"" + field + "\" of type \"" + t +
- // "\") not implemented yet");
+ writer.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+javaTypeName+"SizeInBytes());");
+ }
+ writer.println(" }");
}
}
}
}
- if (doBaseClass) {
- emitCustomJavaCode(writer, containingTypeName);
- }
+ emitCustomJavaCode(writer, containingTypeName);
writer.println("}");
writer.flush();
writer.close();
@@ -1201,14 +1142,39 @@ public class JavaEmitter implements GlueEmitter {
// Internals only below this point
//
- private void generateGetterSignature(PrintWriter writer, boolean baseClass, String returnTypeName, String capitalizedFieldName) {
- writer.print(" public " + (baseClass ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "()");
- }
+ private void generateGetterSignature(PrintWriter writer, boolean abstractMethod, String returnTypeName, String capitalizedFieldName) {
+ writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "()");
+ }
- private void generateSetterSignature(PrintWriter writer, boolean baseClass, String returnTypeName, String capitalizedFieldName, String paramTypeName) {
- writer.print(" public " + (baseClass ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "(" + paramTypeName + " val)");
- }
+ private void generateSetterSignature(PrintWriter writer, boolean abstractMethod, String returnTypeName, String capitalizedFieldName, String paramTypeName) {
+ writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "(" + paramTypeName + " val)");
+ }
+ private void generateOffsetAndSizeArrays(PrintWriter writer, String fieldName, Type fieldType, Field field) {
+ if(null != field) {
+ writer.print(" private static final int[] "+fieldName+"_offset = new int[] { ");
+ for( int i=0; i < machDescTargetConfigs.length; i++ ) {
+ if(0<i) {
+ writer.print(", ");
+ }
+ writer.print(field.getOffset(machDescTargetConfigs[i].md) +
+ " /* " + machDescTargetConfigs[i].name() + " */");
+ }
+ writer.println(" };");
+ }
+ if(null!=fieldType) {
+ writer.print(" private static final int[] "+fieldName+"_size = new int[] { ");
+ for( int i=0; i < machDescTargetConfigs.length; i++ ) {
+ if(0<i) {
+ writer.print(", ");
+ }
+ writer.print(fieldType.getSize(machDescTargetConfigs[i].md) +
+ " /* " + machDescTargetConfigs[i].name() + " */");
+ }
+ writer.println(" };");
+ }
+ }
+
private JavaType typeToJavaType(Type cType, boolean outgoingArgument, MachineDescription curMachDesc) {
// Recognize JNIEnv* case up front
PointerType opt = cType.asPointer();