summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/gluegen/JavaEmitter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/com/jogamp/gluegen/JavaEmitter.java')
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java1158
1 files changed, 880 insertions, 278 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index 822c1c9..3125edf 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -659,21 +659,20 @@ public class JavaEmitter implements GlueEmitter {
(binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue),
!cfg.useNIODirectOnly(binding.getName()),
machDescJava);
- prepCEmitter(binding, cEmitter);
+ prepCEmitter(binding.getName(), binding.getJavaReturnType(), cEmitter);
allEmitters.add(cEmitter);
}
}
}
- protected void prepCEmitter(MethodBinding binding, CMethodBindingEmitter cEmitter)
+ protected void prepCEmitter(String returnSizeLookupName, JavaType javaReturnType, CMethodBindingEmitter cEmitter)
{
// See whether we need an expression to help calculate the
// length of any return type
- JavaType javaReturnType = binding.getJavaReturnType();
if (javaReturnType.isNIOBuffer() ||
javaReturnType.isCompoundTypeWrapper()) {
// See whether capacity has been specified
- String capacity = cfg.returnValueCapacity(binding.getName());
+ final String capacity = cfg.returnValueCapacity(returnSizeLookupName);
if (capacity != null) {
cEmitter.setReturnValueCapacityExpression( new MessageFormat(capacity) );
}
@@ -688,13 +687,13 @@ public class JavaEmitter implements GlueEmitter {
}
// See whether length has been specified
- String len = cfg.returnValueLength(binding.getName());
+ final String len = cfg.returnValueLength(returnSizeLookupName);
if (len != null) {
cEmitter.setReturnValueLengthExpression( new MessageFormat(len) );
}
}
- cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(binding.getName()));
- cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(binding.getName()));
+ cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(returnSizeLookupName));
+ cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(returnSizeLookupName));
}
/**
@@ -827,32 +826,35 @@ public class JavaEmitter implements GlueEmitter {
}
@Override
- public void emitStruct(CompoundType structType, String alternateName) throws Exception {
- String name = structType.getName();
- if (name == null && alternateName != null) {
- name = alternateName;
+ public void emitStruct(final CompoundType structCType, final String alternateName) throws Exception {
+ final String structCTypeName;
+ {
+ String _name = structCType.getName();
+ if (_name == null && alternateName != null) {
+ _name = alternateName;
+ }
+ structCTypeName = _name;
}
- if (name == null) {
- final String structName = structType.getStructName();
+ if (structCTypeName == null) {
+ final String structName = structCType.getStructName();
if ( null != structName && cfg.shouldIgnoreInInterface(structName) ) {
return;
}
-
- LOG.log(WARNING, "skipping emission of unnamed struct \"{0}\"", structType);
+ LOG.log(WARNING, "skipping emission of unnamed struct \"{0}\"", structCType);
return;
}
- if (cfg.shouldIgnoreInInterface(name)) {
+ if (cfg.shouldIgnoreInInterface(structCTypeName)) {
return;
}
- Type containingCType = canonicalize(new PointerType(SizeThunk.POINTER, structType, 0));
- JavaType containingType = typeToJavaType(containingCType, false, null);
- if (!containingType.isCompoundTypeWrapper()) {
+ final Type containingCType = canonicalize(new PointerType(SizeThunk.POINTER, structCType, 0));
+ final JavaType containingJType = typeToJavaType(containingCType, null);
+ if (!containingJType.isCompoundTypeWrapper()) {
return;
}
- String containingTypeName = containingType.getName();
+ final String containingJTypeName = containingJType.getName();
this.requiresStaticInitialization = false; // reset
@@ -874,23 +876,36 @@ public class JavaEmitter implements GlueEmitter {
// 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
- for (int i = 0; i < structType.getNumFields(); i++) {
- if (structType.getField(i).getType().isFunctionPointer()) {
- needsNativeCode = true;
- break;
+ for (int i = 0; i < structCType.getNumFields(); i++) {
+ final Field field = structCType.getField(i);
+ final Type fieldType = field.getType();
+
+ final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName());
+
+ if (!cfg.shouldIgnoreInInterface(cfgFieldName0)) {
+
+ final String renamed = cfg.getJavaSymbolRename(cfgFieldName0);
+ final String fieldName = renamed==null ? field.getName() : renamed;
+ final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName);
+
+ if ( fieldType.isFunctionPointer() || fieldType.isPointer() || requiresGetCStringLength(fieldType, cfgFieldName1) ) {
+ needsNativeCode = true;
+ break;
+ }
}
}
- final String structClassPkg = cfg.packageForStruct(name);
+ final String structClassPkgName = cfg.packageForStruct(structCTypeName);
final PrintWriter javaWriter;
final PrintWriter jniWriter;
try {
javaWriter = openFile(cfg.javaOutputDir() + File.separator +
- CodeGenUtils.packageAsPath(structClassPkg) +
- File.separator + containingTypeName + ".java", containingTypeName);
+ CodeGenUtils.packageAsPath(structClassPkgName) +
+ File.separator + containingJTypeName + ".java", containingJTypeName);
if( null == javaWriter ) {
// suppress output if openFile deliberately returns null.
return;
@@ -901,9 +916,9 @@ public class JavaEmitter implements GlueEmitter {
if (cfg.nativeOutputUsesJavaHierarchy()) {
nRoot += File.separator + CodeGenUtils.packageAsPath(cfg.packageName());
}
- jniWriter = openFile(nRoot + File.separator + containingTypeName + "_JNI.c", containingTypeName);
+ jniWriter = openFile(nRoot + File.separator + containingJTypeName + "_JNI.c", containingJTypeName);
CodeGenUtils.emitAutogeneratedWarning(jniWriter, this);
- emitCHeader(jniWriter, structClassPkg, containingTypeName);
+ emitCHeader(jniWriter, structClassPkgName, containingJTypeName);
} else {
jniWriter = null;
}
@@ -912,7 +927,7 @@ public class JavaEmitter implements GlueEmitter {
}
javaWriter.println();
- javaWriter.println("package " + structClassPkg + ";");
+ javaWriter.println("package " + structClassPkgName + ";");
javaWriter.println();
javaWriter.println("import java.nio.*;");
javaWriter.println();
@@ -929,13 +944,13 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println(";");
}
javaWriter.println();
- List<String> javadoc = cfg.javadocForClass(containingTypeName);
+ List<String> javadoc = cfg.javadocForClass(containingJTypeName);
for (String doc : javadoc) {
javaWriter.println(doc);
}
- javaWriter.print("public class " + containingTypeName + " ");
+ javaWriter.print("public class " + containingJTypeName + " ");
boolean firstIteration = true;
- List<String> userSpecifiedInterfaces = cfg.implementedInterfaces(containingTypeName);
+ List<String> userSpecifiedInterfaces = cfg.implementedInterfaces(containingJTypeName);
for (String userInterface : userSpecifiedInterfaces) {
if (firstIteration) {
javaWriter.print("implements ");
@@ -951,85 +966,90 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println(" private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();");
javaWriter.println();
// generate all offset and size arrays
- generateOffsetAndSizeArrays(javaWriter, " ", containingTypeName, structType, null, null); /* w/o offset */
+ generateOffsetAndSizeArrays(javaWriter, " ", containingJTypeName, structCType, null, null); /* w/o offset */
if( GlueGen.debug() ) {
- System.err.printf("SE.__: t %s: %s%n", structType, containingTypeName);
+ System.err.printf("SE.__: structCType %s%n", structCType.getDebugString());
+ System.err.printf("SE.__: contCTypeName %s%n", containingCType.getDebugString());
+ System.err.printf("SE.__: contJTypeName %s%n", containingJType.getDebugString());
}
- for (int i = 0; i < structType.getNumFields(); i++) {
- final Field field = structType.getField(i);
+ for (int i = 0; i < structCType.getNumFields(); i++) {
+ final Field field = structCType.getField(i);
final Type fieldType = field.getType();
-
- if (!cfg.shouldIgnoreInInterface(name + " " + field.getName())) {
- final String renamed = cfg.getJavaSymbolRename(field.getName());
+ final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName());
+ if ( !cfg.shouldIgnoreInInterface(cfgFieldName0) ) {
+ final String renamed = cfg.getJavaSymbolRename(cfgFieldName0);
final String fieldName = null==renamed ? field.getName() : renamed;
+ final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName);
if (fieldType.isFunctionPointer()) {
// no offset/size for function pointer ..
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s / %s (%s)%n", (i+1), fieldType, field, fieldName, "SKIP FuncPtr");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "SKIP FuncPtr");
}
} 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 + "\")");
+ throw new RuntimeException("Anonymous structs as fields not supported yet, field \"" +
+ cfgFieldName1 + "\", "+fieldType.getDebugString());
}
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s / %s (%s)%n", (i+1), fieldType, field, fieldName, "compound");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "compound");
}
generateOffsetAndSizeArrays(javaWriter, " ", fieldName, fieldType, field, null);
} else if (fieldType.isArray()) {
final Type baseElementType = field.getType().asArray().getBaseElementType();
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s / %s - baseType %s (%s)%n", (i+1), fieldType, field, fieldName, baseElementType, "array");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "array");
+ System.err.printf("SE.os.%02d: baseType %s%n", (i+1), baseElementType.getDebugString());
}
generateOffsetAndSizeArrays(javaWriter, " ", fieldName, fieldType, field, null);
} else {
final JavaType externalJavaType;
try {
- externalJavaType = typeToJavaType(fieldType, false, machDescJava);
+ externalJavaType = typeToJavaType(fieldType, machDescJava);
} catch (Exception e) {
- System.err.println("Error occurred while creating accessor for field \"" +
- field.getName() + "\" in type \"" + name + "\"");
- throw(e);
+ throw new RuntimeException("Error occurred while creating accessor for field \"" +
+ cfgFieldName1 + "\", "+fieldType.getDebugString(), e);
}
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s / %s - javaType %s (%s)%n", (i+1), fieldType, field, fieldName, externalJavaType.getDumpString(), "MISC");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, fieldName, fieldType.getDebugString(), "MISC");
+ System.err.printf("SE.os.%02d: javaType %s%n", (i+1), externalJavaType.getDebugString());
}
if (externalJavaType.isPrimitive()) {
// Primitive type
generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, null);
} else if (externalJavaType.isCPrimitivePointerType()) {
- // FIXME: Primitive Pointer type
- generateOffsetAndSizeArrays(javaWriter, "// Skipped C-Primitive-Ptr-Type: ", fieldName, fieldType, field, externalJavaType.getDumpString());
+ if( requiresGetCStringLength(fieldType, cfgFieldName1) ) {
+ generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, "// "+externalJavaType.getDebugString());
+ } else {
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, field, "// "+externalJavaType.getDebugString());
+ }
} else {
- // FIXME ???
- generateOffsetAndSizeArrays(javaWriter, "// Skipped Complicated Field: ", fieldName, fieldType, field, externalJavaType.getDumpString());
- LOG.log(WARNING, "Complicated fields (field \"{0}\" of type \"{1}\") not implemented yet: {2}",
- new Object[]{field, name, externalJavaType.getDumpString()});
- // throw new RuntimeException("Complicated fields (field \"" + field + "\" of type \"" + t +
- // "\") not implemented yet");
+ generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, "// "+externalJavaType.getDebugString());
}
}
} else if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s (IGNORED)%n", (i+1), fieldType, field);
+ System.err.printf("SE.os.%02d: %s, %s (IGNORED)%n", (i+1), field, fieldType.getDebugString());
}
}
javaWriter.println();
javaWriter.println(" public static int size() {");
- javaWriter.println(" return "+containingTypeName+"_size[mdIdx];");
+ javaWriter.println(" return "+containingJTypeName+"_size[mdIdx];");
javaWriter.println(" }");
javaWriter.println();
- javaWriter.println(" public static " + containingTypeName + " create() {");
+ javaWriter.println(" public static " + containingJTypeName + " create() {");
javaWriter.println(" return create(Buffers.newDirectByteBuffer(size()));");
javaWriter.println(" }");
javaWriter.println();
- javaWriter.println(" public static " + containingTypeName + " create(java.nio.ByteBuffer buf) {");
- javaWriter.println(" return new " + containingTypeName + "(buf);");
+ javaWriter.println(" public static " + containingJTypeName + " create(java.nio.ByteBuffer buf) {");
+ javaWriter.println(" return new " + containingJTypeName + "(buf);");
javaWriter.println(" }");
javaWriter.println();
- javaWriter.println(" " + containingTypeName + "(java.nio.ByteBuffer buf) {");
+ javaWriter.println(" " + containingJTypeName + "(java.nio.ByteBuffer buf) {");
javaWriter.println(" accessor = new StructAccessor(buf);");
javaWriter.println(" }");
javaWriter.println();
@@ -1037,168 +1057,52 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println(" return accessor.getBuffer();");
javaWriter.println(" }");
- for (int i = 0; i < structType.getNumFields(); i++) {
- final Field field = structType.getField(i);
+ Set<MethodBinding> methodBindingSet = new HashSet<MethodBinding>();
+
+ for (int i = 0; i < structCType.getNumFields(); i++) {
+ final Field field = structCType.getField(i);
final Type fieldType = field.getType();
- if (!cfg.shouldIgnoreInInterface(name + " " + field.getName())) {
- final String renamed = cfg.getJavaSymbolRename(field.getName());
+ final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName());
+ if (!cfg.shouldIgnoreInInterface(cfgFieldName0)) {
+ final String renamed = cfg.getJavaSymbolRename(cfgFieldName0);
final String fieldName = renamed==null ? field.getName() : renamed;
+ final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName);
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: %s / %s, %s%n", (i+1), field, cfgFieldName1, fieldType.getDebugString());
+ }
if (fieldType.isFunctionPointer()) {
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: t %s: %s / %s (%s)%n", (i+1), fieldType, field, fieldName, "funcPtr");
- }
- try {
- // Emit method call and associated native code
- final FunctionType funcType = fieldType.asPointer().getTargetType().asFunction();
- final FunctionSymbol funcSym = new FunctionSymbol(fieldName, funcType);
- final MethodBinding binding = bindFunction(funcSym, containingType, containingCType, machDescJava);
- binding.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis
- javaWriter.println();
-
- // Emit public Java entry point for calling this function pointer
- JavaMethodBindingEmitter emitter =
- new JavaMethodBindingEmitter(binding,
- javaWriter,
- cfg.runtimeExceptionType(),
- cfg.unsupportedExceptionType(),
- true,
- cfg.tagNativeBinding(),
- false, // eraseBufferAndArrayTypes
- true, // FIXME: should unify this with the general emission code
- true, // FIXME: should unify this with the general emission code
- false,
- false, // FIXME: should unify this with the general emission code
- false, // FIXME: should unify this with the general emission code
- false, // FIXME: should unify this with the general emission code
- false,
- cfg);
- emitter.addModifier(JavaMethodBindingEmitter.PUBLIC);
- emitter.emit();
-
- // Emit private native Java entry point for calling this function pointer
- emitter =
- new JavaMethodBindingEmitter(binding,
- javaWriter,
- cfg.runtimeExceptionType(),
- cfg.unsupportedExceptionType(),
- false,
- cfg.tagNativeBinding(),
- true,
- true, // FIXME: should unify this with the general emission code
- true, // FIXME: should unify this with the general emission code
- true,
- true, // FIXME: should unify this with the general emission code
- false, // FIXME: should unify this with the general emission code
- false, // FIXME: should unify this with the general emission code
- false,
- cfg);
- emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
- emitter.addModifier(JavaMethodBindingEmitter.NATIVE);
- emitter.emit();
-
- // Emit (private) C entry point for calling this function pointer
- CMethodBindingEmitter cEmitter =
- new CMethodBindingEmitter(binding,
- jniWriter,
- structClassPkg,
- containingTypeName,
- true, // FIXME: this is optional at this point
- false,
- true,
- false, // FIXME: should unify this with the general emission code
- machDescJava);
- prepCEmitter(binding, cEmitter);
- cEmitter.emit();
- } catch (Exception e) {
- System.err.println("While processing field " + field + " of type " + name + ":");
- throw(e);
- }
+ generateFunctionPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
+ containingCType, containingJType, i,
+ new FunctionSymbol(fieldName, fieldType.asPointer().getTargetType().asFunction()), cfgFieldName1);
} 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 + "\")");
+ field + "\" in type \"" + structCTypeName + "\")");
}
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: t %s: %s / %s (%s)%n", (i+1), fieldType, field, fieldName, "compound");
- }
-
javaWriter.println();
- generateGetterSignature(javaWriter, false, fieldType.getName(), capitalizeString(fieldName));
+ generateGetterSignature(javaWriter, fieldType, false, fieldType.getName(), capitalizeString(fieldName), null, null);
javaWriter.println(" {");
javaWriter.println(" return " + fieldType.getName() + ".create( accessor.slice( " +
fieldName+"_offset[mdIdx], "+fieldName+"_size[mdIdx] ) );");
javaWriter.println(" }");
- } else if (fieldType.isArray()) {
- final Type baseElementType = field.getType().asArray().getBaseElementType();
- final JavaType paramType = typeToJavaType(baseElementType, false, machDescJava);
-
- final String paramTypeName = paramType.getName();
- final String capitalized = capitalizeString(fieldName);
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: t %s: %s / %s - baseType %s, paramType %s (%s)%n", (i+1), fieldType, field, fieldName, baseElementType, paramType.getDumpString(), "array");
- }
-
- // Setter
- javaWriter.println();
- generateSetterSignature(javaWriter, false, containingTypeName, capitalized, paramTypeName+"[]");
- javaWriter.println(" {");
- if(baseElementType.isPrimitive()) {
- javaWriter.print (" accessor.set" + capitalizeString(paramTypeName) + "sAt(" + fieldName+"_offset[mdIdx], val);");
- javaWriter.println(" return this;");
- } else {
- javaWriter.println(" final int elemSize = "+paramTypeName+".size();");
- javaWriter.println(" final ByteBuffer destB = getBuffer();");
- javaWriter.println(" int offset = "+fieldName+"_offset[mdIdx];");
- javaWriter.println(" final int total = "+fieldType.asArray().getLength()+" * elemSize;");
- javaWriter.println(" if( total > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"total \"+total+\" > size \"+"+fieldName+"_size[mdIdx]+\", elemSize \"+elemSize+\" * "+fieldType.asArray().getLength()+"\"); };");
- javaWriter.println(" final int limes = offset + total;");
- javaWriter.println(" if( limes >= destB.limit() ) { throw new IndexOutOfBoundsException(\"limes \"+limes+\" >= buffer.limit \"+destB.limit()+\", elemOff \"+offset+\", elemSize \"+elemSize+\" * "+fieldType.asArray().getLength()+"\"); };");
- javaWriter.println(" for(int e=0; e<"+fieldType.asArray().getLength()+"; e++) {");
- javaWriter.println(" final "+paramTypeName+" source = val[e];");
- javaWriter.println(" final ByteBuffer sourceB = source.getBuffer();");
- javaWriter.println(" for(int f=0; f<elemSize; f++) {");
- javaWriter.println(" if( offset >= limes ) { throw new IndexOutOfBoundsException(\"elem-byte[\"+e+\"][\"+f+\"]: offset \"+offset+\" >= limes \"+limes+\", elemSize \"+elemSize+\" * "+fieldType.asArray().getLength()+"\"); };");
- javaWriter.println(" destB.put(offset++, sourceB.get(f));");
- javaWriter.println(" }");
- javaWriter.println(" }");
- javaWriter.println(" return this;");
- }
- javaWriter.println(" }");
- javaWriter.println();
- // Getter
- generateGetterSignature(javaWriter, false, paramTypeName+"[]", capitalized);
- javaWriter.println(" {");
- if(baseElementType.isPrimitive()) {
- javaWriter.print (" return accessor.get" + capitalizeString(paramTypeName) + "sAt(" + fieldName+"_offset[mdIdx], new " +paramTypeName+"["+fieldType.asArray().getLength()+"]);");
- } else {
- javaWriter.println(" final "+paramTypeName+"[] res = new "+paramTypeName+"["+fieldType.asArray().getLength()+"];");
- javaWriter.println(" int offset = "+fieldName+"_offset[mdIdx];");
- javaWriter.println(" final int elemSize = "+paramTypeName+".size();");
- javaWriter.println(" for(int e=0; e<"+fieldType.asArray().getLength()+"; e++) {");
- javaWriter.println(" res[e] = "+paramTypeName+".create(accessor.slice(offset, elemSize));");
- javaWriter.println(" offset += elemSize;");
- javaWriter.println(" }");
- javaWriter.println(" return res;");
- }
- javaWriter.println(" }");
+ } else if ( fieldType.isArray() || fieldType.isPointer() ) {
+ generateArrayGetterSetterCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
+ containingCType, containingJType,
+ i, field, fieldName, cfgFieldName1);
} else {
final JavaType javaType;
-
try {
- javaType = typeToJavaType(fieldType, false, machDescJava);
+ javaType = typeToJavaType(fieldType, machDescJava);
} catch (Exception e) {
System.err.println("Error occurred while creating accessor for field \"" +
- field.getName() + "\" in type \"" + name + "\"");
+ field.getName() + "\", "+fieldType.getDebugString());
throw(e);
}
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: t %s: %s / %s - javaType %s (%s)%n", (i+1), fieldType, field, fieldName, javaType.getDumpString(), "MISC");
- }
if (javaType.isPrimitive()) {
// Primitive type
final boolean fieldTypeNativeSizeFixed = fieldType.getSize().hasFixedNativeSize();
@@ -1213,26 +1117,27 @@ public class JavaEmitter implements GlueEmitter {
final String sizeDenominator = fieldType.isPointer() ? "pointer" : javaTypeName ;
if(GlueGen.debug()) {
- System.err.println("Java.StructEmitter.Primitive: "+field.getName()+", "+fieldType.getName(true)+", "+javaTypeName+", "+
- ", fixedSize "+fieldTypeNativeSizeFixed+", opaque "+isOpaque(fieldType)+", isPointer "+fieldType.isPointer()+", isCompound "+fieldType.isCompound()+
- ", sizeDenominator "+sizeDenominator);
+ System.err.println("Java.StructEmitter.Primitive: "+field.getName()+", "+fieldType.getDebugString()+", "+javaTypeName+", "+
+ ", fixedSize "+fieldTypeNativeSizeFixed+", opaque "+isOpaque(fieldType)+", sizeDenominator "+sizeDenominator);
}
- javaWriter.println();
- // Setter
- generateSetterSignature(javaWriter, false, containingTypeName, capFieldName, javaTypeName);
- javaWriter.println(" {");
- if( fieldTypeNativeSizeFixed ) {
- javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);");
- } else {
- javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
+ if( !fieldType.isConst() ) {
+ // Setter
+ javaWriter.println();
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capFieldName, null, javaTypeName, null, null);
+ javaWriter.println(" {");
+ if( fieldTypeNativeSizeFixed ) {
+ javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);");
+ } else {
+ javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
+ }
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
}
- javaWriter.println(" return this;");
- javaWriter.println(" }");
- javaWriter.println();
// Getter
- generateGetterSignature(javaWriter, false, javaTypeName, capFieldName);
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, javaTypeName, capFieldName, null, null);
javaWriter.println(" {");
javaWriter.print (" return ");
if( fieldTypeNativeSizeFixed ) {
@@ -1241,30 +1146,31 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
}
javaWriter.println(" }");
- } else if (javaType.isCPrimitivePointerType()) {
- // FIXME: Primitive Pointer type
+ } else {
javaWriter.println();
- javaWriter.println(" /** "+fieldName +": "+javaType.getDumpString()+" */");
+ javaWriter.println(" /** UNKNOWN: "+cfgFieldName1 +": "+fieldType.getDebugString()+", "+javaType.getDebugString()+" */");
}
}
}
}
- emitCustomJavaCode(javaWriter, containingTypeName);
+ emitCustomJavaCode(javaWriter, containingJTypeName);
if (needsNativeCode) {
javaWriter.println();
- emitJavaInitCode(javaWriter, containingTypeName);
+ emitJavaInitCode(javaWriter, containingJTypeName);
javaWriter.println();
}
javaWriter.println("}");
javaWriter.flush();
javaWriter.close();
if (needsNativeCode) {
- emitCInitCode(jniWriter, structClassPkg, containingTypeName);
+ emitCInitCode(jniWriter, structClassPkgName, containingJTypeName);
jniWriter.flush();
jniWriter.close();
}
if( GlueGen.debug() ) {
- System.err.printf("SE.XX: t %s: %s%n", structType, containingTypeName);
+ System.err.printf("SE.XX: structCType %s%n", structCType.getDebugString());
+ System.err.printf("SE.XX: contCTypeName %s%n", containingCType.getDebugString());
+ System.err.printf("SE.XX: contJTypeName %s%n", containingJType.getDebugString());
}
}
@Override
@@ -1298,12 +1204,39 @@ public class JavaEmitter implements GlueEmitter {
// Internals only below this point
//
- private void generateGetterSignature(PrintWriter writer, boolean abstractMethod, String returnTypeName, String capitalizedFieldName) {
- writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "()");
+ private void generateGetterSignature(final PrintWriter writer, final Type origFieldType, final boolean abstractMethod,
+ final String returnTypeName, final String capitalizedFieldName,
+ final String customArgs, final String arrayLengthExpr) {
+ writer.print(" /** Getter for native field: "+origFieldType.getDebugString());
+ if( null != arrayLengthExpr ) {
+ writer.print(", with array length of <code>"+arrayLengthExpr+"</code>");
+ }
+ writer.println(" */");
+ writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "(");
+ if( null != customArgs ) {
+ writer.print(customArgs);
+ }
+ writer.print(")");
}
- 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 generateSetterSignature(final PrintWriter writer, final Type origFieldType, final boolean abstractMethod,
+ final String returnTypeName, final String capitalizedFieldName,
+ final String customArgsPre, final String paramTypeName, final String customArgsPost,
+ final String arrayLengthExpr) {
+ writer.print(" /** Setter for native field: "+origFieldType.getDebugString());
+ if( null != arrayLengthExpr ) {
+ writer.print(", with array length of <code>"+arrayLengthExpr+"</code>");
+ }
+ writer.println(" */");
+ writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "(");
+ if( null != customArgsPre ) {
+ writer.print(customArgsPre+", ");
+ }
+ writer.print(paramTypeName + " val");
+ if( null != customArgsPost ) {
+ writer.print(", "+customArgsPost);
+ }
+ writer.print(")");
}
private void generateOffsetAndSizeArrays(PrintWriter writer, String prefix, String fieldName, Type fieldType, Field field, String postfix) {
@@ -1336,31 +1269,682 @@ public class JavaEmitter implements GlueEmitter {
}
}
- private JavaType typeToJavaType(Type cType, boolean outgoingArgument, MachineDescription curMachDesc) {
+ private void generateFunctionPointerCode(final Set<MethodBinding> methodBindingSet,
+ final PrintWriter javaWriter, final PrintWriter jniWriter,
+ final String structCTypeName, final String structClassPkgName,
+ 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);
+ mb.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis
+
+ // JavaTypes representing C pointers in the initial
+ // MethodBinding have not been lowered yet to concrete types
+ final List<MethodBinding> bindings = expandMethodBinding(mb);
+
+ final boolean useNIOOnly = true;
+ final boolean useNIODirectOnly = true;
+
+ for (final MethodBinding binding : bindings) {
+ if(!methodBindingSet.add(binding)) {
+ // skip .. already exisiting binding ..
+ continue;
+ }
+ javaWriter.println();
+ // Emit public Java entry point for calling this function pointer
+ JavaMethodBindingEmitter emitter =
+ new JavaMethodBindingEmitter(binding,
+ javaWriter,
+ cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
+ true,
+ cfg.tagNativeBinding(),
+ false, // eraseBufferAndArrayTypes
+ useNIOOnly,
+ useNIODirectOnly,
+ false,
+ false, // FIXME: should unify this with the general emission code
+ false, // forIndirectBufferAndArrayImplementation
+ false, // FIXME: should unify this with the general emission code
+ false,
+ cfg);
+ emitter.addModifier(JavaMethodBindingEmitter.PUBLIC);
+ emitter.emit();
+
+ // Emit private native Java entry point for calling this function pointer
+ emitter =
+ new JavaMethodBindingEmitter(binding,
+ javaWriter,
+ cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
+ false,
+ cfg.tagNativeBinding(),
+ true, // eraseBufferAndArrayTypes
+ useNIOOnly,
+ useNIODirectOnly,
+ true,
+ true, // FIXME: should unify this with the general emission code
+ false, // forIndirectBufferAndArrayImplementation
+ false, // FIXME: should unify this with the general emission code
+ false,
+ cfg);
+ emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
+ emitter.addModifier(JavaMethodBindingEmitter.NATIVE);
+ emitter.emit();
+
+ // Emit (private) C entry point for calling this function pointer
+ CMethodBindingEmitter cEmitter =
+ new CMethodBindingEmitter(binding,
+ jniWriter,
+ structClassPkgName,
+ containingJType.getName(),
+ true, // FIXME: this is optional at this point
+ false,
+ true,
+ false, // forIndirectBufferAndArrayImplementation
+ machDescJava);
+ cEmitter.setIsCStructFunctionPointer(true);
+ prepCEmitter(returnSizeLookupName, binding.getJavaReturnType(), cEmitter);
+ cEmitter.emit();
+ }
+ }
+
+ private void generateArrayPointerCode(final Set<MethodBinding> methodBindingSet,
+ final PrintWriter javaWriter, final PrintWriter jniWriter,
+ final String structCTypeName, final String structClassPkgName,
+ final Type containingCType, final JavaType containingJType,
+ 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);
+ mb.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis
+
+ // JavaTypes representing C pointers in the initial
+ // MethodBinding have not been lowered yet to concrete types
+ final List<MethodBinding> bindings = expandMethodBinding(mb);
+
+ final boolean useNIOOnly = true;
+ final boolean useNIODirectOnly = true;
+
+ for (final MethodBinding binding : bindings) {
+ if(!methodBindingSet.add(binding)) {
+ // skip .. already exisiting binding ..
+ continue;
+ }
+ JavaMethodBindingEmitter emitter;
+
+ // Emit private native Java entry point for calling this function pointer
+ emitter =
+ new JavaMethodBindingEmitter(binding,
+ javaWriter,
+ cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
+ false,
+ cfg.tagNativeBinding(),
+ true, // eraseBufferAndArrayTypes
+ useNIOOnly,
+ useNIODirectOnly,
+ true,
+ true, // FIXME: should unify this with the general emission code
+ false, // forIndirectBufferAndArrayImplementation
+ false, // FIXME: should unify this with the general emission code
+ false,
+ cfg);
+ if( null != docArrayLenExpr ) {
+ emitter.setReturnedArrayLengthExpression(docArrayLenExpr, true);
+ }
+ emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
+ emitter.addModifier(JavaMethodBindingEmitter.NATIVE);
+ emitter.emit();
+
+ // Emit (private) C entry point for calling this function pointer
+ CMethodBindingEmitter cEmitter =
+ new CMethodBindingEmitter(binding,
+ jniWriter,
+ structClassPkgName,
+ containingJType.getName(),
+ true, // FIXME: this is optional at this point
+ false,
+ true,
+ false, // forIndirectBufferAndArrayImplementation
+ machDescJava);
+ cEmitter.setIsCStructFunctionPointer(false);
+ final String lenExprSet;
+ if( null != nativeArrayLenExpr ) {
+ JavaType javaReturnType = binding.getJavaReturnType();
+ if (javaReturnType.isNIOBuffer() ||
+ javaReturnType.isCompoundTypeWrapper()) {
+ final Type retType = funcSym.getReturnType();
+ final Type baseType = retType.getBaseElementType();
+ lenExprSet = nativeArrayLenExpr+" * sizeof("+baseType.getName()+")";
+ cEmitter.setReturnValueCapacityExpression( new MessageFormat(lenExprSet) );
+ } else if (javaReturnType.isArray() ||
+ javaReturnType.isArrayOfCompoundTypeWrappers()) {
+ lenExprSet = nativeArrayLenExpr;
+ cEmitter.setReturnValueLengthExpression( new MessageFormat(lenExprSet) );
+ } else {
+ lenExprSet = null;
+ }
+ } else {
+ lenExprSet = null;
+ }
+ prepCEmitter(returnSizeLookupName, binding.getJavaReturnType(), cEmitter);
+ cEmitter.emit();
+ }
+ }
+
+ private String getArrayArrayLengthExpr(final ArrayType type, final String returnSizeLookupName, final boolean hasFixedTypeLen[], final int[][] lengthRes) {
+ final int[] length = new int[type.arrayDimension()];
+ lengthRes[0] = length;
+ final StringBuilder lengthExpr = new StringBuilder();
+ hasFixedTypeLen[0] = true;
+ ArrayType typeIter = type;
+ for(int i=0; i<length.length; i++) {
+ if( null!=typeIter && typeIter.hasLength() ) {
+ length[i] = typeIter.getLength();
+ if( 0 < i ) {
+ lengthExpr.append("*");
+ }
+ lengthExpr.append(length[i]);
+ } else {
+ length[i] = -1;
+ hasFixedTypeLen[0] = false;
+ }
+ if( null != typeIter ) {
+ typeIter = typeIter.getElementType().asArray();
+ }
+ }
+ final String cfgVal = cfg.returnedArrayLength(returnSizeLookupName);
+ if( null != cfgVal ) {
+ if( hasFixedTypeLen[0] ) {
+ System.err.println("WARNING: struct array field '"+returnSizeLookupName+"' of '"+type+"' length '"+Arrays.toString(length)+"' overwritten by cfg-expression: "+cfgVal);
+ }
+ return cfgVal;
+ }
+ if( hasFixedTypeLen[0] ) {
+ return lengthExpr.toString();
+ } else {
+ System.err.println("WARNING: struct array field '"+returnSizeLookupName+"' length '"+Arrays.toString(length)+"' without fixed- nor configured-size: "+type.getDebugString());
+ return null;
+ }
+ }
+ private String getPointerArrayLengthExpr(final PointerType type, final String returnSizeLookupName) {
+ final String cfgVal = cfg.returnedArrayLength(returnSizeLookupName);
+ if( null != cfgVal ) {
+ return cfgVal;
+ }
+ return null;
+ }
+
+ private static final String dummyFuncTypeName = "null *";
+ private static final Type int32Type = new IntType("int32_t", SizeThunk.INT32, false, CVAttributes.CONST);
+ // private static final Type int8Type = new IntType("char", SizeThunk.INT8, false, 0);
+ // private static final Type int8PtrType = new PointerType(SizeThunk.POINTER, int8Type, 0);
+ private static final String nativeArrayLengthArg = "arrayLength";
+ private static final String nativeArrayLengthONE = "1";
+ private static final String nativeArrayElemOffsetArg = "elem_offset";
+
+ private boolean requiresGetCStringLength(final Type fieldType, final String returnSizeLookupName) {
+ if( !cfg.returnsString(returnSizeLookupName) ) {
+ return false;
+ }
+ final PointerType pointerType = fieldType.asPointer();
+ if( null != pointerType ) {
+ return null == getPointerArrayLengthExpr(pointerType, returnSizeLookupName);
+ }
+ return false;
+ }
+
+ private void generateArrayGetterSetterCode(final Set<MethodBinding> methodBindingSet,
+ final PrintWriter javaWriter, final PrintWriter jniWriter,
+ final String structCTypeName, final String structClassPkgName,
+ final Type containingCType, final JavaType containingJType,
+ final int i, final Field field, final String fieldName, final String returnSizeLookupName) throws Exception {
+ final Type fieldType = field.getType();
+ final JavaType javaType;
+ try {
+ javaType = typeToJavaType(fieldType, machDescJava);
+ } catch (Exception e) {
+ throw new RuntimeException("Error occurred while creating array/pointer accessor for field \"" +
+ returnSizeLookupName + "\", "+fieldType.getDebugString(), e);
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: javaType %s%n", (i+1), javaType.getDebugString());
+ }
+
+ //
+ // Collect all required information including considering Opaque types
+ //
+ final String containingJTypeName = containingJType.getName();
+ final boolean isOpaque = isOpaque(fieldType);
+ final boolean isString = cfg.returnsString(returnSizeLookupName); // FIXME: Allow custom Charset ? US-ASCII, UTF-8 or UTF-16 ?
+ final boolean useGetCStringLength;
+ final String arrayLengthExpr;
+ final int[] arrayLengths;
+ final boolean useFixedTypeLen[] = { false };
+ final boolean isPointer;
+ final boolean isPrimitive;
+ final boolean isConst;
+ final JavaType baseJElemType;
+ final String baseJElemTypeName;
+ final boolean hasSingleElement;
+ final String capitalFieldName;
+ final String baseJElemTypeNameC;
+ final String baseJElemTypeNameU;
+ final boolean isByteBuffer;
+ {
+ final Type baseCElemType;
+ final ArrayType arrayType = fieldType.asArray();
+ String _arrayLengthExpr = null;
+ if( isOpaque || javaType.isPrimitive() ) {
+ // Overridden by JavaConfiguration.typeInfo(..), i.e. Opaque!
+ // Emulating array w/ 1 element
+ isPrimitive = true;
+ _arrayLengthExpr = nativeArrayLengthONE;
+ arrayLengths = new int[] { 1 };
+ baseCElemType = null;
+ isPointer = false;
+ isConst = fieldType.isConst();
+ baseJElemType = null;
+ baseJElemTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava);
+ } else {
+ if( null != arrayType ) {
+ final int[][] lengthRes = new int[1][];
+ _arrayLengthExpr = getArrayArrayLengthExpr(arrayType, returnSizeLookupName, useFixedTypeLen, lengthRes);
+ arrayLengths = lengthRes[0];
+ baseCElemType = arrayType.getBaseElementType();
+ isPointer = false;
+ } else {
+ final PointerType pointerType = fieldType.asPointer();
+ _arrayLengthExpr = getPointerArrayLengthExpr(pointerType, returnSizeLookupName);
+ arrayLengths = null;
+ baseCElemType = pointerType.getBaseElementType();
+ isPointer = true;
+ if( 1 != pointerType.pointerDepth() ) {
+ javaWriter.println();
+ final String msg = "SKIP ptr-ptr (depth "+pointerType.pointerDepth()+"): "+returnSizeLookupName +": "+fieldType;
+ javaWriter.println(" // "+msg);
+ System.err.println("WARNING: "+msg);
+ return;
+ }
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: baseCType %s%n", (i+1), baseCElemType.getDebugString());
+ }
+ isPrimitive = baseCElemType.isPrimitive();
+ isConst = baseCElemType.isConst();
+ try {
+ baseJElemType = typeToJavaType(baseCElemType, machDescJava);
+ } catch (Exception e ) {
+ throw new RuntimeException("Error occurred while creating array/pointer accessor for field \"" +
+ returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(), e);
+ }
+ baseJElemTypeName = baseJElemType.getName();
+
+ if( baseCElemType.isPrimitive() && !baseCElemType.getSize().hasFixedNativeSize() ) {
+ javaWriter.println();
+ final String msg = "SKIP primitive w/ platform dependent sized type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ javaWriter.println(" // "+msg);
+ System.err.println("WARNING: "+msg);
+ return;
+ }
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: baseJElemType %s%n", (i+1), (null != baseJElemType ? baseJElemType.getDebugString() : null));
+ }
+ capitalFieldName = capitalizeString(fieldName);
+ baseJElemTypeNameC = capitalizeString(baseJElemTypeName);
+ baseJElemTypeNameU = baseJElemTypeName.toUpperCase();
+ isByteBuffer = "Byte".equals(baseJElemTypeNameC);
+ if( null == _arrayLengthExpr && isString && isPointer ) {
+ useGetCStringLength = true;
+ _arrayLengthExpr = "getCStringLengthImpl(pString)+1";
+ this.requiresStaticInitialization = true;
+ LOG.log(INFO, "StaticInit Trigger.3 \"{0}\"", returnSizeLookupName);
+ } else {
+ useGetCStringLength = false;
+ }
+ arrayLengthExpr = _arrayLengthExpr;
+ if( null == arrayLengthExpr ) {
+ javaWriter.println();
+ final String msg = "SKIP unsized array in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ javaWriter.println(" // "+msg);
+ System.err.println("WARNING: "+msg);
+ return;
+ }
+ boolean _hasSingleElement=false;
+ try {
+ _hasSingleElement = 1 ==Integer.parseInt(_arrayLengthExpr);
+ } catch (Exception e ) {}
+ hasSingleElement = _hasSingleElement;
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: baseJElemTypeName %s, array-lengths %s%n", (i+1), baseJElemTypeName, Arrays.toString(arrayLengths));
+ System.err.printf("SE.ac.%02d: arrayLengthExpr: %s, hasSingleElement %b, isByteBuffer %b, isString %b, isPointer %b, isPrimitive %b, isOpaque %b, isConst %b, useGetCStringLength %b%n",
+ (i+1), arrayLengthExpr, hasSingleElement, isByteBuffer, isString, isPointer, isPrimitive, isOpaque, isConst, useGetCStringLength);
+ }
+
+ //
+ // Emit ..
+ //
+ if( !hasSingleElement && useFixedTypeLen[0] ) {
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, "final int", capitalFieldName+"ArrayLength", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" return "+arrayLengthExpr+";");
+ javaWriter.println(" }");
+ }
+ if( !isConst ) {
+ // Setter
+ javaWriter.println();
+ if( isPrimitive ) {
+ // Setter Primitive
+ if( isPointer ) {
+ // Setter Primitive Pointer
+ final String msg = "SKIP setter for primitive-pointer type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ javaWriter.println(" // "+msg);
+ System.err.println("INFO: "+msg);
+ } else {
+ // Setter Primitive Array
+ if( hasSingleElement ) {
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val);");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ } else {
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int offset", baseJElemTypeName+"[]", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + val.length \"+val.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" final int elemSize = Buffers.SIZEOF_"+baseJElemTypeNameU+";");
+ javaWriter.println(" final ByteBuffer destB = getBuffer();");
+ javaWriter.println(" final int bTotal = arrayLength * elemSize;");
+ javaWriter.println(" if( bTotal > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"bTotal \"+bTotal+\" > size \"+"+fieldName+"_size[mdIdx]+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int bLimes = bOffset + bTotal;");
+ javaWriter.println(" if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException(\"bLimes \"+bLimes+\" > buffer.limit \"+destB.limit()+\", elemOff \"+bOffset+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" bOffset += elemSize * offset;");
+ javaWriter.println(" accessor.set" + baseJElemTypeNameC + "sAt(bOffset, val);");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ }
+ }
+ } else {
+ // Setter Struct
+ if( isPointer ) {
+ // Setter Struct Pointer
+ final String msg = "SKIP setter for complex-pointer type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ javaWriter.println(" // "+msg);
+ System.err.println("INFO: "+msg);
+ } else {
+ // Setter Struct Array
+ if( hasSingleElement ) {
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();");
+ javaWriter.println(" final ByteBuffer destB = getBuffer();");
+ javaWriter.println(" if( elemSize > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"elemSize \"+elemSize+\" > size \"+"+fieldName+"_size[mdIdx]); };");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int bLimes = bOffset + elemSize;");
+ javaWriter.println(" if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException(\"bLimes \"+bLimes+\" > buffer.limit \"+destB.limit()+\", elemOff \"+bOffset+\", elemSize \"+elemSize); };");
+ javaWriter.println(" final ByteBuffer sourceB = val.getBuffer();");
+ javaWriter.println(" for(int f=0; f<elemSize; f++) {");
+ javaWriter.println(" if( bOffset >= bLimes ) { throw new IndexOutOfBoundsException(\"elem-byte[0][\"+f+\"]: bOffset \"+bOffset+\" >= bLimes \"+bLimes+\", elemSize \"+elemSize); };");
+ javaWriter.println(" destB.put(bOffset++, sourceB.get(f));");
+ javaWriter.println(" }");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ } else {
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int offset", baseJElemTypeName+"[]", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + val.length \"+val.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();");
+ javaWriter.println(" final ByteBuffer destB = getBuffer();");
+ javaWriter.println(" final int bTotal = arrayLength * elemSize;");
+ javaWriter.println(" if( bTotal > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"bTotal \"+bTotal+\" > size \"+"+fieldName+"_size[mdIdx]+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int bLimes = bOffset + bTotal;");
+ javaWriter.println(" if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException(\"bLimes \"+bLimes+\" > buffer.limit \"+destB.limit()+\", elemOff \"+bOffset+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" bOffset += elemSize * offset;");
+ javaWriter.println(" for(int index=0; index<val.length; index++) {");
+ javaWriter.println(" final ByteBuffer sourceB = val[index].getBuffer();");
+ javaWriter.println(" for(int f=0; f<elemSize; f++) {");
+ javaWriter.println(" if( bOffset >= bLimes ) { throw new IndexOutOfBoundsException(\"elem-byte[\"+(offset+index)+\"][\"+f+\"]: bOffset \"+bOffset+\" >= bLimes \"+bLimes+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" destB.put(bOffset++, sourceB.get(f));");
+ javaWriter.println(" }");
+ javaWriter.println(" }");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ javaWriter.println();
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int index", baseJElemTypeName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();");
+ javaWriter.println(" final ByteBuffer destB = getBuffer();");
+ javaWriter.println(" final int bTotal = arrayLength * elemSize;");
+ javaWriter.println(" if( bTotal > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"bTotal \"+bTotal+\" > size \"+"+fieldName+"_size[mdIdx]+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int bLimes = bOffset + bTotal;");
+ javaWriter.println(" if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException(\"bLimes \"+bLimes+\" > buffer.limit \"+destB.limit()+\", elemOff \"+bOffset+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" bOffset += elemSize * index;");
+ javaWriter.println(" final ByteBuffer sourceB = val.getBuffer();");
+ javaWriter.println(" for(int f=0; f<elemSize; f++) {");
+ javaWriter.println(" if( bOffset >= bLimes ) { throw new IndexOutOfBoundsException(\"elem-byte[\"+index+\"][\"+f+\"]: bOffset \"+bOffset+\" >= bLimes \"+bLimes+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" destB.put(bOffset++, sourceB.get(f));");
+ javaWriter.println(" }");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ }
+ }
+ }
+ }
+ // Getter
+ javaWriter.println();
+ if( isPrimitive ) {
+ // Getter Primitive
+ if( isPointer ) {
+ // Getter Primitive Pointer
+ final FunctionType ft = new FunctionType(dummyFuncTypeName, SizeThunk.POINTER, fieldType, 0);
+ ft.addArgument(containingCType.getCVVariant(containingCType.getCVAttributes() | CVAttributes.CONST),
+ CMethodBindingEmitter.cThisArgumentName());
+ ft.addArgument(int32Type, nativeArrayLengthArg);
+ final FunctionSymbol fs = new FunctionSymbol("get"+capitalFieldName, ft);
+ jniWriter.println();
+ jniWriter.print("static "+fs.toString());
+ jniWriter.println("{");
+ jniWriter.println(" return "+CMethodBindingEmitter.cThisArgumentName()+"->"+field.getName()+";");
+ jniWriter.println("}");
+ jniWriter.println();
+ generateArrayPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
+ containingCType, containingJType, i, fs, returnSizeLookupName, arrayLengthExpr, nativeArrayLengthArg);
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeNameC+"Buffer", capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ if( useGetCStringLength ) {
+ javaWriter.println(" final int arrayLength = get"+capitalFieldName+"ArrayLength();");
+ } else {
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ }
+ javaWriter.println(" final ByteBuffer _res = get"+capitalFieldName+"0(getBuffer(), arrayLength);");
+ javaWriter.println(" if (_res == null) return null;");
+ javaWriter.print(" return Buffers.nativeOrder(_res)");
+ if( !isByteBuffer ) {
+ javaWriter.print(".as"+baseJElemTypeNameC+"Buffer()");
+ }
+ javaWriter.println(";");
+ javaWriter.println(" }");
+ if( isString && isByteBuffer ) {
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, "String", capitalFieldName+"AsString", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ if( useGetCStringLength ) {
+ javaWriter.println(" final int arrayLength = get"+capitalFieldName+"ArrayLength();");
+ } else {
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ }
+ javaWriter.println(" final ByteBuffer bb = get"+capitalFieldName+"0(getBuffer(), arrayLength);");
+ javaWriter.println(" if (bb == null) return null;");
+ javaWriter.println(" final byte[] ba = new byte[arrayLength];");
+ javaWriter.println(" int i = -1;");
+ javaWriter.println(" while( ++i < arrayLength ) {");
+ javaWriter.println(" ba[i] = bb.get(i);");
+ javaWriter.println(" if( (byte)0 == ba[i] ) break;");
+ javaWriter.println(" }");
+ javaWriter.println(" return new String(ba, 0, i);");
+ javaWriter.println(" }");
+ }
+ if( useGetCStringLength ) {
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, "final int", capitalFieldName+"ArrayLength", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final long pString = PointerBuffer.wrap( accessor.slice(" + fieldName+"_offset[mdIdx], PointerBuffer.ELEMENT_SIZE) ).get(0);");
+ javaWriter.println(" return "+arrayLengthExpr+";");
+ javaWriter.println(" }");
+ }
+ } else {
+ // Getter Primitive Array
+ if( hasSingleElement ) {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx]);");
+ javaWriter.println(" }");
+ javaWriter.println();
+ } else {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeNameC+"Buffer", capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.print(" return accessor.slice(" + fieldName+"_offset[mdIdx], Buffers.SIZEOF_"+baseJElemTypeNameU+" * "+arrayLengthExpr+")");
+ if( !isByteBuffer ) {
+ javaWriter.print(".as"+baseJElemTypeNameC+"Buffer()");
+ }
+ javaWriter.println(";");
+ javaWriter.println(" }");
+ javaWriter.println();
+ if( isString && isByteBuffer ) {
+ generateGetterSignature(javaWriter, fieldType, false, "String", capitalFieldName+"AsString", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int offset = " + fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" final ByteBuffer bb = getBuffer();");
+ javaWriter.println(" final byte[] ba = new byte[arrayLength];");
+ javaWriter.println(" int i = -1;");
+ javaWriter.println(" while( ++i < arrayLength ) {");
+ javaWriter.println(" ba[i] = bb.get(offset+i);");
+ javaWriter.println(" if( (byte)0 == ba[i] ) break;");
+ javaWriter.println(" }");
+ javaWriter.println(" return new String(ba, 0, i);");
+ javaWriter.println(" }");
+ } else {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "sAt(" + fieldName+"_offset[mdIdx] + (Buffers.SIZEOF_"+baseJElemTypeNameU+" * offset), result);");
+ javaWriter.println(" }");
+ javaWriter.println();
+ }
+ }
+ }
+ } else {
+ // Getter Struct
+ if( isPointer ) {
+ // Getter Struct Pointer
+ final FunctionType ft = new FunctionType(dummyFuncTypeName, SizeThunk.POINTER, fieldType, 0);
+ ft.addArgument(containingCType.getCVVariant(containingCType.getCVAttributes() | CVAttributes.CONST),
+ CMethodBindingEmitter.cThisArgumentName());
+ ft.addArgument(int32Type, nativeArrayElemOffsetArg);
+ final FunctionSymbol fs = new FunctionSymbol("get"+capitalFieldName, ft);
+ jniWriter.println();
+ jniWriter.print("static "+fs.toString());
+ jniWriter.println("{");
+ jniWriter.println(" return "+CMethodBindingEmitter.cThisArgumentName()+"->"+field.getName()+"+"+nativeArrayElemOffsetArg+";");
+ jniWriter.println("}");
+ jniWriter.println();
+ generateArrayPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
+ containingCType, containingJType, i, fs, returnSizeLookupName, arrayLengthExpr, nativeArrayLengthONE);
+ javaWriter.println();
+ if( hasSingleElement ) {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final ByteBuffer source = getBuffer();");
+ javaWriter.println(" final ByteBuffer _res = get"+capitalFieldName+"0(source, 0);");
+ javaWriter.println(" if (_res == null) return null;");
+ javaWriter.println(" return "+baseJElemTypeName+".create(_res);");
+ javaWriter.println(" }");
+ } else {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" final ByteBuffer source = getBuffer();");
+ javaWriter.println(" for(int index=0; index<result.length; index++) {");
+ javaWriter.println(" final ByteBuffer _res = get"+capitalFieldName+"0(source, offset+index);");
+ javaWriter.println(" if (_res == null) return null;");
+ javaWriter.println(" result[index] = "+baseJElemTypeName+".create(_res);");
+ javaWriter.println(" }");
+ javaWriter.println(" return result;");
+ javaWriter.println(" }");
+ }
+ } else {
+ // Getter Struct Array
+ if( hasSingleElement ) {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" return "+baseJElemTypeName+".create(accessor.slice("+fieldName+"_offset[mdIdx], "+baseJElemTypeName+".size()));");
+ javaWriter.println(" }");
+ } else {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx] + ( elemSize * offset );");
+ javaWriter.println(" for(int index=0; index<result.length; index++) {");
+ javaWriter.println(" result[index] = "+baseJElemTypeName+".create(accessor.slice(bOffset, elemSize));");
+ javaWriter.println(" bOffset += elemSize;");
+ javaWriter.println(" }");
+ javaWriter.println(" return result;");
+ javaWriter.println(" }");
+ }
+ }
+ }
+ }
+
+ private static final boolean DEBUG_TYPEC2JAVA = false;
+ private JavaType typeToJavaType(final Type cType, final MachineDescription curMachDesc) {
+ final JavaType jt = typeToJavaTypeImpl(cType, curMachDesc);
+ if( DEBUG_TYPEC2JAVA ) {
+ System.err.println("typeToJavaType: "+cType.getDebugString()+" -> "+jt.getDebugString());
+ }
+ return jt;
+ }
+ private boolean isJNIEnvPointer(final Type cType) {
+ final PointerType opt = cType.asPointer();
+ return (opt != null) &&
+ (opt.getTargetType().getName() != null) &&
+ (opt.getTargetType().getName().equals("JNIEnv"));
+ }
+ private JavaType typeToJavaTypeImpl(final Type cType, final MachineDescription curMachDesc) {
// Recognize JNIEnv* case up front
- PointerType opt = cType.asPointer();
- if ((opt != null) &&
- (opt.getTargetType().getName() != null) &&
- (opt.getTargetType().getName().equals("JNIEnv"))) {
- return JavaType.createForJNIEnv();
+ if( isJNIEnvPointer(cType) ) {
+ return JavaType.createForJNIEnv();
}
- Type t = cType;
-
// Opaque specifications override automatic conversions
// in case the identity is being used .. not if ptr-ptr
- TypeInfo info = cfg.typeInfo(t, typedefDictionary);
+ final TypeInfo info = cfg.typeInfo(cType, typedefDictionary);
if (info != null) {
boolean isPointerPointer = false;
- if (t.pointerDepth() > 0 || t.arrayDimension() > 0) {
+ if (cType.pointerDepth() > 0 || cType.arrayDimension() > 0) {
Type targetType; // target type
- if (t.isPointer()) {
+ if (cType.isPointer()) {
// t is <type>*, we need to get <type>
- targetType = t.asPointer().getTargetType();
+ targetType = cType.asPointer().getTargetType();
} else {
// t is <type>[], we need to get <type>
- targetType = t.asArray().getBaseElementType();
+ targetType = cType.asArray().getBaseElementType();
}
- if (t.pointerDepth() == 2 || t.arrayDimension() == 2) {
+ if (cType.pointerDepth() == 2 || cType.arrayDimension() == 2) {
// Get the target type of the target type (targetType was computer earlier
// as to be a pointer to the target type, so now we need to get its
// target type)
@@ -1369,7 +1953,9 @@ public class JavaEmitter implements GlueEmitter {
// t is<type>**, targetType is <type>*, we need to get <type>
Type bottomType = targetType.asPointer().getTargetType();
- LOG.log(INFO, "Opaque Type: {0}, targetType: {1}, bottomType: {2} is ptr-ptr", new Object[]{t, targetType, bottomType});
+ if( GlueGen.debug() ) {
+ LOG.log(INFO, "Opaque Type: {0}, targetType: {1}, bottomType: {2} is ptr-ptr", new Object[]{cType.getDebugString(), targetType, bottomType});
+ }
}
}
}
@@ -1378,35 +1964,35 @@ public class JavaEmitter implements GlueEmitter {
}
}
- if (t.isInt() || t.isEnum()) {
- switch ((int) t.getSize(curMachDesc)) {
+ if (cType.isInt() || cType.isEnum()) {
+ switch ((int) cType.getSize(curMachDesc)) {
case 1: return javaType(Byte.TYPE);
case 2: return javaType(Short.TYPE);
case 4: return javaType(Integer.TYPE);
case 8: return javaType(Long.TYPE);
default: throw new RuntimeException("Unknown integer type of size " +
- t.getSize(curMachDesc) + " and name " + t.getName());
+ cType.getSize(curMachDesc) + " and name " + cType.getName());
}
- } else if (t.isFloat()) {
+ } else if (cType.isFloat()) {
return javaType(Float.TYPE);
- } else if (t.isDouble()) {
+ } else if (cType.isDouble()) {
return javaType(Double.TYPE);
- } else if (t.isVoid()) {
+ } else if (cType.isVoid()) {
return javaType(Void.TYPE);
- } else if (t.pointerDepth() > 0 || t.arrayDimension() > 0) {
+ } else if (cType.pointerDepth() > 0 || cType.arrayDimension() > 0) {
Type targetType; // target type
- if (t.isPointer()) {
+ if (cType.isPointer()) {
// t is <type>*, we need to get <type>
- targetType = t.asPointer().getTargetType();
+ targetType = cType.asPointer().getTargetType();
} else {
// t is <type>[], we need to get <type>
- targetType = t.asArray().getBaseElementType();
+ targetType = cType.asArray().getBaseElementType();
}
// Handle Types of form pointer-to-type or array-of-type, like
// char* or int[]; these are expanded out into Java primitive
// arrays, NIO buffers, or both in expandMethodBinding
- if (t.pointerDepth() == 1 || t.arrayDimension() == 1) {
+ if (cType.pointerDepth() == 1 || cType.arrayDimension() == 1) {
if (targetType.isVoid()) {
return JavaType.createForCVoidPointer();
} else if (targetType.isInt()) {
@@ -1421,39 +2007,39 @@ public class JavaEmitter implements GlueEmitter {
case 4: return JavaType.createForCInt32Pointer();
case 8: return JavaType.createForCInt64Pointer();
default: throw new RuntimeException("Unknown integer array type of size " +
- t.getSize(curMachDesc) + " and name " + t.getName());
+ cType.getSize(curMachDesc) + " and name " + cType.getName()+", "+cType.getDebugString());
}
} else if (targetType.isFloat()) {
return JavaType.createForCFloatPointer();
} else if (targetType.isDouble()) {
return JavaType.createForCDoublePointer();
} else if (targetType.isCompound()) {
- if (t.isArray()) { // FIXME: Compound and Compound-Arrays
+ if (cType.isArray()) { // FIXME: Compound and Compound-Arrays
return JavaType.createForCArray(targetType);
}
// Special cases for known JNI types (in particular for converting jawt.h)
- if (t.getName() != null &&
- t.getName().equals("jobject")) {
+ if (cType.getName() != null &&
+ cType.getName().equals("jobject")) {
return javaType(java.lang.Object.class);
}
String name = targetType.getName();
if (name == null) {
// Try containing pointer type for any typedefs
- name = t.getName();
+ name = cType.getName();
if (name == null) {
- throw new RuntimeException("Couldn't find a proper type name for pointer type " + t);
+ throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString());
}
}
return JavaType.createForCStruct(cfg.renameJavaType(name));
} else {
throw new RuntimeException("Don't know how to convert pointer/array type \"" +
- t + "\"");
+ cType.getDebugString() + "\"");
}
}
// Handle Types of form pointer-to-pointer-to-type or
// array-of-arrays-of-type, like char** or int[][]
- else if (t.pointerDepth() == 2 || t.arrayDimension() == 2) {
+ else if (cType.pointerDepth() == 2 || cType.arrayDimension() == 2) {
// Get the target type of the target type (targetType was computer earlier
// as to be a pointer to the target type, so now we need to get its
// target type)
@@ -1461,11 +2047,21 @@ public class JavaEmitter implements GlueEmitter {
if (targetType.isPointer()) {
// t is<type>**, targetType is <type>*, we need to get <type>
bottomType = targetType.asPointer().getTargetType();
+ if( GlueGen.debug() ) {
+ LOG.log(INFO, "typeToJavaType(ptr-ptr): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType});
+ }
return JavaType.forNIOPointerBufferClass();
- } else {
+ } else if(targetType.isArray()) {
// t is<type>[][], targetType is <type>[], we need to get <type>
bottomType = targetType.asArray().getBaseElementType();
- LOG.log(WARNING, "typeToJavaType(ptr-ptr): {0}, targetType: {1}, bottomType: {2} -> Unhandled!", new Object[]{t, targetType, bottomType});
+ if( GlueGen.debug() ) {
+ LOG.log(INFO, "typeToJavaType(ptr-ptr.array): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType});
+ }
+ } else {
+ bottomType = targetType;
+ if( GlueGen.debug() ) {
+ LOG.log(INFO, "typeToJavaType(ptr-ptr.primitive): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType});
+ }
}
// Warning: The below code is not backed up by an implementation,
@@ -1479,14 +2075,14 @@ public class JavaEmitter implements GlueEmitter {
case 4: return javaType(ArrayTypes.intBufferArrayClass);
case 8: return javaType(ArrayTypes.longBufferArrayClass);
default: throw new RuntimeException("Unknown two-dimensional integer array type of element size " +
- bottomType.getSize(curMachDesc) + " and name " + bottomType.getName());
+ bottomType.getSize(curMachDesc) + " and name " + bottomType.getName()+", "+bottomType.getDebugString());
}
} else if (bottomType.isFloat()) {
return javaType(ArrayTypes.floatBufferArrayClass);
} else if (bottomType.isDouble()) {
return javaType(ArrayTypes.doubleBufferArrayClass);
} else {
- throw new RuntimeException("Unexpected primitive type " + bottomType.getName() +
+ throw new RuntimeException("Unexpected primitive type " + bottomType.getDebugString() +
" in two-dimensional array");
}
} else if (bottomType.isVoid()) {
@@ -1497,7 +2093,7 @@ public class JavaEmitter implements GlueEmitter {
return JavaType.createForCArray(bottomType);
} else {
throw new RuntimeException(
- "Could not convert C type \"" + t + "\" " +
+ "Could not convert C type \"" + cType.getDebugString() + "\" " +
"to appropriate Java type; need to add more support for " +
"depth=2 pointer/array types [debug info: targetType=\"" +
targetType + "\"]");
@@ -1505,23 +2101,23 @@ public class JavaEmitter implements GlueEmitter {
} else {
// can't handle this type of pointer/array argument
throw new RuntimeException(
- "Could not convert C pointer/array \"" + t + "\" to " +
+ "Could not convert C pointer/array \"" + cType.getDebugString() + "\" to " +
"appropriate Java type; types with pointer/array depth " +
"greater than 2 are not yet supported [debug info: " +
- "pointerDepth=" + t.pointerDepth() + " arrayDimension=" +
- t.arrayDimension() + " targetType=\"" + targetType + "\"]");
+ "pointerDepth=" + cType.pointerDepth() + " arrayDimension=" +
+ cType.arrayDimension() + " targetType=\"" + targetType + "\"]");
}
- } else if(t.isCompound() ) { // FIXME: Compound and Compound-Arrays
- final String name = t.getName();
+ } else if(cType.isCompound() ) { // FIXME: Compound and Compound-Arrays
+ final String name = cType.getName();
if (name == null) {
- throw new RuntimeException("Couldn't find a proper type name for pointer type " + t);
+ throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString());
}
return JavaType.createForCStruct(cfg.renameJavaType(name));
} else {
throw new RuntimeException(
- "Could not convert C type \"" + t + "\" (class " +
- t.getClass().getName() + ") to appropriate Java type");
+ "Could not convert C type \"" + cType.getDebugString() + "\" (class " +
+ cType.getClass().getName() + ") to appropriate Java type");
}
}
@@ -1897,6 +2493,10 @@ public class JavaEmitter implements GlueEmitter {
cWriter.println(" return _initClazzAccess(env);");
cWriter.println("}");
cWriter.println();
+ cWriter.println("JNIEXPORT jint JNICALL "+JavaEmitter.getJNIMethodNamePrefix(packageName, className)+"_getCStringLengthImpl(JNIEnv *env, jclass _unused, jlong pString) {");
+ cWriter.println(" return 0 != pString ? strlen((const char*)(intptr_t)pString) : 0;");
+ cWriter.println("}");
+ cWriter.println();
}
}
@@ -1905,6 +2505,9 @@ public class JavaEmitter implements GlueEmitter {
jWriter.println();
jWriter.println(" private static native boolean initializeImpl();");
jWriter.println();
+ jWriter.println();
+ jWriter.println(" private static native int getCStringLengthImpl(final long pString);");
+ jWriter.println();
if( !cfg.manualStaticInitCall(className) ) {
jWriter.println(staticClassInitCallJavaCode);
}
@@ -1958,7 +2561,7 @@ public class JavaEmitter implements GlueEmitter {
}
binding.setJavaReturnType(javaType(java.lang.String.class));
} else {
- binding.setJavaReturnType(typeToJavaType(sym.getReturnType(), false, curMachDesc));
+ binding.setJavaReturnType(typeToJavaType(sym.getReturnType(), curMachDesc));
}
// System.out.println("bindFunction(1) "+binding.getJavaReturnType());
@@ -1969,7 +2572,7 @@ public class JavaEmitter implements GlueEmitter {
for (int i = 0; i < sym.getNumArguments(); i++) {
Type cArgType = sym.getArgumentType(i);
- JavaType mappedType = typeToJavaType(cArgType, true, curMachDesc);
+ JavaType mappedType = typeToJavaType(cArgType, curMachDesc);
// System.out.println("C arg type -> \"" + cArgType + "\"" );
// System.out.println(" Java -> \"" + mappedType + "\"" );
@@ -2147,5 +2750,4 @@ public class JavaEmitter implements GlueEmitter {
private final String capitalizeString(String string) {
return Character.toUpperCase(string.charAt(0)) + string.substring(1);
}
-
}