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