JniCodeEmitter.java revision bd393b7f39a71a13893aea8b64474b0b07ebe0dd
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 {
6150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            throw new RuntimeException("Uknown 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                }
203ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                out.println(iii + indent +
204ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            (mUseCPlusPlus ? "_env" : "(*_env)") +
205ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            "->ThrowNew(" +
206ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            (mUseCPlusPlus ? "" : "_env, ") +
207ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            "IAEClass, " +
208ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            "\"" +
209ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            (isBuffer ?
210ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                             "remaining()" : "length - " + offset) +
211ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            " < needed\");");
212ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                out.println(iii + indent + "goto exit;");
213ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                needsExit = true;
214ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                out.println(iii + "}");
215ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich            }
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    boolean isNullAllowed(CFunc cfunc) {
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String[] checks = mChecker.getChecks(cfunc.getName());
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int index = 1;
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (checks != null) {
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            while (index < checks.length) {
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (checks[index].equals("return")) {
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 2;
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].startsWith("check")) {
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 3;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("ifcheck")) {
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 5;
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("unsupported")) {
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 1;
230e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else if (checks[index].equals("requires")) {
231e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    index += 2;
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("nullAllowed")) {
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return true;
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    System.out.println("Error: unknown keyword \"" +
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                       checks[index] + "\"");
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    System.exit(0);
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String getErrorReturnValue(CFunc cfunc) {
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        CType returnType = cfunc.getType();
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        boolean isVoid = returnType.isVoid();
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (isVoid) {
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return null;
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String[] checks = mChecker.getChecks(cfunc.getName());
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int index = 1;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (checks != null) {
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            while (index < checks.length) {
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (checks[index].equals("return")) {
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return checks[index + 1];
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].startsWith("check")) {
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 3;
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("ifcheck")) {
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 5;
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("unsupported")) {
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 1;
264e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else if (checks[index].equals("requires")) {
265e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    index += 2;
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("nullAllowed")) {
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 1;
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    System.out.println("Error: unknown keyword \"" +
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                       checks[index] + "\"");
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    System.exit(0);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return null;
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    boolean isUnsupportedFunc(CFunc cfunc) {
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String[] checks = mChecker.getChecks(cfunc.getName());
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int index = 1;
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (checks != null) {
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            while (index < checks.length) {
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (checks[index].equals("unsupported")) {
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return true;
286e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else if (checks[index].equals("requires")) {
287e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    index += 2;
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("return")) {
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 2;
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].startsWith("check")) {
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 3;
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("ifcheck")) {
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 5;
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (checks[index].equals("nullAllowed")) {
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    index += 1;
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    System.out.println("Error: unknown keyword \"" +
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                       checks[index] + "\"");
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    System.exit(0);
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
305e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich
306e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich    String isRequiresFunc(CFunc cfunc) {
307e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich        String[] checks = mChecker.getChecks(cfunc.getName());
308e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich        int index = 1;
309e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich        if (checks != null) {
310e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            while (index < checks.length) {
311e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                if (checks[index].equals("unsupported")) {
312e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    index += 1;
313e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else if (checks[index].equals("requires")) {
314e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    return checks[index+1];
315e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else if (checks[index].equals("return")) {
316e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    index += 2;
317e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else if (checks[index].startsWith("check")) {
318e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    index += 3;
319e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else if (checks[index].equals("ifcheck")) {
320e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    index += 5;
321e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else if (checks[index].equals("nullAllowed")) {
322e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    index += 1;
323e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                } else {
324e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    System.out.println("Error: unknown keyword \"" +
325e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                                       checks[index] + "\"");
326e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                    System.exit(0);
327e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                }
328e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            }
329e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich        }
330e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich        return null;
331e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich    }
332e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    void emitNativeBoundsChecks(CFunc cfunc, String cname, PrintStream out,
334ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich            boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) {
335ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
336ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                String[] checks = mChecker.getChecks(cfunc.getName());
337ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
338ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                boolean lastWasIfcheck = false;
339ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
340ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                int index = 1;
341ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                if (checks != null) {
342ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    while (index < checks.length) {
343ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        if (checks[index].startsWith("check")) {
344ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            if (lastWasIfcheck) {
345ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                printIfcheckPostamble(out, isBuffer, emitExceptionCheck,
346ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                                      offset, remaining, iii);
347ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            }
348ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            lastWasIfcheck = false;
349ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            if (cname != null && !cname.equals(checks[index + 1])) {
350ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                index += 3;
351ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                continue;
352ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            }
353ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            out.println(iii + "if (" + remaining + " < " +
354ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        checks[index + 2] +
355ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        ") {");
356ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            if (emitExceptionCheck) {
357ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                out.println(iii + indent + "_exception = 1;");
358ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            }
359ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    String exceptionClassName = "IAEClass";
360ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    // If the "check" keyword was of the form
361ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    // "check_<class name>", use the class name in the
362ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    // exception to be thrown
363ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    int underscore = checks[index].indexOf('_');
364ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    if (underscore >= 0) {
365ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    exceptionClassName = checks[index].substring(underscore + 1) + "Class";
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
367ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            out.println(iii + indent +
368ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        (mUseCPlusPlus ? "_env" : "(*_env)") +
369ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        "->ThrowNew(" +
370ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        (mUseCPlusPlus ? "" : "_env, ") +
371ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        exceptionClassName + ", " +
372ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        "\"" +
373ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        (isBuffer ?
374ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                         "remaining()" : "length - " + offset) +
375ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        " < " + checks[index + 2] +
376ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        "\");");
377ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
378ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            out.println(iii + indent + "goto exit;");
379ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            needsExit = true;
380ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            out.println(iii + "}");
381ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
382ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            index += 3;
383ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        } else if (checks[index].equals("ifcheck")) {
384ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            String[] matches = checks[index + 4].split(",");
385ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
386ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            if (!lastWasIfcheck) {
387ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                out.println(iii + "int _needed;");
388ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                out.println(iii +
389ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                            "switch (" +
390ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                            checks[index + 3] +
391ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                            ") {");
392ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            }
393ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
394ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            for (int i = 0; i < matches.length; i++) {
395ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                out.println("#if defined(" + matches[i] + ")");
396ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                out.println(iii +
397ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                            "    case " +
398ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                            matches[i] +
399ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                            ":");
400ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                out.println("#endif // defined(" + matches[i] + ")");
401ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            }
402ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            out.println(iii +
403ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        "        _needed = " +
404ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        checks[index + 2] +
405ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        ";");
406ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            out.println(iii +
407ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                        "        break;");
408ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
409ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            lastWasIfcheck = true;
410ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            index += 5;
411ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        } else if (checks[index].equals("return")) {
412ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            // ignore
413ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            index += 2;
414ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        } else if (checks[index].equals("unsupported")) {
415ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            // ignore
416ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            index += 1;
417e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                        } else if (checks[index].equals("requires")) {
418e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                            // ignore
419e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                            index += 2;
420ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        } else if (checks[index].equals("nullAllowed")) {
421ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            // ignore
422ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            index += 1;
423ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        } else {
424ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            System.out.println("Error: unknown keyword \"" +
425ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                                               checks[index] + "\"");
426ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                            System.exit(0);
427ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        }
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
429ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                }
4306cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
431ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                if (lastWasIfcheck) {
432ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                    printIfcheckPostamble(out, isBuffer, emitExceptionCheck, iii);
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
436ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich    boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, List<Integer> nonPrimitiveArgs) {
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (nonPrimitiveArgs.size() > 0) {
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int idx = nonPrimitiveArgs.get(i).intValue();
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int cIndex = jfunc.getArgCIndex(idx);
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (jfunc.getArgType(idx).isArray()) {
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (!cfunc.getArgType(cIndex).isConst()) {
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        return true;
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (jfunc.getArgType(idx).isBuffer()) {
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (!cfunc.getArgType(cIndex).isConst()) {
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        return true;
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return false;
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
4556cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /**
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Emit a function in several variants:
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * if nativeDecl: public native <returntype> func(args);
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * if !nativeDecl:
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *   if interfaceDecl:  public <returntype> func(args);
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     *   if !interfaceDecl: public <returntype> func(args) { body }
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
465ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich    void emitFunction(JFunc jfunc, PrintStream out, boolean nativeDecl, boolean interfaceDecl) {
46666089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich        boolean isPointerFunc = isPointerFunc(jfunc);
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!nativeDecl && !interfaceDecl && !isPointerFunc) {
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // If it's not a pointer function, we've already emitted it
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // with nativeDecl == true
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return;
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
474427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich        String maybeStatic = mUseStaticMethods ? "static " : "";
475427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (isPointerFunc) {
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent +
478427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich                        (nativeDecl ? "private " + maybeStatic +"native " :
479427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich                         (interfaceDecl ? "" : "public ") + maybeStatic) +
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        jfunc.getType() + " " +
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        jfunc.getName() +
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        (nativeDecl ? "Bounds" : "") +
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "(");
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent +
486427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich                        (nativeDecl ? "public " + maybeStatic +"native " :
487427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich                         (interfaceDecl ? "" : "public ") + maybeStatic) +
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        jfunc.getType() + " " +
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        jfunc.getName() +
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "(");
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
4926cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int numArgs = jfunc.getNumArgs();
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i = 0; i < numArgs; i++) {
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            String argName = jfunc.getArgName(i);
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            JType argType = jfunc.getArgType(i);
4976cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.print(indent + indent + argType + " " + argName);
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (i == numArgs - 1) {
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (isPointerFunc && nativeDecl) {
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(",");
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + indent + "int remaining");
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println();
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(",");
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (nativeDecl || interfaceDecl) {
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent + ");");
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent + ") {");
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            String iii = indent + indent;
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich            // emitBoundsChecks(jfunc, out, iii);
51946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich            emitFunctionCall(jfunc, out, iii, false);
52046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich
52146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich            // Set the pointer after we call the native code, so that if
52246d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich            // the native code throws an exception we don't modify the
52346d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich            // pointer. We assume that the native code is written so that
52446d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich            // if an exception is thrown, then the underlying glXXXPointer
52546d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich            // function will not have been called.
52646d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            String fname = jfunc.getName();
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (isPointerFunc) {
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // TODO - deal with VBO variants
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (fname.equals("glColorPointer")) {
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "if ((size == 4) &&");
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "    ((type == GL_FLOAT) ||");
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_UNSIGNED_BYTE) ||");
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_FIXED)) &&");
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "    (stride >= 0)) {");
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + indent + "_colorPointer = pointer;");
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "}");
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (fname.equals("glNormalPointer")) {
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "if (((type == GL_FLOAT) ||");
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_BYTE) ||");
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_SHORT) ||");
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_FIXED)) &&");
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "    (stride >= 0)) {");
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + indent + "_normalPointer = pointer;");
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "}");
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (fname.equals("glTexCoordPointer")) {
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "if (((size == 2) ||");
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (size == 3) ||");
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (size == 4)) &&");
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "    ((type == GL_FLOAT) ||");
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_BYTE) ||");
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_SHORT) ||");
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_FIXED)) &&");
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "    (stride >= 0)) {");
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + indent + "_texCoordPointer = pointer;");
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "}");
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (fname.equals("glVertexPointer")) {
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "if (((size == 2) ||");
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (size == 3) ||");
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (size == 4)) &&");
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "    ((type == GL_FLOAT) ||");
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_BYTE) ||");
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_SHORT) ||");
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "     (type == GL_FIXED)) &&");
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "    (stride >= 0)) {");
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + indent + "_vertexPointer = pointer;");
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(iii + "}");
56866089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                } else if (fname.equals("glPointSizePointerOES")) {
56966089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "if (((type == GL_FLOAT) ||");
57066089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (type == GL_FIXED)) &&");
57166089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "    (stride >= 0)) {");
57266089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + indent + "_pointSizePointerOES = pointer;");
57366089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "}");
57466089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                } else if (fname.equals("glMatrixIndexPointerOES")) {
57566089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "if (((size == 2) ||");
57666089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (size == 3) ||");
57766089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (size == 4)) &&");
57866089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "    ((type == GL_FLOAT) ||");
57966089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (type == GL_BYTE) ||");
58066089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (type == GL_SHORT) ||");
58166089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (type == GL_FIXED)) &&");
58266089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "    (stride >= 0)) {");
58366089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + indent + "_matrixIndexPointerOES = pointer;");
58466089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "}");
58566089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                } else if (fname.equals("glWeightPointer")) {
58666089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "if (((size == 2) ||");
58766089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (size == 3) ||");
58866089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (size == 4)) &&");
58966089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "    ((type == GL_FLOAT) ||");
59066089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (type == GL_BYTE) ||");
59166089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (type == GL_SHORT) ||");
59266089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "     (type == GL_FIXED)) &&");
59366089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "    (stride >= 0)) {");
59466089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + indent + "_weightPointerOES = pointer;");
59566089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                    out.println(iii + "}");
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            boolean isVoid = jfunc.getType().isVoid();
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!isVoid) {
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(indent + indent + "return _returnValue;");
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent + "}");
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.println();
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
609ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich    public void addNativeRegistration(String s) {
610ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        nativeRegistrations.add(s);
611ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich    }
6126cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
613427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich    public void emitNativeRegistration(String registrationFunctionName,
614427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich            PrintStream cStream) {
615ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println("static const char *classPathName = \"" +
616ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        mClassPathName +
617ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        "\";");
618ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println();
619ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
620ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println("static JNINativeMethod methods[] = {");
621ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
622ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println("{\"_nativeClassInit\", \"()V\", (void*)nativeClassInit },");
623ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
624ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        Iterator<String> i = nativeRegistrations.iterator();
625ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        while (i.hasNext()) {
626ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich            cStream.println(i.next());
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
628ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
629ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println("};");
630ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println();
631ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
632ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
633427f585f726af6e3bd1fb835f26b2af9f609c483Jack Palevich        cStream.println("int " + registrationFunctionName + "(JNIEnv *_env)");
634ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println("{");
635ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println(indent +
636ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        "int err;");
637ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
638ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println(indent +
639ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich                        "err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));");
640ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
641ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println(indent + "return err;");
642ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        cStream.println("}");
643ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich    }
644ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich
645ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich    public JniCodeEmitter() {
646ffac1eff58b59ffdaca1c4a296fa7dead51c487bJack Palevich        super();
647edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String getJniType(JType jType) {
650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (jType.isVoid()) {
651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return "void";
652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
653edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
654edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String baseType = jType.getBaseType();
655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (jType.isPrimitive()) {
656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (baseType.equals("String")) {
657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return "jstring";
658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                return "j" + baseType;
660edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
661edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else if (jType.isArray()) {
662edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return "j" + baseType + "Array";
663edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return "jobject";
665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
6676cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    String getJniMangledName(String name) {
669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        name = name.replaceAll("_", "_1");
670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        name = name.replaceAll(";", "_2");
671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        name = name.replaceAll("\\[", "_3");
672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return name;
673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    public void emitJniCode(JFunc jfunc, PrintStream out) {
676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        CFunc cfunc = jfunc.getCFunc();
6776cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit comment identifying original C function
679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Example:
681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // /* void glClipPlanef ( GLenum plane, const GLfloat *equation ) */
683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.println("/* " + cfunc.getOriginal() + " */");
685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit JNI signature (name)
687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Example:
689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // void
691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // android_glClipPlanef__I_3FI
692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String outName = "android_" + jfunc.getName();
69566089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich        boolean isPointerFunc = isPointerFunc(jfunc);
696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        boolean isVBOPointerFunc = (outName.endsWith("Pointer") ||
69766089a33ea4efda711a3a5180f0b001bdac48dcfJack Palevich                outName.endsWith("PointerOES") ||
698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            outName.endsWith("DrawElements")) &&
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            !jfunc.getCFunc().hasPointerArg();
700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (isPointerFunc) {
701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            outName += "Bounds";
702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.print("static ");
705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.println(getJniType(jfunc.getType()));
706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.print(outName);
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String rsignature = getJniName(jfunc.getType());
709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String signature = "";
711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int numArgs = jfunc.getNumArgs();
712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i = 0; i < numArgs; i++) {
713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            JType argType = jfunc.getArgType(i);
714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            signature += getJniName(argType);
715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (isPointerFunc) {
717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            signature += "I";
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Append signature to function name
72150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        String sig = getJniMangledName(signature).replace('.', '_').replace('/', '_');
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.print("__" + sig);
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        outName += "__" + sig;
7246cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        signature = signature.replace('.', '/');
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        rsignature = rsignature.replace('.', '/');
7276cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.println();
729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (rsignature.length() == 0) {
730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            rsignature = "V";
731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
733edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String s = "{\"" +
734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            jfunc.getName() +
735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (isPointerFunc ? "Bounds" : "") +
736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "\", \"(" + signature +")" +
737edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            rsignature +
738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            "\", (void *) " +
739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            outName +
740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            " },";
741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        nativeRegistrations.add(s);
742edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
743edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        List<Integer> nonPrimitiveArgs = new ArrayList<Integer>();
74450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        List<Integer> stringArgs = new ArrayList<Integer>();
745edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int numBufferArgs = 0;
746edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        List<String> bufferArgNames = new ArrayList<String>();
747edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit JNI signature (arguments)
749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Example:
751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // (JNIEnv *_env, jobject this, jint plane, jfloatArray equation_ref, jint offset) {
753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.print("  (JNIEnv *_env, jobject _this");
755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i = 0; i < numArgs; i++) {
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.print(", ");
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            JType argType = jfunc.getArgType(i);
758edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            String suffix;
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!argType.isPrimitive()) {
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (argType.isArray()) {
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    suffix = "_ref";
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    suffix = "_buf";
764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
765edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                nonPrimitiveArgs.add(new Integer(i));
766edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (jfunc.getArgType(i).isBuffer()) {
767edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int cIndex = jfunc.getArgCIndex(i);
768edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    String cname = cfunc.getArgName(cIndex);
769edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    bufferArgNames.add(cname);
770edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    numBufferArgs++;
771edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
772edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
773edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                suffix = "";
774edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
77550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            if (argType.isString()) {
77650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                stringArgs.add(new Integer(i));
77750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            }
778edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
779edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.print(getJniType(argType) + " " + jfunc.getArgName(i) + suffix);
780edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
781edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (isPointerFunc) {
782edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.print(", jint remaining");
783edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
784edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.println(") {");
7856cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
786edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int numArrays = 0;
787edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int numBuffers = 0;
78850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        int numStrings = 0;
789edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
790edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            int idx = nonPrimitiveArgs.get(i).intValue();
79150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            JType argType = jfunc.getArgType(idx);
79250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            if (argType.isArray()) {
793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ++numArrays;
794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
79550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            if (argType.isBuffer()) {
796edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                ++numBuffers;
797edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
79850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            if (argType.isString()) {
79950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                ++numStrings;
80050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            }
801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
802edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
803edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit method body
804edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
805edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit local variable declarations for _exception and _returnValue
806edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
807edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Example:
808edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
809edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // android::gl::ogles_context_t *ctx;
8106cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich        //
811edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // jint _exception;
812edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // GLenum _returnValue;
813edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
814edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        CType returnType = cfunc.getType();
815edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        boolean isVoid = returnType.isVoid();
816edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
817edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        boolean isUnsupported = isUnsupportedFunc(cfunc);
818edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (isUnsupported) {
819edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent +
820edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "_env->ThrowNew(UOEClass,");
821edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent +
822edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "    \"" + cfunc.getName() + "\");");
823edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!isVoid) {
824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                String retval = getErrorReturnValue(cfunc);
825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(indent + "return " + retval + ";");
826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println("}");
828edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println();
829edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return;
830edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
831e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich
832e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich        String requiresExtension = isRequiresFunc(cfunc);
833e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich        if (requiresExtension != null) {
834e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            out.println(indent +
835e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                        "if (! supportsExtension(_env, _this, have_" + requiresExtension + "ID)) {");
836e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            out.println(indent + indent +
837e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                        "_env->ThrowNew(UOEClass,");
838e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            out.println(indent + indent +
839e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                        "    \"" + cfunc.getName() + "\");");
840e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            if (isVoid) {
841e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                out.println(indent + indent + "    return;");
842e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            } else {
843e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                String retval = getErrorReturnValue(cfunc);
844e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich                out.println(indent + indent + "    return " + retval + ";");
845e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            }
846e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich            out.println(indent + "}");
847e44e45c454a1f6ab89bce338d4ef12471549a7a2Jack Palevich        }
848edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mUseContextPointer) {
849edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent +
850edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                "android::gl::ogles_context_t *ctx = getContext(_env, _this);");
851edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
852edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        boolean initializeReturnValue = stringArgs.size() > 0;
85450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
85550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0 || numStrings > 0) &&
856edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs);
857edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // mChecker.getChecks(cfunc.getName()) != null
858edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
859edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit an _exeption variable if there will be error checks
860edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (emitExceptionCheck) {
861edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent + "jint _exception = 0;");
862edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
863edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
864edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit a single _array or multiple _XXXArray variables
865edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (numBufferArgs == 1) {
866edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(indent + "jarray _array = (jarray) 0;");
867edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
868edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int i = 0; i < numBufferArgs; i++) {
869edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(indent + "jarray _" + bufferArgNames.get(i) +
870edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            "Array = (jarray) 0;");
871edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
872edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
873edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!isVoid) {
874edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            String retval = getErrorReturnValue(cfunc);
875edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (retval != null) {
876edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(indent + returnType.getDeclaration() +
877edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            " _returnValue = " + retval + ";");
87850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            } else if (initializeReturnValue) {
87950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + returnType.getDeclaration() +
88050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                " _returnValue = 0;");
881edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
882edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(indent + returnType.getDeclaration() +
883edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            " _returnValue;");
884edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
885edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
886edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
887edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit local variable declarations for pointer arguments
888edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
889edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Example:
890edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
891edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // GLfixed *eqn_base;
892edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // GLfixed *eqn;
893edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //
894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String offset = "offset";
895edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String remaining = "_remaining";
896edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (nonPrimitiveArgs.size() > 0) {
897edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
898edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int idx = nonPrimitiveArgs.get(i).intValue();
899edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int cIndex = jfunc.getArgCIndex(idx);
900edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                String cname = cfunc.getArgName(cIndex);
901edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
903edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                String decl = type.getDeclaration();
904edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (jfunc.getArgType(idx).isArray()) {
905edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent +
906edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                decl +
907edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                (decl.endsWith("*") ? "" : " ") +
908edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                jfunc.getArgName(idx) +
909edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "_base = (" + decl + ") 0;");
910edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
91150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
912edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "_" + cname + "Remaining";
913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(indent +
914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            "jint " + remaining + ";");
915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(indent +
916edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            decl +
917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            (decl.endsWith("*") ? "" : " ") +
9186cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich                            jfunc.getArgName(idx) +
919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            " = (" + decl + ") 0;");
920edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
921edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
922edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println();
923edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
924edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
92550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        // Emit local variable declaration for strings
92650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        if (stringArgs.size() > 0) {
92750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            for (int i = 0; i < stringArgs.size(); i++) {
92850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                int idx = stringArgs.get(i).intValue();
92950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                int cIndex = jfunc.getArgCIndex(idx);
93050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                String cname = cfunc.getArgName(cIndex);
93150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
93250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "const char* _native" + cname + " = 0;");
93350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            }
93450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
93550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            out.println();
93650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        }
93750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
93850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        // Null pointer checks and GetStringUTFChars
93950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        if (stringArgs.size() > 0) {
94050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            for (int i = 0; i < stringArgs.size(); i++) {
94150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                int idx = stringArgs.get(i).intValue();
94250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                int cIndex = jfunc.getArgCIndex(idx);
94350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                String cname = cfunc.getArgName(cIndex);
94450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
94550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
94650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                String decl = type.getDeclaration();
94750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "if (!" + cname + ") {");
94850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "    _env->ThrowNew(IAEClass, \"" + cname + " == null\");");
94950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "    goto exit;");
95050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                needsExit = true;
95150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "}");
95250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
95350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "_native" + cname + " = _env->GetStringUTFChars(" + cname + ", 0);");
95450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            }
95550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
95650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            out.println();
95750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        }
95850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
959edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit 'GetPrimitiveArrayCritical' for arrays
960edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // Emit 'GetPointer' calls for Buffer pointers
961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int bufArgIdx = 0;
962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (nonPrimitiveArgs.size() > 0) {
963edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int idx = nonPrimitiveArgs.get(i).intValue();
965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int cIndex = jfunc.getArgCIndex(idx);
9666cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
967edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                String cname = cfunc.getArgName(cIndex);
968edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                offset = numArrays <= 1 ? "offset" :
969edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    cname + "Offset";
97050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
971edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    "_" + cname + "Remaining";
972edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
973edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (jfunc.getArgType(idx).isArray()) {
974edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent +
9756cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich                                "if (!" +
976edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                cname +
977edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "_ref) {");
978edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (emitExceptionCheck) {
979edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        out.println(indent + indent + "_exception = 1;");
980edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
981edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "    " +
982edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                (mUseCPlusPlus ? "_env" : "(*_env)") +
983edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "->ThrowNew(" +
984edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                (mUseCPlusPlus ? "" : "_env, ") +
985edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "IAEClass, " +
986edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "\"" + cname +
987edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                " == null\");");
988edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "    goto exit;");
989edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    needsExit = true;
990edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "}");
991edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
992edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "if (" + offset + " < 0) {");
993edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (emitExceptionCheck) {
994edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        out.println(indent + indent + "_exception = 1;");
995edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
996edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "    " +
997edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                (mUseCPlusPlus ? "_env" : "(*_env)") +
998edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "->ThrowNew(" +
999edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                (mUseCPlusPlus ? "" : "_env, ") +
1000edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "IAEClass, " +
1001edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "\"" + offset + " < 0\");");
1002edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "    goto exit;");
1003edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    needsExit = true;
1004edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "}");
1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + remaining + " = " +
10076cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich                                    (mUseCPlusPlus ? "_env" : "(*_env)") +
1008edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                    "->GetArrayLength(" +
1009edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                    (mUseCPlusPlus ? "" : "_env, ") +
1010edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                    cname + "_ref) - " + offset + ";");
1011edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1012edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    emitNativeBoundsChecks(cfunc, cname, out, false,
1013edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                           emitExceptionCheck,
1014edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                           offset, remaining, "    ");
1015edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1016edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent +
1017edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                cname +
1018edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "_base = (" +
1019edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                cfunc.getArgType(cIndex).getDeclaration() +
1020edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                ")");
1021edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "    " +
1022edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                (mUseCPlusPlus ? "_env" : "(*_env)") +
1023edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "->GetPrimitiveArrayCritical(" +
10246cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich                                (mUseCPlusPlus ? "" : "_env, ") +
1025edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                jfunc.getArgName(idx) +
1026edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "_ref, (jboolean *)0);");
1027edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent +
1028edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                cname + " = " + cname + "_base + " + offset +
1029edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                ";");
1030edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println();
1031edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
1032edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    String array = numBufferArgs <= 1 ? "_array" :
1033edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        "_" + bufferArgNames.get(bufArgIdx++) + "Array";
1034edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
103546d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                    boolean nullAllowed = isNullAllowed(cfunc) || isPointerFunc;
1036edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (nullAllowed) {
1037edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        out.println(indent + "if (" + cname + "_buf) {");
1038edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        out.print(indent);
1039edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
10406cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
104146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                    if (isPointerFunc) {
104246d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        out.println(indent +
1043edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                cname +
1044edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                " = (" +
1045edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                cfunc.getArgType(cIndex).getDeclaration() +
10466eedc8d3b598163f797a2f75d05fdc20809a4364Jack Palevich                                ") getDirectBufferPointer(_env, " +
104746d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                cname + "_buf);");
104846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        String iii = "    ";
10495afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich                        out.println(iii + indent + "if ( ! " + cname + " ) {");
105046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        out.println(iii + iii + indent + "return;");
105146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        out.println(iii + indent + "}");
105246d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                    } else {
105346d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        out.println(indent +
105446d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    cname +
105546d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    " = (" +
105646d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    cfunc.getArgType(cIndex).getDeclaration() +
105746d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    ")getPointer(_env, " +
105846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    cname +
105946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    "_buf, &" + array + ", &" + remaining +
106046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    ");");
106146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                    }
1062edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10635afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich                    emitNativeBoundsChecks(cfunc, cname, out, true,
10645afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich                                           emitExceptionCheck,
10655afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich                                           offset, remaining, nullAllowed ? "        " : "    ");
10665afdc87704f82cb6c3576695dd157b65ae6f3d33Jack Palevich
1067edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (nullAllowed) {
1068edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        out.println(indent + "}");
1069edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
1070edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1071edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1072edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1073edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1074edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!isVoid) {
1075edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.print(indent + "_returnValue = ");
1076edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1077edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.print(indent);
1078edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1079edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        String name = cfunc.getName();
1080edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1081edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (mUseContextPointer) {
1082edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            name = name.substring(2, name.length()); // Strip off 'gl' prefix
1083edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            name = name.substring(0, 1).toLowerCase() +
1084edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                name.substring(1, name.length());
1085edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.print("ctx->procs.");
1086edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
10876cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
1088edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.print(name + (isPointerFunc ? "Bounds" : "") + "(");
1089edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
10906cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich        numArgs = cfunc.getNumArgs();
1091edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (numArgs == 0) {
1092edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (mUseContextPointer) {
1093edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println("ctx);");
1094edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
1095edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println(");");
1096edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1097edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
1098edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (mUseContextPointer) {
1099edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println("ctx,");
1100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
1101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.println();
1102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int i = 0; i < numArgs; i++) {
1104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                String typecast;
1105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (i == numArgs - 1 && isVBOPointerFunc) {
1106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    typecast = "const GLvoid *";
1107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
1108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    typecast = cfunc.getArgType(i).getDeclaration();
1109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                out.print(indent + indent +
1111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                          "(" +
1112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                          typecast +
111350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                          ")");
111450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                if (cfunc.getArgType(i).isConstCharPointer()) {
111550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                    out.print("_native");
111650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                }
111750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.print(cfunc.getArgName(i));
1118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (i == numArgs - 1) {
1120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (isPointerFunc) {
1121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        out.println(",");
1122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        out.println(indent + indent + "(GLsizei)remaining");
1123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    } else {
1124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        out.println();
1125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
1126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
1127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(",");
1128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent + ");");
1131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (needsExit) {
1134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println();
1135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println("exit:");
1136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            needsExit = false;
1137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        bufArgIdx = 0;
1140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (nonPrimitiveArgs.size() > 0) {
1141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
1142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int idx = nonPrimitiveArgs.get(i).intValue();
1143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int cIndex = jfunc.getArgCIndex(idx);
1145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (jfunc.getArgType(idx).isArray()) {
11466cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich
1147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // If the argument is 'const', GL will not write to it.
1148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // In this case, we can use the 'JNI_ABORT' flag to avoid
1149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // the need to write back to the Java array
1150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent +
1151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "if (" + jfunc.getArgName(idx) + "_base) {");
1152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + indent +
1153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                (mUseCPlusPlus ? "_env" : "(*_env)") +
1154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "->ReleasePrimitiveArrayCritical(" +
11556cbca50b6a438151a6c5f4dbdccc7057c19b73faJack Palevich                                (mUseCPlusPlus ? "" : "_env, ") +
1156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                jfunc.getArgName(idx) + "_ref, " +
1157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                cfunc.getArgName(cIndex) +
1158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                "_base,");
1159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + indent + indent +
1160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                (cfunc.getArgType(cIndex).isConst() ?
1161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                 "JNI_ABORT" :
1162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                 "_exception ? JNI_ABORT: 0") +
1163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                                ");");
1164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    out.println(indent + "}");
1165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (jfunc.getArgType(idx).isBuffer()) {
116646d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                    if (! isPointerFunc) {
116746d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        String array = numBufferArgs <= 1 ? "_array" :
116846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                            "_" + bufferArgNames.get(bufArgIdx++) + "Array";
116946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        out.println(indent + "if (" + array + ") {");
117046d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        out.println(indent + indent +
117146d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    "releasePointer(_env, " + array + ", " +
117246d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    cfunc.getArgName(cIndex) +
117346d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    ", " +
117446d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    (cfunc.getArgType(cIndex).isConst() ?
117546d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                     "JNI_FALSE" : "_exception ? JNI_FALSE :" +
117646d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                             " JNI_TRUE") +
117746d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                                    ");");
117846d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                        out.println(indent + "}");
117946d25a371d58c63cbd72f5d08348e9b75c2ac22cJack Palevich                    }
1180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
1181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
1182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
118450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        // Emit local variable declaration for strings
118550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        if (stringArgs.size() > 0) {
118650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            for (int i = 0; i < stringArgs.size(); i++) {
118750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                int idx = stringArgs.get(i).intValue();
118850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                int cIndex = jfunc.getArgCIndex(idx);
118950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                String cname = cfunc.getArgName(cIndex);
119050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
119150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "if (_native" + cname + ") {");
119250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "    _env->ReleaseStringUTFChars(" + cname + ", _native" + cname + ");");
119350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich                out.println(indent + "}");
119450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            }
119550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
119650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich            out.println();
119750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich        }
119850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
119950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich
1200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!isVoid) {
1201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            out.println(indent + "return _returnValue;");
1202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
1203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.println("}");
1205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        out.println();
1206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
1209