diff options
Diffstat (limited to 'src/java/com/sun/gluegen/JavaMethodBindingEmitter.java')
-rw-r--r-- | src/java/com/sun/gluegen/JavaMethodBindingEmitter.java | 859 |
1 files changed, 0 insertions, 859 deletions
diff --git a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java deleted file mode 100644 index f7bbc99..0000000 --- a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java +++ /dev/null @@ -1,859 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -package com.sun.gluegen; - -import java.io.*; -import java.util.*; -import java.text.MessageFormat; - -import com.sun.gluegen.cgram.types.*; -import com.sun.gluegen.cgram.*; - -/** - * An emitter that emits only the interface for a Java<->C JNI binding. - */ -public class JavaMethodBindingEmitter extends FunctionEmitter { - - public static final EmissionModifier PUBLIC = new EmissionModifier("public"); - public static final EmissionModifier PROTECTED = new EmissionModifier("protected"); - public static final EmissionModifier PRIVATE = new EmissionModifier("private"); - public static final EmissionModifier ABSTRACT = new EmissionModifier("abstract"); - public static final EmissionModifier FINAL = new EmissionModifier("final"); - public static final EmissionModifier NATIVE = new EmissionModifier("native"); - public static final EmissionModifier SYNCHRONIZED = new EmissionModifier("synchronized"); - - protected final CommentEmitter defaultJavaCommentEmitter = new DefaultCommentEmitter(); - protected final CommentEmitter defaultInterfaceCommentEmitter = new InterfaceCommentEmitter(); - - // Exception type raised in the generated code if runtime checks fail - private String runtimeExceptionType; - private String unsupportedExceptionType; - - protected boolean emitBody; - protected boolean eraseBufferAndArrayTypes; - protected boolean directNIOOnly; - protected boolean forImplementingMethodCall; - protected boolean forDirectBufferImplementation; - protected boolean forIndirectBufferAndArrayImplementation; - protected boolean isUnimplemented; - protected boolean tagNativeBinding; - - protected MethodBinding binding; - - // Manually-specified prologue and epilogue code - protected List<String> prologue; - protected List<String> epilogue; - - // A non-null value indicates that rather than returning a compound - // type accessor we are returning an array of such accessors; this - // expression is a MessageFormat string taking the names of the - // incoming Java arguments as parameters and computing as an int the - // number of elements of the returned array. - private String returnedArrayLengthExpression; - - // A suffix used to create a temporary outgoing array of Buffers to - // represent an array of compound type wrappers - private static final String COMPOUND_ARRAY_SUFFIX = "_buf_array_copy"; - - // Only present to provide more clear comments - private JavaConfiguration cfg; - - public JavaMethodBindingEmitter(MethodBinding binding, - PrintWriter output, - String runtimeExceptionType, - String unsupportedExceptionType, - boolean emitBody, - boolean tagNativeBinding, - boolean eraseBufferAndArrayTypes, - boolean directNIOOnly, - boolean forImplementingMethodCall, - boolean forDirectBufferImplementation, - boolean forIndirectBufferAndArrayImplementation, - boolean isUnimplemented, - boolean isInterface, - JavaConfiguration configuration) { - super(output, isInterface); - this.binding = binding; - this.runtimeExceptionType = runtimeExceptionType; - this.unsupportedExceptionType = unsupportedExceptionType; - this.emitBody = emitBody; - this.tagNativeBinding = tagNativeBinding; - this.eraseBufferAndArrayTypes = eraseBufferAndArrayTypes; - this.directNIOOnly = directNIOOnly; - this.forImplementingMethodCall = forImplementingMethodCall; - this.forDirectBufferImplementation = forDirectBufferImplementation; - this.forIndirectBufferAndArrayImplementation = forIndirectBufferAndArrayImplementation; - this.isUnimplemented = isUnimplemented; - if (forImplementingMethodCall) { - setCommentEmitter(defaultJavaCommentEmitter); - } else { - setCommentEmitter(defaultInterfaceCommentEmitter); - } - cfg = configuration; - } - - public JavaMethodBindingEmitter(JavaMethodBindingEmitter arg) { - super(arg); - binding = arg.binding; - runtimeExceptionType = arg.runtimeExceptionType; - unsupportedExceptionType = arg.unsupportedExceptionType; - emitBody = arg.emitBody; - tagNativeBinding = arg.tagNativeBinding; - eraseBufferAndArrayTypes = arg.eraseBufferAndArrayTypes; - directNIOOnly = arg.directNIOOnly; - forImplementingMethodCall = arg.forImplementingMethodCall; - forDirectBufferImplementation = arg.forDirectBufferImplementation; - forIndirectBufferAndArrayImplementation = arg.forIndirectBufferAndArrayImplementation; - isUnimplemented = arg.isUnimplemented; - prologue = arg.prologue; - epilogue = arg.epilogue; - returnedArrayLengthExpression = arg.returnedArrayLengthExpression; - cfg = arg.cfg; - } - - public final MethodBinding getBinding() { return binding; } - - public boolean isForImplementingMethodCall() { return forImplementingMethodCall; } - public boolean isForDirectBufferImplementation() { return forDirectBufferImplementation; } - public boolean isForIndirectBufferAndArrayImplementation() { return forIndirectBufferAndArrayImplementation; } - - public String getName() { - return binding.getName(); - } - - protected String getArgumentName(int i) { - return binding.getArgumentName(i); - } - - /** The type of exception (must subclass - <code>java.lang.RuntimeException</code>) raised if runtime - checks fail in the generated code. */ - public String getRuntimeExceptionType() { - return runtimeExceptionType; - } - - public String getUnsupportedExceptionType() { - return unsupportedExceptionType; - } - - /** If the underlying function returns an array (currently only - arrays of compound types are supported) as opposed to a pointer - to an object, this method should be called to provide a - MessageFormat string containing an expression that computes the - number of elements of the returned array. The parameters to the - MessageFormat expression are the names of the incoming Java - arguments. */ - public void setReturnedArrayLengthExpression(String expr) { - returnedArrayLengthExpression = expr; - } - - /** Sets the manually-generated prologue code for this emitter. */ - public void setPrologue(List<String> prologue) { - this.prologue = prologue; - } - - /** Sets the manually-generated epilogue code for this emitter. */ - public void setEpilogue(List<String> epilogue) { - this.epilogue = epilogue; - } - - /** Indicates whether this emitter will print only a signature, or - whether it will emit Java code for the body of the method as - well. */ - public boolean signatureOnly() { - return !emitBody; - } - - /** Accessor for subclasses. */ - public void setEmitBody(boolean emitBody) { - this.emitBody = emitBody; - } - - /** Accessor for subclasses. */ - public void setEraseBufferAndArrayTypes(boolean erase) { - this.eraseBufferAndArrayTypes = erase; - } - - /** Accessor for subclasses. */ - public void setForImplementingMethodCall(boolean impl) { - this.forImplementingMethodCall = impl; - } - - /** Accessor for subclasses. */ - public void setForDirectBufferImplementation(boolean direct) { - this.forDirectBufferImplementation = direct; - } - - /** Accessor for subclasses. */ - public void setForIndirectBufferAndArrayImplementation(boolean indirect) { - this.forIndirectBufferAndArrayImplementation = indirect; - } - - protected void emitReturnType(PrintWriter writer) { - writer.print(getReturnTypeString(false)); - } - - protected String erasedTypeString(JavaType type, boolean skipBuffers) { - if (eraseBufferAndArrayTypes) { - if (type.isNIOBuffer()) { - if (!skipBuffers) { - // Direct buffers and arrays sent down as Object (but - // returned as e.g. ByteBuffer) - return "Object"; - } - if (!type.isNIOByteBuffer()) { - // Return buffer requiring change of view from ByteBuffer to e.g. LongBuffer - return "ByteBuffer"; - } - } else if (type.isPrimitiveArray()) { - if (!skipBuffers) { - // Direct buffers and arrays sent down as Object (but - // returned as e.g. ByteBuffer) - return "Object"; - } - } else if (type.isNIOBufferArray()) { - // Arrays of direct Buffers sent down as Object[] - // (Note we don't yet support returning void**) - return "Object[]"; - } else if (type.isCompoundTypeWrapper()) { - // Compound type wrappers are unwrapped to ByteBuffer - return "ByteBuffer"; - } else if (type.isArrayOfCompoundTypeWrappers()) { - if (skipBuffers) { - return "ByteBuffer"; - } else { - // In the case where this is called with a false skipBuffers - // argument we want to erase the array of compound type - // wrappers to ByteBuffer[] - return "ByteBuffer[]"; - } - } - } - String name = type.getName(); - int index = name.lastIndexOf('.')+1; // always >= 0 - name = name.substring(index); - - if (type.isArrayOfCompoundTypeWrappers()) { - // We don't want to bake the array specification into the type name - return name + "[]"; - } - return name; - } - - protected String getReturnTypeString(boolean skipArray) { - // The first arm of the "if" clause is used by the glue code - // generation for arrays of compound type wrappers - if (skipArray || - // The following arm is used by most other kinds of return types - (getReturnedArrayLengthExpression() == null && - !binding.getJavaReturnType().isArrayOfCompoundTypeWrappers()) || - // The following arm is used specifically to get the splitting up - // of one returned ByteBuffer into an array of compound type - // wrappers to work (e.g., XGetVisualInfo) - (eraseBufferAndArrayTypes && - binding.getJavaReturnType().isCompoundTypeWrapper() && - (getReturnedArrayLengthExpression() != null))) { - return erasedTypeString(binding.getJavaReturnType(), true); - } - return erasedTypeString(binding.getJavaReturnType(), true) + "[]"; - } - - protected void emitName(PrintWriter writer) { - if (forImplementingMethodCall) { - writer.print(getImplMethodName()); - } else { - writer.print(getName()); - } - } - - protected int emitArguments(PrintWriter writer) { - boolean needComma = false; - int numEmitted = 0; - - if (forImplementingMethodCall && binding.hasContainingType()) { - // Always emit outgoing "this" argument - writer.print("ByteBuffer "); - writer.print(javaThisArgumentName()); - ++numEmitted; - needComma = true; - } - - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType type = binding.getJavaArgumentType(i); - if (type.isVoid()) { - // Make sure this is the only param to the method; if it isn't, - // there's something wrong with our parsing of the headers. - if (binding.getNumArguments() != 1) { - throw new InternalError( - "\"void\" argument type found in " + - "multi-argument function \"" + binding + "\""); - } - continue; - } - - if (type.isJNIEnv() || binding.isArgumentThisPointer(i)) { - // Don't need to expose these at the Java level - continue; - } - - if (needComma) { - writer.print(", "); - } - - writer.print(erasedTypeString(type, false)); - writer.print(" "); - writer.print(getArgumentName(i)); - - ++numEmitted; - needComma = true; - - // Add Buffer and array index offset arguments after each associated argument - if (forDirectBufferImplementation || forIndirectBufferAndArrayImplementation) { - if (type.isNIOBuffer()) { - writer.print(", int " + byteOffsetArgName(i)); - if(!directNIOOnly) { - writer.print(", boolean " + isNIOArgName(i)); - } - } else if (type.isNIOBufferArray()) { - writer.print(", int[] " + byteOffsetArrayArgName(i)); - } - } - - // Add offset argument after each primitive array - if (type.isPrimitiveArray()) { - if(directNIOOnly) { - throw new RuntimeException("NIODirectOnly "+binding+" is set, but "+getArgumentName(i)+" is a primitive array"); - } - writer.print(", int " + offsetArgName(i)); - } - } - return numEmitted; - } - - - protected String getImplMethodName() { - return binding.getName() + ( directNIOOnly ? "0" : "1" ); - } - - protected String byteOffsetArgName(int i) { - return byteOffsetArgName(getArgumentName(i)); - } - - protected String byteOffsetArgName(String s) { - return s + "_byte_offset"; - } - - protected String isNIOArgName(int i) { - return isNIOArgName(binding.getArgumentName(i)); - } - - protected String isNIOArgName(String s) { - return s + "_is_direct"; - } - - protected String byteOffsetArrayArgName(int i) { - return getArgumentName(i) + "_byte_offset_array"; - } - - protected String offsetArgName(int i) { - return getArgumentName(i) + "_offset"; - } - - protected void emitBody(PrintWriter writer) { - if (!emitBody) { - writer.println(';'); - } else { - MethodBinding mBinding = getBinding(); - writer.println(" {"); - writer.println(); - if (isUnimplemented) { - writer.println(" throw new " + getUnsupportedExceptionType() + "(\"Unimplemented\");"); - } else { - emitPrologueOrEpilogue(prologue, writer); - emitPreCallSetup(mBinding, writer); - //emitReturnVariableSetup(binding, writer); - emitReturnVariableSetupAndCall(mBinding, writer); - } - writer.println(" }"); - } - } - - protected void emitPrologueOrEpilogue(List<String> code, PrintWriter writer) { - if (code != null) { - String[] argumentNames = argumentNameArray(); - for (String str : code) { - try { - MessageFormat fmt = new MessageFormat(str); - writer.println(" " + fmt.format(argumentNames)); - } catch (IllegalArgumentException e) { - // (Poorly) handle case where prologue / epilogue contains blocks of code with braces - writer.println(" " + str); - } - } - } - } - - protected void emitPreCallSetup(MethodBinding binding, PrintWriter writer) { - emitArrayLengthAndNIOBufferChecks(binding, writer); - emitCompoundArrayCopies(binding, writer); - } - - protected void emitArrayLengthAndNIOBufferChecks(MethodBinding binding, PrintWriter writer) { - - // Check lengths of any incoming arrays if necessary - for (int i = 0; i < binding.getNumArguments(); i++) { - Type type = binding.getCArgumentType(i); - if (type.isArray()) { - ArrayType arrayType = type.asArray(); - writer.println(" if (" + getArgumentName(i) + ".length < " + - arrayType.getLength() + ")"); - writer.println(" throw new " + getRuntimeExceptionType() + - "(\"Length of array \\\"" + getArgumentName(i) + - "\\\" was less than the required " + arrayType.getLength() + "\");"); - // FIXME: What is this ??? Until resolved - throw an exception ! - throw new RuntimeException("????? "+binding+": binding.getCArgumentType("+i+").isArray(): "+type); - } else { - JavaType javaType = binding.getJavaArgumentType(i); - if (javaType.isNIOBuffer()) { - if (directNIOOnly) { - writer.println(" if (!Buffers.isDirect(" + getArgumentName(i) + "))"); - writer.println(" throw new " + getRuntimeExceptionType() + "(\"Argument \\\"" + - getArgumentName(i) + "\\\" was not a direct buffer\");"); - } else { - writer.print(" boolean " + isNIOArgName(i) + " = "); - writer.println(getArgumentName(i) + " != null && Buffers.isDirect(" + getArgumentName(i) + ");"); - } - } else if (javaType.isNIOBufferArray()) { - // All buffers passed down in an array of NIO buffers must be direct - String argName = getArgumentName(i); - String arrayName = byteOffsetArrayArgName(i); - writer.println(" int[] " + arrayName + " = new int[" + argName + ".length];"); - // Check direct buffer properties of all buffers within - writer.println(" if (" + argName + " != null) {"); - writer.println(" for (int _ctr = 0; _ctr < " + argName + ".length; _ctr++) {"); - writer.println(" if (!Buffers.isDirect(" + argName + "[_ctr])) {"); - writer.println(" throw new " + getRuntimeExceptionType() + - "(\"Element \" + _ctr + \" of argument \\\"" + - getArgumentName(i) + "\\\" was not a direct buffer\");"); - writer.println(" }"); - // get the Buffer Array offset values and save them into another array to send down to JNI - writer.print (" " + arrayName + "[_ctr] = Buffers.getDirectBufferByteOffset("); - writer.println(argName + "[_ctr]);"); - writer.println(" }"); - writer.println(" }"); - } else if (javaType.isPrimitiveArray()) { - String argName = getArgumentName(i); - String offsetArg = offsetArgName(i); - writer.println(" if(" + argName + " != null && " + argName + ".length <= " + offsetArg + ")"); - writer.print (" throw new " + getRuntimeExceptionType()); - writer.println("(\"array offset argument \\\"" + offsetArg + "\\\" (\" + " + offsetArg + - " + \") equals or exceeds array length (\" + " + argName + ".length + \")\");"); - } - } - } - } - - protected void emitCompoundArrayCopies(MethodBinding binding, PrintWriter writer) { - // If the method binding uses outgoing arrays of compound type - // wrappers, we need to generate a temporary copy of this array - // into a ByteBuffer[] for processing by the native code - if (binding.signatureUsesArraysOfCompoundTypeWrappers()) { - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType javaType = binding.getJavaArgumentType(i); - if (javaType.isArrayOfCompoundTypeWrappers()) { - String argName = getArgumentName(i); - String tempArrayName = argName + COMPOUND_ARRAY_SUFFIX; - writer.println(" ByteBuffer[] " + tempArrayName + " = new ByteBuffer[" + argName + ".length];"); - writer.println(" for (int _ctr = 0; _ctr < + " + argName + ".length; _ctr++) {"); - writer.println(" " + javaType.getName() + " _tmp = " + argName + "[_ctr];"); - writer.println(" " + tempArrayName + "[_ctr] = ((_tmp == null) ? null : _tmp.getBuffer());"); - writer.println(" }"); - } - } - } - } - - protected void emitCall(MethodBinding binding, PrintWriter writer) { - writer.print(getImplMethodName()); - writer.print("("); - emitCallArguments(binding, writer); - writer.print(");"); - } - - - protected void emitReturnVariableSetupAndCall(MethodBinding binding, PrintWriter writer) { - writer.print(" "); - JavaType returnType = binding.getJavaReturnType(); - boolean needsResultAssignment = false; - - if (!returnType.isVoid()) { - if (returnType.isCompoundTypeWrapper() || - returnType.isNIOBuffer()) { - writer.println("ByteBuffer _res;"); - needsResultAssignment = true; - } else if (returnType.isArrayOfCompoundTypeWrappers()) { - writer.println("ByteBuffer[] _res;"); - needsResultAssignment = true; - } else if (((epilogue != null) && (epilogue.size() > 0)) || - binding.signatureUsesArraysOfCompoundTypeWrappers()) { - emitReturnType(writer); - writer.println(" _res;"); - needsResultAssignment = true; - } - } - - if (needsResultAssignment) { - writer.print(" _res = "); - } else { - writer.print(" "); - if (!returnType.isVoid()) { - writer.print("return "); - } - } - - emitCall(binding, writer); - writer.println(); - - emitPostCallCleanup(binding, writer); - emitPrologueOrEpilogue(epilogue, writer); - if (needsResultAssignment) { - emitCallResultReturn(binding, writer); - } - } - - protected int emitCallArguments(MethodBinding binding, PrintWriter writer) { - boolean needComma = false; - int numArgsEmitted = 0; - - if (binding.hasContainingType()) { - // Emit this pointer - assert(binding.getContainingType().isCompoundTypeWrapper()); - writer.print("getBuffer()"); - needComma = true; - ++numArgsEmitted; - } - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType type = binding.getJavaArgumentType(i); - if (type.isJNIEnv() || binding.isArgumentThisPointer(i)) { - // Don't need to expose these at the Java level - continue; - } - - if (type.isVoid()) { - // Make sure this is the only param to the method; if it isn't, - // there's something wrong with our parsing of the headers. - assert(binding.getNumArguments() == 1); - continue; - } - - if (needComma) { - writer.print(", "); - } - - if (type.isCompoundTypeWrapper()) { - writer.print("(("); - } - - if (type.isNIOBuffer()) { - if(type.isNIOInt64Buffer() || type.isNIOPointerBuffer()) { - if (directNIOOnly) { - writer.print( getArgumentName(i)+ " != null ? " + getArgumentName(i) + ".getBuffer() : null"); - } else { - writer.print( isNIOArgName(i) + " ? ( " + getArgumentName(i)+ " != null ? " + getArgumentName(i) + ".getBuffer() : null )"); - writer.print( " : Buffers.getArray(" + getArgumentName(i) + ")" ); - } - } else { - if (directNIOOnly) { - writer.print( getArgumentName(i) ); - } else { - writer.print( isNIOArgName(i) + " ? " + getArgumentName(i) + " : Buffers.getArray(" + getArgumentName(i) + ")" ); - } - } - } else if (type.isArrayOfCompoundTypeWrappers()) { - writer.print(getArgumentName(i) + COMPOUND_ARRAY_SUFFIX); - } else { - writer.print(getArgumentName(i)); - } - - if (type.isCompoundTypeWrapper()) { - writer.print(" == null) ? null : "); - writer.print(getArgumentName(i)); - writer.print(".getBuffer())"); - } - - if (type.isNIOBuffer()) { - if (directNIOOnly) { - writer.print( ", Buffers.getDirectBufferByteOffset(" + getArgumentName(i) + ")"); - } else { - writer.print( ", " + isNIOArgName(i) + " ? Buffers.getDirectBufferByteOffset(" + getArgumentName(i) + ")"); - writer.print( " : Buffers.getIndirectBufferByteOffset(" + getArgumentName(i) + ")"); - } - } else if (type.isNIOBufferArray()) { - writer.print(", " + byteOffsetArrayArgName(i)); - } else if (type.isPrimitiveArray()) { - if(type.isFloatArray()) { - writer.print(", Buffers.SIZEOF_FLOAT * "); - } else if(type.isDoubleArray()) { - writer.print(", Buffers.SIZEOF_DOUBLE * "); - } else if(type.isByteArray()) { - writer.print(", "); - } else if(type.isLongArray()) { - writer.print(", Buffers.SIZEOF_LONG * "); - } else if(type.isShortArray()) { - writer.print(", Buffers.SIZEOF_SHORT * "); - } else if(type.isIntArray()) { - writer.print(", Buffers.SIZEOF_INT * "); - } else { - throw new RuntimeException("Unsupported type for calculating array offset argument for " + - getArgumentName(i) + - " -- error occurred while processing Java glue code for " + getName()); - } - writer.print(offsetArgName(i)); - } - - if (type.isNIOBuffer()) { - if (!directNIOOnly) { - writer.print( ", " + isNIOArgName(i) ); - } - } else if (type.isPrimitiveArray()) { - if (directNIOOnly) { - throw new RuntimeException("NIODirectOnly "+binding+" is set, but "+getArgumentName(i)+" is a primitive array"); - } - writer.print( ", false"); - } - - needComma = true; - ++numArgsEmitted; - } - return numArgsEmitted; - } - - protected void emitPostCallCleanup(MethodBinding binding, PrintWriter writer) { - if (binding.signatureUsesArraysOfCompoundTypeWrappers()) { - // For each such array, we need to take the ByteBuffer[] that - // came back from the C method invocation and wrap the - // ByteBuffers back into the wrapper types - for (int i = 0; i < binding.getNumArguments(); i++) { - JavaType javaArgType = binding.getJavaArgumentType(i); - if (javaArgType.isArrayOfCompoundTypeWrappers()) { - String argName = binding.getArgumentName(i); - writer.println(" for (int _ctr = 0; _ctr < " + argName + ".length; _ctr++) {"); - writer.println(" if ((" + argName + "[_ctr] == null && " + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr] == null) ||"); - writer.println(" (" + argName + "[_ctr] != null && " + argName + "[_ctr].getBuffer() == " + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr])) {"); - writer.println(" // No copy back needed"); - writer.println(" } else {"); - writer.println(" if (" + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr] == null) {"); - writer.println(" " + argName + "[_ctr] = null;"); - writer.println(" } else {"); - writer.println(" " + argName + "[_ctr] = " + javaArgType.getName() + ".create(" + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr]);"); - writer.println(" }"); - writer.println(" }"); - writer.println(" }"); - } - } - } - } - - protected void emitCallResultReturn(MethodBinding binding, PrintWriter writer) { - JavaType returnType = binding.getJavaReturnType(); - - if (returnType.isCompoundTypeWrapper()) { - String fmt = getReturnedArrayLengthExpression(); - writer.println(" if (_res == null) return null;"); - if (fmt == null) { - writer.print(" return " + returnType.getName() + ".create(Buffers.nativeOrder(_res))"); - } else { - writer.println(" Buffers.nativeOrder(_res);"); - String expr = new MessageFormat(fmt).format(argumentNameArray()); - PointerType cReturnTypePointer = binding.getCReturnType().asPointer(); - CompoundType cReturnType = null; - if (cReturnTypePointer != null) { - cReturnType = cReturnTypePointer.getTargetType().asCompound(); - } - if (cReturnType == null) { - throw new RuntimeException("ReturnedArrayLength directive currently only supported for pointers to compound types " + - "(error occurred while generating Java glue code for " + getName() + ")"); - } - writer.println(" " + getReturnTypeString(false) + " _retarray = new " + getReturnTypeString(true) + "[" + expr + "];"); - writer.println(" for (int _count = 0; _count < " + expr + "; _count++) {"); - // Create temporary ByteBuffer slice - // FIXME: probably need Type.getAlignedSize() for arrays of - // compound types (rounding up to machine-dependent alignment) - writer.println(" _res.position(_count * " + getReturnTypeString(true) + ".size());"); - writer.println(" _res.limit ((1 + _count) * " + getReturnTypeString(true) + ".size());"); - writer.println(" ByteBuffer _tmp = _res.slice();"); - writer.println(" Buffers.nativeOrder(_tmp);"); - writer.println(" _res.position(0);"); - writer.println(" _res.limit(_res.capacity());"); - writer.println(" _retarray[_count] = " + getReturnTypeString(true) + ".create(_tmp);"); - writer.println(" }"); - writer.print (" return _retarray"); - } - writer.println(";"); - } else if (returnType.isNIOBuffer()) { - writer.println(" if (_res == null) return null;"); - writer.println(" Buffers.nativeOrder(_res);"); - if (!returnType.isNIOByteBuffer()) { - // See whether we have to expand pointers to longs - if (getBinding().getCReturnType().pointerDepth() >= 2) { - if (returnType.isNIOPointerBuffer()) { - writer.println(" return PointerBuffer.wrap(_res);"); - } else if (returnType.isNIOInt64Buffer()) { - writer.println(" return Int64Buffer.wrap(_res);"); - } else { - throw new RuntimeException("While emitting glue code for " + getName() + - ": can not legally make pointers opaque to anything but PointerBuffer or Int64Buffer/long"); - } - } else if (getBinding().getCReturnType().pointerDepth() == 1 && - returnType.isNIOInt64Buffer()) { - writer.println(" return Int64Buffer.wrap(_res);"); - } else { - String returnTypeName = returnType.getName().substring("java.nio.".length()); - writer.println(" return _res.as" + returnTypeName + "();"); - } - } else { - writer.println(" return _res;"); - } - } else if (returnType.isArrayOfCompoundTypeWrappers()) { - writer.println(" if (_res == null) return null;"); - writer.println(" " + getReturnTypeString(false) + " _retarray = new " + getReturnTypeString(true) + "[_res.length];"); - writer.println(" for (int _count = 0; _count < _res.length; _count++) {"); - writer.println(" _retarray[_count] = " + getReturnTypeString(true) + ".create(_res[_count]);"); - writer.println(" }"); - writer.println(" return _retarray;"); - } else { - // Assume it's a primitive type or other type we don't have to - // do any conversion on - writer.println(" return _res;"); - } - } - - protected String[] argumentNameArray() { - String[] argumentNames = new String[binding.getNumArguments()]; - for (int i = 0; i < binding.getNumArguments(); i++) { - argumentNames[i] = getArgumentName(i); - if (binding.getJavaArgumentType(i).isPrimitiveArray()) { - // Add on _offset argument in comma-separated expression - argumentNames[i] = argumentNames[i] + ", " + offsetArgName(i); - } - } - return argumentNames; - } - - public static String javaThisArgumentName() { - return "jthis0"; - } - - @Override - protected String getCommentStartString() { return "/** "; } - - @Override - protected String getBaseIndentString() { return " "; } - - protected String getReturnedArrayLengthExpression() { - return returnedArrayLengthExpression; - } - - /** - * Class that emits a generic comment for JavaMethodBindingEmitters; the comment - * includes the C signature of the native method that is being bound by the - * emitter java method. - */ - protected class DefaultCommentEmitter implements CommentEmitter { - public void emit(FunctionEmitter emitter, PrintWriter writer) { - emitBeginning(emitter, writer); - emitBindingCSignature(((JavaMethodBindingEmitter)emitter).getBinding(), writer); - emitEnding(emitter, writer); - } - protected void emitBeginning(FunctionEmitter emitter, PrintWriter writer) { - writer.print("Entry point to C language function: "); - } - protected void emitBindingCSignature(MethodBinding binding, PrintWriter writer) { - writer.print("<code> "); - writer.print(binding.getCSymbol().toString(tagNativeBinding)); - writer.print(" </code> "); - } - protected void emitEnding(FunctionEmitter emitter, PrintWriter writer) { - // If argument type is a named enum, then emit a comment detailing the - // acceptable values of that enum. - // If we're emitting a direct buffer variant only, then declare - // that the NIO buffer arguments must be direct. - MethodBinding binding = ((JavaMethodBindingEmitter)emitter).getBinding(); - for (int i = 0; i < binding.getNumArguments(); i++) { - Type type = binding.getCArgumentType(i); - JavaType javaType = binding.getJavaArgumentType(i); - // don't emit param comments for anonymous enums, since we can't - // distinguish between the values found within multiple anonymous - // enums in the same C translation unit. - if (type.isEnum() && !HeaderParser.ANONYMOUS_ENUM_NAME.equals(type.getName())) { - EnumType enumType = (EnumType)type; - writer.println(); - writer.print(emitter.getBaseIndentString()); - writer.print(" "); - writer.print("@param "); - writer.print(getArgumentName(i)); - writer.print(" valid values are: <code>"); - for (int j = 0; j < enumType.getNumEnumerates(); ++j) { - if (j>0) writer.print(", "); - writer.print(enumType.getEnumName(j)); - } - writer.println("</code>"); - } else if (directNIOOnly && javaType.isNIOBuffer()) { - writer.println(); - writer.print(emitter.getBaseIndentString()); - writer.print(" "); - writer.print("@param "); - writer.print(getArgumentName(i)); - writer.print(" a direct {@link " + javaType.getName() + "}"); - } - } - } - } - - protected class InterfaceCommentEmitter extends JavaMethodBindingEmitter.DefaultCommentEmitter { - - @Override - protected void emitBeginning(FunctionEmitter emitter, - PrintWriter writer) { - writer.print("Interface to C language function: <br> "); - } - } -} - |