aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-06-16 01:16:55 +0200
committerSven Gothel <[email protected]>2023-06-16 01:16:55 +0200
commitaeadfab9572e4b441b1bc1f0708cf4c72dfe181e (patch)
tree55255fa60b9753dbc812f6ba6677124b3099f3d3 /src
parent0a9105dd3ebbcf4b98664e50333334bff677031c (diff)
GlueGen Struct [4]: JavaConfiguration Change: Drop 'ManualStaticInitCall', 'ForceStaticInitCode'; Add 'ReturnsStringOnly', 'MaxOneElement' and 'ImmutableAccess'
Drop 'ManualStaticInitCall', 'ForceStaticInitCode': With new CCodeUnit's `JVMUtil_NewDirectByteBufferCopy(..)` implementation and generalized Buffers' methods, no specific init code is required anymore. Add 'ReturnsStringOnly', 'MaxOneElement' and 'ImmutableAccess': - 'ReturnsStringOnly' only String getter, drop ByteBuffer/byte[] - 'MaxOneElement' only one element maximum for pointer reference - 'ImmutableAccess' strict read-only, also reduces generated code a lot
Diffstat (limited to 'src')
-rw-r--r--src/java/com/jogamp/gluegen/JavaConfiguration.java144
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java29
-rw-r--r--src/java/com/jogamp/gluegen/MethodBinding.java23
3 files changed, 93 insertions, 103 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java
index 019ca2d..f392525 100644
--- a/src/java/com/jogamp/gluegen/JavaConfiguration.java
+++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java
@@ -1,6 +1,6 @@
/*
+ * Copyright (c) 2010-2023 JogAmp Community. All rights reserved.
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -138,8 +138,10 @@ public class JavaConfiguration {
private final Map<String, MethodAccess> accessControl = new HashMap<String, MethodAccess>();
private final Map<String, TypeInfo> typeInfoMap = new HashMap<String, TypeInfo>();
private final Set<String> returnsString = new HashSet<String>();
+ private final Set<String> returnsStringOnly = new HashSet<String>();
private final Map<String, JavaType> returnsOpaqueJType = new HashMap<String, JavaType>();
private final Map<String, String> returnedArrayLengths = new HashMap<String, String>();
+ private final Set<String> maxOneElement = new HashSet<String>();
/**
* Key is function that has some byte[] or short[] arguments that should be
@@ -159,10 +161,9 @@ public class JavaConfiguration {
private final Set<String> useNIOOnly = new HashSet<String>();
private boolean forceUseNIODirectOnly4All = false;
private final Set<String> useNIODirectOnly = new HashSet<String>();
+ private final Set<String> immutableAccessSymbols = new HashSet<String>();
private final Set<String> manuallyImplement = new HashSet<String>();
private final Map<String, String> delegatedImplementation = new HashMap<String, String>();
- private final Set<String> manualStaticInitCall = new HashSet<String>();
- private final Set<String> forceStaticInitCode = new HashSet<String>();
private final Map<String, List<String>> customJavaCode = new HashMap<String, List<String>>();
private final Map<String, List<String>> classJavadoc = new HashMap<String, List<String>>();
private final Map<String, List<String>> methodJavadoc = new HashMap<String, List<String>>();
@@ -520,10 +521,17 @@ public class JavaConfiguration {
oneInSet(returnsString, symbol.getAliasedNames());
}
+ /** Indicates whether the given function (which returns a
+ <code>char*</code> in C) should be translated as returning a
+ <code>java.lang.String</code> only. Excluding other variants for struct field access. */
+ public boolean returnsStringOnly(final String functionName) {
+ return returnsStringOnly.contains(functionName);
+ }
+
/**
* Returns a MessageFormat string of the Java expression calculating
* the number of elements in the returned array from the specified function
- * name. The literal <code>1</code> indicates a single object.
+ * name or struct-field array-size. The literal <code>1</code> indicates a constant single object.
* <p>
* If symbol references a struct fields, see {@link #canonicalStructFieldSymbol(String, String)},
* it describes field's array-length or element-count referenced by a pointer.
@@ -535,8 +543,17 @@ public class JavaConfiguration {
* either {@link #returnValueCapacity(String)} or {@link #returnValueLength(String)}!
* </p>
*/
- public String returnedArrayLength(final String functionName) {
- return returnedArrayLengths.get(functionName);
+ public String returnedArrayLength(final String symbol) {
+ return returnedArrayLengths.get(symbol);
+ }
+
+ /**
+ * Indicates whether the given symbol covers no or one single object.
+ * This is useful for struct-field pointer, indicating a null value
+ * holding no object or at most referincing memory for one single object.
+ */
+ public boolean maxOneElement(final String symbol) {
+ return maxOneElement.contains(symbol);
}
/** Returns a list of <code>Integer</code>s which are the indices of <code>const char*</code>
@@ -571,32 +588,6 @@ public class JavaConfiguration {
return forceUseNIODirectOnly4All || useNIODirectOnly.contains(functionName);
}
- /**
- * Returns true if the static initialization java code calling <code>initializeImpl()</code>
- * for the given class will be manually implemented by the end user
- * as requested via configuration directive <code>ManualStaticInitCall 'class-name'</code>.
- */
- public boolean manualStaticInitCall(final String clazzName) {
- return manualStaticInitCall.contains(clazzName);
- }
-
- /**
- * Returns true if the static initialization java code implementing <code>initializeImpl()</code>
- * and the native code implementing:
- * <pre>
- * static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, jlong capacity);
- * </pre>
- * for the given class will be included in the generated code, always,
- * as requested via configuration directive <code>ForceStaticInitCode 'class-name'</code>.
- * <p>
- * If case above code has been generated, static class initialization is generated
- * to call <code>initializeImpl()</code>, see {@link #manualStaticInitCall(String)}.
- * </p>
- */
- public boolean forceStaticInitCode(final String clazzName) {
- return forceStaticInitCode.contains(clazzName);
- }
-
/** Returns a list of Strings containing user-implemented code for
the given Java type name (not fully-qualified, only the class
name); returns either null or an empty list if there is no
@@ -835,6 +826,43 @@ public class JavaConfiguration {
}
/**
+ * Returns true if the glue code for the given aliased symbol
+ * shall produce code for immutable access only.
+ * <p>
+ * This is implemented for whole struct-type symbols or struct-field names,
+ * where no setter methods will be produced if marked immutable.
+ * </p>
+ */
+ public final boolean immutableAccess(final AliasedSymbol symbol) {
+ final String name = symbol.getName();
+ final Set<String> aliases = symbol.getAliasedNames();
+
+ if ( immutableAccessSymbols.contains( name ) ||
+ oneInSet(immutableAccessSymbols, aliases)
+ )
+ {
+ LOG.log(INFO, getASTLocusTag(symbol), "Immutable access: {0}", symbol);
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Returns true if the glue code for the given symbol
+ * shall produce code for immutable access only.
+ * <p>
+ * This is implemented for whole struct-type symbols or struct-field names,
+ * where no setter methods will be produced if marked immutable.
+ * </p>
+ */
+ public final boolean immutableAccess(final String symbol) {
+ if ( immutableAccessSymbols.contains( symbol ) ) {
+ LOG.log(INFO, "Immutable access: {0}", symbol);
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Variant of {@link #manuallyImplement(AliasedSymbol)},
* where this method only considers the {@link AliasedSymbol#getName() current-name}
* of the given symbol, not the {@link #getJavaSymbolRename(String) renamed-symbol}.
@@ -1257,12 +1285,16 @@ public class JavaConfiguration {
readOpaque(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("ReturnsString")) {
readReturnsString(tok, filename, lineNo);
+ } else if (cmd.equalsIgnoreCase("ReturnsStringOnly")) {
+ readReturnsStringOnly(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("ReturnsOpaque")) {
readReturnsOpaque(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("ReturnedArrayLength")) {
readReturnedArrayLength(tok, filename, lineNo);
// Warning: make sure delimiters are reset at the top of this loop
// because ReturnedArrayLength changes them.
+ } else if (cmd.equalsIgnoreCase("MaxOneElement")) {
+ readMaxOneElement(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("ArgumentIsString")) {
readArgumentIsString(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("ExtendedInterfaceSymbolsIgnore")) {
@@ -1287,12 +1319,10 @@ public class JavaConfiguration {
readUnimplemented(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("IgnoreField")) {
readIgnoreField(tok, filename, lineNo);
+ } else if (cmd.equalsIgnoreCase("ImmutableAccess")) {
+ readImmutableAccess(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("ManuallyImplement")) {
readManuallyImplement(tok, filename, lineNo);
- } else if (cmd.equalsIgnoreCase("ManualStaticInitCall")) {
- readManualStaticInitCall(tok, filename, lineNo);
- } else if (cmd.equalsIgnoreCase("ForceStaticInitCode")) {
- readForceStaticInitCode(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("CustomJavaCode")) {
readCustomJavaCode(tok, filename, lineNo);
// Warning: make sure delimiters are reset at the top of this loop
@@ -1476,6 +1506,16 @@ public class JavaConfiguration {
}
}
+ protected void readReturnsStringOnly(final StringTokenizer tok, final String filename, final int lineNo) {
+ try {
+ final String name = tok.nextToken();
+ returnsStringOnly.add(name);
+ } catch (final NoSuchElementException e) {
+ throw new RuntimeException("Error parsing \"ReturnsStringOnly\" command at line " + lineNo +
+ " in file \"" + filename + "\"", e);
+ }
+ }
+
protected void readReturnedArrayLength(final StringTokenizer tok, final String filename, final int lineNo) {
try {
final String functionName = tok.nextToken();
@@ -1488,6 +1528,16 @@ public class JavaConfiguration {
}
}
+ protected void readMaxOneElement(final StringTokenizer tok, final String filename, final int lineNo) {
+ try {
+ final String name = tok.nextToken();
+ maxOneElement.add(name);
+ } catch (final NoSuchElementException e) {
+ throw new RuntimeException("Error parsing \"MaxOneElement\" command at line " + lineNo +
+ " in file \"" + filename + "\"", e);
+ }
+ }
+
protected void readExtendedIntfImplSymbols(final StringTokenizer tok, final String filename, final int lineNo, final boolean forInterface, final boolean forImplementation, final boolean onlyList) {
File javaFile;
BufferedReader javaReader;
@@ -1598,30 +1648,22 @@ public class JavaConfiguration {
}
}
- protected void readManuallyImplement(final StringTokenizer tok, final String filename, final int lineNo) {
+ protected void readImmutableAccess(final StringTokenizer tok, final String filename, final int lineNo) {
try {
final String name = tok.nextToken();
- manuallyImplement.add(name);
+ immutableAccessSymbols.add(name);
} catch (final NoSuchElementException e) {
- throw new RuntimeException("Error parsing \"ManuallyImplement\" command at line " + lineNo +
+ throw new RuntimeException("Error parsing \"ImmutableAccess\" command at line " + lineNo +
" in file \"" + filename + "\"", e);
}
}
- protected void readManualStaticInitCall(final StringTokenizer tok, final String filename, final int lineNo) {
- try {
- final String name = tok.nextToken();
- manualStaticInitCall.add(name);
- } catch (final NoSuchElementException e) {
- throw new RuntimeException("Error parsing \"ManualStaticInitCall\" command at line " + lineNo +
- " in file \"" + filename + "\"", e);
- }
- }
- protected void readForceStaticInitCode(final StringTokenizer tok, final String filename, final int lineNo) {
+
+ protected void readManuallyImplement(final StringTokenizer tok, final String filename, final int lineNo) {
try {
final String name = tok.nextToken();
- forceStaticInitCode.add(name);
+ manuallyImplement.add(name);
} catch (final NoSuchElementException e) {
- throw new RuntimeException("Error parsing \"ForceStaticInitCode\" command at line " + lineNo +
+ throw new RuntimeException("Error parsing \"ManuallyImplement\" command at line " + lineNo +
" in file \"" + filename + "\"", e);
}
}
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index 577bca4..4e8a35f 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -408,22 +408,6 @@ public class JavaEmitter implements GlueEmitter {
}
/**
- * Returns <code>true</code> if implementation (java and native-code)
- * requires {@link #staticClassInitCodeCCode} and {@link #staticClassInitCallJavaCode}
- * and have <code>initializeImpl()</code> being called at static class initialization.
- * <p>
- * This is currently true, if one of the following method returns <code>true</code>
- * <ul>
- * <li>{@link MethodBinding#signatureRequiresStaticInitialization() one of the binding's signature requires it}</li>
- * <li>{@link JavaConfiguration#forceStaticInitCode(String)}</li>
- * </ul>
- * </p>
- */
- protected final boolean requiresStaticInitialization(final String clazzName) {
- return requiresStaticInitialization || cfg.forceStaticInitCode(clazzName);
- }
-
- /**
* Generates the public emitters for this MethodBinding which will
* produce either simply signatures (for the interface class, if
* any) or function definitions with or without a body (depending on
@@ -466,13 +450,6 @@ public class JavaEmitter implements GlueEmitter {
null != prologue ||
null != epilogue;
- if( !requiresStaticInitialization ) {
- requiresStaticInitialization = binding.signatureRequiresStaticInitialization();
- if( requiresStaticInitialization ) {
- LOG.log(INFO, cSymbol.getASTLocusTag(), "StaticInit Trigger.1 \"{0}\"", binding);
- }
- }
-
final boolean emitBody = !signatureOnly && needsBody;
final boolean isNativeMethod = !isUnimplemented && !needsBody && !signatureOnly;
@@ -535,12 +512,6 @@ public class JavaEmitter implements GlueEmitter {
cfg.javaEpilogueForMethod(binding, false, false) != null ;
if ( !cfg.isUnimplemented( cSymbol ) ) {
- if( !requiresStaticInitialization ) {
- requiresStaticInitialization = binding.signatureRequiresStaticInitialization();
- if( requiresStaticInitialization ) {
- LOG.log(INFO, cSymbol.getASTLocusTag(), "StaticInit Trigger.2 \"{0}\"", binding);
- }
- }
// If we already generated a public native entry point for this
// method, don't emit another one
diff --git a/src/java/com/jogamp/gluegen/MethodBinding.java b/src/java/com/jogamp/gluegen/MethodBinding.java
index efa938f..42bae04 100644
--- a/src/java/com/jogamp/gluegen/MethodBinding.java
+++ b/src/java/com/jogamp/gluegen/MethodBinding.java
@@ -69,7 +69,6 @@ public class MethodBinding {
private boolean signatureUsesCPrimitivePointers;
private boolean signatureUsesCArrays;
private boolean signatureUsesJavaPrimitiveArrays;
- private boolean signatureRequiresStaticInitialization;
private int thisPointerIndex = -1;
/**
@@ -96,7 +95,6 @@ public class MethodBinding {
this.signatureUsesCPrimitivePointers = bindingToCopy.signatureUsesCPrimitivePointers;
this.signatureUsesCArrays = bindingToCopy.signatureUsesCArrays;
this.signatureUsesJavaPrimitiveArrays = bindingToCopy.signatureUsesJavaPrimitiveArrays;
- this.signatureRequiresStaticInitialization = bindingToCopy.signatureRequiresStaticInitialization;
this.thisPointerIndex = bindingToCopy.thisPointerIndex;
}
@@ -284,21 +282,6 @@ public class MethodBinding {
}
/**
- * Returns true if the wrapper implementation requires
- * static native code to be initialized, see {@link JavaConfiguration#forceStaticInitCode(String)}.
- * <p>
- * Currently triggered by:
- * <ul>
- * <li>Return type is a "compound type" and not a pointer</li>
- * </ul>
- * </p>
- */
- public boolean signatureRequiresStaticInitialization() {
- computeSignatureProperties();
- return signatureRequiresStaticInitialization;
- }
-
- /**
* Returns true if the return type or any of the outgoing arguments
* in the method's signature use arrays of "compound type wrappers",
* or NIO-based wrappers for C data structures.
@@ -371,17 +354,11 @@ public class MethodBinding {
signatureUsesCPrimitivePointers = false;
signatureUsesCArrays = false;
signatureUsesJavaPrimitiveArrays = false;
- signatureRequiresStaticInitialization = false;
if ( javaReturnType.isCompoundTypeWrapper() ) {
// Needs wrapping and/or setting of byte order (neither of which
// can be done easily from native code)
signatureUsesCompoundTypeWrappers = true;
-
- final Type cReturnType = getCReturnType();
- if ( !cReturnType.isPointer() ) { // FIXME: Compound call-by-value
- signatureRequiresStaticInitialization = true;
- }
}
if (javaReturnType.isNIOBuffer() ||