All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.lib.javassist.expr.NewArray Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.3.0
Show newest version
/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 */

package com.feilong.lib.javassist.expr;

import com.feilong.lib.javassist.CannotCompileException;
import com.feilong.lib.javassist.CtBehavior;
import com.feilong.lib.javassist.CtClass;
import com.feilong.lib.javassist.CtPrimitiveType;
import com.feilong.lib.javassist.NotFoundException;
import com.feilong.lib.javassist.bytecode.BadBytecode;
import com.feilong.lib.javassist.bytecode.Bytecode;
import com.feilong.lib.javassist.bytecode.CodeAttribute;
import com.feilong.lib.javassist.bytecode.CodeIterator;
import com.feilong.lib.javassist.bytecode.ConstPool;
import com.feilong.lib.javassist.bytecode.Descriptor;
import com.feilong.lib.javassist.bytecode.MethodInfo;
import com.feilong.lib.javassist.bytecode.Opcode;
import com.feilong.lib.javassist.compiler.CompileError;
import com.feilong.lib.javassist.compiler.Javac;
import com.feilong.lib.javassist.compiler.JvstCodeGen;
import com.feilong.lib.javassist.compiler.JvstTypeChecker;
import com.feilong.lib.javassist.compiler.ProceedHandler;
import com.feilong.lib.javassist.compiler.ast.ASTList;

/**
 * Array creation.
 *
 * 

* This class does not provide methods for obtaining the initial * values of array elements. */ public class NewArray extends Expr{ int opcode; protected NewArray(int pos, CodeIterator i, CtClass declaring, MethodInfo m, int op){ super(pos, i, declaring, m); opcode = op; } /** * Returns the method or constructor containing the array creation * represented by this object. */ @Override public CtBehavior where(){ return super.where(); } /** * Returns the line number of the source line containing the * array creation. * * @return -1 if this information is not available. */ @Override public int getLineNumber(){ return super.getLineNumber(); } /** * Returns the source file containing the array creation. * * @return null if this information is not available. */ @Override public String getFileName(){ return super.getFileName(); } /** * Returns the list of exceptions that the expression may throw. * This list includes both the exceptions that the try-catch statements * including the expression can catch and the exceptions that * the throws declaration allows the method to throw. */ @Override public CtClass[] mayThrow(){ return super.mayThrow(); } /** * Returns the type of array components. If the created array is * a two-dimensional array of int, * the type returned by this method is * not int[] but int. */ public CtClass getComponentType() throws NotFoundException{ if (opcode == Opcode.NEWARRAY){ int atype = iterator.byteAt(currentPos + 1); return getPrimitiveType(atype); }else if (opcode == Opcode.ANEWARRAY || opcode == Opcode.MULTIANEWARRAY){ int index = iterator.u16bitAt(currentPos + 1); String desc = getConstPool().getClassInfo(index); int dim = Descriptor.arrayDimension(desc); desc = Descriptor.toArrayComponent(desc, dim); return Descriptor.toCtClass(desc, thisClass.getClassPool()); }else{ throw new RuntimeException("bad opcode: " + opcode); } } CtClass getPrimitiveType(int atype){ switch (atype) { case Opcode.T_BOOLEAN: return CtClass.booleanType; case Opcode.T_CHAR: return CtClass.charType; case Opcode.T_FLOAT: return CtClass.floatType; case Opcode.T_DOUBLE: return CtClass.doubleType; case Opcode.T_BYTE: return CtClass.byteType; case Opcode.T_SHORT: return CtClass.shortType; case Opcode.T_INT: return CtClass.intType; case Opcode.T_LONG: return CtClass.longType; default: throw new RuntimeException("bad atype: " + atype); } } /** * Returns the dimension of the created array. */ public int getDimension(){ if (opcode == Opcode.NEWARRAY){ return 1; }else if (opcode == Opcode.ANEWARRAY || opcode == Opcode.MULTIANEWARRAY){ int index = iterator.u16bitAt(currentPos + 1); String desc = getConstPool().getClassInfo(index); return Descriptor.arrayDimension(desc) + (opcode == Opcode.ANEWARRAY ? 1 : 0); }else{ throw new RuntimeException("bad opcode: " + opcode); } } /** * Returns the number of dimensions of arrays to be created. * If the opcode is multianewarray, this method returns the second * operand. Otherwise, it returns 1. */ public int getCreatedDimensions(){ if (opcode == Opcode.MULTIANEWARRAY){ return iterator.byteAt(currentPos + 3); } return 1; } /** * Replaces the array creation with the bytecode derived from * the given source text. * *

* $0 is available even if the called method is static. * If the field access is writing, $_ is available but the value * of $_ is ignored. * * @param statement * a Java statement except try-catch. */ @Override public void replace(String statement) throws CannotCompileException{ try{ replace2(statement); }catch (CompileError e){ throw new CannotCompileException(e); }catch (NotFoundException e){ throw new CannotCompileException(e); }catch (BadBytecode e){ throw new CannotCompileException("broken method"); } } private void replace2(String statement) throws CompileError,NotFoundException,BadBytecode,CannotCompileException{ thisClass.getClassFile(); // to call checkModify(). ConstPool constPool = getConstPool(); int pos = currentPos; CtClass retType; int codeLength; int index = 0; int dim = 1; String desc; if (opcode == Opcode.NEWARRAY){ index = iterator.byteAt(currentPos + 1); // atype CtPrimitiveType cpt = (CtPrimitiveType) getPrimitiveType(index); desc = "[" + cpt.getDescriptor(); codeLength = 2; }else if (opcode == Opcode.ANEWARRAY){ index = iterator.u16bitAt(pos + 1); desc = constPool.getClassInfo(index); if (desc.startsWith("[")){ desc = "[" + desc; }else{ desc = "[L" + desc + ";"; } codeLength = 3; }else if (opcode == Opcode.MULTIANEWARRAY){ index = iterator.u16bitAt(currentPos + 1); desc = constPool.getClassInfo(index); dim = iterator.byteAt(currentPos + 3); codeLength = 4; }else{ throw new RuntimeException("bad opcode: " + opcode); } retType = Descriptor.toCtClass(desc, thisClass.getClassPool()); Javac jc = new Javac(thisClass); CodeAttribute ca = iterator.get(); CtClass[] params = new CtClass[dim]; for (int i = 0; i < dim; ++i){ params[i] = CtClass.intType; } int paramVar = ca.getMaxLocals(); jc.recordParams(javaLangObject, params, true, paramVar, withinStatic()); /* * Is $_ included in the source code? */ checkResultValue(retType, statement); int retVar = jc.recordReturnType(retType, true); jc.recordProceed(new ProceedForArray(retType, opcode, index, dim)); Bytecode bytecode = jc.getBytecode(); storeStack(params, true, paramVar, bytecode); jc.recordLocalVariables(ca, pos); bytecode.addOpcode(ACONST_NULL); // initialize $_ bytecode.addAstore(retVar); jc.compileStmnt(statement); bytecode.addAload(retVar); replace0(pos, bytecode, codeLength); } /* * $proceed( ..) */ static class ProceedForArray implements ProceedHandler{ CtClass arrayType; int opcode; int index, dimension; ProceedForArray(CtClass type, int op, int i, int dim){ arrayType = type; opcode = op; index = i; dimension = dim; } @Override public void doit(JvstCodeGen gen,Bytecode bytecode,ASTList args) throws CompileError{ int num = gen.getMethodArgsLength(args); if (num != dimension){ throw new CompileError(Javac.proceedName + "() with a wrong number of parameters"); } gen.atMethodArgs(args, new int[num], new int[num], new String[num]); bytecode.addOpcode(opcode); if (opcode == Opcode.ANEWARRAY){ bytecode.addIndex(index); }else if (opcode == Opcode.NEWARRAY){ bytecode.add(index); }else /* if (opcode == Opcode.MULTIANEWARRAY) */ { bytecode.addIndex(index); bytecode.add(dimension); bytecode.growStack(1 - dimension); } gen.setType(arrayType); } @Override public void setReturnType(JvstTypeChecker c,ASTList args) throws CompileError{ c.setType(arrayType); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy