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