diff options
Diffstat (limited to 'src/java')
-rw-r--r-- | src/java/com/sun/gluegen/CMethodBindingEmitter.java | 25 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/FunctionEmitter.java | 17 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaConfiguration.java | 57 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaEmitter.java | 6 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaMethodBindingEmitter.java | 60 | ||||
-rwxr-xr-x | src/java/com/sun/gluegen/opengl/GLConfiguration.java | 20 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/runtime/BufferFactory.java | 39 |
7 files changed, 109 insertions, 115 deletions
diff --git a/src/java/com/sun/gluegen/CMethodBindingEmitter.java b/src/java/com/sun/gluegen/CMethodBindingEmitter.java index 9222588..1ffd362 100644 --- a/src/java/com/sun/gluegen/CMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/CMethodBindingEmitter.java @@ -988,13 +988,8 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.print(" return (*env)->NewDirectByteBuffer(env, _res, "); // See whether capacity has been specified if (returnValueCapacityExpression != null) { - String[] argumentNames = new String[binding.getNumArguments()]; - for (int i = 0; i < binding.getNumArguments(); i++) - { - argumentNames[i] = binding.getArgumentName(i); - } writer.print( - returnValueCapacityExpression.format(argumentNames)); + returnValueCapacityExpression.format(argumentNameArray())); } else { if (cReturnType.isPointer() && cReturnType.asPointer().getTargetType().isCompound()) { @@ -1025,11 +1020,7 @@ public class CMethodBindingEmitter extends FunctionEmitter throw new RuntimeException("Error while generating C code: no length specified for array returned from function " + binding); } - String[] argumentNames = new String[binding.getNumArguments()]; - for (int i = 0; i < binding.getNumArguments(); i++) { - argumentNames[i] = binding.getArgumentName(i); - } - writer.println(" " + arrayResLength + " = " + returnValueLengthExpression.format(argumentNames) + ";"); + writer.println(" " + arrayResLength + " = " + returnValueLengthExpression.format(argumentNameArray()) + ";"); writer.println(" " + arrayRes + " = (*env)->NewObjectArray(env, " + arrayResLength + ", (*env)->FindClass(env, \"java/nio/ByteBuffer\"), NULL);"); writer.println(" for (" + arrayIdx + " = 0; " + arrayIdx + " < " + arrayResLength + "; " + arrayIdx + "++) {"); Type retType = binding.getCSymbol().getReturnType(); @@ -1408,6 +1399,18 @@ public class CMethodBindingEmitter extends FunctionEmitter return binding.getArgumentName(i) + "_byte_offset_array"; } + protected String[] argumentNameArray() { + String[] argumentNames = new String[binding.getNumArguments()]; + for (int i = 0; i < binding.getNumArguments(); i++) { + argumentNames[i] = binding.getArgumentName(i); + if (binding.getJavaArgumentType(i).isPrimitiveArray()) { + // Add on _offset argument in comma-separated expression + argumentNames[i] = argumentNames[i] + ", " + byteOffsetArgName(i); + } + } + return argumentNames; + } + protected String pointerConversionArgumentName(int i) { return "_ptr" + i; } diff --git a/src/java/com/sun/gluegen/FunctionEmitter.java b/src/java/com/sun/gluegen/FunctionEmitter.java index 3fa6f03..0d0f225 100644 --- a/src/java/com/sun/gluegen/FunctionEmitter.java +++ b/src/java/com/sun/gluegen/FunctionEmitter.java @@ -47,7 +47,7 @@ public abstract class FunctionEmitter { public static final EmissionModifier STATIC = new EmissionModifier("static"); - private HashSet modifiers = new HashSet(4); + private ArrayList modifiers = new ArrayList(); private CommentEmitter commentEmitter = null; private PrintWriter defaultOutput; @@ -64,7 +64,7 @@ public abstract class FunctionEmitter * Makes this FunctionEmitter a copy of the passed one. */ public FunctionEmitter(FunctionEmitter arg) { - modifiers = (HashSet) arg.modifiers.clone(); + modifiers = (ArrayList) arg.modifiers.clone(); commentEmitter = arg.commentEmitter; defaultOutput = arg.defaultOutput; } @@ -203,6 +203,19 @@ public abstract class FunctionEmitter public final String toString() { return emittedForm; } private String emittedForm; + + public int hashCode() { + return emittedForm.hashCode(); + } + + public boolean equals(Object arg) { + if (arg == null || (!(arg instanceof EmissionModifier))) { + return false; + } + + return emittedForm.equals(((EmissionModifier) arg).emittedForm); + } + protected EmissionModifier(String emittedForm) { this.emittedForm = emittedForm; } } } diff --git a/src/java/com/sun/gluegen/JavaConfiguration.java b/src/java/com/sun/gluegen/JavaConfiguration.java index ae8c46e..b5f43d6 100644 --- a/src/java/com/sun/gluegen/JavaConfiguration.java +++ b/src/java/com/sun/gluegen/JavaConfiguration.java @@ -116,8 +116,6 @@ public class JavaConfiguration { private Map/*<String,String>*/ javaMethodRenames = new HashMap(); private Map/*<String,List<String>>*/ javaPrologues = new HashMap(); private Map/*<String,List<String>>*/ javaEpilogues = new HashMap(); - private Map/*<String,Map<Integer,String>>*/ rangeChecks = new HashMap(); - private Map/*<String,Map<Integer,String>>*/ byteRangeChecks = new HashMap(); /** Reads the configuration file. @param filename path to file that should be read @@ -571,22 +569,6 @@ public class JavaConfiguration { return res; } - /** Returns a map of Integer argument numbers to expressions to be - used to range check the given arguments to the given function. - Returns null if there were no range check expressions supplied - for this function. */ - public Map/*<Integer, String>*/ rangeCheckExpressions(String functionName) { - return (Map/*<Integer, String>*/) rangeChecks.get(functionName); - } - - /** Returns a map of Integer argument numbers to expressions to be - used to range check (in size of bytes) the given arguments to - the given function. Returns null if there were no range check - expressions supplied for this function. */ - public Map/*<Integer, String>*/ byteRangeCheckExpressions(String functionName) { - return (Map/*<Integer, String>*/) byteRangeChecks.get(functionName); - } - //---------------------------------------------------------------------- // Internals only below this point // @@ -1142,13 +1124,7 @@ public class JavaConfiguration { methodName = methodName + descriptor; } } - Map code = (prologue ? javaPrologues : javaEpilogues); - List/*<String>*/ data = (List/*<String>*/) code.get(methodName); - if (data == null) { - data = new ArrayList/*<String>*/(); - code.put(methodName, data); - } - data.add(restOfLine); + addJavaPrologueOrEpilogue(methodName, restOfLine, prologue); } catch (NoSuchElementException e) { throw new RuntimeException("Error parsing \"" + (prologue ? "JavaPrologue" : "JavaEpilogue") + @@ -1157,27 +1133,28 @@ public class JavaConfiguration { } } + protected void addJavaPrologueOrEpilogue(String methodName, String code, boolean prologue) { + Map codes = (prologue ? javaPrologues : javaEpilogues); + List/*<String>*/ data = (List/*<String>*/) codes.get(methodName); + if (data == null) { + data = new ArrayList/*<String>*/(); + codes.put(methodName, data); + } + data.add(code); + } + protected void readRangeCheck(StringTokenizer tok, String filename, int lineNo, boolean inBytes) { try { String functionName = tok.nextToken(); int argNum = Integer.parseInt(tok.nextToken()); String restOfLine = tok.nextToken("\n\r\f"); restOfLine = restOfLine.trim(); - Map/*<Integer, String>*/ checksForFunction = null; - if (inBytes) { - checksForFunction = (Map/*<Integer, String>*/) byteRangeChecks.get(functionName); - } else { - checksForFunction = (Map/*<Integer, String>*/) rangeChecks.get(functionName); - } - if (checksForFunction == null) { - checksForFunction = new HashMap/*<Integer, String>*/(); - if (inBytes) { - byteRangeChecks.put(functionName, checksForFunction); - } else { - rangeChecks.put(functionName, checksForFunction); - } - } - checksForFunction.put(new Integer(argNum), restOfLine); + // Construct a JavaPrologue for this + addJavaPrologueOrEpilogue(functionName, + "BufferFactory.rangeCheck" + + (inBytes ? "Bytes" : "") + + "({" + argNum + "}, " + restOfLine + ");", + true); } catch (Exception e) { throw new RuntimeException("Error parsing \"RangeCheck" + (inBytes ? "Bytes" : "") + "\" command at line " + lineNo + " in file \"" + filename + "\"", e); diff --git a/src/java/com/sun/gluegen/JavaEmitter.java b/src/java/com/sun/gluegen/JavaEmitter.java index f079906..d4bafb7 100644 --- a/src/java/com/sun/gluegen/JavaEmitter.java +++ b/src/java/com/sun/gluegen/JavaEmitter.java @@ -377,8 +377,6 @@ public class JavaEmitter implements GlueEmitter { emitter.setReturnedArrayLengthExpression(cfg.returnedArrayLength(binding.getName())); emitter.setPrologue(prologue); emitter.setEpilogue(epilogue); - emitter.setRangeCheckExpressions(cfg.rangeCheckExpressions(binding.getName())); - emitter.setByteRangeCheckExpressions(cfg.byteRangeCheckExpressions(binding.getName())); allEmitters.add(emitter); } @@ -432,8 +430,6 @@ public class JavaEmitter implements GlueEmitter { } emitter.addModifier(JavaMethodBindingEmitter.NATIVE); emitter.setReturnedArrayLengthExpression(cfg.returnedArrayLength(binding.getName())); - emitter.setRangeCheckExpressions(cfg.rangeCheckExpressions(binding.getName())); - emitter.setByteRangeCheckExpressions(cfg.byteRangeCheckExpressions(binding.getName())); allEmitters.add(emitter); // Optionally emit the entry point taking arrays which handles @@ -459,8 +455,6 @@ public class JavaEmitter implements GlueEmitter { } emitter.addModifier(JavaMethodBindingEmitter.NATIVE); emitter.setReturnedArrayLengthExpression(cfg.returnedArrayLength(binding.getName())); - emitter.setRangeCheckExpressions(cfg.rangeCheckExpressions(binding.getName())); - emitter.setByteRangeCheckExpressions(cfg.byteRangeCheckExpressions(binding.getName())); allEmitters.add(emitter); } } diff --git a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java index 7e08977..0032b61 100644 --- a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java @@ -87,10 +87,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter // 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, @@ -133,8 +129,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter prologue = arg.prologue; epilogue = arg.epilogue; returnedArrayLengthExpression = arg.returnedArrayLengthExpression; - rangeCheckExpressions = arg.rangeCheckExpressions; - byteRangeCheckExpressions = arg.byteRangeCheckExpressions; } public final MethodBinding getBinding() { return binding; } @@ -199,14 +193,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter 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)); @@ -369,8 +355,10 @@ public class JavaMethodBindingEmitter extends FunctionEmitter protected void emitPrologueOrEpilogue(List/*<String>*/ code, PrintWriter writer) { if (code != null) { + String[] argumentNames = argumentNameArray(); for (Iterator iter = code.iterator(); iter.hasNext(); ) { - writer.println(" " + (String) iter.next()); + MessageFormat fmt = new MessageFormat((String) iter.next()); + writer.println(" " + fmt.format(argumentNames)); } } } @@ -438,44 +426,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter } } } - - 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) { @@ -700,6 +650,10 @@ public class JavaMethodBindingEmitter extends FunctionEmitter 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; } diff --git a/src/java/com/sun/gluegen/opengl/GLConfiguration.java b/src/java/com/sun/gluegen/opengl/GLConfiguration.java index a44f3fe..e331d16 100755 --- a/src/java/com/sun/gluegen/opengl/GLConfiguration.java +++ b/src/java/com/sun/gluegen/opengl/GLConfiguration.java @@ -125,9 +125,14 @@ public class GLConfiguration extends ProcAddressConfiguration { // Need to generate appropriate prologue based on both buffer // object kind and whether this variant of the MethodBinding // is the one accepting a "long" as argument - if (res == null) { - res = new ArrayList(); + // + // NOTE we MUST NOT mutate the array returned from the super + // call! + ArrayList res2 = new ArrayList(); + if (res != null) { + res2.addAll(res); } + res = res2; String prologue = "check"; @@ -152,6 +157,17 @@ public class GLConfiguration extends ProcAddressConfiguration { prologue = prologue + "();"; res.add(0, prologue); + + // Must also filter out bogus rangeCheck directives for VBO/PBO + // variants + if (emitter.isBufferObjectMethodBinding(binding)) { + for (Iterator iter = res.iterator(); iter.hasNext(); ) { + String line = (String) iter.next(); + if (line.indexOf("BufferFactory.rangeCheck") >= 0) { + iter.remove(); + } + } + } } return res; diff --git a/src/java/com/sun/gluegen/runtime/BufferFactory.java b/src/java/com/sun/gluegen/runtime/BufferFactory.java index ce46d14..4f095f4 100644 --- a/src/java/com/sun/gluegen/runtime/BufferFactory.java +++ b/src/java/com/sun/gluegen/runtime/BufferFactory.java @@ -44,6 +44,7 @@ import java.nio.*; public class BufferFactory { public static final int SIZEOF_BYTE = 1; public static final int SIZEOF_SHORT = 2; + public static final int SIZEOF_CHAR = 2; public static final int SIZEOF_INT = 4; public static final int SIZEOF_FLOAT = 4; public static final int SIZEOF_LONG = 8; @@ -77,7 +78,7 @@ public class BufferFactory { } else if (buf instanceof LongBuffer) { return ((LongBuffer) buf).isDirect(); } - throw new RuntimeException("Unknown buffer type " + buf.getClass().getName()); + throw new RuntimeException("Unexpected buffer type " + buf.getClass().getName()); } @@ -101,6 +102,8 @@ public class BufferFactory { return (buf.position() * SIZEOF_DOUBLE); } else if (buf instanceof LongBuffer) { return (buf.position() * SIZEOF_LONG); + } else if (buf instanceof CharBuffer) { + return (buf.position() * SIZEOF_CHAR); } throw new RuntimeException("Disallowed array backing store type in buffer " @@ -127,6 +130,8 @@ public class BufferFactory { return ((DoubleBuffer) buf).array(); } else if (buf instanceof LongBuffer) { return ((LongBuffer) buf).array(); + } else if (buf instanceof CharBuffer) { + return ((CharBuffer) buf).array(); } throw new RuntimeException("Disallowed array backing store type in buffer " @@ -156,48 +161,78 @@ public class BufferFactory { return (SIZEOF_DOUBLE*(((DoubleBuffer)buf).arrayOffset() + pos)); } else if(buf instanceof LongBuffer) { return (SIZEOF_LONG*(((LongBuffer)buf).arrayOffset() + pos)); + } else if(buf instanceof CharBuffer) { + return (SIZEOF_CHAR*(((CharBuffer)buf).arrayOffset() + pos)); } throw new RuntimeException("Unknown buffer type " + buf.getClass().getName()); } public static void rangeCheck(byte[] array, int offset, int minElementsRemaining) { + if (array == null) { + return; + } + if (array.length < offset + minElementsRemaining) { throw new ArrayIndexOutOfBoundsException("Required " + minElementsRemaining + " elements in array, only had " + (array.length - offset)); } } public static void rangeCheck(char[] array, int offset, int minElementsRemaining) { + if (array == null) { + return; + } + if (array.length < offset + minElementsRemaining) { throw new ArrayIndexOutOfBoundsException("Required " + minElementsRemaining + " elements in array, only had " + (array.length - offset)); } } public static void rangeCheck(short[] array, int offset, int minElementsRemaining) { + if (array == null) { + return; + } + if (array.length < offset + minElementsRemaining) { throw new ArrayIndexOutOfBoundsException("Required " + minElementsRemaining + " elements in array, only had " + (array.length - offset)); } } public static void rangeCheck(int[] array, int offset, int minElementsRemaining) { + if (array == null) { + return; + } + if (array.length < offset + minElementsRemaining) { throw new ArrayIndexOutOfBoundsException("Required " + minElementsRemaining + " elements in array, only had " + (array.length - offset)); } } public static void rangeCheck(long[] array, int offset, int minElementsRemaining) { + if (array == null) { + return; + } + if (array.length < offset + minElementsRemaining) { throw new ArrayIndexOutOfBoundsException("Required " + minElementsRemaining + " elements in array, only had " + (array.length - offset)); } } public static void rangeCheck(float[] array, int offset, int minElementsRemaining) { + if (array == null) { + return; + } + if (array.length < offset + minElementsRemaining) { throw new ArrayIndexOutOfBoundsException("Required " + minElementsRemaining + " elements in array, only had " + (array.length - offset)); } } public static void rangeCheck(double[] array, int offset, int minElementsRemaining) { + if (array == null) { + return; + } + if (array.length < offset + minElementsRemaining) { throw new ArrayIndexOutOfBoundsException("Required " + minElementsRemaining + " elements in array, only had " + (array.length - offset)); } @@ -232,6 +267,8 @@ public class BufferFactory { bytesRemaining = elementsRemaining * SIZEOF_DOUBLE; } else if (buffer instanceof LongBuffer) { bytesRemaining = elementsRemaining * SIZEOF_LONG; + } else if (buffer instanceof CharBuffer) { + bytesRemaining = elementsRemaining * SIZEOF_CHAR; } if (bytesRemaining < minBytesRemaining) { throw new IndexOutOfBoundsException("Required " + minBytesRemaining + " remaining bytes in buffer, only had " + bytesRemaining); |