169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.expr;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.*;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.*;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.compiler.*;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.compiler.ast.ASTList;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Array creation.
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This class does not provide methods for obtaining the initial
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * values of array elements.
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class NewArray extends Expr {
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    int opcode;
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected NewArray(int pos, CodeIterator i, CtClass declaring,
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                       MethodInfo m, int op) {
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        super(pos, i, declaring, m);
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        opcode = op;
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the method or constructor containing the array creation
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * represented by this object.
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtBehavior where() { return super.where(); }
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the line number of the source line containing the
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * array creation.
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return -1       if this information is not available.
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public int getLineNumber() {
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return super.getLineNumber();
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the source file containing the array creation.
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return null     if this information is not available.
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public String getFileName() {
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return super.getFileName();
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the list of exceptions that the expression may throw.
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This list includes both the exceptions that the try-catch statements
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * including the expression can catch and the exceptions that
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the throws declaration allows the method to throw.
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass[] mayThrow() {
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return super.mayThrow();
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the type of array components.  If the created array is
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * a two-dimensional array of <tt>int</tt>,
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the type returned by this method is
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * not <tt>int[]</tt> but <tt>int</tt>.
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass getComponentType() throws NotFoundException {
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode == Opcode.NEWARRAY) {
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int atype = iterator.byteAt(currentPos + 1);
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return getPrimitiveType(atype);
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (opcode == Opcode.ANEWARRAY
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                 || opcode == Opcode.MULTIANEWARRAY) {
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int index = iterator.u16bitAt(currentPos + 1);
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String desc = getConstPool().getClassInfo(index);
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int dim = Descriptor.arrayDimension(desc);
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            desc = Descriptor.toArrayComponent(desc, dim);
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return Descriptor.toCtClass(desc, thisClass.getClassPool());
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("bad opcode: " + opcode);
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    CtClass getPrimitiveType(int atype) {
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (atype) {
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_BOOLEAN :
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CtClass.booleanType;
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_CHAR :
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CtClass.charType;
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_FLOAT :
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CtClass.floatType;
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_DOUBLE :
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CtClass.doubleType;
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_BYTE :
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CtClass.byteType;
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_SHORT :
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CtClass.shortType;
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_INT :
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CtClass.intType;
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case Opcode.T_LONG :
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return CtClass.longType;
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        default :
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("bad atype: " + atype);
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the dimension of the created array.
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public int getDimension() {
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode == Opcode.NEWARRAY)
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 1;
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (opcode == Opcode.ANEWARRAY
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                 || opcode == Opcode.MULTIANEWARRAY) {
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int index = iterator.u16bitAt(currentPos + 1);
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String desc = getConstPool().getClassInfo(index);
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return Descriptor.arrayDimension(desc)
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    + (opcode == Opcode.ANEWARRAY ? 1 : 0);
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("bad opcode: " + opcode);
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the number of dimensions of arrays to be created.
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If the opcode is multianewarray, this method returns the second
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * operand.  Otherwise, it returns 1.
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public int getCreatedDimensions() {
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode == Opcode.MULTIANEWARRAY)
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return iterator.byteAt(currentPos + 3);
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return 1;
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Replaces the array creation with the bytecode derived from
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the given source text.
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>$0 is available even if the called method is static.
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If the field access is writing, $_ is available but the value
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * of $_ is ignored.
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param statement         a Java statement except try-catch.
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void replace(String statement) throws CannotCompileException {
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            replace2(statement);
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (CompileError e) { throw new CannotCompileException(e); }
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (NotFoundException e) { throw new CannotCompileException(e); }
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (BadBytecode e) {
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new CannotCompileException("broken method");
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void replace2(String statement)
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CompileError, NotFoundException, BadBytecode,
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal               CannotCompileException
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        thisClass.getClassFile();   // to call checkModify().
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ConstPool constPool = getConstPool();
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int pos = currentPos;
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass retType;
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int codeLength;
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index = 0;
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int dim = 1;
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String desc;
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (opcode == Opcode.NEWARRAY) {
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            index = iterator.byteAt(currentPos + 1);    // atype
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            CtPrimitiveType cpt = (CtPrimitiveType)getPrimitiveType(index);
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            desc = "[" + cpt.getDescriptor();
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            codeLength = 2;
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (opcode == Opcode.ANEWARRAY) {
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            index = iterator.u16bitAt(pos + 1);
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            desc = constPool.getClassInfo(index);
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (desc.startsWith("["))
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                desc = "[" + desc;
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                desc = "[L" + desc + ";";
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            codeLength = 3;
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else if (opcode == Opcode.MULTIANEWARRAY) {
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            index = iterator.u16bitAt(currentPos + 1);
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            desc = constPool.getClassInfo(index);
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            dim = iterator.byteAt(currentPos + 3);
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            codeLength = 4;
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("bad opcode: " + opcode);
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        retType = Descriptor.toCtClass(desc, thisClass.getClassPool());
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Javac jc = new Javac(thisClass);
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CodeAttribute ca = iterator.get();
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass[] params = new CtClass[dim];
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int i = 0; i < dim; ++i)
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            params[i] = CtClass.intType;
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int paramVar = ca.getMaxLocals();
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        jc.recordParams(javaLangObject, params,
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        true, paramVar, withinStatic());
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        /* Is $_ included in the source code?
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         */
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        checkResultValue(retType, statement);
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int retVar = jc.recordReturnType(retType, true);
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        jc.recordProceed(new ProceedForArray(retType, opcode, index, dim));
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Bytecode bytecode = jc.getBytecode();
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        storeStack(params, true, paramVar, bytecode);
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        jc.recordLocalVariables(ca, pos);
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        bytecode.addOpcode(ACONST_NULL);        // initialize $_
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        bytecode.addAstore(retVar);
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        jc.compileStmnt(statement);
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        bytecode.addAload(retVar);
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        replace0(pos, bytecode, codeLength);
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* <array type> $proceed(<dim> ..)
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    static class ProceedForArray implements ProceedHandler {
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass arrayType;
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int opcode;
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int index, dimension;
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ProceedForArray(CtClass type, int op, int i, int dim) {
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            arrayType = type;
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            opcode = op;
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            index = i;
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            dimension = dim;
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throws CompileError
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        {
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int num = gen.getMethodArgsLength(args);
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (num != dimension)
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new CompileError(Javac.proceedName
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        + "() with a wrong number of parameters");
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            gen.atMethodArgs(args, new int[num],
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                             new int[num], new String[num]);
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            bytecode.addOpcode(opcode);
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (opcode == Opcode.ANEWARRAY)
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                bytecode.addIndex(index);
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else if (opcode == Opcode.NEWARRAY)
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                bytecode.add(index);
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else /* if (opcode == Opcode.MULTIANEWARRAY) */ {
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                bytecode.addIndex(index);
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                bytecode.add(dimension);
27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                bytecode.growStack(1 - dimension);
27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            gen.setType(arrayType);
27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public void setReturnType(JvstTypeChecker c, ASTList args)
27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throws CompileError
27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        {
27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            c.setType(arrayType);
28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
283