Improve glgen
+ gen script is really a bash script rather than a sh script, so declare that to be true. (For example, it uses pushd, which is a part of bash, but not a part of sh. Not sure how this worked until now. Possibly gen was only run in environments where /bin/sh was really bash. + Check the results of the java compile of the code generator, and abort the script if the compile fails. + Turn on the bash shell option that guards against using uninitialized variables in the script. + Remove the generated class files. Refactor JniCodeEmitter into two classes: a general-purpose JniCodeEmitter and a specific Jsr239CodeEmitter. The hope is to use JniCodeEmitter as a base for emitting static OpenGL ES bindings.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
set -u
|
||||
rm -rf out generated
|
||||
|
||||
mkdir out
|
||||
@@ -12,12 +13,18 @@ echo "public interface Canvas {}" >> out/android/graphics/Canvas.java
|
||||
GLFILE=out/javax/microedition/khronos/opengles/GL.java
|
||||
cp stubs/GLHeader.java-if $GLFILE
|
||||
|
||||
GLGEN_FILES="CFunc.java CType.java CodeEmitter.java GenerateGL.java JFunc.java JType.java JniCodeEmitter.java ParameterChecker.java"
|
||||
GLGEN_FILES="CFunc.java CType.java CodeEmitter.java GenerateGL.java JFunc.java JniCodeEmitter.java JType.java Jsr239CodeEmitter.java ParameterChecker.java"
|
||||
|
||||
pushd src > /dev/null
|
||||
javac ${GLGEN_FILES}
|
||||
JAVAC_RESULT=$?
|
||||
if [ $JAVAC_RESULT -ne 0 ]; then
|
||||
echo "Could not compile glgen."
|
||||
exit $JAVAC_RESULT
|
||||
fi
|
||||
popd > /dev/null
|
||||
java -classpath src GenerateGL -c glspec-1.0 glspec-1.0ext glspec-1.1 glspec-1.1ext glspec-1.1extpack glspec-checks
|
||||
rm src/*.class
|
||||
|
||||
pushd out > /dev/null
|
||||
mkdir classes
|
||||
|
||||
@@ -23,7 +23,6 @@ public class GenerateGL {
|
||||
PrintStream glImplStream,
|
||||
PrintStream cStream) throws Exception {
|
||||
String s = null;
|
||||
int counter = 0;
|
||||
while ((s = specReader.readLine()) != null) {
|
||||
if (s.trim().startsWith("//")) {
|
||||
continue;
|
||||
@@ -120,7 +119,7 @@ public class GenerateGL {
|
||||
ParameterChecker checker = new ParameterChecker(checksReader);
|
||||
|
||||
CodeEmitter emitter =
|
||||
new JniCodeEmitter(classPathName,
|
||||
new Jsr239CodeEmitter(classPathName,
|
||||
checker,
|
||||
gl10Stream, gl10ExtStream,
|
||||
gl11Stream, gl11ExtStream, gl11ExtPackStream,
|
||||
|
||||
@@ -4,90 +4,47 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Emits a Java interface and Java & C implementation for a C function.
|
||||
*
|
||||
* <p> The Java interface will have Buffer and array variants for functions that
|
||||
* have a typed pointer argument. The array variant will convert a single "<type> *data"
|
||||
* argument to a pair of arguments "<type>[] data, int offset".
|
||||
*/
|
||||
public class JniCodeEmitter implements CodeEmitter {
|
||||
public class JniCodeEmitter {
|
||||
|
||||
// If true, use C++ style for calling through a JNIEnv *:
|
||||
// env->Func(...)
|
||||
// If false, use C style:
|
||||
// (*env)->Func(env, ...)
|
||||
static final boolean mUseCPlusPlus = true;
|
||||
|
||||
boolean mUseContextPointer = true;
|
||||
|
||||
String mClassPathName;
|
||||
|
||||
ParameterChecker mChecker;
|
||||
PrintStream mJava10InterfaceStream;
|
||||
PrintStream mJava10ExtInterfaceStream;
|
||||
PrintStream mJava11InterfaceStream;
|
||||
PrintStream mJava11ExtInterfaceStream;
|
||||
PrintStream mJava11ExtPackInterfaceStream;
|
||||
PrintStream mJavaImplStream;
|
||||
PrintStream mCStream;
|
||||
|
||||
PrintStream mJavaInterfaceStream;
|
||||
|
||||
List<String> nativeRegistrations = new ArrayList<String>();
|
||||
|
||||
protected boolean mUseContextPointer = true;
|
||||
protected String mClassPathName;
|
||||
protected ParameterChecker mChecker;
|
||||
protected List<String> nativeRegistrations = new ArrayList<String>();
|
||||
boolean needsExit;
|
||||
|
||||
static String indent = " ";
|
||||
|
||||
protected static String indent = " ";
|
||||
HashSet<String> mFunctionsEmitted = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* @param java10InterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 functions
|
||||
* @param java10ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 extension functions
|
||||
* @param java11InterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 functions
|
||||
* @param java11ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension functions
|
||||
* @param java11ExtPackInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension Pack functions
|
||||
* @param javaImplStream the PrintStream to which to emit the Java implementation
|
||||
* @param cStream the PrintStream to which to emit the C implementation
|
||||
*/
|
||||
public JniCodeEmitter(String classPathName,
|
||||
ParameterChecker checker,
|
||||
PrintStream java10InterfaceStream,
|
||||
PrintStream java10ExtInterfaceStream,
|
||||
PrintStream java11InterfaceStream,
|
||||
PrintStream java11ExtInterfaceStream,
|
||||
PrintStream java11ExtPackInterfaceStream,
|
||||
PrintStream javaImplStream,
|
||||
PrintStream cStream,
|
||||
boolean useContextPointer) {
|
||||
mClassPathName = classPathName;
|
||||
mChecker = checker;
|
||||
mJava10InterfaceStream = java10InterfaceStream;
|
||||
mJava10ExtInterfaceStream = java10ExtInterfaceStream;
|
||||
mJava11InterfaceStream = java11InterfaceStream;
|
||||
mJava11ExtInterfaceStream = java11ExtInterfaceStream;
|
||||
mJava11ExtPackInterfaceStream = java11ExtPackInterfaceStream;
|
||||
mJavaImplStream = javaImplStream;
|
||||
mCStream = cStream;
|
||||
mUseContextPointer = useContextPointer;
|
||||
}
|
||||
|
||||
public void setVersion(int version, boolean ext, boolean pack) {
|
||||
if (version == 0) {
|
||||
mJavaInterfaceStream = ext ? mJava10ExtInterfaceStream :
|
||||
mJava10InterfaceStream;
|
||||
} else if (version == 1) {
|
||||
mJavaInterfaceStream = ext ?
|
||||
(pack ? mJava11ExtPackInterfaceStream :
|
||||
mJava11ExtInterfaceStream) :
|
||||
mJava11InterfaceStream;
|
||||
} else {
|
||||
throw new RuntimeException("Bad version: " + version);
|
||||
public static String getJniName(JType jType) {
|
||||
String jniName = "";
|
||||
if (jType.isClass()) {
|
||||
return "L" + jType.getBaseType() + ";";
|
||||
} else if (jType.isArray()) {
|
||||
jniName = "[";
|
||||
}
|
||||
|
||||
String baseType = jType.getBaseType();
|
||||
if (baseType.equals("int")) {
|
||||
jniName += "I";
|
||||
} else if (baseType.equals("float")) {
|
||||
jniName += "F";
|
||||
} else if (baseType.equals("boolean")) {
|
||||
jniName += "Z";
|
||||
} else if (baseType.equals("short")) {
|
||||
jniName += "S";
|
||||
} else if (baseType.equals("long")) {
|
||||
jniName += "L";
|
||||
} else if (baseType.equals("byte")) {
|
||||
jniName += "B";
|
||||
}
|
||||
return jniName;
|
||||
}
|
||||
|
||||
public void emitCode(CFunc cfunc, String original) {
|
||||
|
||||
public void emitCode(CFunc cfunc, String original,
|
||||
PrintStream javaInterfaceStream,
|
||||
PrintStream javaImplStream,
|
||||
PrintStream cStream) {
|
||||
JFunc jfunc;
|
||||
String signature;
|
||||
boolean duplicate;
|
||||
@@ -107,12 +64,12 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
}
|
||||
|
||||
if (!duplicate) {
|
||||
emitNativeDeclaration(jfunc, mJavaImplStream);
|
||||
emitJavaCode(jfunc, mJavaImplStream);
|
||||
emitNativeDeclaration(jfunc, javaImplStream);
|
||||
emitJavaCode(jfunc, javaImplStream);
|
||||
}
|
||||
emitJavaInterfaceCode(jfunc, mJavaInterfaceStream);
|
||||
emitJavaInterfaceCode(jfunc, javaInterfaceStream);
|
||||
if (!duplicate) {
|
||||
emitJniCode(jfunc, mCStream);
|
||||
emitJniCode(jfunc, cStream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,12 +84,12 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
}
|
||||
|
||||
if (!duplicate) {
|
||||
emitNativeDeclaration(jfunc, mJavaImplStream);
|
||||
emitNativeDeclaration(jfunc, javaImplStream);
|
||||
}
|
||||
emitJavaInterfaceCode(jfunc, mJavaInterfaceStream);
|
||||
emitJavaInterfaceCode(jfunc, javaInterfaceStream);
|
||||
if (!duplicate) {
|
||||
emitJavaCode(jfunc, mJavaImplStream);
|
||||
emitJniCode(jfunc, mCStream);
|
||||
emitJavaCode(jfunc, javaImplStream);
|
||||
emitJniCode(jfunc, cStream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +108,7 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
emitFunction(jfunc, out, false, false);
|
||||
}
|
||||
|
||||
void emitFunctionCall(JFunc jfunc, PrintStream out, String iii, boolean grabArray ) {
|
||||
void emitFunctionCall(JFunc jfunc, PrintStream out, String iii, boolean grabArray) {
|
||||
boolean isVoid = jfunc.getType().isVoid();
|
||||
boolean isPointerFunc = jfunc.getName().endsWith("Pointer") &&
|
||||
jfunc.getCFunc().hasPointerArg();
|
||||
@@ -194,37 +151,36 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
out.println(iii + ");");
|
||||
}
|
||||
|
||||
void printIfcheckPostamble(PrintStream out, boolean isBuffer,
|
||||
boolean emitExceptionCheck, String iii) {
|
||||
printIfcheckPostamble(out, isBuffer, emitExceptionCheck,
|
||||
"offset", "_remaining", iii);
|
||||
}
|
||||
void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck,
|
||||
String iii) {
|
||||
printIfcheckPostamble(out, isBuffer, emitExceptionCheck,
|
||||
"offset", "_remaining", iii);
|
||||
}
|
||||
|
||||
void printIfcheckPostamble(PrintStream out, boolean isBuffer,
|
||||
boolean emitExceptionCheck,
|
||||
String offset, String remaining, String iii) {
|
||||
out.println(iii + " default:");
|
||||
out.println(iii + " _needed = 0;");
|
||||
out.println(iii + " break;");
|
||||
out.println(iii + "}");
|
||||
void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck,
|
||||
String offset, String remaining, String iii) {
|
||||
out.println(iii + " default:");
|
||||
out.println(iii + " _needed = 0;");
|
||||
out.println(iii + " break;");
|
||||
out.println(iii + "}");
|
||||
|
||||
out.println(iii + "if (" + remaining + " < _needed) {");
|
||||
if (emitExceptionCheck) {
|
||||
out.println(iii + indent + "_exception = 1;");
|
||||
}
|
||||
out.println(iii + indent +
|
||||
(mUseCPlusPlus ? "_env" : "(*_env)") +
|
||||
"->ThrowNew(" +
|
||||
(mUseCPlusPlus ? "" : "_env, ") +
|
||||
"IAEClass, " +
|
||||
"\"" +
|
||||
(isBuffer ?
|
||||
"remaining()" : "length - " + offset) +
|
||||
" < needed\");");
|
||||
out.println(iii + indent + "goto exit;");
|
||||
needsExit = true;
|
||||
out.println(iii + "}");
|
||||
}
|
||||
out.println(iii + "if (" + remaining + " < _needed) {");
|
||||
if (emitExceptionCheck) {
|
||||
out.println(iii + indent + "_exception = 1;");
|
||||
}
|
||||
out.println(iii + indent +
|
||||
(mUseCPlusPlus ? "_env" : "(*_env)") +
|
||||
"->ThrowNew(" +
|
||||
(mUseCPlusPlus ? "" : "_env, ") +
|
||||
"IAEClass, " +
|
||||
"\"" +
|
||||
(isBuffer ?
|
||||
"remaining()" : "length - " + offset) +
|
||||
" < needed\");");
|
||||
out.println(iii + indent + "goto exit;");
|
||||
needsExit = true;
|
||||
out.println(iii + "}");
|
||||
}
|
||||
|
||||
boolean isNullAllowed(CFunc cfunc) {
|
||||
String[] checks = mChecker.getChecks(cfunc.getName());
|
||||
@@ -310,115 +266,106 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
}
|
||||
|
||||
void emitNativeBoundsChecks(CFunc cfunc, String cname, PrintStream out,
|
||||
boolean isBuffer, boolean emitExceptionCheck,
|
||||
String offset, String remaining, String iii) {
|
||||
CType returnType = cfunc.getType();
|
||||
boolean isVoid = returnType.isVoid();
|
||||
boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) {
|
||||
|
||||
String[] checks = mChecker.getChecks(cfunc.getName());
|
||||
String checkVar;
|
||||
String retval = getErrorReturnValue(cfunc);
|
||||
String[] checks = mChecker.getChecks(cfunc.getName());
|
||||
|
||||
boolean lastWasIfcheck = false;
|
||||
boolean lastWasIfcheck = false;
|
||||
|
||||
int index = 1;
|
||||
if (checks != null) {
|
||||
boolean remainingDeclared = false;
|
||||
boolean nullCheckDeclared = false;
|
||||
boolean offsetChecked = false;
|
||||
while (index < checks.length) {
|
||||
if (checks[index].startsWith("check")) {
|
||||
if (lastWasIfcheck) {
|
||||
printIfcheckPostamble(out, isBuffer, emitExceptionCheck,
|
||||
offset, remaining, iii);
|
||||
int index = 1;
|
||||
if (checks != null) {
|
||||
while (index < checks.length) {
|
||||
if (checks[index].startsWith("check")) {
|
||||
if (lastWasIfcheck) {
|
||||
printIfcheckPostamble(out, isBuffer, emitExceptionCheck,
|
||||
offset, remaining, iii);
|
||||
}
|
||||
lastWasIfcheck = false;
|
||||
if (cname != null && !cname.equals(checks[index + 1])) {
|
||||
index += 3;
|
||||
continue;
|
||||
}
|
||||
out.println(iii + "if (" + remaining + " < " +
|
||||
checks[index + 2] +
|
||||
") {");
|
||||
if (emitExceptionCheck) {
|
||||
out.println(iii + indent + "_exception = 1;");
|
||||
}
|
||||
String exceptionClassName = "IAEClass";
|
||||
// If the "check" keyword was of the form
|
||||
// "check_<class name>", use the class name in the
|
||||
// exception to be thrown
|
||||
int underscore = checks[index].indexOf('_');
|
||||
if (underscore >= 0) {
|
||||
exceptionClassName = checks[index].substring(underscore + 1) + "Class";
|
||||
}
|
||||
lastWasIfcheck = false;
|
||||
if (cname != null && !cname.equals(checks[index + 1])) {
|
||||
index += 3;
|
||||
continue;
|
||||
out.println(iii + indent +
|
||||
(mUseCPlusPlus ? "_env" : "(*_env)") +
|
||||
"->ThrowNew(" +
|
||||
(mUseCPlusPlus ? "" : "_env, ") +
|
||||
exceptionClassName + ", " +
|
||||
"\"" +
|
||||
(isBuffer ?
|
||||
"remaining()" : "length - " + offset) +
|
||||
" < " + checks[index + 2] +
|
||||
"\");");
|
||||
|
||||
out.println(iii + indent + "goto exit;");
|
||||
needsExit = true;
|
||||
out.println(iii + "}");
|
||||
|
||||
index += 3;
|
||||
} else if (checks[index].equals("ifcheck")) {
|
||||
String[] matches = checks[index + 4].split(",");
|
||||
|
||||
if (!lastWasIfcheck) {
|
||||
out.println(iii + "int _needed;");
|
||||
out.println(iii +
|
||||
"switch (" +
|
||||
checks[index + 3] +
|
||||
") {");
|
||||
}
|
||||
|
||||
for (int i = 0; i < matches.length; i++) {
|
||||
out.println("#if defined(" + matches[i] + ")");
|
||||
out.println(iii +
|
||||
" case " +
|
||||
matches[i] +
|
||||
":");
|
||||
out.println("#endif // defined(" + matches[i] + ")");
|
||||
}
|
||||
out.println(iii +
|
||||
" _needed = " +
|
||||
checks[index + 2] +
|
||||
";");
|
||||
out.println(iii +
|
||||
" break;");
|
||||
|
||||
lastWasIfcheck = true;
|
||||
index += 5;
|
||||
} else if (checks[index].equals("return")) {
|
||||
// ignore
|
||||
index += 2;
|
||||
} else if (checks[index].equals("unsupported")) {
|
||||
// ignore
|
||||
index += 1;
|
||||
} else if (checks[index].equals("nullAllowed")) {
|
||||
// ignore
|
||||
index += 1;
|
||||
} else {
|
||||
System.out.println("Error: unknown keyword \"" +
|
||||
checks[index] + "\"");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
out.println(iii + "if (" + remaining + " < " +
|
||||
checks[index + 2] +
|
||||
") {");
|
||||
if (emitExceptionCheck) {
|
||||
out.println(iii + indent + "_exception = 1;");
|
||||
}
|
||||
String exceptionClassName = "IAEClass";
|
||||
// If the "check" keyword was of the form
|
||||
// "check_<class name>", use the class name in the
|
||||
// exception to be thrown
|
||||
int underscore = checks[index].indexOf('_');
|
||||
if (underscore >= 0) {
|
||||
exceptionClassName = checks[index].substring(underscore + 1) + "Class";
|
||||
}
|
||||
out.println(iii + indent +
|
||||
(mUseCPlusPlus ? "_env" : "(*_env)") +
|
||||
"->ThrowNew(" +
|
||||
(mUseCPlusPlus ? "" : "_env, ") +
|
||||
exceptionClassName + ", " +
|
||||
"\"" +
|
||||
(isBuffer ?
|
||||
"remaining()" : "length - " + offset) +
|
||||
" < " + checks[index + 2] +
|
||||
"\");");
|
||||
}
|
||||
|
||||
out.println(iii + indent + "goto exit;");
|
||||
needsExit = true;
|
||||
out.println(iii + "}");
|
||||
|
||||
index += 3;
|
||||
} else if (checks[index].equals("ifcheck")) {
|
||||
String[] matches = checks[index + 4].split(",");
|
||||
|
||||
if (!lastWasIfcheck) {
|
||||
out.println(iii + "int _needed;");
|
||||
out.println(iii +
|
||||
"switch (" +
|
||||
checks[index + 3] +
|
||||
") {");
|
||||
}
|
||||
|
||||
for (int i = 0; i < matches.length; i++) {
|
||||
out.println("#if defined(" + matches[i] + ")");
|
||||
out.println(iii +
|
||||
" case " +
|
||||
matches[i] +
|
||||
":");
|
||||
out.println("#endif // defined(" + matches[i] + ")");
|
||||
}
|
||||
out.println(iii +
|
||||
" _needed = " +
|
||||
checks[index + 2] +
|
||||
";");
|
||||
out.println(iii +
|
||||
" break;");
|
||||
|
||||
lastWasIfcheck = true;
|
||||
index += 5;
|
||||
} else if (checks[index].equals("return")) {
|
||||
// ignore
|
||||
index += 2;
|
||||
} else if (checks[index].equals("unsupported")) {
|
||||
// ignore
|
||||
index += 1;
|
||||
} else if (checks[index].equals("nullAllowed")) {
|
||||
// ignore
|
||||
index += 1;
|
||||
} else {
|
||||
System.out.println("Error: unknown keyword \"" +
|
||||
checks[index] + "\"");
|
||||
System.exit(0);
|
||||
if (lastWasIfcheck) {
|
||||
printIfcheckPostamble(out, isBuffer, emitExceptionCheck, iii);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastWasIfcheck) {
|
||||
printIfcheckPostamble(out, isBuffer, emitExceptionCheck, iii);
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasNonConstArg(JFunc jfunc, CFunc cfunc,
|
||||
List<Integer> nonPrimitiveArgs) {
|
||||
boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, List<Integer> nonPrimitiveArgs) {
|
||||
if (nonPrimitiveArgs.size() > 0) {
|
||||
for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
|
||||
int idx = nonPrimitiveArgs.get(i).intValue();
|
||||
@@ -447,9 +394,7 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
* if interfaceDecl: public <returntype> func(args);
|
||||
* if !interfaceDecl: public <returntype> func(args) { body }
|
||||
*/
|
||||
void emitFunction(JFunc jfunc,
|
||||
PrintStream out,
|
||||
boolean nativeDecl, boolean interfaceDecl) {
|
||||
void emitFunction(JFunc jfunc, PrintStream out, boolean nativeDecl, boolean interfaceDecl) {
|
||||
boolean isPointerFunc =
|
||||
jfunc.getName().endsWith("Pointer") &&
|
||||
jfunc.getCFunc().hasPointerArg();
|
||||
@@ -559,29 +504,43 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
out.println();
|
||||
}
|
||||
|
||||
public static String getJniName(JType jType) {
|
||||
String jniName = "";
|
||||
if (jType.isClass()) {
|
||||
return "L" + jType.getBaseType() + ";";
|
||||
} else if (jType.isArray()) {
|
||||
jniName = "[";
|
||||
public void addNativeRegistration(String s) {
|
||||
nativeRegistrations.add(s);
|
||||
}
|
||||
|
||||
public void emitNativeRegistration(PrintStream cStream) {
|
||||
cStream.println("static const char *classPathName = \"" +
|
||||
mClassPathName +
|
||||
"\";");
|
||||
cStream.println();
|
||||
|
||||
cStream.println("static JNINativeMethod methods[] = {");
|
||||
|
||||
cStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },");
|
||||
|
||||
Iterator<String> i = nativeRegistrations.iterator();
|
||||
while (i.hasNext()) {
|
||||
cStream.println(i.next());
|
||||
}
|
||||
|
||||
String baseType = jType.getBaseType();
|
||||
if (baseType.equals("int")) {
|
||||
jniName += "I";
|
||||
} else if (baseType.equals("float")) {
|
||||
jniName += "F";
|
||||
} else if (baseType.equals("boolean")) {
|
||||
jniName += "Z";
|
||||
} else if (baseType.equals("short")) {
|
||||
jniName += "S";
|
||||
} else if (baseType.equals("long")) {
|
||||
jniName += "L";
|
||||
} else if (baseType.equals("byte")) {
|
||||
jniName += "B";
|
||||
}
|
||||
return jniName;
|
||||
cStream.println("};");
|
||||
cStream.println();
|
||||
|
||||
|
||||
cStream.println("int register_com_google_android_gles_jni_GLImpl(JNIEnv *_env)");
|
||||
cStream.println("{");
|
||||
cStream.println(indent +
|
||||
"int err;");
|
||||
|
||||
cStream.println(indent +
|
||||
"err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));");
|
||||
|
||||
cStream.println(indent + "return err;");
|
||||
cStream.println("}");
|
||||
}
|
||||
|
||||
public JniCodeEmitter() {
|
||||
super();
|
||||
}
|
||||
|
||||
String getJniType(JType jType) {
|
||||
@@ -721,8 +680,6 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
int numBuffers = 0;
|
||||
for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
|
||||
int idx = nonPrimitiveArgs.get(i).intValue();
|
||||
int cIndex = jfunc.getArgCIndex(idx);
|
||||
String cname = cfunc.getArgName(cIndex);
|
||||
if (jfunc.getArgType(idx).isArray()) {
|
||||
++numArrays;
|
||||
}
|
||||
@@ -832,8 +789,6 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
out.println();
|
||||
}
|
||||
|
||||
String retval = isVoid ? "" : " _returnValue";
|
||||
|
||||
// Emit 'GetPrimitiveArrayCritical' for arrays
|
||||
// Emit 'GetPointer' calls for Buffer pointers
|
||||
int bufArgIdx = 0;
|
||||
@@ -1047,38 +1002,4 @@ public class JniCodeEmitter implements CodeEmitter {
|
||||
out.println();
|
||||
}
|
||||
|
||||
public void addNativeRegistration(String s) {
|
||||
nativeRegistrations.add(s);
|
||||
}
|
||||
|
||||
public void emitNativeRegistration() {
|
||||
mCStream.println("static const char *classPathName = \"" +
|
||||
mClassPathName +
|
||||
"\";");
|
||||
mCStream.println();
|
||||
|
||||
mCStream.println("static JNINativeMethod methods[] = {");
|
||||
|
||||
mCStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },");
|
||||
|
||||
Iterator<String> i = nativeRegistrations.iterator();
|
||||
while (i.hasNext()) {
|
||||
mCStream.println(i.next());
|
||||
}
|
||||
|
||||
mCStream.println("};");
|
||||
mCStream.println();
|
||||
|
||||
|
||||
mCStream.println("int register_com_google_android_gles_jni_GLImpl(JNIEnv *_env)");
|
||||
mCStream.println("{");
|
||||
mCStream.println(indent +
|
||||
"int err;");
|
||||
|
||||
mCStream.println(indent +
|
||||
"err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));");
|
||||
|
||||
mCStream.println(indent + "return err;");
|
||||
mCStream.println("}");
|
||||
}
|
||||
}
|
||||
|
||||
74
opengl/tools/glgen/src/Jsr239CodeEmitter.java
Normal file
74
opengl/tools/glgen/src/Jsr239CodeEmitter.java
Normal file
@@ -0,0 +1,74 @@
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* Emits a Java interface and Java & C implementation for a C function.
|
||||
*
|
||||
* <p> The Java interface will have Buffer and array variants for functions that
|
||||
* have a typed pointer argument. The array variant will convert a single "<type> *data"
|
||||
* argument to a pair of arguments "<type>[] data, int offset".
|
||||
*/
|
||||
public class Jsr239CodeEmitter extends JniCodeEmitter implements CodeEmitter {
|
||||
|
||||
PrintStream mJava10InterfaceStream;
|
||||
PrintStream mJava10ExtInterfaceStream;
|
||||
PrintStream mJava11InterfaceStream;
|
||||
PrintStream mJava11ExtInterfaceStream;
|
||||
PrintStream mJava11ExtPackInterfaceStream;
|
||||
PrintStream mJavaImplStream;
|
||||
PrintStream mCStream;
|
||||
|
||||
PrintStream mJavaInterfaceStream;
|
||||
|
||||
/**
|
||||
* @param java10InterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 functions
|
||||
* @param java10ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.0 extension functions
|
||||
* @param java11InterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 functions
|
||||
* @param java11ExtInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension functions
|
||||
* @param java11ExtPackInterfaceStream the PrintStream to which to emit the Java interface for GL 1.1 Extension Pack functions
|
||||
* @param javaImplStream the PrintStream to which to emit the Java implementation
|
||||
* @param cStream the PrintStream to which to emit the C implementation
|
||||
*/
|
||||
public Jsr239CodeEmitter(String classPathName,
|
||||
ParameterChecker checker,
|
||||
PrintStream java10InterfaceStream,
|
||||
PrintStream java10ExtInterfaceStream,
|
||||
PrintStream java11InterfaceStream,
|
||||
PrintStream java11ExtInterfaceStream,
|
||||
PrintStream java11ExtPackInterfaceStream,
|
||||
PrintStream javaImplStream,
|
||||
PrintStream cStream,
|
||||
boolean useContextPointer) {
|
||||
mClassPathName = classPathName;
|
||||
mChecker = checker;
|
||||
mJava10InterfaceStream = java10InterfaceStream;
|
||||
mJava10ExtInterfaceStream = java10ExtInterfaceStream;
|
||||
mJava11InterfaceStream = java11InterfaceStream;
|
||||
mJava11ExtInterfaceStream = java11ExtInterfaceStream;
|
||||
mJava11ExtPackInterfaceStream = java11ExtPackInterfaceStream;
|
||||
mJavaImplStream = javaImplStream;
|
||||
mCStream = cStream;
|
||||
mUseContextPointer = useContextPointer;
|
||||
}
|
||||
|
||||
public void setVersion(int version, boolean ext, boolean pack) {
|
||||
if (version == 0) {
|
||||
mJavaInterfaceStream = ext ? mJava10ExtInterfaceStream :
|
||||
mJava10InterfaceStream;
|
||||
} else if (version == 1) {
|
||||
mJavaInterfaceStream = ext ?
|
||||
(pack ? mJava11ExtPackInterfaceStream :
|
||||
mJava11ExtInterfaceStream) :
|
||||
mJava11InterfaceStream;
|
||||
} else {
|
||||
throw new RuntimeException("Bad version: " + version);
|
||||
}
|
||||
}
|
||||
|
||||
public void emitCode(CFunc cfunc, String original) {
|
||||
emitCode(cfunc, original, mJavaInterfaceStream, mJavaImplStream, mCStream);
|
||||
}
|
||||
|
||||
public void emitNativeRegistration() {
|
||||
emitNativeRegistration(mCStream);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user