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