aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/gluegen/JavaMethodBindingEmitter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/com/sun/gluegen/JavaMethodBindingEmitter.java')
-rw-r--r--src/classes/com/sun/gluegen/JavaMethodBindingEmitter.java784
1 files changed, 0 insertions, 784 deletions
diff --git a/src/classes/com/sun/gluegen/JavaMethodBindingEmitter.java b/src/classes/com/sun/gluegen/JavaMethodBindingEmitter.java
deleted file mode 100644
index 7e08977a6..000000000
--- a/src/classes/com/sun/gluegen/JavaMethodBindingEmitter.java
+++ /dev/null
@@ -1,784 +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;
-
- protected boolean emitBody;
- protected boolean eraseBufferAndArrayTypes;
- protected boolean directNIOOnly;
- protected boolean forImplementingMethodCall;
- protected boolean forDirectBufferImplementation;
- protected boolean forIndirectBufferAndArrayImplementation;
- protected boolean isUnimplemented;
-
- 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;
-
- // Range-check expressions for various Buffer arguments
- private Map/*<Integer, String>*/ rangeCheckExpressions;
- private Map/*<Integer, String>*/ byteRangeCheckExpressions;
-
- public JavaMethodBindingEmitter(MethodBinding binding,
- PrintWriter output,
- String runtimeExceptionType,
- boolean emitBody,
- boolean eraseBufferAndArrayTypes,
- boolean directNIOOnly,
- boolean forImplementingMethodCall,
- boolean forDirectBufferImplementation,
- boolean forIndirectBufferAndArrayImplementation,
- boolean isUnimplemented)
- {
- super(output);
- this.binding = binding;
- this.runtimeExceptionType = runtimeExceptionType;
- this.emitBody = emitBody;
- 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);
- }
- }
-
- public JavaMethodBindingEmitter(JavaMethodBindingEmitter arg) {
- super(arg);
- binding = arg.binding;
- runtimeExceptionType = arg.runtimeExceptionType;
- emitBody = arg.emitBody;
- 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;
- rangeCheckExpressions = arg.rangeCheckExpressions;
- byteRangeCheckExpressions = arg.byteRangeCheckExpressions;
- }
-
- public final MethodBinding getBinding() { return binding; }
-
- public boolean isForImplementingMethodCall() { return forImplementingMethodCall; }
-
- public String getName() {
- return binding.getRenamedMethodName();
- }
-
- 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;
- }
-
- /** 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;
- }
-
- public void setRangeCheckExpressions(Map/*<Integer, String>*/ rangeChecks) {
- this.rangeCheckExpressions = rangeChecks;
- }
-
- public void setByteRangeCheckExpressions(Map/*<Integer, String>*/ rangeChecks) {
- this.byteRangeCheckExpressions = rangeChecks;
- }
-
- protected void emitReturnType(PrintWriter writer)
- {
- writer.print(getReturnTypeString(false));
- }
-
- protected String erasedTypeString(JavaType type, boolean skipBuffers) {
- if (eraseBufferAndArrayTypes) {
- if (type.isNIOBuffer() ||
- type.isPrimitiveArray()) {
- if (!skipBuffers) {
- // Direct buffers and arrays sent down as Object (but
- // returned as e.g. ByteBuffer)
- return "Object";
- }
- } else if (type.isCompoundTypeWrapper()) {
- // Compound type wrappers are unwrapped to ByteBuffer
- return "java.nio.ByteBuffer";
- } else if (type.isArrayOfCompoundTypeWrappers()) {
- return "java.nio.ByteBuffer";
- }
- }
- return type.getName();
- }
-
- 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) {
- if (forIndirectBufferAndArrayImplementation) {
- writer.print(getImplMethodName(false));
- } else {
- writer.print(getImplMethodName(true));
- }
- } 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("java.nio.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));
- } else if (type.isNIOBufferArray()) {
- writer.print(", int[] " +
- byteOffsetArrayArgName(i));
- }
- }
-
- // Add offset argument after each primitive array
- if (type.isPrimitiveArray()) {
- writer.print(", int " + offsetArgName(i));
- }
- }
- return numEmitted;
- }
-
-
- protected String getImplMethodName(boolean direct) {
- if (direct) {
- return binding.getRenamedMethodName() + "0";
- } else {
- return binding.getRenamedMethodName() + "1";
- }
- }
-
- protected String byteOffsetArgName(int i) {
- return byteOffsetArgName(getArgumentName(i));
- }
-
- protected String byteOffsetArgName(String s) {
- return s + "_byte_offset";
- }
-
- 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 binding = getBinding();
- writer.println();
- writer.println(" {");
- if (isUnimplemented) {
- writer.println(" throw new " + getRuntimeExceptionType() + "(\"Unimplemented\");");
- } else {
- emitPrologueOrEpilogue(prologue, writer);
- emitPreCallSetup(binding, writer);
- //emitReturnVariableSetup(binding, writer);
- emitReturnVariableSetupAndCall(binding, writer);
- }
- writer.println(" }");
- }
- }
-
- protected void emitPrologueOrEpilogue(List/*<String>*/ code, PrintWriter writer) {
- if (code != null) {
- for (Iterator iter = code.iterator(); iter.hasNext(); ) {
- writer.println(" " + (String) iter.next());
- }
- }
- }
-
- protected void emitPreCallSetup(MethodBinding binding, PrintWriter writer) {
- emitArrayLengthAndNIOBufferChecks(binding, writer);
- }
-
- protected void emitArrayLengthAndNIOBufferChecks(MethodBinding binding, PrintWriter writer) {
- int numBufferOffsetArrayArgs = 0;
- boolean firstBuffer = true;
- // 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() + "\");");
- } else {
- JavaType javaType = binding.getJavaArgumentType(i);
- if (javaType.isNIOBuffer()) {
- if (directNIOOnly) {
- writer.println(" if (!BufferFactory.isDirect(" + getArgumentName(i) + "))");
- writer.println(" throw new " + getRuntimeExceptionType() + "(\"Argument \\\"" +
- getArgumentName(i) + "\\\" was not a direct buffer\");");
- } else {
- if(firstBuffer) {
- firstBuffer = false;
- writer.println(" boolean _direct = BufferFactory.isDirect(" + getArgumentName(i) + ");");
- } else {
- writer.println(" if (_direct != BufferFactory.isDirect(" + getArgumentName(i) + "))");
- writer.println(" throw new " + getRuntimeExceptionType() +
- "(\"Argument \\\"" + getArgumentName(i) +
- "\\\" : Buffers passed to this method must all be either direct or indirect\");");
- }
- }
- } 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 (!BufferFactory.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] = BufferFactory.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 + \")\");");
- }
- }
- }
-
- emitManuallySpecifiedRangeChecks(rangeCheckExpressions, false, writer);
- emitManuallySpecifiedRangeChecks(byteRangeCheckExpressions, true, writer);
- }
-
- protected void emitManuallySpecifiedRangeChecks(Map/*<Integer, String>*/ rangeChecks,
- boolean inBytes,
- PrintWriter writer) {
- if (rangeChecks == null) {
- return;
- }
-
- // Check lengths of arrays and buffers with user-specified checks
- for (Iterator iter = rangeChecks.keySet().iterator(); iter.hasNext(); ) {
- Integer argNumBox = (Integer) iter.next();
- int argNum = argNumBox.intValue();
- JavaType type = binding.getJavaArgumentType(argNum);
- String argName = getArgumentName(argNum);
- if (type.isPrimitiveArray()) {
- String offsetArg = offsetArgName(argNum);
- if (inBytes) {
- throw new RuntimeException("Can not specify RangeCheckBytes for primitive array arguments (failed on function " +
- binding.getName() + ", argument " + argName + ")");
- }
- writer.println(" BufferFactory.rangeCheck(" + argName + ", " + offsetArg + ", " +
- new MessageFormat((String) rangeChecks.get(argNumBox)).format(argumentNameArray()) +
- ");");
- } else if (!type.isPrimitive()) {
- // Assume it's a Buffer
- writer.print(" BufferFactory.rangeCheck");
- if (inBytes) {
- writer.print("Bytes");
- }
- writer.println("(" + argName + ", " +
- new MessageFormat((String) rangeChecks.get(argNumBox)).format(argumentNameArray()) +
- ");");
- }
- }
- }
-
- protected void emitCall(MethodBinding binding, PrintWriter writer, boolean direct) {
- writer.print(getImplMethodName(direct));
- writer.print("(");
- emitCallArguments(binding, writer, direct);
- 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.isNIOByteBuffer()) {
- writer.println("ByteBuffer _res;");
- needsResultAssignment = true;
- } else if (returnType.isArrayOfCompoundTypeWrappers()) {
- writer.println("ByteBuffer[] _res;");
- needsResultAssignment = true;
- } else if ((epilogue != null) && (epilogue.size() > 0)) {
- emitReturnType(writer);
- writer.println(" _res;");
- needsResultAssignment = true;
- }
- }
-
- if (binding.signatureCanUseIndirectNIO() && !directNIOOnly) {
- // Must generate two calls for this gated on whether the NIO
- // buffers coming in are all direct or indirect
- writer.println("if (_direct) {");
- writer.print (" ");
- }
-
- if (needsResultAssignment) {
- writer.print(" _res = ");
- } else {
- writer.print(" ");
- if (!returnType.isVoid()) {
- writer.print("return ");
- }
- }
-
- if (binding.signatureUsesJavaPrimitiveArrays() &&
- !binding.signatureCanUseIndirectNIO()) {
- // FIXME: what happens with a C function of the form
- // void foo(int* arg0, void* arg1);
- // ?
-
- // Only one call being made in this body, going to indirect
- // buffer / array entry point
- emitCall(binding, writer, false);
- writer.println();
- } else {
- emitCall(binding, writer, true);
- }
-
- if (binding.signatureCanUseIndirectNIO() && !directNIOOnly) {
- // Must generate two calls for this gated on whether the NIO
- // buffers coming in are all direct or indirect
- writer.println();
- writer.println(" } else {");
- writer.print (" ");
- if (needsResultAssignment) {
- writer.print(" _res = ");
- } else {
- writer.print(" ");
- if (!returnType.isVoid()) {
- writer.print("return ");
- }
- }
- emitCall(binding, writer, false);
- writer.println();
- writer.println(" }");
- } else {
- writer.println();
- }
- emitPrologueOrEpilogue(epilogue, writer);
- if (needsResultAssignment) {
- emitCallResultReturn(binding, writer);
- }
- }
-
- protected int emitCallArguments(MethodBinding binding, PrintWriter writer, boolean direct) {
- 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() && !direct) {
- writer.print("BufferFactory.getArray(" + getArgumentName(i) + ")");
- } else {
- writer.print(getArgumentName(i));
- }
-
- if (type.isCompoundTypeWrapper()) {
- writer.print(" == null) ? null : ");
- writer.print(getArgumentName(i));
- writer.print(".getBuffer())");
- }
- needComma = true;
- ++numArgsEmitted;
- if (type.isNIOBuffer()) {
- if (direct) {
- writer.print(", BufferFactory.getDirectBufferByteOffset(" + getArgumentName(i) + ")");
- } else {
- writer.print(", BufferFactory.getIndirectBufferByteOffset(" + getArgumentName(i) + ")");
- }
- } else if (type.isNIOBufferArray()) {
- writer.print(", " + byteOffsetArrayArgName(i));
- }
-
- // Add Array offset parameter for primitive arrays
- if (type.isPrimitiveArray()) {
- if(type.isFloatArray()) {
- writer.print(", BufferFactory.SIZEOF_FLOAT * ");
- } else if(type.isDoubleArray()) {
- writer.print(", BufferFactory.SIZEOF_DOUBLE * ");
- } else if(type.isByteArray()) {
- writer.print(", ");
- } else if(type.isLongArray()) {
- writer.print(", BufferFactory.SIZEOF_LONG * ");
- } else if(type.isShortArray()) {
- writer.print(", BufferFactory.SIZEOF_SHORT * ");
- } else if(type.isIntArray()) {
- writer.print(", BufferFactory.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));
- }
- }
- return numArgsEmitted;
- }
-
- 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(_res.order(ByteOrder.nativeOrder()))");
- } else {
- writer.println(" _res.order(ByteOrder.nativeOrder());");
- 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(" _tmp.order(ByteOrder.nativeOrder());");
- 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(" return _res.order(ByteOrder.nativeOrder());");
- } 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);
- }
- return argumentNames;
- }
-
- public static String javaThisArgumentName() {
- return "jthis0";
- }
-
- protected String getCommentStartString() { return "/** "; }
-
- 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: <br> ");
- }
- protected void emitBindingCSignature(MethodBinding binding, PrintWriter writer) {
- writer.print("<code> ");
- writer.print(binding.getCSymbol());
- 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() && type.getName() != HeaderParser.ANONYMOUS_ENUM_NAME) {
- 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
- {
- protected void emitBeginning(FunctionEmitter emitter,
- PrintWriter writer) {
- writer.print("Interface to C language function: <br> ");
- }
- }
-}
-