115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root/* 215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2006 The Android Open Source Project 315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * 415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * you may not use this file except in compliance with the License. 615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * You may obtain a copy of the License at 715a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * 815a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * http://www.apache.org/licenses/LICENSE-2.0 915a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * 1015a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Unless required by applicable law or agreed to in writing, software 1115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 1215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * See the License for the specific language governing permissions and 1415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * limitations under the License. 1515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root */ 1615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintStream; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashSet; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 234e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevichpublic class JniCodeEmitter { 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 254e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich static final boolean mUseCPlusPlus = true; 264e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich protected boolean mUseContextPointer = true; 2727f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich protected boolean mUseStaticMethods = false; 284e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich protected String mClassPathName; 294e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich protected ParameterChecker mChecker; 304e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich protected List<String> nativeRegistrations = new ArrayList<String>(); 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean needsExit; 324e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich protected static String indent = " "; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashSet<String> mFunctionsEmitted = new HashSet<String>(); 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 354e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich public static String getJniName(JType jType) { 364e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich String jniName = ""; 374e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich if (jType.isClass()) { 384e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich return "L" + jType.getBaseType() + ";"; 394e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } else if (jType.isArray()) { 404e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich jniName = "["; 414e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 434e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich String baseType = jType.getBaseType(); 444e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich if (baseType.equals("int")) { 454e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich jniName += "I"; 464e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } else if (baseType.equals("float")) { 474e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich jniName += "F"; 484e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } else if (baseType.equals("boolean")) { 494e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich jniName += "Z"; 504e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } else if (baseType.equals("short")) { 514e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich jniName += "S"; 524e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } else if (baseType.equals("long")) { 534e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich jniName += "L"; 544e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } else if (baseType.equals("byte")) { 554e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich jniName += "B"; 56560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } else if (baseType.equals("String")) { 57560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich jniName += "Ljava/lang/String;"; 58560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } else if (baseType.equals("void")) { 59560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich // nothing. 60560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } else { 6124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes throw new RuntimeException("Unknown primitive basetype " + baseType); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 634e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich return jniName; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 664e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 674e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich public void emitCode(CFunc cfunc, String original, 684e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich PrintStream javaInterfaceStream, 694e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich PrintStream javaImplStream, 704e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich PrintStream cStream) { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JFunc jfunc; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String signature; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean duplicate; 743cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cfunc.hasTypedPointerArg()) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc = JFunc.convert(cfunc, true); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't emit duplicate functions 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // These may appear because they are defined in multiple 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Java interfaces (e.g., GL11/GL11ExtensionPack) 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project signature = jfunc.toString(); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project duplicate = false; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFunctionsEmitted.contains(signature)) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project duplicate = true; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFunctionsEmitted.add(signature); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!duplicate) { 904e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich emitNativeDeclaration(jfunc, javaImplStream); 914e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich emitJavaCode(jfunc, javaImplStream); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9327f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich if (javaInterfaceStream != null) { 9427f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich emitJavaInterfaceCode(jfunc, javaInterfaceStream); 9527f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!duplicate) { 974e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich emitJniCode(jfunc, cStream); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc = JFunc.convert(cfunc, false); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project signature = jfunc.toString(); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project duplicate = false; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFunctionsEmitted.contains(signature)) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project duplicate = true; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFunctionsEmitted.add(signature); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!duplicate) { 1124e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich emitNativeDeclaration(jfunc, javaImplStream); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11427f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich if (javaInterfaceStream != null) { 11527f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich emitJavaInterfaceCode(jfunc, javaInterfaceStream); 11627f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich } 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!duplicate) { 1184e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich emitJavaCode(jfunc, javaImplStream); 1194e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich emitJniCode(jfunc, cStream); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void emitNativeDeclaration(JFunc jfunc, PrintStream out) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(" // C function " + jfunc.getCFunc().getOriginal()); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project emitFunction(jfunc, out, true, false); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void emitJavaInterfaceCode(JFunc jfunc, PrintStream out) { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project emitFunction(jfunc, out, false, true); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void emitJavaCode(JFunc jfunc, PrintStream out) { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project emitFunction(jfunc, out, false, false); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1373cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 138be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich boolean isPointerFunc(JFunc jfunc) { 139be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich String name = jfunc.getName(); 140be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich return (name.endsWith("Pointer") || name.endsWith("PointerOES")) 141be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich && jfunc.getCFunc().hasPointerArg(); 142be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich } 143be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich 1444e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich void emitFunctionCall(JFunc jfunc, PrintStream out, String iii, boolean grabArray) { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isVoid = jfunc.getType().isVoid(); 146be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich boolean isPointerFunc = isPointerFunc(jfunc); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isVoid) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getType() + " _returnValue;"); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (isVoid ? "" : "_returnValue = ") + 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getName() + 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (isPointerFunc ? "Bounds" : "" ) + 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "("); 1573cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numArgs = jfunc.getNumArgs(); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numArgs; i++) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String argName = jfunc.getArgName(i); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JType argType = jfunc.getArgType(i); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (grabArray && argType.isTypedBuffer()) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String typeName = argType.getBaseType(); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typeName = typeName.substring(9, typeName.length() - 6); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + indent + "get" + typeName + "Array(" + argName + "),"); 1673cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich out.print(iii + indent + "getOffset(" + argName + ")"); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(iii + indent + argName); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == numArgs - 1) { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPointerFunc) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(","); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + indent + argName + ".remaining()"); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(","); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1823cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + ");"); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1864e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck, 1874e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich String iii) { 1884e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich printIfcheckPostamble(out, isBuffer, emitExceptionCheck, 1894e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich "offset", "_remaining", iii); 1904e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1924e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck, 1934e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich String offset, String remaining, String iii) { 1944e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich out.println(iii + " default:"); 1954e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich out.println(iii + " _needed = 0;"); 1964e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich out.println(iii + " break;"); 1974e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich out.println(iii + "}"); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1994e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich out.println(iii + "if (" + remaining + " < _needed) {"); 2004e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich if (emitExceptionCheck) { 2014e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich out.println(iii + indent + "_exception = 1;"); 2024e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } 20324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + indent + "jniThrowException(_env, " + 20424ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "\"java/lang/IllegalArgumentException\", " + 20524ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "\"" + (isBuffer ? "remaining()" : "length - " + offset) + " < needed\");"); 2064e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich out.println(iii + indent + "goto exit;"); 2074e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich needsExit = true; 2084e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich out.println(iii + "}"); 2094e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isNullAllowed(CFunc cfunc) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] checks = mChecker.getChecks(cfunc.getName()); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = 1; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checks != null) { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (index < checks.length) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checks[index].equals("return")) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 2; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].startsWith("check")) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 3; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("ifcheck")) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 5; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("unsupported")) { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 1; 2248a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else if (checks[index].equals("requires")) { 2258a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich index += 2; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("nullAllowed")) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("Error: unknown keyword \"" + 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checks[index] + "\""); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(0); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String getErrorReturnValue(CFunc cfunc) { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CType returnType = cfunc.getType(); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isVoid = returnType.isVoid(); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isVoid) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] checks = mChecker.getChecks(cfunc.getName()); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = 1; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checks != null) { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (index < checks.length) { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checks[index].equals("return")) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return checks[index + 1]; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].startsWith("check")) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 3; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("ifcheck")) { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 5; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("unsupported")) { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 1; 2588a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else if (checks[index].equals("requires")) { 2598a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich index += 2; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("nullAllowed")) { 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 1; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("Error: unknown keyword \"" + 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checks[index] + "\""); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(0); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isUnsupportedFunc(CFunc cfunc) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] checks = mChecker.getChecks(cfunc.getName()); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = 1; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checks != null) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (index < checks.length) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checks[index].equals("unsupported")) { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2808a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else if (checks[index].equals("requires")) { 2818a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich index += 2; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("return")) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 2; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].startsWith("check")) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 3; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("ifcheck")) { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 5; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (checks[index].equals("nullAllowed")) { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index += 1; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("Error: unknown keyword \"" + 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checks[index] + "\""); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(0); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 29924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 3008a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich String isRequiresFunc(CFunc cfunc) { 3018a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich String[] checks = mChecker.getChecks(cfunc.getName()); 3028a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich int index = 1; 3038a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich if (checks != null) { 3048a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich while (index < checks.length) { 3058a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich if (checks[index].equals("unsupported")) { 3068a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich index += 1; 3078a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else if (checks[index].equals("requires")) { 3088a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich return checks[index+1]; 3098a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else if (checks[index].equals("return")) { 3108a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich index += 2; 3118a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else if (checks[index].startsWith("check")) { 3128a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich index += 3; 3138a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else if (checks[index].equals("ifcheck")) { 3148a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich index += 5; 3158a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else if (checks[index].equals("nullAllowed")) { 3168a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich index += 1; 3178a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else { 3188a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich System.out.println("Error: unknown keyword \"" + 3198a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich checks[index] + "\""); 3208a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich System.exit(0); 3218a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } 3228a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } 3238a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } 3248a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich return null; 3258a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } 32624ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void emitNativeBoundsChecks(CFunc cfunc, String cname, PrintStream out, 3284e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) { 3294e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 33024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes String[] checks = mChecker.getChecks(cfunc.getName()); 33124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 33224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes boolean lastWasIfcheck = false; 33324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 33424ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes int index = 1; 33524ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes if (checks != null) { 33624ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes while (index < checks.length) { 33724ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes if (checks[index].startsWith("check")) { 33824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes if (lastWasIfcheck) { 33924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes printIfcheckPostamble(out, isBuffer, emitExceptionCheck, 34024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes offset, remaining, iii); 34124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } 34224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes lastWasIfcheck = false; 34324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes if (cname != null && !cname.equals(checks[index + 1])) { 34424ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes index += 3; 34524ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes continue; 34624ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } 34724ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + "if (" + remaining + " < " + checks[index + 2] + ") {"); 34824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes if (emitExceptionCheck) { 34924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + indent + "_exception = 1;"); 35024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } 35124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes String exceptionClassName = "java/lang/IllegalArgumentException"; 3524e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich // If the "check" keyword was of the form 3534e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich // "check_<class name>", use the class name in the 3544e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich // exception to be thrown 3554e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich int underscore = checks[index].indexOf('_'); 3564e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich if (underscore >= 0) { 35724ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes String abbr = checks[index].substring(underscore + 1); 35824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes if (abbr.equals("AIOOBE")) { 35924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes exceptionClassName = "java/lang/ArrayIndexOutOfBoundsException"; 3604e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } else { 36124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes throw new RuntimeException("unknown exception abbreviation: " + abbr); 3624e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36424ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + indent + "jniThrowException(_env, " + 36524ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "\"" + exceptionClassName + "\", " + 36624ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "\"" + (isBuffer ? "remaining()" : "length - " + offset) + " < " + checks[index + 2] + "\");"); 36724ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 36824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + indent + "goto exit;"); 36924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes needsExit = true; 37024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + "}"); 37124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 37224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes index += 3; 37324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } else if (checks[index].equals("ifcheck")) { 37424ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes String[] matches = checks[index + 4].split(","); 3753cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 37624ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes if (!lastWasIfcheck) { 37724ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + "int _needed;"); 37824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + "switch (" + checks[index + 3] + ") {"); 37924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } 38024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 38124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes for (int i = 0; i < matches.length; i++) { 38224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println("#if defined(" + matches[i] + ")"); 38324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + " case " + matches[i] + ":"); 38424ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println("#endif // defined(" + matches[i] + ")"); 38524ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } 38624ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + " _needed = " + checks[index + 2] + ";"); 38724ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(iii + " break;"); 38824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 38924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes lastWasIfcheck = true; 39024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes index += 5; 39124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } else if (checks[index].equals("return")) { 39224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes // ignore 39324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes index += 2; 39424ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } else if (checks[index].equals("unsupported")) { 39524ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes // ignore 39624ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes index += 1; 39724ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } else if (checks[index].equals("requires")) { 39824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes // ignore 39924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes index += 2; 40024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } else if (checks[index].equals("nullAllowed")) { 40124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes // ignore 40224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes index += 1; 40324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } else { 40424ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes System.out.println("Error: unknown keyword \"" + checks[index] + "\""); 40524ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes System.exit(0); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 40824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } 40924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 41024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes if (lastWasIfcheck) { 41124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes printIfcheckPostamble(out, isBuffer, emitExceptionCheck, iii); 41224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } 41324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4154e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, List<Integer> nonPrimitiveArgs) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nonPrimitiveArgs.size() > 0) { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cIndex = jfunc.getArgCIndex(idx); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jfunc.getArgType(idx).isArray()) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!cfunc.getArgType(cIndex).isConst()) { 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (jfunc.getArgType(idx).isBuffer()) { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!cfunc.getArgType(cIndex).isConst()) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4343cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Emit a function in several variants: 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if nativeDecl: public native <returntype> func(args); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if !nativeDecl: 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if interfaceDecl: public <returntype> func(args); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if !interfaceDecl: public <returntype> func(args) { body } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4444e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich void emitFunction(JFunc jfunc, PrintStream out, boolean nativeDecl, boolean interfaceDecl) { 445be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich boolean isPointerFunc = isPointerFunc(jfunc); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!nativeDecl && !interfaceDecl && !isPointerFunc) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If it's not a pointer function, we've already emitted it 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with nativeDecl == true 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45327f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich String maybeStatic = mUseStaticMethods ? "static " : ""; 45427f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPointerFunc) { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 45727f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich (nativeDecl ? "private " + maybeStatic +"native " : 45827f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich (interfaceDecl ? "" : "public ") + maybeStatic) + 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getType() + " " + 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getName() + 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (nativeDecl ? "Bounds" : "") + 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "("); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 46527f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich (nativeDecl ? "public " + maybeStatic +"native " : 46627f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich (interfaceDecl ? "" : "public ") + maybeStatic) + 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getType() + " " + 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getName() + 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "("); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4713cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numArgs = jfunc.getNumArgs(); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numArgs; i++) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String argName = jfunc.getArgName(i); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JType argType = jfunc.getArgType(i); 4763cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(indent + indent + argType + " " + argName); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == numArgs - 1) { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPointerFunc && nativeDecl) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(","); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + indent + "int remaining"); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(","); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nativeDecl || interfaceDecl) { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + ");"); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + ") {"); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String iii = indent + indent; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 497e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich // emitBoundsChecks(jfunc, out, iii); 498e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich emitFunctionCall(jfunc, out, iii, false); 499e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich 500e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich // Set the pointer after we call the native code, so that if 501e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich // the native code throws an exception we don't modify the 502e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich // pointer. We assume that the native code is written so that 503e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich // if an exception is thrown, then the underlying glXXXPointer 504e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich // function will not have been called. 505e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String fname = jfunc.getName(); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPointerFunc) { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO - deal with VBO variants 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fname.equals("glColorPointer")) { 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + "if ((size == 4) &&"); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " ((type == GL_FLOAT) ||"); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_UNSIGNED_BYTE) ||"); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_FIXED)) &&"); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (stride >= 0)) {"); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + indent + "_colorPointer = pointer;"); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + "}"); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (fname.equals("glNormalPointer")) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + "if (((type == GL_FLOAT) ||"); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_BYTE) ||"); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_SHORT) ||"); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_FIXED)) &&"); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (stride >= 0)) {"); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + indent + "_normalPointer = pointer;"); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + "}"); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (fname.equals("glTexCoordPointer")) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + "if (((size == 2) ||"); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (size == 3) ||"); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (size == 4)) &&"); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " ((type == GL_FLOAT) ||"); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_BYTE) ||"); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_SHORT) ||"); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_FIXED)) &&"); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (stride >= 0)) {"); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + indent + "_texCoordPointer = pointer;"); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + "}"); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (fname.equals("glVertexPointer")) { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + "if (((size == 2) ||"); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (size == 3) ||"); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (size == 4)) &&"); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " ((type == GL_FLOAT) ||"); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_BYTE) ||"); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_SHORT) ||"); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (type == GL_FIXED)) &&"); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + " (stride >= 0)) {"); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + indent + "_vertexPointer = pointer;"); 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(iii + "}"); 547be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich } else if (fname.equals("glPointSizePointerOES")) { 548be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + "if (((type == GL_FLOAT) ||"); 549be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (type == GL_FIXED)) &&"); 550be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (stride >= 0)) {"); 551be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + indent + "_pointSizePointerOES = pointer;"); 552be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + "}"); 553be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich } else if (fname.equals("glMatrixIndexPointerOES")) { 554be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + "if (((size == 2) ||"); 555be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (size == 3) ||"); 556be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (size == 4)) &&"); 557be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " ((type == GL_FLOAT) ||"); 558be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (type == GL_BYTE) ||"); 559be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (type == GL_SHORT) ||"); 560be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (type == GL_FIXED)) &&"); 561be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (stride >= 0)) {"); 562be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + indent + "_matrixIndexPointerOES = pointer;"); 563be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + "}"); 564be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich } else if (fname.equals("glWeightPointer")) { 565be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + "if (((size == 2) ||"); 566be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (size == 3) ||"); 567be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (size == 4)) &&"); 568be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " ((type == GL_FLOAT) ||"); 569be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (type == GL_BYTE) ||"); 570be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (type == GL_SHORT) ||"); 571be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (type == GL_FIXED)) &&"); 572be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + " (stride >= 0)) {"); 573be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + indent + "_weightPointerOES = pointer;"); 574be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich out.println(iii + "}"); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isVoid = jfunc.getType().isVoid(); 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isVoid) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + indent + "return _returnValue;"); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "}"); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5884e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich public void addNativeRegistration(String s) { 5894e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich nativeRegistrations.add(s); 5904e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } 5913cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 59227f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich public void emitNativeRegistration(String registrationFunctionName, 59327f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich PrintStream cStream) { 5944e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println("static const char *classPathName = \"" + 5954e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich mClassPathName + 5964e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich "\";"); 5974e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println(); 5984e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 5994e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println("static JNINativeMethod methods[] = {"); 6004e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 6014e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },"); 6024e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 6034e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich Iterator<String> i = nativeRegistrations.iterator(); 6044e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich while (i.hasNext()) { 6054e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println(i.next()); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6074e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 6084e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println("};"); 6094e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println(); 6104e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 6114e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 61227f8002e591b5c579f75b2580183b5d1c4219cd4Jack Palevich cStream.println("int " + registrationFunctionName + "(JNIEnv *_env)"); 6134e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println("{"); 6144e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println(indent + 6154e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich "int err;"); 6164e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 6174e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println(indent + 6184e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich "err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));"); 6194e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 6204e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println(indent + "return err;"); 6214e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich cStream.println("}"); 6224e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich } 6234e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich 6244e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich public JniCodeEmitter() { 6254e70a9e4627f42671d0671f2fda2ade7a19879bbJack Palevich super(); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String getJniType(JType jType) { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jType.isVoid()) { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "void"; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String baseType = jType.getBaseType(); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jType.isPrimitive()) { 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (baseType.equals("String")) { 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "jstring"; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "j" + baseType; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (jType.isArray()) { 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "j" + baseType + "Array"; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "jobject"; 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6463cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String getJniMangledName(String name) { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name.replaceAll("_", "_1"); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name.replaceAll(";", "_2"); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name.replaceAll("\\[", "_3"); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return name; 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void emitJniCode(JFunc jfunc, PrintStream out) { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CFunc cfunc = jfunc.getCFunc(); 6563cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit comment identifying original C function 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Example: 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // /* void glClipPlanef ( GLenum plane, const GLfloat *equation ) */ 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println("/* " + cfunc.getOriginal() + " */"); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit JNI signature (name) 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Example: 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // void 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // android_glClipPlanef__I_3FI 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String outName = "android_" + jfunc.getName(); 674be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich boolean isPointerFunc = isPointerFunc(jfunc); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isVBOPointerFunc = (outName.endsWith("Pointer") || 676be6eac828f5af8b608c3fa6749330f1dcd6b6206Jack Palevich outName.endsWith("PointerOES") || 677224107a421e2611b15d1ec736df54bca9ee3e78dJack Palevich outName.endsWith("DrawElements") || outName.endsWith("VertexAttribPointer")) && 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !jfunc.getCFunc().hasPointerArg(); 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPointerFunc) { 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outName += "Bounds"; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print("static "); 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(getJniType(jfunc.getType())); 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(outName); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String rsignature = getJniName(jfunc.getType()); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String signature = ""; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numArgs = jfunc.getNumArgs(); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numArgs; i++) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JType argType = jfunc.getArgType(i); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project signature += getJniName(argType); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPointerFunc) { 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project signature += "I"; 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Append signature to function name 700560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich String sig = getJniMangledName(signature).replace('.', '_').replace('/', '_'); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print("__" + sig); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outName += "__" + sig; 7033cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project signature = signature.replace('.', '/'); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rsignature = rsignature.replace('.', '/'); 7063cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rsignature.length() == 0) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rsignature = "V"; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String s = "{\"" + 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getName() + 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (isPointerFunc ? "Bounds" : "") + 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "\", \"(" + signature +")" + 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rsignature + 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "\", (void *) " + 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outName + 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " },"; 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeRegistrations.add(s); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Integer> nonPrimitiveArgs = new ArrayList<Integer>(); 723560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich List<Integer> stringArgs = new ArrayList<Integer>(); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numBufferArgs = 0; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> bufferArgNames = new ArrayList<String>(); 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit JNI signature (arguments) 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Example: 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (JNIEnv *_env, jobject this, jint plane, jfloatArray equation_ref, jint offset) { 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(" (JNIEnv *_env, jobject _this"); 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numArgs; i++) { 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(", "); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JType argType = jfunc.getArgType(i); 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String suffix; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!argType.isPrimitive()) { 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (argType.isArray()) { 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project suffix = "_ref"; 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project suffix = "_buf"; 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nonPrimitiveArgs.add(new Integer(i)); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jfunc.getArgType(i).isBuffer()) { 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cIndex = jfunc.getArgCIndex(i); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String cname = cfunc.getArgName(cIndex); 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bufferArgNames.add(cname); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numBufferArgs++; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project suffix = ""; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 754560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich if (argType.isString()) { 755560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich stringArgs.add(new Integer(i)); 756560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(getJniType(argType) + " " + jfunc.getArgName(i) + suffix); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPointerFunc) { 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(", jint remaining"); 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(") {"); 7643cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numArrays = 0; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numBuffers = 0; 767560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich int numStrings = 0; 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < nonPrimitiveArgs.size(); i++) { 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 770560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich JType argType = jfunc.getArgType(idx); 771560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich if (argType.isArray()) { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ++numArrays; 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 774560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich if (argType.isBuffer()) { 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ++numBuffers; 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 777560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich if (argType.isString()) { 778560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich ++numStrings; 779560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit method body 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit local variable declarations for _exception and _returnValue 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Example: 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // android::gl::ogles_context_t *ctx; 7893cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich // 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // jint _exception; 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // GLenum _returnValue; 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CType returnType = cfunc.getType(); 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isVoid = returnType.isVoid(); 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isUnsupported = isUnsupportedFunc(cfunc); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isUnsupported) { 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 79924ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "jniThrowException(_env, \"java/lang/UnsupportedOperationException\","); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " \"" + cfunc.getName() + "\");"); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isVoid) { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String retval = getErrorReturnValue(cfunc); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "return " + retval + ";"); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println("}"); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 81024ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes 8118a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich String requiresExtension = isRequiresFunc(cfunc); 8128a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich if (requiresExtension != null) { 8138a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich out.println(indent + 8148a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich "if (! supportsExtension(_env, _this, have_" + requiresExtension + "ID)) {"); 8158a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich out.println(indent + indent + 81624ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "jniThrowException(_env, \"java/lang/UnsupportedOperationException\","); 8178a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich out.println(indent + indent + 8188a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich " \"" + cfunc.getName() + "\");"); 8198a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich if (isVoid) { 8208a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich out.println(indent + indent + " return;"); 8218a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } else { 8228a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich String retval = getErrorReturnValue(cfunc); 8238a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich out.println(indent + indent + " return " + retval + ";"); 8248a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } 8258a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich out.println(indent + "}"); 8268a4de4be9ed522c704a45a44a265669e10a8f2ebJack Palevich } 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUseContextPointer) { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android::gl::ogles_context_t *ctx = getContext(_env, _this);"); 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 832560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich boolean initializeReturnValue = stringArgs.size() > 0; 833560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 834560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0 || numStrings > 0) && 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mChecker.getChecks(cfunc.getName()) != null 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit an _exeption variable if there will be error checks 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (emitExceptionCheck) { 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "jint _exception = 0;"); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit a single _array or multiple _XXXArray variables 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numBufferArgs == 1) { 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "jarray _array = (jarray) 0;"); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numBufferArgs; i++) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "jarray _" + bufferArgNames.get(i) + 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Array = (jarray) 0;"); 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isVoid) { 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String retval = getErrorReturnValue(cfunc); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retval != null) { 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + returnType.getDeclaration() + 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " _returnValue = " + retval + ";"); 857560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } else if (initializeReturnValue) { 858560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + returnType.getDeclaration() + 859560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich " _returnValue = 0;"); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + returnType.getDeclaration() + 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " _returnValue;"); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit local variable declarations for pointer arguments 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Example: 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // GLfixed *eqn_base; 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // GLfixed *eqn; 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String offset = "offset"; 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String remaining = "_remaining"; 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nonPrimitiveArgs.size() > 0) { 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < nonPrimitiveArgs.size(); i++) { 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cIndex = jfunc.getArgCIndex(idx); 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String cname = cfunc.getArgName(cIndex); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CType type = cfunc.getArgType(jfunc.getArgCIndex(idx)); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String decl = type.getDeclaration(); 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jfunc.getArgType(idx).isArray()) { 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project decl + 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (decl.endsWith("*") ? "" : " ") + 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getArgName(idx) + 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_base = (" + decl + ") 0;"); 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 890560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" : 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_" + cname + "Remaining"; 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "jint " + remaining + ";"); 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project decl + 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (decl.endsWith("*") ? "" : " ") + 8973cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich jfunc.getArgName(idx) + 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " = (" + decl + ") 0;"); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 904560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich // Emit local variable declaration for strings 905560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich if (stringArgs.size() > 0) { 906560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich for (int i = 0; i < stringArgs.size(); i++) { 907560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich int idx = stringArgs.get(i).intValue(); 908560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich int cIndex = jfunc.getArgCIndex(idx); 909560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich String cname = cfunc.getArgName(cIndex); 910560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 911560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + "const char* _native" + cname + " = 0;"); 912560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 913560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 914560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(); 915560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 916560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 917560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich // Null pointer checks and GetStringUTFChars 918560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich if (stringArgs.size() > 0) { 919560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich for (int i = 0; i < stringArgs.size(); i++) { 920560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich int idx = stringArgs.get(i).intValue(); 921560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich int cIndex = jfunc.getArgCIndex(idx); 922560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich String cname = cfunc.getArgName(cIndex); 923560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 924560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich CType type = cfunc.getArgType(jfunc.getArgCIndex(idx)); 925560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich String decl = type.getDeclaration(); 926560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + "if (!" + cname + ") {"); 92724ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(indent + " jniThrowException(_env, " + 92824ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "\"java/lang/IllegalArgumentException\", \"" + cname + " == null\");"); 929560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + " goto exit;"); 930560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich needsExit = true; 931560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + "}"); 932560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 933560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + "_native" + cname + " = _env->GetStringUTFChars(" + cname + ", 0);"); 934560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 935560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 936560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(); 937560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 938560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit 'GetPrimitiveArrayCritical' for arrays 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Emit 'GetPointer' calls for Buffer pointers 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bufArgIdx = 0; 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nonPrimitiveArgs.size() > 0) { 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < nonPrimitiveArgs.size(); i++) { 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cIndex = jfunc.getArgCIndex(idx); 9463cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String cname = cfunc.getArgName(cIndex); 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset = numArrays <= 1 ? "offset" : 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cname + "Offset"; 950560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" : 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_" + cname + "Remaining"; 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jfunc.getArgType(idx).isArray()) { 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 9553cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich "if (!" + 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cname + 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_ref) {"); 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (emitExceptionCheck) { 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + indent + "_exception = 1;"); 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 96124ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(indent + " jniThrowException(_env, " + 96224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "\"java/lang/IllegalArgumentException\", " + 96324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "\"" + cname + " == null\");"); 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + " goto exit;"); 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project needsExit = true; 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "}"); 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "if (" + offset + " < 0) {"); 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (emitExceptionCheck) { 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + indent + "_exception = 1;"); 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 97224ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes out.println(indent + " jniThrowException(_env, " + 97324ce5fb2cc09d0a14406e7b935f8648c5720d27eElliott Hughes "\"java/lang/IllegalArgumentException\", \"" + offset + " < 0\");"); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + " goto exit;"); 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project needsExit = true; 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "}"); 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + remaining + " = " + 9793cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich (mUseCPlusPlus ? "_env" : "(*_env)") + 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "->GetArrayLength(" + 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mUseCPlusPlus ? "" : "_env, ") + 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cname + "_ref) - " + offset + ";"); 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project emitNativeBoundsChecks(cfunc, cname, out, false, 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project emitExceptionCheck, 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offset, remaining, " "); 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cname + 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_base = (" + 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cfunc.getArgType(cIndex).getDeclaration() + 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ")"); 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + " " + 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mUseCPlusPlus ? "_env" : "(*_env)") + 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "->GetPrimitiveArrayCritical(" + 9963cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich (mUseCPlusPlus ? "" : "_env, ") + 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getArgName(idx) + 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_ref, (jboolean *)0);"); 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cname + " = " + cname + "_base + " + offset + 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ";"); 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String array = numBufferArgs <= 1 ? "_array" : 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_" + bufferArgNames.get(bufArgIdx++) + "Array"; 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1007e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich boolean nullAllowed = isNullAllowed(cfunc) || isPointerFunc; 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nullAllowed) { 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "if (" + cname + "_buf) {"); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(indent); 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10123cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 1013e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich if (isPointerFunc) { 1014e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich out.println(indent + 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cname + 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " = (" + 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cfunc.getArgType(cIndex).getDeclaration() + 101816e7972f0d986eebf846ea8feb50f4435a9c6970Jack Palevich ") getDirectBufferPointer(_env, " + 1019e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich cname + "_buf);"); 1020e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich String iii = " "; 1021c620a52b69a5f29563e06497e30877809f5d67a5Jack Palevich out.println(iii + indent + "if ( ! " + cname + " ) {"); 1022e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich out.println(iii + iii + indent + "return;"); 1023e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich out.println(iii + indent + "}"); 1024e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich } else { 1025e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich out.println(indent + 1026e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich cname + 1027e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich " = (" + 1028e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich cfunc.getArgType(cIndex).getDeclaration() + 1029e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich ")getPointer(_env, " + 1030e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich cname + 1031e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich "_buf, &" + array + ", &" + remaining + 1032e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich ");"); 1033e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1035c620a52b69a5f29563e06497e30877809f5d67a5Jack Palevich emitNativeBoundsChecks(cfunc, cname, out, true, 1036c620a52b69a5f29563e06497e30877809f5d67a5Jack Palevich emitExceptionCheck, 1037c620a52b69a5f29563e06497e30877809f5d67a5Jack Palevich offset, remaining, nullAllowed ? " " : " "); 1038c620a52b69a5f29563e06497e30877809f5d67a5Jack Palevich 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nullAllowed) { 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "}"); 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isVoid) { 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(indent + "_returnValue = "); 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(indent); 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = cfunc.getName(); 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUseContextPointer) { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name.substring(2, name.length()); // Strip off 'gl' prefix 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = name.substring(0, 1).toLowerCase() + 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name.substring(1, name.length()); 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print("ctx->procs."); 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10593cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(name + (isPointerFunc ? "Bounds" : "") + "("); 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10623cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich numArgs = cfunc.getNumArgs(); 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numArgs == 0) { 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUseContextPointer) { 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println("ctx);"); 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(");"); 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUseContextPointer) { 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println("ctx,"); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numArgs; i++) { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String typecast; 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == numArgs - 1 && isVBOPointerFunc) { 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typecast = "const GLvoid *"; 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typecast = cfunc.getArgType(i).getDeclaration(); 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.print(indent + indent + 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(" + 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typecast + 1085560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich ")"); 1086560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich if (cfunc.getArgType(i).isConstCharPointer()) { 1087560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.print("_native"); 1088560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 1089560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.print(cfunc.getArgName(i)); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i == numArgs - 1) { 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPointerFunc) { 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(","); 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + indent + "(GLsizei)remaining"); 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(","); 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + ");"); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (needsExit) { 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println("exit:"); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project needsExit = false; 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bufArgIdx = 0; 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nonPrimitiveArgs.size() > 0) { 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) { 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int cIndex = jfunc.getArgCIndex(idx); 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (jfunc.getArgType(idx).isArray()) { 11183cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the argument is 'const', GL will not write to it. 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // In this case, we can use the 'JNI_ABORT' flag to avoid 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the need to write back to the Java array 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "if (" + jfunc.getArgName(idx) + "_base) {"); 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + indent + 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mUseCPlusPlus ? "_env" : "(*_env)") + 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "->ReleasePrimitiveArrayCritical(" + 11273cae8fede973a66c10ee07446e8dd8d7c2ead2c1Jack Palevich (mUseCPlusPlus ? "" : "_env, ") + 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfunc.getArgName(idx) + "_ref, " + 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cfunc.getArgName(cIndex) + 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_base,"); 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + indent + indent + 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (cfunc.getArgType(cIndex).isConst() ? 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "JNI_ABORT" : 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "_exception ? JNI_ABORT: 0") + 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ");"); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "}"); 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (jfunc.getArgType(idx).isBuffer()) { 1138e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich if (! isPointerFunc) { 1139e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich String array = numBufferArgs <= 1 ? "_array" : 1140e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich "_" + bufferArgNames.get(bufArgIdx++) + "Array"; 1141e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich out.println(indent + "if (" + array + ") {"); 1142e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich out.println(indent + indent + 1143e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich "releasePointer(_env, " + array + ", " + 1144e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich cfunc.getArgName(cIndex) + 1145e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich ", " + 1146e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich (cfunc.getArgType(cIndex).isConst() ? 1147e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich "JNI_FALSE" : "_exception ? JNI_FALSE :" + 1148e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich " JNI_TRUE") + 1149e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich ");"); 1150e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich out.println(indent + "}"); 1151e20ea783a12f1031482c3aa01938efe39dcbf0a2Jack Palevich } 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1156560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich // Emit local variable declaration for strings 1157560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich if (stringArgs.size() > 0) { 1158560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich for (int i = 0; i < stringArgs.size(); i++) { 1159560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich int idx = stringArgs.get(i).intValue(); 1160560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich int cIndex = jfunc.getArgCIndex(idx); 1161560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich String cname = cfunc.getArgName(cIndex); 1162560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 1163560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + "if (_native" + cname + ") {"); 1164560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + " _env->ReleaseStringUTFChars(" + cname + ", _native" + cname + ");"); 1165560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(indent + "}"); 1166560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 1167560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 1168560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich out.println(); 1169560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich } 1170560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 1171560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isVoid) { 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(indent + "return _returnValue;"); 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println("}"); 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.println(); 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1181