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 * Expression for accessing a field. 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class FieldAccess extends Expr { 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int opcode; 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected FieldAccess(int pos, CodeIterator i, CtClass declaring, 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal MethodInfo m, int op) { 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(pos, i, declaring, m); 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal opcode = op; 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the method or constructor containing the field-access 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * expression represented by this object. 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public CtBehavior where() { return super.where(); } 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the line number of the source line containing the 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * field access. 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return -1 if this information is not available. 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int getLineNumber() { 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return super.getLineNumber(); 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the source file containing the field access. 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return null if this information is not available. 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getFileName() { 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return super.getFileName(); 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns true if the field is static. 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean isStatic() { 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return isStatic(opcode); 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static boolean isStatic(int c) { 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return c == Opcode.GETSTATIC || c == Opcode.PUTSTATIC; 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns true if the field is read. 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean isReader() { 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return opcode == Opcode.GETFIELD || opcode == Opcode.GETSTATIC; 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns true if the field is written in. 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean isWriter() { 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return opcode == Opcode.PUTFIELD || opcode == Opcode.PUTSTATIC; 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the class in which the field is declared. 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private CtClass getCtClass() throws NotFoundException { 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return thisClass.getClassPool().get(getClassName()); 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the name of the class in which the field is declared. 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getClassName() { 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = iterator.u16bitAt(currentPos + 1); 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return getConstPool().getFieldrefClassName(index); 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the name of the field. 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getFieldName() { 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = iterator.u16bitAt(currentPos + 1); 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return getConstPool().getFieldrefName(index); 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the field accessed by this expression. 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public CtField getField() throws NotFoundException { 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass cc = getCtClass(); 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return cc.getField(getFieldName()); 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the list of exceptions that the expression may throw. 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This list includes both the exceptions that the try-catch statements 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * including the expression can catch and the exceptions that 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the throws declaration allows the method to throw. 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public CtClass[] mayThrow() { 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return super.mayThrow(); 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the signature of the field type. 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The signature is represented by a character string 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * called field descriptor, which is defined in the JVM specification. 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.bytecode.Descriptor#toCtClass(String, ClassPool) 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @since 3.1 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getSignature() { 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = iterator.u16bitAt(currentPos + 1); 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return getConstPool().getFieldrefType(index); 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Replaces the method call with the bytecode derived from 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the given source text. 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>$0 is available even if the called method is static. 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the field access is writing, $_ is available but the value 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * of $_ is ignored. 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param statement a Java statement except try-catch. 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void replace(String statement) throws CannotCompileException { 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal thisClass.getClassFile(); // to call checkModify(). 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ConstPool constPool = getConstPool(); 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int pos = currentPos; 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = iterator.u16bitAt(pos + 1); 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Javac jc = new Javac(thisClass); 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CodeAttribute ca = iterator.get(); 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass[] params; 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass retType; 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass fieldType 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = Descriptor.toCtClass(constPool.getFieldrefType(index), 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal thisClass.getClassPool()); 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean read = isReader(); 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (read) { 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal params = new CtClass[0]; 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal retType = fieldType; 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal params = new CtClass[1]; 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal params[0] = fieldType; 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal retType = CtClass.voidType; 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int paramVar = ca.getMaxLocals(); 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jc.recordParams(constPool.getFieldrefClassName(index), params, 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal true, paramVar, withinStatic()); 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* Is $_ included in the source code? 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean included = checkResultValue(retType, statement); 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (read) 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal included = true; 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int retVar = jc.recordReturnType(retType, included); 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (read) 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jc.recordProceed(new ProceedForRead(retType, opcode, 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index, paramVar)); 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // because $type is not the return type... 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jc.recordType(fieldType); 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jc.recordProceed(new ProceedForWrite(params[0], opcode, 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index, paramVar)); 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Bytecode bytecode = jc.getBytecode(); 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal storeStack(params, isStatic(), paramVar, bytecode); 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jc.recordLocalVariables(ca, pos); 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (included) 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (retType == CtClass.voidType) { 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addOpcode(ACONST_NULL); 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addAstore(retVar); 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addConstZero(retType); 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addStore(retVar, retType); // initialize $_ 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jc.compileStmnt(statement); 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (read) 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addLoad(retVar, retType); 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal replace0(pos, bytecode, 3); 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (CompileError e) { throw new CannotCompileException(e); } 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (NotFoundException e) { throw new CannotCompileException(e); } 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (BadBytecode e) { 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CannotCompileException("broken method"); 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* <field type> $proceed() 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static class ProceedForRead implements ProceedHandler { 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass fieldType; 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int opcode; 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int targetVar, index; 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProceedForRead(CtClass type, int op, int i, int var) { 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fieldType = type; 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targetVar = var; 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal opcode = op; 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index = i; 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (args != null && !gen.isParamListName(args)) 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError(Javac.proceedName 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + "() cannot take a parameter for field reading"); 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int stack; 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isStatic(opcode)) 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack = 0; 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack = -1; 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addAload(targetVar); 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (fieldType instanceof CtPrimitiveType) 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack += ((CtPrimitiveType)fieldType).getDataSize(); 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++stack; 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.add(opcode); 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addIndex(index); 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.growStack(stack); 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setType(fieldType); 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setReturnType(JvstTypeChecker c, ASTList args) 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.setType(fieldType); 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* void $proceed(<field type>) 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the return type is not the field type but void. 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static class ProceedForWrite implements ProceedHandler { 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass fieldType; 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int opcode; 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int targetVar, index; 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProceedForWrite(CtClass type, int op, int i, int var) { 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal fieldType = type; 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targetVar = var; 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal opcode = op; 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index = i; 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (gen.getMethodArgsLength(args) != 1) 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError(Javac.proceedName 28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + "() cannot take more than one parameter " 29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + "for field writing"); 29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int stack; 29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isStatic(opcode)) 29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack = 0; 29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack = -1; 29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addAload(targetVar); 29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.atMethodArgs(args, new int[1], new int[1], new String[1]); 30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.doNumCast(fieldType); 30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (fieldType instanceof CtPrimitiveType) 30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack -= ((CtPrimitiveType)fieldType).getDataSize(); 30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal --stack; 30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.add(opcode); 30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.addIndex(index); 30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.growStack(stack); 31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setType(CtClass.voidType); 31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.addNullIfVoid(); 31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setReturnType(JvstTypeChecker c, ASTList args) 31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.atMethodArgs(args, new int[1], new int[1], new String[1]); 31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.setType(CtClass.voidType); 31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.addNullIfVoid(); 32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 323