JniCodeEmitter.java revision 9875750593aae7c2a62f33c620809d49162393eb
1bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root/* 2bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * Copyright (C) 2006 The Android Open Source Project 3bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * 4bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * you may not use this file except in compliance with the License. 6bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * You may obtain a copy of the License at 7bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * 8bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * 10bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * Unless required by applicable law or agreed to in writing, software 11bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * See the License for the specific language governing permissions and 14bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root * limitations under the License. 15bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root */ 16bd393b7f39a71a13893aea8b64474b0b07ebe0ddKenny Root 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport java.io.PrintStream; 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport java.util.ArrayList; 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport java.util.HashSet; 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport java.util.Iterator; 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport java.util.List; 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevichpublic class JniCodeEmitter { 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich static final boolean mUseCPlusPlus = true; 26ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich protected boolean mUseContextPointer = true; 27427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich protected boolean mUseStaticMethods = false; 28ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich protected String mClassPathName; 29ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich protected ParameterChecker mChecker; 30ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich protected List<String> nativeRegistrations = new ArrayList<String>(); 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean needsExit; 32ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich protected static String indent = " "; 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project HashSet<String> mFunctionsEmitted = new HashSet<String>(); 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 35ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich public static String getJniName(JType jType) { 36ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich String jniName = ""; 37ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich if (jType.isClass()) { 38ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich return "L" + jType.getBaseType() + ";"; 39ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } else if (jType.isArray()) { 40ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich jniName = "["; 41ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 43ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich String baseType = jType.getBaseType(); 44ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich if (baseType.equals("int")) { 45ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich jniName += "I"; 46ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } else if (baseType.equals("float")) { 47ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich jniName += "F"; 48ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } else if (baseType.equals("boolean")) { 49ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich jniName += "Z"; 50ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } else if (baseType.equals("short")) { 51ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich jniName += "S"; 52ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } else if (baseType.equals("long")) { 53ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich jniName += "L"; 54ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } else if (baseType.equals("byte")) { 55ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich jniName += "B"; 5650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } else if (baseType.equals("String")) { 5750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich jniName += "Ljava/lang/String;"; 5850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } else if (baseType.equals("void")) { 5950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich // nothing. 6050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } else { 619875750593aae7c2a62f33c620809d49162393ebElliott Hughes throw new RuntimeException("Unknown primitive basetype " + baseType); 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 63ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich return jniName; 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 66ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 67ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich public void emitCode(CFunc cfunc, String original, 68ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich PrintStream javaInterfaceStream, 69ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich PrintStream javaImplStream, 70ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich PrintStream cStream) { 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project JFunc jfunc; 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String signature; 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean duplicate; 746cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (cfunc.hasTypedPointerArg()) { 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc = JFunc.convert(cfunc, true); 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Don't emit duplicate functions 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // These may appear because they are defined in multiple 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Java interfaces (e.g., GL11/GL11ExtensionPack) 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signature = jfunc.toString(); 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project duplicate = false; 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mFunctionsEmitted.contains(signature)) { 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project duplicate = true; 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFunctionsEmitted.add(signature); 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!duplicate) { 90ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich emitNativeDeclaration(jfunc, javaImplStream); 91ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich emitJavaCode(jfunc, javaImplStream); 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 93427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich if (javaInterfaceStream != null) { 94427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich emitJavaInterfaceCode(jfunc, javaInterfaceStream); 95427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich } 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!duplicate) { 97ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich emitJniCode(jfunc, cStream); 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc = JFunc.convert(cfunc, false); 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signature = jfunc.toString(); 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project duplicate = false; 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mFunctionsEmitted.contains(signature)) { 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project duplicate = true; 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFunctionsEmitted.add(signature); 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!duplicate) { 112ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich emitNativeDeclaration(jfunc, javaImplStream); 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 114427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich if (javaInterfaceStream != null) { 115427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich emitJavaInterfaceCode(jfunc, javaInterfaceStream); 116427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich } 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!duplicate) { 118ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich emitJavaCode(jfunc, javaImplStream); 119ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich emitJniCode(jfunc, cStream); 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public void emitNativeDeclaration(JFunc jfunc, PrintStream out) { 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(" // C function " + jfunc.getCFunc().getOriginal()); 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project emitFunction(jfunc, out, true, false); 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public void emitJavaInterfaceCode(JFunc jfunc, PrintStream out) { 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project emitFunction(jfunc, out, false, true); 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public void emitJavaCode(JFunc jfunc, PrintStream out) { 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project emitFunction(jfunc, out, false, false); 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1376cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 13866089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich boolean isPointerFunc(JFunc jfunc) { 13966089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich String name = jfunc.getName(); 14066089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich return (name.endsWith("Pointer") || name.endsWith("PointerOES")) 14166089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich && jfunc.getCFunc().hasPointerArg(); 14266089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich } 14366089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich 144ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich void emitFunctionCall(JFunc jfunc, PrintStream out, String iii, boolean grabArray) { 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean isVoid = jfunc.getType().isVoid(); 14666089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich boolean isPointerFunc = isPointerFunc(jfunc); 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!isVoid) { 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getType() + " _returnValue;"); 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (isVoid ? "" : "_returnValue = ") + 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getName() + 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (isPointerFunc ? "Bounds" : "" ) + 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "("); 1576cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int numArgs = jfunc.getNumArgs(); 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < numArgs; i++) { 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String argName = jfunc.getArgName(i); 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project JType argType = jfunc.getArgType(i); 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (grabArray && argType.isTypedBuffer()) { 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String typeName = argType.getBaseType(); 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project typeName = typeName.substring(9, typeName.length() - 6); 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + indent + "get" + typeName + "Array(" + argName + "),"); 1676cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich out.print(iii + indent + "getOffset(" + argName + ")"); 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(iii + indent + argName); 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i == numArgs - 1) { 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isPointerFunc) { 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(","); 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + indent + argName + ".remaining()"); 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(","); 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1826cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + ");"); 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 186ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck, 187ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich String iii) { 188ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich printIfcheckPostamble(out, isBuffer, emitExceptionCheck, 189ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich "offset", "_remaining", iii); 190ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich void printIfcheckPostamble(PrintStream out, boolean isBuffer, boolean emitExceptionCheck, 193ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich String offset, String remaining, String iii) { 194ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich out.println(iii + " default:"); 195ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich out.println(iii + " _needed = 0;"); 196ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich out.println(iii + " break;"); 197ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich out.println(iii + "}"); 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 199ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich out.println(iii + "if (" + remaining + " < _needed) {"); 200ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich if (emitExceptionCheck) { 201ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich out.println(iii + indent + "_exception = 1;"); 202ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } 2039875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + indent + "jniThrowException(_env, " + 2049875750593aae7c2a62f33c620809d49162393ebElliott Hughes "\"java/lang/IllegalArgumentException\", " + 2059875750593aae7c2a62f33c620809d49162393ebElliott Hughes "\"" + (isBuffer ? "remaining()" : "length - " + offset) + " < needed\");"); 206ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich out.println(iii + indent + "goto exit;"); 207ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich needsExit = true; 208ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich out.println(iii + "}"); 209ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean isNullAllowed(CFunc cfunc) { 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String[] checks = mChecker.getChecks(cfunc.getName()); 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int index = 1; 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (checks != null) { 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (index < checks.length) { 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (checks[index].equals("return")) { 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 2; 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].startsWith("check")) { 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 3; 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("ifcheck")) { 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 5; 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("unsupported")) { 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 1; 224e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else if (checks[index].equals("requires")) { 225e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich index += 2; 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("nullAllowed")) { 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project System.out.println("Error: unknown keyword \"" + 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project checks[index] + "\""); 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project System.exit(0); 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String getErrorReturnValue(CFunc cfunc) { 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CType returnType = cfunc.getType(); 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean isVoid = returnType.isVoid(); 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isVoid) { 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return null; 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String[] checks = mChecker.getChecks(cfunc.getName()); 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int index = 1; 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (checks != null) { 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (index < checks.length) { 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (checks[index].equals("return")) { 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return checks[index + 1]; 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].startsWith("check")) { 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 3; 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("ifcheck")) { 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 5; 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("unsupported")) { 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 1; 258e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else if (checks[index].equals("requires")) { 259e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich index += 2; 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("nullAllowed")) { 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 1; 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project System.out.println("Error: unknown keyword \"" + 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project checks[index] + "\""); 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project System.exit(0); 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return null; 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean isUnsupportedFunc(CFunc cfunc) { 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String[] checks = mChecker.getChecks(cfunc.getName()); 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int index = 1; 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (checks != null) { 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (index < checks.length) { 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (checks[index].equals("unsupported")) { 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 280e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else if (checks[index].equals("requires")) { 281e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich index += 2; 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("return")) { 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 2; 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].startsWith("check")) { 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 3; 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("ifcheck")) { 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 5; 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (checks[index].equals("nullAllowed")) { 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index += 1; 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project System.out.println("Error: unknown keyword \"" + 292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project checks[index] + "\""); 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project System.exit(0); 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 2999875750593aae7c2a62f33c620809d49162393ebElliott Hughes 300e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich String isRequiresFunc(CFunc cfunc) { 301e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich String[] checks = mChecker.getChecks(cfunc.getName()); 302e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich int index = 1; 303e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich if (checks != null) { 304e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich while (index < checks.length) { 305e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich if (checks[index].equals("unsupported")) { 306e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich index += 1; 307e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else if (checks[index].equals("requires")) { 308e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich return checks[index+1]; 309e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else if (checks[index].equals("return")) { 310e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich index += 2; 311e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else if (checks[index].startsWith("check")) { 312e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich index += 3; 313e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else if (checks[index].equals("ifcheck")) { 314e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich index += 5; 315e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else if (checks[index].equals("nullAllowed")) { 316e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich index += 1; 317e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else { 318e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich System.out.println("Error: unknown keyword \"" + 319e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich checks[index] + "\""); 320e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich System.exit(0); 321e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } 322e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } 323e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } 324e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich return null; 325e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } 3269875750593aae7c2a62f33c620809d49162393ebElliott Hughes 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void emitNativeBoundsChecks(CFunc cfunc, String cname, PrintStream out, 328ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) { 329ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 3309875750593aae7c2a62f33c620809d49162393ebElliott Hughes String[] checks = mChecker.getChecks(cfunc.getName()); 3319875750593aae7c2a62f33c620809d49162393ebElliott Hughes 3329875750593aae7c2a62f33c620809d49162393ebElliott Hughes boolean lastWasIfcheck = false; 3339875750593aae7c2a62f33c620809d49162393ebElliott Hughes 3349875750593aae7c2a62f33c620809d49162393ebElliott Hughes int index = 1; 3359875750593aae7c2a62f33c620809d49162393ebElliott Hughes if (checks != null) { 3369875750593aae7c2a62f33c620809d49162393ebElliott Hughes while (index < checks.length) { 3379875750593aae7c2a62f33c620809d49162393ebElliott Hughes if (checks[index].startsWith("check")) { 3389875750593aae7c2a62f33c620809d49162393ebElliott Hughes if (lastWasIfcheck) { 3399875750593aae7c2a62f33c620809d49162393ebElliott Hughes printIfcheckPostamble(out, isBuffer, emitExceptionCheck, 3409875750593aae7c2a62f33c620809d49162393ebElliott Hughes offset, remaining, iii); 3419875750593aae7c2a62f33c620809d49162393ebElliott Hughes } 3429875750593aae7c2a62f33c620809d49162393ebElliott Hughes lastWasIfcheck = false; 3439875750593aae7c2a62f33c620809d49162393ebElliott Hughes if (cname != null && !cname.equals(checks[index + 1])) { 3449875750593aae7c2a62f33c620809d49162393ebElliott Hughes index += 3; 3459875750593aae7c2a62f33c620809d49162393ebElliott Hughes continue; 3469875750593aae7c2a62f33c620809d49162393ebElliott Hughes } 3479875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + "if (" + remaining + " < " + checks[index + 2] + ") {"); 3489875750593aae7c2a62f33c620809d49162393ebElliott Hughes if (emitExceptionCheck) { 3499875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + indent + "_exception = 1;"); 3509875750593aae7c2a62f33c620809d49162393ebElliott Hughes } 3519875750593aae7c2a62f33c620809d49162393ebElliott Hughes String exceptionClassName = "java/lang/IllegalArgumentException"; 352ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich // If the "check" keyword was of the form 353ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich // "check_<class name>", use the class name in the 354ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich // exception to be thrown 355ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich int underscore = checks[index].indexOf('_'); 356ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich if (underscore >= 0) { 3579875750593aae7c2a62f33c620809d49162393ebElliott Hughes String abbr = checks[index].substring(underscore + 1); 3589875750593aae7c2a62f33c620809d49162393ebElliott Hughes if (abbr.equals("AIOOBE")) { 3599875750593aae7c2a62f33c620809d49162393ebElliott Hughes exceptionClassName = "java/lang/ArrayIndexOutOfBoundsException"; 360ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } else { 3619875750593aae7c2a62f33c620809d49162393ebElliott Hughes throw new RuntimeException("unknown exception abbreviation: " + abbr); 362ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3649875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + indent + "jniThrowException(_env, " + 3659875750593aae7c2a62f33c620809d49162393ebElliott Hughes "\"" + exceptionClassName + "\", " + 3669875750593aae7c2a62f33c620809d49162393ebElliott Hughes "\"" + (isBuffer ? "remaining()" : "length - " + offset) + " < " + checks[index + 2] + "\");"); 3679875750593aae7c2a62f33c620809d49162393ebElliott Hughes 3689875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + indent + "goto exit;"); 3699875750593aae7c2a62f33c620809d49162393ebElliott Hughes needsExit = true; 3709875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + "}"); 3719875750593aae7c2a62f33c620809d49162393ebElliott Hughes 3729875750593aae7c2a62f33c620809d49162393ebElliott Hughes index += 3; 3739875750593aae7c2a62f33c620809d49162393ebElliott Hughes } else if (checks[index].equals("ifcheck")) { 3749875750593aae7c2a62f33c620809d49162393ebElliott Hughes String[] matches = checks[index + 4].split(","); 3756cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 3769875750593aae7c2a62f33c620809d49162393ebElliott Hughes if (!lastWasIfcheck) { 3779875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + "int _needed;"); 3789875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + "switch (" + checks[index + 3] + ") {"); 3799875750593aae7c2a62f33c620809d49162393ebElliott Hughes } 3809875750593aae7c2a62f33c620809d49162393ebElliott Hughes 3819875750593aae7c2a62f33c620809d49162393ebElliott Hughes for (int i = 0; i < matches.length; i++) { 3829875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println("#if defined(" + matches[i] + ")"); 3839875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + " case " + matches[i] + ":"); 3849875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println("#endif // defined(" + matches[i] + ")"); 3859875750593aae7c2a62f33c620809d49162393ebElliott Hughes } 3869875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + " _needed = " + checks[index + 2] + ";"); 3879875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(iii + " break;"); 3889875750593aae7c2a62f33c620809d49162393ebElliott Hughes 3899875750593aae7c2a62f33c620809d49162393ebElliott Hughes lastWasIfcheck = true; 3909875750593aae7c2a62f33c620809d49162393ebElliott Hughes index += 5; 3919875750593aae7c2a62f33c620809d49162393ebElliott Hughes } else if (checks[index].equals("return")) { 3929875750593aae7c2a62f33c620809d49162393ebElliott Hughes // ignore 3939875750593aae7c2a62f33c620809d49162393ebElliott Hughes index += 2; 3949875750593aae7c2a62f33c620809d49162393ebElliott Hughes } else if (checks[index].equals("unsupported")) { 3959875750593aae7c2a62f33c620809d49162393ebElliott Hughes // ignore 3969875750593aae7c2a62f33c620809d49162393ebElliott Hughes index += 1; 3979875750593aae7c2a62f33c620809d49162393ebElliott Hughes } else if (checks[index].equals("requires")) { 3989875750593aae7c2a62f33c620809d49162393ebElliott Hughes // ignore 3999875750593aae7c2a62f33c620809d49162393ebElliott Hughes index += 2; 4009875750593aae7c2a62f33c620809d49162393ebElliott Hughes } else if (checks[index].equals("nullAllowed")) { 4019875750593aae7c2a62f33c620809d49162393ebElliott Hughes // ignore 4029875750593aae7c2a62f33c620809d49162393ebElliott Hughes index += 1; 4039875750593aae7c2a62f33c620809d49162393ebElliott Hughes } else { 4049875750593aae7c2a62f33c620809d49162393ebElliott Hughes System.out.println("Error: unknown keyword \"" + checks[index] + "\""); 4059875750593aae7c2a62f33c620809d49162393ebElliott Hughes System.exit(0); 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 4089875750593aae7c2a62f33c620809d49162393ebElliott Hughes } 4099875750593aae7c2a62f33c620809d49162393ebElliott Hughes 4109875750593aae7c2a62f33c620809d49162393ebElliott Hughes if (lastWasIfcheck) { 4119875750593aae7c2a62f33c620809d49162393ebElliott Hughes printIfcheckPostamble(out, isBuffer, emitExceptionCheck, iii); 4129875750593aae7c2a62f33c620809d49162393ebElliott Hughes } 4139875750593aae7c2a62f33c620809d49162393ebElliott Hughes } 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 415ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, List<Integer> nonPrimitiveArgs) { 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (nonPrimitiveArgs.size() > 0) { 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) { 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int cIndex = jfunc.getArgCIndex(idx); 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (jfunc.getArgType(idx).isArray()) { 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!cfunc.getArgType(cIndex).isConst()) { 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (jfunc.getArgType(idx).isBuffer()) { 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!cfunc.getArgType(cIndex).isConst()) { 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 4346cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /** 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Emit a function in several variants: 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * if nativeDecl: public native <returntype> func(args); 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * if !nativeDecl: 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * if interfaceDecl: public <returntype> func(args); 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * if !interfaceDecl: public <returntype> func(args) { body } 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 444ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich void emitFunction(JFunc jfunc, PrintStream out, boolean nativeDecl, boolean interfaceDecl) { 44566089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich boolean isPointerFunc = isPointerFunc(jfunc); 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!nativeDecl && !interfaceDecl && !isPointerFunc) { 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If it's not a pointer function, we've already emitted it 449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // with nativeDecl == true 450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 453427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich String maybeStatic = mUseStaticMethods ? "static " : ""; 454427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isPointerFunc) { 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 457427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich (nativeDecl ? "private " + maybeStatic +"native " : 458427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich (interfaceDecl ? "" : "public ") + maybeStatic) + 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getType() + " " + 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getName() + 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (nativeDecl ? "Bounds" : "") + 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "("); 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 465427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich (nativeDecl ? "public " + maybeStatic +"native " : 466427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich (interfaceDecl ? "" : "public ") + maybeStatic) + 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getType() + " " + 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getName() + 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "("); 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 4716cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int numArgs = jfunc.getNumArgs(); 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < numArgs; i++) { 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String argName = jfunc.getArgName(i); 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project JType argType = jfunc.getArgType(i); 4766cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(indent + indent + argType + " " + argName); 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i == numArgs - 1) { 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isPointerFunc && nativeDecl) { 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(","); 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + indent + "int remaining"); 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(","); 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (nativeDecl || interfaceDecl) { 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + ");"); 492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + ") {"); 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String iii = indent + indent; 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49746d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich // emitBoundsChecks(jfunc, out, iii); 49846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich emitFunctionCall(jfunc, out, iii, false); 49946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich 50046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich // Set the pointer after we call the native code, so that if 50146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich // the native code throws an exception we don't modify the 50246d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich // pointer. We assume that the native code is written so that 50346d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich // if an exception is thrown, then the underlying glXXXPointer 50446d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich // function will not have been called. 50546d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String fname = jfunc.getName(); 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isPointerFunc) { 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO - deal with VBO variants 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (fname.equals("glColorPointer")) { 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + "if ((size == 4) &&"); 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " ((type == GL_FLOAT) ||"); 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_UNSIGNED_BYTE) ||"); 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_FIXED)) &&"); 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (stride >= 0)) {"); 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + indent + "_colorPointer = pointer;"); 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + "}"); 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (fname.equals("glNormalPointer")) { 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + "if (((type == GL_FLOAT) ||"); 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_BYTE) ||"); 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_SHORT) ||"); 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_FIXED)) &&"); 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (stride >= 0)) {"); 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + indent + "_normalPointer = pointer;"); 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + "}"); 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (fname.equals("glTexCoordPointer")) { 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + "if (((size == 2) ||"); 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (size == 3) ||"); 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (size == 4)) &&"); 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " ((type == GL_FLOAT) ||"); 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_BYTE) ||"); 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_SHORT) ||"); 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_FIXED)) &&"); 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (stride >= 0)) {"); 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + indent + "_texCoordPointer = pointer;"); 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + "}"); 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (fname.equals("glVertexPointer")) { 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + "if (((size == 2) ||"); 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (size == 3) ||"); 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (size == 4)) &&"); 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " ((type == GL_FLOAT) ||"); 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_BYTE) ||"); 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_SHORT) ||"); 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (type == GL_FIXED)) &&"); 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + " (stride >= 0)) {"); 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + indent + "_vertexPointer = pointer;"); 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(iii + "}"); 54766089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich } else if (fname.equals("glPointSizePointerOES")) { 54866089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + "if (((type == GL_FLOAT) ||"); 54966089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (type == GL_FIXED)) &&"); 55066089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (stride >= 0)) {"); 55166089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + indent + "_pointSizePointerOES = pointer;"); 55266089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + "}"); 55366089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich } else if (fname.equals("glMatrixIndexPointerOES")) { 55466089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + "if (((size == 2) ||"); 55566089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (size == 3) ||"); 55666089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (size == 4)) &&"); 55766089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " ((type == GL_FLOAT) ||"); 55866089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (type == GL_BYTE) ||"); 55966089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (type == GL_SHORT) ||"); 56066089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (type == GL_FIXED)) &&"); 56166089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (stride >= 0)) {"); 56266089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + indent + "_matrixIndexPointerOES = pointer;"); 56366089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + "}"); 56466089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich } else if (fname.equals("glWeightPointer")) { 56566089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + "if (((size == 2) ||"); 56666089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (size == 3) ||"); 56766089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (size == 4)) &&"); 56866089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " ((type == GL_FLOAT) ||"); 56966089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (type == GL_BYTE) ||"); 57066089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (type == GL_SHORT) ||"); 57166089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (type == GL_FIXED)) &&"); 57266089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + " (stride >= 0)) {"); 57366089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + indent + "_weightPointerOES = pointer;"); 57466089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich out.println(iii + "}"); 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean isVoid = jfunc.getType().isVoid(); 579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!isVoid) { 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + indent + "return _returnValue;"); 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "}"); 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 588ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich public void addNativeRegistration(String s) { 589ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich nativeRegistrations.add(s); 590ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } 5916cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 592427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich public void emitNativeRegistration(String registrationFunctionName, 593427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich PrintStream cStream) { 594ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println("static const char *classPathName = \"" + 595ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich mClassPathName + 596ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich "\";"); 597ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println(); 598ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 599ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println("static JNINativeMethod methods[] = {"); 600ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 601ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },"); 602ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 603ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich Iterator<String> i = nativeRegistrations.iterator(); 604ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich while (i.hasNext()) { 605ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println(i.next()); 606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 607ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 608ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println("};"); 609ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println(); 610ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 611ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 612427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich cStream.println("int " + registrationFunctionName + "(JNIEnv *_env)"); 613ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println("{"); 614ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println(indent + 615ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich "int err;"); 616ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 617ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println(indent + 618ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich "err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));"); 619ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 620ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println(indent + "return err;"); 621ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich cStream.println("}"); 622ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich } 623ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich 624ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich public JniCodeEmitter() { 625ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich super(); 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String getJniType(JType jType) { 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (jType.isVoid()) { 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return "void"; 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String baseType = jType.getBaseType(); 634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (jType.isPrimitive()) { 635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (baseType.equals("String")) { 636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return "jstring"; 637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 638edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return "j" + baseType; 639edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 640edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (jType.isArray()) { 641edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return "j" + baseType + "Array"; 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return "jobject"; 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 645edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 6466cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String getJniMangledName(String name) { 648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project name = name.replaceAll("_", "_1"); 649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project name = name.replaceAll(";", "_2"); 650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project name = name.replaceAll("\\[", "_3"); 651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return name; 652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project public void emitJniCode(JFunc jfunc, PrintStream out) { 655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CFunc cfunc = jfunc.getCFunc(); 6566cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit comment identifying original C function 658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Example: 660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // /* void glClipPlanef ( GLenum plane, const GLfloat *equation ) */ 662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println("/* " + cfunc.getOriginal() + " */"); 664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit JNI signature (name) 666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Example: 668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // void 670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // android_glClipPlanef__I_3FI 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String outName = "android_" + jfunc.getName(); 67466089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich boolean isPointerFunc = isPointerFunc(jfunc); 675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean isVBOPointerFunc = (outName.endsWith("Pointer") || 67666089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich outName.endsWith("PointerOES") || 677b3ffef9dfe43a0b33aef57b279ab0e8b98df6e8cJack Palevich outName.endsWith("DrawElements") || outName.endsWith("VertexAttribPointer")) && 678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project !jfunc.getCFunc().hasPointerArg(); 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isPointerFunc) { 680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outName += "Bounds"; 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print("static "); 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(getJniType(jfunc.getType())); 685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(outName); 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String rsignature = getJniName(jfunc.getType()); 688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String signature = ""; 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int numArgs = jfunc.getNumArgs(); 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < numArgs; i++) { 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project JType argType = jfunc.getArgType(i); 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signature += getJniName(argType); 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isPointerFunc) { 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signature += "I"; 697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Append signature to function name 70050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich String sig = getJniMangledName(signature).replace('.', '_').replace('/', '_'); 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print("__" + sig); 702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outName += "__" + sig; 7036cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project signature = signature.replace('.', '/'); 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsignature = rsignature.replace('.', '/'); 7066cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (rsignature.length() == 0) { 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsignature = "V"; 710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String s = "{\"" + 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getName() + 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (isPointerFunc ? "Bounds" : "") + 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "\", \"(" + signature +")" + 716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rsignature + 717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "\", (void *) " + 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outName + 719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " },"; 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nativeRegistrations.add(s); 721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project List<Integer> nonPrimitiveArgs = new ArrayList<Integer>(); 72350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich List<Integer> stringArgs = new ArrayList<Integer>(); 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int numBufferArgs = 0; 725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project List<String> bufferArgNames = new ArrayList<String>(); 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit JNI signature (arguments) 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Example: 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (JNIEnv *_env, jobject this, jint plane, jfloatArray equation_ref, jint offset) { 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(" (JNIEnv *_env, jobject _this"); 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < numArgs; i++) { 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(", "); 736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project JType argType = jfunc.getArgType(i); 737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String suffix; 738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!argType.isPrimitive()) { 739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (argType.isArray()) { 740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project suffix = "_ref"; 741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project suffix = "_buf"; 743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 744edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project nonPrimitiveArgs.add(new Integer(i)); 745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (jfunc.getArgType(i).isBuffer()) { 746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int cIndex = jfunc.getArgCIndex(i); 747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String cname = cfunc.getArgName(cIndex); 748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bufferArgNames.add(cname); 749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project numBufferArgs++; 750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project suffix = ""; 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 75450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (argType.isString()) { 75550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich stringArgs.add(new Integer(i)); 75650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(getJniType(argType) + " " + jfunc.getArgName(i) + suffix); 759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isPointerFunc) { 761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(", jint remaining"); 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(") {"); 7646cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int numArrays = 0; 766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int numBuffers = 0; 76750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int numStrings = 0; 768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < nonPrimitiveArgs.size(); i++) { 769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 77050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich JType argType = jfunc.getArgType(idx); 77150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (argType.isArray()) { 772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ++numArrays; 773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 77450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (argType.isBuffer()) { 775edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ++numBuffers; 776edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 77750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (argType.isString()) { 77850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich ++numStrings; 77950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit method body 783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit local variable declarations for _exception and _returnValue 785edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Example: 787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 788edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // android::gl::ogles_context_t *ctx; 7896cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich // 790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // jint _exception; 791edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // GLenum _returnValue; 792edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CType returnType = cfunc.getType(); 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean isVoid = returnType.isVoid(); 795edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project boolean isUnsupported = isUnsupportedFunc(cfunc); 797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isUnsupported) { 798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 7999875750593aae7c2a62f33c620809d49162393ebElliott Hughes "jniThrowException(_env, \"java/lang/UnsupportedOperationException\","); 800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " \"" + cfunc.getName() + "\");"); 802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!isVoid) { 803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String retval = getErrorReturnValue(cfunc); 804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "return " + retval + ";"); 805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println("}"); 807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 8109875750593aae7c2a62f33c620809d49162393ebElliott Hughes 811e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich String requiresExtension = isRequiresFunc(cfunc); 812e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich if (requiresExtension != null) { 813e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich out.println(indent + 814e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich "if (! supportsExtension(_env, _this, have_" + requiresExtension + "ID)) {"); 815e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich out.println(indent + indent + 8169875750593aae7c2a62f33c620809d49162393ebElliott Hughes "jniThrowException(_env, \"java/lang/UnsupportedOperationException\","); 817e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich out.println(indent + indent + 818e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich " \"" + cfunc.getName() + "\");"); 819e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich if (isVoid) { 820e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich out.println(indent + indent + " return;"); 821e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } else { 822e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich String retval = getErrorReturnValue(cfunc); 823e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich out.println(indent + indent + " return " + retval + ";"); 824e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } 825e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich out.println(indent + "}"); 826e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich } 827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mUseContextPointer) { 828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "android::gl::ogles_context_t *ctx = getContext(_env, _this);"); 830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 831edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 83250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich boolean initializeReturnValue = stringArgs.size() > 0; 83350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 83450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0 || numStrings > 0) && 835edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs); 836edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // mChecker.getChecks(cfunc.getName()) != null 837edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 838edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit an _exeption variable if there will be error checks 839edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (emitExceptionCheck) { 840edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "jint _exception = 0;"); 841edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 842edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 843edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit a single _array or multiple _XXXArray variables 844edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (numBufferArgs == 1) { 845edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "jarray _array = (jarray) 0;"); 846edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 847edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < numBufferArgs; i++) { 848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "jarray _" + bufferArgNames.get(i) + 849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "Array = (jarray) 0;"); 850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!isVoid) { 853edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String retval = getErrorReturnValue(cfunc); 854edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (retval != null) { 855edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + returnType.getDeclaration() + 856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " _returnValue = " + retval + ";"); 85750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } else if (initializeReturnValue) { 85850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + returnType.getDeclaration() + 85950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich " _returnValue = 0;"); 860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + returnType.getDeclaration() + 862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " _returnValue;"); 863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit local variable declarations for pointer arguments 867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Example: 869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // GLfixed *eqn_base; 871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // GLfixed *eqn; 872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // 873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String offset = "offset"; 874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String remaining = "_remaining"; 875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (nonPrimitiveArgs.size() > 0) { 876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < nonPrimitiveArgs.size(); i++) { 877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 878edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int cIndex = jfunc.getArgCIndex(idx); 879edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String cname = cfunc.getArgName(cIndex); 880edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CType type = cfunc.getArgType(jfunc.getArgCIndex(idx)); 882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String decl = type.getDeclaration(); 883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (jfunc.getArgType(idx).isArray()) { 884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project decl + 886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (decl.endsWith("*") ? "" : " ") + 887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getArgName(idx) + 888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_base = (" + decl + ") 0;"); 889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 89050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" : 891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_" + cname + "Remaining"; 892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "jint " + remaining + ";"); 894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project decl + 896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (decl.endsWith("*") ? "" : " ") + 8976cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich jfunc.getArgName(idx) + 898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " = (" + decl + ") 0;"); 899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 90450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich // Emit local variable declaration for strings 90550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (stringArgs.size() > 0) { 90650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich for (int i = 0; i < stringArgs.size(); i++) { 90750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int idx = stringArgs.get(i).intValue(); 90850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int cIndex = jfunc.getArgCIndex(idx); 90950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich String cname = cfunc.getArgName(cIndex); 91050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 91150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + "const char* _native" + cname + " = 0;"); 91250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 91350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 91450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(); 91550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 91650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 91750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich // Null pointer checks and GetStringUTFChars 91850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (stringArgs.size() > 0) { 91950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich for (int i = 0; i < stringArgs.size(); i++) { 92050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int idx = stringArgs.get(i).intValue(); 92150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int cIndex = jfunc.getArgCIndex(idx); 92250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich String cname = cfunc.getArgName(cIndex); 92350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 92450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich CType type = cfunc.getArgType(jfunc.getArgCIndex(idx)); 92550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich String decl = type.getDeclaration(); 92650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + "if (!" + cname + ") {"); 9279875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(indent + " jniThrowException(_env, " + 9289875750593aae7c2a62f33c620809d49162393ebElliott Hughes "\"java/lang/IllegalArgumentException\", \"" + cname + " == null\");"); 92950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + " goto exit;"); 93050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich needsExit = true; 93150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + "}"); 93250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 93350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + "_native" + cname + " = _env->GetStringUTFChars(" + cname + ", 0);"); 93450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 93550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 93650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(); 93750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 93850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 939edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit 'GetPrimitiveArrayCritical' for arrays 940edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Emit 'GetPointer' calls for Buffer pointers 941edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int bufArgIdx = 0; 942edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (nonPrimitiveArgs.size() > 0) { 943edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < nonPrimitiveArgs.size(); i++) { 944edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 945edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int cIndex = jfunc.getArgCIndex(idx); 9466cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 947edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String cname = cfunc.getArgName(cIndex); 948edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project offset = numArrays <= 1 ? "offset" : 949edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cname + "Offset"; 95050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" : 951edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_" + cname + "Remaining"; 952edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 953edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (jfunc.getArgType(idx).isArray()) { 954edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 9556cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich "if (!" + 956edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cname + 957edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_ref) {"); 958edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (emitExceptionCheck) { 959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + indent + "_exception = 1;"); 960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 9619875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(indent + " jniThrowException(_env, " + 9629875750593aae7c2a62f33c620809d49162393ebElliott Hughes "\"java/lang/IllegalArgumentException\", " + 9639875750593aae7c2a62f33c620809d49162393ebElliott Hughes "\"" + cname + " == null\");"); 964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + " goto exit;"); 965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project needsExit = true; 966edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "}"); 967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "if (" + offset + " < 0) {"); 969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (emitExceptionCheck) { 970edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + indent + "_exception = 1;"); 971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 9729875750593aae7c2a62f33c620809d49162393ebElliott Hughes out.println(indent + " jniThrowException(_env, " + 9739875750593aae7c2a62f33c620809d49162393ebElliott Hughes "\"java/lang/IllegalArgumentException\", \"" + offset + " < 0\");"); 974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + " goto exit;"); 975edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project needsExit = true; 976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "}"); 977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + remaining + " = " + 9796cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich (mUseCPlusPlus ? "_env" : "(*_env)") + 980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "->GetArrayLength(" + 981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (mUseCPlusPlus ? "" : "_env, ") + 982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cname + "_ref) - " + offset + ";"); 983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project emitNativeBoundsChecks(cfunc, cname, out, false, 985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project emitExceptionCheck, 986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project offset, remaining, " "); 987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cname + 990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_base = (" + 991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cfunc.getArgType(cIndex).getDeclaration() + 992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ")"); 993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + " " + 994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (mUseCPlusPlus ? "_env" : "(*_env)") + 995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "->GetPrimitiveArrayCritical(" + 9966cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich (mUseCPlusPlus ? "" : "_env, ") + 997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getArgName(idx) + 998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_ref, (jboolean *)0);"); 999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cname + " = " + cname + "_base + " + offset + 1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ";"); 1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String array = numBufferArgs <= 1 ? "_array" : 1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_" + bufferArgNames.get(bufArgIdx++) + "Array"; 1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 100746d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich boolean nullAllowed = isNullAllowed(cfunc) || isPointerFunc; 1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (nullAllowed) { 1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "if (" + cname + "_buf) {"); 1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(indent); 1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10126cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 101346d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich if (isPointerFunc) { 101446d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich out.println(indent + 1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cname + 1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project " = (" + 1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cfunc.getArgType(cIndex).getDeclaration() + 10186eedc8d3b598163f797a2f75d05fdc20809a4364Jack Palevich ") getDirectBufferPointer(_env, " + 101946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich cname + "_buf);"); 102046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich String iii = " "; 10215afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich out.println(iii + indent + "if ( ! " + cname + " ) {"); 102246d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich out.println(iii + iii + indent + "return;"); 102346d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich out.println(iii + indent + "}"); 102446d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich } else { 102546d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich out.println(indent + 102646d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich cname + 102746d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich " = (" + 102846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich cfunc.getArgType(cIndex).getDeclaration() + 102946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich ")getPointer(_env, " + 103046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich cname + 103146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich "_buf, &" + array + ", &" + remaining + 103246d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich ");"); 103346d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich } 1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10355afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich emitNativeBoundsChecks(cfunc, cname, out, true, 10365afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich emitExceptionCheck, 10375afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich offset, remaining, nullAllowed ? " " : " "); 10385afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich 1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (nullAllowed) { 1040edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "}"); 1041edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1042edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1046edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!isVoid) { 1047edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(indent + "_returnValue = "); 1048edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1049edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(indent); 1050edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1051edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String name = cfunc.getName(); 1052edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1053edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mUseContextPointer) { 1054edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project name = name.substring(2, name.length()); // Strip off 'gl' prefix 1055edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project name = name.substring(0, 1).toLowerCase() + 1056edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project name.substring(1, name.length()); 1057edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print("ctx->procs."); 1058edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 10596cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 1060edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(name + (isPointerFunc ? "Bounds" : "") + "("); 1061edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 10626cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich numArgs = cfunc.getNumArgs(); 1063edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (numArgs == 0) { 1064edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mUseContextPointer) { 1065edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println("ctx);"); 1066edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(");"); 1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mUseContextPointer) { 1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println("ctx,"); 1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = 0; i < numArgs; i++) { 1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String typecast; 1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i == numArgs - 1 && isVBOPointerFunc) { 1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project typecast = "const GLvoid *"; 1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project typecast = cfunc.getArgType(i).getDeclaration(); 1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.print(indent + indent + 1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "(" + 1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project typecast + 108550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich ")"); 108650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (cfunc.getArgType(i).isConstCharPointer()) { 108750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.print("_native"); 108850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 108950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.print(cfunc.getArgName(i)); 1090edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i == numArgs - 1) { 1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (isPointerFunc) { 1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(","); 1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + indent + "(GLsizei)remaining"); 1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(","); 1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + ");"); 1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (needsExit) { 1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println("exit:"); 1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project needsExit = false; 1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bufArgIdx = 0; 1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (nonPrimitiveArgs.size() > 0) { 1113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) { 1114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int idx = nonPrimitiveArgs.get(i).intValue(); 1115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int cIndex = jfunc.getArgCIndex(idx); 1117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (jfunc.getArgType(idx).isArray()) { 11186cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich 1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the argument is 'const', GL will not write to it. 1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // In this case, we can use the 'JNI_ABORT' flag to avoid 1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the need to write back to the Java array 1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + 1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "if (" + jfunc.getArgName(idx) + "_base) {"); 1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + indent + 1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (mUseCPlusPlus ? "_env" : "(*_env)") + 1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "->ReleasePrimitiveArrayCritical(" + 11276cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich (mUseCPlusPlus ? "" : "_env, ") + 1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project jfunc.getArgName(idx) + "_ref, " + 1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cfunc.getArgName(cIndex) + 1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_base,"); 1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + indent + indent + 1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (cfunc.getArgType(cIndex).isConst() ? 1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "JNI_ABORT" : 1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "_exception ? JNI_ABORT: 0") + 1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ");"); 1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "}"); 1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (jfunc.getArgType(idx).isBuffer()) { 113846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich if (! isPointerFunc) { 113946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich String array = numBufferArgs <= 1 ? "_array" : 114046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich "_" + bufferArgNames.get(bufArgIdx++) + "Array"; 114146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich out.println(indent + "if (" + array + ") {"); 114246d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich out.println(indent + indent + 114346d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich "releasePointer(_env, " + array + ", " + 114446d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich cfunc.getArgName(cIndex) + 114546d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich ", " + 114646d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich (cfunc.getArgType(cIndex).isConst() ? 114746d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich "JNI_FALSE" : "_exception ? JNI_FALSE :" + 114846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich " JNI_TRUE") + 114946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich ");"); 115046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich out.println(indent + "}"); 115146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich } 1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 115650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich // Emit local variable declaration for strings 115750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (stringArgs.size() > 0) { 115850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich for (int i = 0; i < stringArgs.size(); i++) { 115950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int idx = stringArgs.get(i).intValue(); 116050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int cIndex = jfunc.getArgCIndex(idx); 116150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich String cname = cfunc.getArgName(cIndex); 116250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 116350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + "if (_native" + cname + ") {"); 116450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + " _env->ReleaseStringUTFChars(" + cname + ", _native" + cname + ");"); 116550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(indent + "}"); 116650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 116750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 116850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich out.println(); 116950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 117050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 117150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 1172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!isVoid) { 1173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(indent + "return _returnValue;"); 1174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println("}"); 1177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project out.println(); 1178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 1181