diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2003-04-23 17:08:37 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2003-04-23 17:08:37 +0000 |
commit | cdeddfd6fc34a06734f9fa525cf5c7437a6c8fb6 (patch) | |
tree | 0471a4d9b985b11969ecd6f521f660e3d468f1d1 /src/main/javassist/expr | |
parent | fb431982111b03608b888953f7ed8ba7e98f421c (diff) | |
download | javassist-cdeddfd6fc34a06734f9fa525cf5c7437a6c8fb6.tar.gz javassist-cdeddfd6fc34a06734f9fa525cf5c7437a6c8fb6.zip |
Changed the copyright notices and removed tab characters.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@9 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main/javassist/expr')
-rw-r--r-- | src/main/javassist/expr/Cast.java | 167 | ||||
-rw-r--r-- | src/main/javassist/expr/Expr.java | 235 | ||||
-rw-r--r-- | src/main/javassist/expr/ExprEditor.java | 220 | ||||
-rw-r--r-- | src/main/javassist/expr/FieldAccess.java | 341 | ||||
-rw-r--r-- | src/main/javassist/expr/Instanceof.java | 169 | ||||
-rw-r--r-- | src/main/javassist/expr/MethodCall.java | 211 | ||||
-rw-r--r-- | src/main/javassist/expr/NewExpr.java | 237 | ||||
-rw-r--r-- | src/main/javassist/expr/package.html | 8 |
8 files changed, 769 insertions, 819 deletions
diff --git a/src/main/javassist/expr/Cast.java b/src/main/javassist/expr/Cast.java index 44648e78..3747abf7 100644 --- a/src/main/javassist/expr/Cast.java +++ b/src/main/javassist/expr/Cast.java @@ -1,28 +1,17 @@ /* - * This file is part of the Javassist toolkit. + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2003 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. You may obtain a copy of the License at - * either http://www.mozilla.org/MPL/. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * 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. - * - * The Original Code is Javassist. - * - * The Initial Developer of the Original Code is Shigeru Chiba. Portions - * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. - * All Rights Reserved. - * - * Contributor(s): - * - * The development of this software is supported in part by the PRESTO - * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. */ - package javassist.expr; import javassist.*; @@ -38,7 +27,7 @@ public class Cast extends Expr { * Undocumented constructor. Do not use; internal-use only. */ Cast(int pos, CodeIterator i, CtClass declaring, MethodInfo m) { - super(pos, i, declaring, m); + super(pos, i, declaring, m); } /** @@ -51,19 +40,19 @@ public class Cast extends Expr { * Returns the line number of the source line containing the * type-cast expression. * - * @return -1 if this information is not available. + * @return -1 if this information is not available. */ public int getLineNumber() { - return super.getLineNumber(); + return super.getLineNumber(); } /** * Returns the source file containing the type-cast expression. * - * @return null if this information is not available. + * @return null if this information is not available. */ public String getFileName() { - return super.getFileName(); + return super.getFileName(); } /** @@ -71,11 +60,11 @@ public class Cast extends Expr { * the type specified by the cast. */ public CtClass getType() throws NotFoundException { - ConstPool cp = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - String name = cp.getClassInfo(index); - return Descriptor.toCtClass(name, thisClass.getClassPool()); + ConstPool cp = getConstPool(); + int pos = currentPos; + int index = iterator.u16bitAt(pos + 1); + String name = cp.getClassInfo(index); + return Descriptor.toCtClass(name, thisClass.getClassPool()); } /** @@ -85,7 +74,7 @@ public class Cast extends Expr { * the throws declaration allows the method to throw. */ public CtClass[] mayThrow() { - return super.mayThrow(); + return super.mayThrow(); } /** @@ -94,69 +83,69 @@ public class Cast extends Expr { * * <p>$0 is available but the value is <code>null</code>. * - * @param statement a Java statement. + * @param statement a Java statement. */ public void replace(String statement) throws CannotCompileException { - ConstPool constPool = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - - Javac jc = new Javac(thisClass); - ClassPool cp = thisClass.getClassPool(); - CodeAttribute ca = iterator.get(); - - try { - CtClass[] params - = new CtClass[] { cp.get(javaLangObject) }; - CtClass retType = getType(); - - int paramVar = ca.getMaxLocals(); - jc.recordParams(javaLangObject, params, true, paramVar, - withinStatic()); - int retVar = jc.recordReturnType(retType, true); - jc.recordProceed(new ProceedForCast(index, retType)); - - /* Is $_ included in the source code? - */ - checkResultValue(retType, statement); - - Bytecode bytecode = jc.getBytecode(); - storeStack(params, true, paramVar, bytecode); - jc.compileStmnt(statement); - bytecode.addLoad(retVar, retType); - - replace0(pos, bytecode, 3); - } - catch (CompileError e) { throw new CannotCompileException(e); } - catch (NotFoundException e) { throw new CannotCompileException(e); } - catch (BadBytecode e) { - throw new CannotCompileException("broken method"); - } + ConstPool constPool = getConstPool(); + int pos = currentPos; + int index = iterator.u16bitAt(pos + 1); + + Javac jc = new Javac(thisClass); + ClassPool cp = thisClass.getClassPool(); + CodeAttribute ca = iterator.get(); + + try { + CtClass[] params + = new CtClass[] { cp.get(javaLangObject) }; + CtClass retType = getType(); + + int paramVar = ca.getMaxLocals(); + jc.recordParams(javaLangObject, params, true, paramVar, + withinStatic()); + int retVar = jc.recordReturnType(retType, true); + jc.recordProceed(new ProceedForCast(index, retType)); + + /* Is $_ included in the source code? + */ + checkResultValue(retType, statement); + + Bytecode bytecode = jc.getBytecode(); + storeStack(params, true, paramVar, bytecode); + jc.compileStmnt(statement); + bytecode.addLoad(retVar, retType); + + replace0(pos, bytecode, 3); + } + catch (CompileError e) { throw new CannotCompileException(e); } + catch (NotFoundException e) { throw new CannotCompileException(e); } + catch (BadBytecode e) { + throw new CannotCompileException("broken method"); + } } /* <type> $proceed(Object obj) */ static class ProceedForCast implements ProceedHandler { - int index; - CtClass retType; - - ProceedForCast(int i, CtClass t) { - index = i; - retType = t; - } - - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) - throws CompileError - { - if (gen.atMethodArgsLength(args) != 1) - throw new CompileError(Javac.proceedName - + "() cannot take more than one parameter " - + "for cast"); - - gen.atMethodArgs(args, new int[1], new int[1], new String[1]); - bytecode.addOpcode(Opcode.CHECKCAST); - bytecode.addIndex(index); - gen.setType(retType); - } + int index; + CtClass retType; + + ProceedForCast(int i, CtClass t) { + index = i; + retType = t; + } + + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + throws CompileError + { + if (gen.atMethodArgsLength(args) != 1) + throw new CompileError(Javac.proceedName + + "() cannot take more than one parameter " + + "for cast"); + + gen.atMethodArgs(args, new int[1], new int[1], new String[1]); + bytecode.addOpcode(Opcode.CHECKCAST); + bytecode.addIndex(index); + gen.setType(retType); + } } } diff --git a/src/main/javassist/expr/Expr.java b/src/main/javassist/expr/Expr.java index d88d7939..f0defd48 100644 --- a/src/main/javassist/expr/Expr.java +++ b/src/main/javassist/expr/Expr.java @@ -1,28 +1,17 @@ /* - * This file is part of the Javassist toolkit. + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2003 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. You may obtain a copy of the License at - * either http://www.mozilla.org/MPL/. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * 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. - * - * The Original Code is Javassist. - * - * The Initial Developer of the Original Code is Shigeru Chiba. Portions - * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. - * All Rights Reserved. - * - * Contributor(s): - * - * The development of this software is supported in part by the PRESTO - * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. */ - package javassist.expr; import javassist.*; @@ -46,14 +35,14 @@ abstract class Expr implements Opcode { static final String javaLangObject = "java.lang.Object"; Expr(int pos, CodeIterator i, CtClass declaring, MethodInfo m) { - currentPos = pos; - iterator = i; - thisClass = declaring; - thisMethod = m; + currentPos = pos; + iterator = i; + thisClass = declaring; + thisMethod = m; } final ConstPool getConstPool() { - return thisMethod.getConstPool(); + return thisMethod.getConstPool(); } final boolean edited() { return edited; } @@ -66,20 +55,20 @@ abstract class Expr implements Opcode { * Returns true if this method is static. */ final boolean withinStatic() { - return (thisMethod.getAccessFlags() & AccessFlag.STATIC) != 0; + return (thisMethod.getAccessFlags() & AccessFlag.STATIC) != 0; } /** * Returns the constructor or method containing the expression. */ public CtBehavior where() { - MethodInfo mi = thisMethod; - CtBehavior[] cb = thisClass.getDeclaredBehaviors(); - for (int i = cb.length - 1; i >= 0; --i) - if (cb[i].getMethodInfo() == mi) - return cb[i]; + MethodInfo mi = thisMethod; + CtBehavior[] cb = thisClass.getDeclaredBehaviors(); + for (int i = cb.length - 1; i >= 0; --i) + if (cb[i].getMethodInfo() == mi) + return cb[i]; - throw new RuntimeException("fatal: not found"); + throw new RuntimeException("fatal: not found"); } /** @@ -89,86 +78,86 @@ abstract class Expr implements Opcode { * the throws declaration allows the method to throw. */ public CtClass[] mayThrow() { - ClassPool pool = thisClass.getClassPool(); - ConstPool cp = thisMethod.getConstPool(); - LinkedList list = new LinkedList(); - try { - CodeAttribute ca = thisMethod.getCodeAttribute(); - ExceptionTable et = ca.getExceptionTable(); - int pos = currentPos; - int n = et.size(); - for (int i = 0; i < n; ++i) - if (et.startPc(i) <= pos && pos < et.endPc(i)) { - int t = et.catchType(i); - if (t > 0) - try { - addClass(list, pool.get(cp.getClassInfo(t))); - } - catch (NotFoundException e) {} - } - } - catch (NullPointerException e) {} - - ExceptionsAttribute ea = thisMethod.getExceptionsAttribute(); - if (ea != null) { - String[] exceptions = ea.getExceptions(); - if (exceptions != null) { - int n = exceptions.length; - for (int i = 0; i < n; ++i) - try { - addClass(list, pool.get(exceptions[i])); - } - catch (NotFoundException e) {} - } - } - - return (CtClass[])list.toArray(new CtClass[list.size()]); + ClassPool pool = thisClass.getClassPool(); + ConstPool cp = thisMethod.getConstPool(); + LinkedList list = new LinkedList(); + try { + CodeAttribute ca = thisMethod.getCodeAttribute(); + ExceptionTable et = ca.getExceptionTable(); + int pos = currentPos; + int n = et.size(); + for (int i = 0; i < n; ++i) + if (et.startPc(i) <= pos && pos < et.endPc(i)) { + int t = et.catchType(i); + if (t > 0) + try { + addClass(list, pool.get(cp.getClassInfo(t))); + } + catch (NotFoundException e) {} + } + } + catch (NullPointerException e) {} + + ExceptionsAttribute ea = thisMethod.getExceptionsAttribute(); + if (ea != null) { + String[] exceptions = ea.getExceptions(); + if (exceptions != null) { + int n = exceptions.length; + for (int i = 0; i < n; ++i) + try { + addClass(list, pool.get(exceptions[i])); + } + catch (NotFoundException e) {} + } + } + + return (CtClass[])list.toArray(new CtClass[list.size()]); } private static void addClass(LinkedList list, CtClass c) { - Iterator it = list.iterator(); - while (it.hasNext()) - if (it.next() == c) - return; + Iterator it = list.iterator(); + while (it.hasNext()) + if (it.next() == c) + return; - list.add(c); + list.add(c); } /** * Returns the line number of the source line containing the * expression. * - * @return -1 if this information is not available. + * @return -1 if this information is not available. */ public int getLineNumber() { - return thisMethod.getLineNumber(currentPos); + return thisMethod.getLineNumber(currentPos); } /** * Returns the source file containing the expression. * - * @return null if this information is not available. + * @return null if this information is not available. */ public String getFileName() { - ClassFile cf = thisClass.getClassFile2(); - if (cf == null) - return null; - else - return cf.getSourceFile(); + ClassFile cf = thisClass.getClassFile2(); + if (cf == null) + return null; + else + return cf.getSourceFile(); } static final boolean checkResultValue(CtClass retType, String prog) - throws CannotCompileException + throws CannotCompileException { - /* Is $_ included in the source code? - */ - boolean hasIt = (prog.indexOf(Javac.resultVarName) >= 0); - if (!hasIt && retType != CtClass.voidType) - throw new CannotCompileException( - "the resulting value is not stored in " - + Javac.resultVarName); - - return hasIt; + /* Is $_ included in the source code? + */ + boolean hasIt = (prog.indexOf(Javac.resultVarName) >= 0); + if (!hasIt && retType != CtClass.voidType) + throw new CannotCompileException( + "the resulting value is not stored in " + + Javac.resultVarName); + + return hasIt; } /* If isStaticCall is true, null is assigned to $0. So $0 must @@ -178,46 +167,46 @@ abstract class Expr implements Opcode { * be less than 0. */ static final void storeStack(CtClass[] params, boolean isStaticCall, - int regno, Bytecode bytecode) { - storeStack0(0, params.length, params, regno + 1, bytecode); - if (isStaticCall) - bytecode.addOpcode(ACONST_NULL); + int regno, Bytecode bytecode) { + storeStack0(0, params.length, params, regno + 1, bytecode); + if (isStaticCall) + bytecode.addOpcode(ACONST_NULL); - bytecode.addAstore(regno); + bytecode.addAstore(regno); } private static void storeStack0(int i, int n, CtClass[] params, - int regno, Bytecode bytecode) { - if (i >= n) - return; - else { - CtClass c = params[i]; - int size; - if (c instanceof CtPrimitiveType) - size = ((CtPrimitiveType)c).getDataSize(); - else - size = 1; - - storeStack0(i + 1, n, params, regno + size, bytecode); - bytecode.addStore(regno, c); - } + int regno, Bytecode bytecode) { + if (i >= n) + return; + else { + CtClass c = params[i]; + int size; + if (c instanceof CtPrimitiveType) + size = ((CtPrimitiveType)c).getDataSize(); + else + size = 1; + + storeStack0(i + 1, n, params, regno + size, bytecode); + bytecode.addStore(regno, c); + } } protected void replace0(int pos, Bytecode bytecode, int size) - throws BadBytecode + throws BadBytecode { - byte[] code = bytecode.get(); - edited = true; - int gap = code.length - size; - if (gap > 0) - iterator.insertGap(pos, gap); - else - for (int i = 0; i < size; ++i) - iterator.writeByte(NOP, pos + i); - - iterator.write(code, pos); - iterator.insert(bytecode.getExceptionTable(), pos); - maxLocals = bytecode.getMaxLocals(); - maxStack = bytecode.getMaxStack(); + byte[] code = bytecode.get(); + edited = true; + int gap = code.length - size; + for (int i = 0; i < size; ++i) + iterator.writeByte(NOP, pos + i); + + if (gap > 0) + iterator.insertGap(pos, gap); + + iterator.write(code, pos); + iterator.insert(bytecode.getExceptionTable(), pos); + maxLocals = bytecode.getMaxLocals(); + maxStack = bytecode.getMaxStack(); } } diff --git a/src/main/javassist/expr/ExprEditor.java b/src/main/javassist/expr/ExprEditor.java index c6814ef5..f9508818 100644 --- a/src/main/javassist/expr/ExprEditor.java +++ b/src/main/javassist/expr/ExprEditor.java @@ -1,28 +1,17 @@ /* - * This file is part of the Javassist toolkit. + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2003 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. You may obtain a copy of the License at - * either http://www.mozilla.org/MPL/. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * 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. - * - * The Original Code is Javassist. - * - * The Initial Developer of the Original Code is Shigeru Chiba. Portions - * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. - * All Rights Reserved. - * - * Contributor(s): - * - * The development of this software is supported in part by the PRESTO - * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. */ - package javassist.expr; import javassist.bytecode.*; @@ -83,104 +72,117 @@ public class ExprEditor { public ExprEditor() {} static class NewOp { - NewOp next; - int pos; - String type; - - NewOp(NewOp n, int p, String t) { - next = n; - pos = p; - type = t; - } + NewOp next; + int pos; + String type; + + NewOp(NewOp n, int p, String t) { + next = n; + pos = p; + type = t; + } } /** * Undocumented method. Do not use; internal-use only. */ public boolean doit(CtClass clazz, MethodInfo minfo) - throws CannotCompileException + throws CannotCompileException { - CodeAttribute codeAttr = minfo.getCodeAttribute(); - if (codeAttr == null) - return false; - - CodeIterator iterator = codeAttr.iterator(); - boolean edited = false; - int maxLocals = codeAttr.getMaxLocals(); - int maxStack = 0; - - NewOp newList = null; - ConstPool cp = minfo.getConstPool(); - - while (iterator.hasNext()) - try { - Expr expr = null; - int pos = iterator.next(); - int c = iterator.byteAt(pos); - - if (c == Opcode.INVOKESTATIC || c == Opcode.INVOKEINTERFACE - || c == Opcode.INVOKEVIRTUAL) { - expr = new MethodCall(pos, iterator, clazz, minfo); - edit((MethodCall)expr); - } - else if (c == Opcode.GETFIELD || c == Opcode.GETSTATIC - || c == Opcode.PUTFIELD || c == Opcode.PUTSTATIC) { - expr = new FieldAccess(pos, iterator, clazz, minfo, c); - edit((FieldAccess)expr); - } - else if (c == Opcode.NEW) { - int index = iterator.u16bitAt(pos + 1); - newList = new NewOp(newList, pos, - cp.getClassInfo(index)); - } - else if (c == Opcode.INVOKESPECIAL) { - if (newList != null && cp.isConstructor(newList.type, - iterator.u16bitAt(pos + 1)) > 0) { - expr = new NewExpr(pos, iterator, clazz, minfo, - newList.type, newList.pos); - edit((NewExpr)expr); - newList = newList.next; - } - else { - expr = new MethodCall(pos, iterator, clazz, minfo); - MethodCall mcall = (MethodCall)expr; - if (!mcall.getMethodName().equals( - MethodInfo.nameInit)) - edit(mcall); - } - } - else if (c == Opcode.INSTANCEOF) { - expr = new Instanceof(pos, iterator, clazz, minfo); - edit((Instanceof)expr); - } - else if (c == Opcode.CHECKCAST) { - expr = new Cast(pos, iterator, clazz, minfo); - edit((Cast)expr); - } - - if (expr != null && expr.edited()) { - edited = true; - if (maxLocals < expr.locals()) - maxLocals = expr.locals(); - - if (maxStack < expr.stack()) - maxStack = expr.stack(); - } - } - catch (BadBytecode e) { - throw new CannotCompileException(e); - } - - codeAttr.setMaxLocals(maxLocals); - codeAttr.setMaxStack(codeAttr.getMaxStack() + maxStack); - return edited; + CodeAttribute codeAttr = minfo.getCodeAttribute(); + if (codeAttr == null) + return false; + + CodeIterator iterator = codeAttr.iterator(); + boolean edited = false; + int maxLocals = codeAttr.getMaxLocals(); + int maxStack = 0; + + NewOp newList = null; + ConstPool cp = minfo.getConstPool(); + + while (iterator.hasNext()) + try { + Expr expr = null; + int pos = iterator.next(); + int c = iterator.byteAt(pos); + + if (c == Opcode.INVOKESTATIC || c == Opcode.INVOKEINTERFACE + || c == Opcode.INVOKEVIRTUAL) { + expr = new MethodCall(pos, iterator, clazz, minfo); + edit((MethodCall)expr); + } + else if (c == Opcode.GETFIELD || c == Opcode.GETSTATIC + || c == Opcode.PUTFIELD || c == Opcode.PUTSTATIC) { + expr = new FieldAccess(pos, iterator, clazz, minfo, c); + edit((FieldAccess)expr); + } + else if (c == Opcode.NEW) { + int index = iterator.u16bitAt(pos + 1); + newList = new NewOp(newList, pos, + cp.getClassInfo(index)); + } + else if (c == Opcode.INVOKESPECIAL) { + if (newList != null && cp.isConstructor(newList.type, + iterator.u16bitAt(pos + 1)) > 0) { + expr = new NewExpr(pos, iterator, clazz, minfo, + newList.type, newList.pos); + edit((NewExpr)expr); + newList = newList.next; + } + else { + expr = new MethodCall(pos, iterator, clazz, minfo); + MethodCall mcall = (MethodCall)expr; + if (!mcall.getMethodName().equals( + MethodInfo.nameInit)) + edit(mcall); + } + } + else if (c == Opcode.INSTANCEOF) { + expr = new Instanceof(pos, iterator, clazz, minfo); + edit((Instanceof)expr); + } + else if (c == Opcode.CHECKCAST) { + expr = new Cast(pos, iterator, clazz, minfo); + edit((Cast)expr); + } + + if (expr != null && expr.edited()) { + edited = true; + maxLocals = max(maxLocals, expr.locals()); + maxStack = max(maxStack, expr.stack()); + } + } + catch (BadBytecode e) { + throw new CannotCompileException(e); + } + + ExceptionTable et = codeAttr.getExceptionTable(); + int n = et.size(); + for (int i = 0; i < n; ++i) { + Handler h = new Handler(et, i, iterator, clazz, minfo); + edit(h); + if (h.edited()) { + edited = true; + maxLocals = max(maxLocals, h.locals()); + maxStack = max(maxStack, h.stack()); + } + } + + codeAttr.setMaxLocals(maxLocals); + codeAttr.setMaxStack(codeAttr.getMaxStack() + maxStack); + return edited; + } + + private int max(int i, int j) { + return i > j ? i : j; } /** * Edits a <tt>new</tt> expression (overridable). * The default implementation performs nothing. * - * @param e the <tt>new</tt> expression creating an object. + * @param e the <tt>new</tt> expression creating an object. */ public void edit(NewExpr e) throws CannotCompileException {} @@ -208,4 +210,10 @@ public class ExprEditor { * The default implementation performs nothing. */ public void edit(Cast c) throws CannotCompileException {} + + /** + * Edits a catch clause (overridable). + * The default implementation performs nothing. + */ + public void edit(Handler h) throws CannotCompileException {} } diff --git a/src/main/javassist/expr/FieldAccess.java b/src/main/javassist/expr/FieldAccess.java index a524b07d..75382830 100644 --- a/src/main/javassist/expr/FieldAccess.java +++ b/src/main/javassist/expr/FieldAccess.java @@ -1,28 +1,17 @@ /* - * This file is part of the Javassist toolkit. + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2003 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. You may obtain a copy of the License at - * either http://www.mozilla.org/MPL/. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * 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. - * - * The Original Code is Javassist. - * - * The Initial Developer of the Original Code is Shigeru Chiba. Portions - * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. - * All Rights Reserved. - * - * Contributor(s): - * - * The development of this software is supported in part by the PRESTO - * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. */ - package javassist.expr; import javassist.*; @@ -37,9 +26,9 @@ public class FieldAccess extends Expr { int opcode; FieldAccess(int pos, CodeIterator i, CtClass declaring, MethodInfo m, - int op) { - super(pos, i, declaring, m); - opcode = op; + int op) { + super(pos, i, declaring, m); + opcode = op; } /** @@ -52,75 +41,75 @@ public class FieldAccess extends Expr { * Returns the line number of the source line containing the * field access. * - * @return -1 if this information is not available. + * @return -1 if this information is not available. */ public int getLineNumber() { - return super.getLineNumber(); + return super.getLineNumber(); } /** * Returns the source file containing the field access. * - * @return null if this information is not available. + * @return null if this information is not available. */ public String getFileName() { - return super.getFileName(); + return super.getFileName(); } /** * Returns true if the field is static. */ public boolean isStatic() { - return isStatic(opcode); + return isStatic(opcode); } static boolean isStatic(int c) { - return c == Opcode.GETSTATIC || c == Opcode.PUTSTATIC; + return c == Opcode.GETSTATIC || c == Opcode.PUTSTATIC; } /** * Returns true if the field is read. */ public boolean isReader() { - return opcode == Opcode.GETFIELD || opcode == Opcode.GETSTATIC; + return opcode == Opcode.GETFIELD || opcode == Opcode.GETSTATIC; } /** * Returns true if the field is written in. */ public boolean isWriter() { - return opcode == Opcode.PUTFIELD || opcode == Opcode.PUTSTATIC; + return opcode == Opcode.PUTFIELD || opcode == Opcode.PUTSTATIC; } /** * Returns the class in which the field is declared. */ private CtClass getCtClass() throws NotFoundException { - return thisClass.getClassPool().get(getClassName()); + return thisClass.getClassPool().get(getClassName()); } /** * Returns the name of the class in which the field is declared. */ public String getClassName() { - int index = iterator.u16bitAt(currentPos + 1); - return getConstPool().getFieldrefClassName(index); + int index = iterator.u16bitAt(currentPos + 1); + return getConstPool().getFieldrefClassName(index); } /** * Returns the name of the field. */ public String getFieldName() { - int index = iterator.u16bitAt(currentPos + 1); - return getConstPool().getFieldrefName(index); + int index = iterator.u16bitAt(currentPos + 1); + return getConstPool().getFieldrefName(index); } /** * Returns the field accessed by this expression. */ public CtField getField() throws NotFoundException { - CtClass cc = getCtClass(); - return cc.getField(getFieldName()); + CtClass cc = getCtClass(); + return cc.getField(getFieldName()); } /** @@ -130,16 +119,16 @@ public class FieldAccess extends Expr { * the throws declaration allows the method to throw. */ public CtClass[] mayThrow() { - return super.mayThrow(); + return super.mayThrow(); } /* * Returns the type of the field. public CtClass getFieldType() throws NotFoundException { - int index = iterator.u16bitAt(currentPos + 1); - String type = getConstPool().getFieldrefType(index); - return Descriptor.toCtClass(type, thisClass.getClassPool()); + int index = iterator.u16bitAt(currentPos + 1); + String type = getConstPool().getFieldrefType(index); + return Descriptor.toCtClass(type, thisClass.getClassPool()); } */ @@ -151,150 +140,150 @@ public class FieldAccess extends Expr { * If the field access is writing, $_ is available but the value * of $_ is ignored. * - * @param statement a Java statement. + * @param statement a Java statement. */ public void replace(String statement) throws CannotCompileException { - ConstPool constPool = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - - Javac jc = new Javac(thisClass); - CodeAttribute ca = iterator.get(); - try { - CtClass[] params; - CtClass retType; - CtClass fieldType - = Descriptor.toCtClass(constPool.getFieldrefType(index), - thisClass.getClassPool()); - boolean read = isReader(); - if (read) { - params = new CtClass[0]; - retType = fieldType; - } - else { - params = new CtClass[1]; - params[0] = fieldType; - retType = CtClass.voidType; - } - - int paramVar = ca.getMaxLocals(); - jc.recordParams(constPool.getFieldrefClassName(index), params, - true, paramVar, withinStatic()); - - /* Is $_ included in the source code? - */ - boolean included = checkResultValue(retType, statement); - - int retVar = jc.recordReturnType(retType, included); - if (read) - jc.recordProceed(new ProceedForRead(retType, opcode, - index, paramVar)); - else { - // because $type is not the return type... - jc.recordType(fieldType); - jc.recordProceed(new ProceedForWrite(params[0], opcode, - index, paramVar)); - } - - Bytecode bytecode = jc.getBytecode(); - storeStack(params, isStatic(), paramVar, bytecode); - jc.compileStmnt(statement); - if (read) - bytecode.addLoad(retVar, retType); - - replace0(pos, bytecode, 3); - } - catch (CompileError e) { throw new CannotCompileException(e); } - catch (NotFoundException e) { throw new CannotCompileException(e); } - catch (BadBytecode e) { - throw new CannotCompileException("broken method"); - } + ConstPool constPool = getConstPool(); + int pos = currentPos; + int index = iterator.u16bitAt(pos + 1); + + Javac jc = new Javac(thisClass); + CodeAttribute ca = iterator.get(); + try { + CtClass[] params; + CtClass retType; + CtClass fieldType + = Descriptor.toCtClass(constPool.getFieldrefType(index), + thisClass.getClassPool()); + boolean read = isReader(); + if (read) { + params = new CtClass[0]; + retType = fieldType; + } + else { + params = new CtClass[1]; + params[0] = fieldType; + retType = CtClass.voidType; + } + + int paramVar = ca.getMaxLocals(); + jc.recordParams(constPool.getFieldrefClassName(index), params, + true, paramVar, withinStatic()); + + /* Is $_ included in the source code? + */ + boolean included = checkResultValue(retType, statement); + + int retVar = jc.recordReturnType(retType, included); + if (read) + jc.recordProceed(new ProceedForRead(retType, opcode, + index, paramVar)); + else { + // because $type is not the return type... + jc.recordType(fieldType); + jc.recordProceed(new ProceedForWrite(params[0], opcode, + index, paramVar)); + } + + Bytecode bytecode = jc.getBytecode(); + storeStack(params, isStatic(), paramVar, bytecode); + jc.compileStmnt(statement); + if (read) + bytecode.addLoad(retVar, retType); + + replace0(pos, bytecode, 3); + } + catch (CompileError e) { throw new CannotCompileException(e); } + catch (NotFoundException e) { throw new CannotCompileException(e); } + catch (BadBytecode e) { + throw new CannotCompileException("broken method"); + } } /* <field type> $proceed() */ static class ProceedForRead implements ProceedHandler { - CtClass fieldType; - int opcode; - int targetVar, index; - - ProceedForRead(CtClass type, int op, int i, int var) { - fieldType = type; - targetVar = var; - opcode = op; - index = i; - } - - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) - throws CompileError - { - if (args != null && !gen.isParamListName(args)) - throw new CompileError(Javac.proceedName - + "() cannot take a parameter for field reading"); - - int stack; - if (isStatic(opcode)) - stack = 0; - else { - stack = -1; - bytecode.addAload(targetVar); - } - - if (fieldType instanceof CtPrimitiveType) - stack += ((CtPrimitiveType)fieldType).getDataSize(); - else - ++stack; - - bytecode.add(opcode); - bytecode.addIndex(index); - bytecode.growStack(stack); - gen.setType(fieldType); - } + CtClass fieldType; + int opcode; + int targetVar, index; + + ProceedForRead(CtClass type, int op, int i, int var) { + fieldType = type; + targetVar = var; + opcode = op; + index = i; + } + + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + throws CompileError + { + if (args != null && !gen.isParamListName(args)) + throw new CompileError(Javac.proceedName + + "() cannot take a parameter for field reading"); + + int stack; + if (isStatic(opcode)) + stack = 0; + else { + stack = -1; + bytecode.addAload(targetVar); + } + + if (fieldType instanceof CtPrimitiveType) + stack += ((CtPrimitiveType)fieldType).getDataSize(); + else + ++stack; + + bytecode.add(opcode); + bytecode.addIndex(index); + bytecode.growStack(stack); + gen.setType(fieldType); + } } /* void $proceed(<field type>) - * the return type is not the field type but void. + * the return type is not the field type but void. */ static class ProceedForWrite implements ProceedHandler { - CtClass fieldType; - int opcode; - int targetVar, index; - - ProceedForWrite(CtClass type, int op, int i, int var) { - fieldType = type; - targetVar = var; - opcode = op; - index = i; - } - - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) - throws CompileError - { - if (gen.atMethodArgsLength(args) != 1) - throw new CompileError(Javac.proceedName - + "() cannot take more than one parameter " - + "for field writing"); - - int stack; - if (isStatic(opcode)) - stack = 0; - else { - stack = -1; - bytecode.addAload(targetVar); - } - - gen.atMethodArgs(args, new int[1], new int[1], new String[1]); - gen.doNumCast(fieldType); - if (fieldType instanceof CtPrimitiveType) - stack -= ((CtPrimitiveType)fieldType).getDataSize(); - else - --stack; - - bytecode.add(opcode); - bytecode.addIndex(index); - bytecode.growStack(stack); - gen.setType(CtClass.voidType); - gen.addNullIfVoid(); - } + CtClass fieldType; + int opcode; + int targetVar, index; + + ProceedForWrite(CtClass type, int op, int i, int var) { + fieldType = type; + targetVar = var; + opcode = op; + index = i; + } + + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + throws CompileError + { + if (gen.atMethodArgsLength(args) != 1) + throw new CompileError(Javac.proceedName + + "() cannot take more than one parameter " + + "for field writing"); + + int stack; + if (isStatic(opcode)) + stack = 0; + else { + stack = -1; + bytecode.addAload(targetVar); + } + + gen.atMethodArgs(args, new int[1], new int[1], new String[1]); + gen.doNumCast(fieldType); + if (fieldType instanceof CtPrimitiveType) + stack -= ((CtPrimitiveType)fieldType).getDataSize(); + else + --stack; + + bytecode.add(opcode); + bytecode.addIndex(index); + bytecode.growStack(stack); + gen.setType(CtClass.voidType); + gen.addNullIfVoid(); + } } } diff --git a/src/main/javassist/expr/Instanceof.java b/src/main/javassist/expr/Instanceof.java index 5b980f8e..ce66d977 100644 --- a/src/main/javassist/expr/Instanceof.java +++ b/src/main/javassist/expr/Instanceof.java @@ -1,28 +1,17 @@ /* - * This file is part of the Javassist toolkit. + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2003 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. You may obtain a copy of the License at - * either http://www.mozilla.org/MPL/. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * 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. - * - * The Original Code is Javassist. - * - * The Initial Developer of the Original Code is Shigeru Chiba. Portions - * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. - * All Rights Reserved. - * - * Contributor(s): - * - * The development of this software is supported in part by the PRESTO - * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. */ - package javassist.expr; import javassist.*; @@ -38,7 +27,7 @@ public class Instanceof extends Expr { * Undocumented constructor. Do not use; internal-use only. */ Instanceof(int pos, CodeIterator i, CtClass declaring, MethodInfo m) { - super(pos, i, declaring, m); + super(pos, i, declaring, m); } /** @@ -51,20 +40,20 @@ public class Instanceof extends Expr { * Returns the line number of the source line containing the * instanceof expression. * - * @return -1 if this information is not available. + * @return -1 if this information is not available. */ public int getLineNumber() { - return super.getLineNumber(); + return super.getLineNumber(); } /** * Returns the source file containing the * instanceof expression. * - * @return null if this information is not available. + * @return null if this information is not available. */ public String getFileName() { - return super.getFileName(); + return super.getFileName(); } /** @@ -73,11 +62,11 @@ public class Instanceof extends Expr { * of the instanceof operator. */ public CtClass getType() throws NotFoundException { - ConstPool cp = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - String name = cp.getClassInfo(index); - return Descriptor.toCtClass(name, thisClass.getClassPool()); + ConstPool cp = getConstPool(); + int pos = currentPos; + int index = iterator.u16bitAt(pos + 1); + String name = cp.getClassInfo(index); + return Descriptor.toCtClass(name, thisClass.getClassPool()); } /** @@ -87,7 +76,7 @@ public class Instanceof extends Expr { * the throws declaration allows the method to throw. */ public CtClass[] mayThrow() { - return super.mayThrow(); + return super.mayThrow(); } /** @@ -96,70 +85,70 @@ public class Instanceof extends Expr { * * <p>$0 is available but the value is <code>null</code>. * - * @param statement a Java statement. + * @param statement a Java statement. */ public void replace(String statement) throws CannotCompileException { - ConstPool constPool = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - - Javac jc = new Javac(thisClass); - ClassPool cp = thisClass.getClassPool(); - CodeAttribute ca = iterator.get(); - - try { - CtClass[] params - = new CtClass[] { cp.get(javaLangObject) }; - CtClass retType = CtClass.booleanType; - - int paramVar = ca.getMaxLocals(); - jc.recordParams(javaLangObject, params, true, paramVar, - withinStatic()); - int retVar = jc.recordReturnType(retType, true); - jc.recordProceed(new ProceedForInstanceof(index)); - - // because $type is not the return type... - jc.recordType(getType()); - - /* Is $_ included in the source code? - */ - checkResultValue(retType, statement); - - Bytecode bytecode = jc.getBytecode(); - storeStack(params, true, paramVar, bytecode); - jc.compileStmnt(statement); - bytecode.addLoad(retVar, retType); - - replace0(pos, bytecode, 3); - } - catch (CompileError e) { throw new CannotCompileException(e); } - catch (NotFoundException e) { throw new CannotCompileException(e); } - catch (BadBytecode e) { - throw new CannotCompileException("broken method"); - } + ConstPool constPool = getConstPool(); + int pos = currentPos; + int index = iterator.u16bitAt(pos + 1); + + Javac jc = new Javac(thisClass); + ClassPool cp = thisClass.getClassPool(); + CodeAttribute ca = iterator.get(); + + try { + CtClass[] params + = new CtClass[] { cp.get(javaLangObject) }; + CtClass retType = CtClass.booleanType; + + int paramVar = ca.getMaxLocals(); + jc.recordParams(javaLangObject, params, true, paramVar, + withinStatic()); + int retVar = jc.recordReturnType(retType, true); + jc.recordProceed(new ProceedForInstanceof(index)); + + // because $type is not the return type... + jc.recordType(getType()); + + /* Is $_ included in the source code? + */ + checkResultValue(retType, statement); + + Bytecode bytecode = jc.getBytecode(); + storeStack(params, true, paramVar, bytecode); + jc.compileStmnt(statement); + bytecode.addLoad(retVar, retType); + + replace0(pos, bytecode, 3); + } + catch (CompileError e) { throw new CannotCompileException(e); } + catch (NotFoundException e) { throw new CannotCompileException(e); } + catch (BadBytecode e) { + throw new CannotCompileException("broken method"); + } } /* boolean $proceed(Object obj) */ static class ProceedForInstanceof implements ProceedHandler { - int index; - - ProceedForInstanceof(int i) { - index = i; - } - - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) - throws CompileError - { - if (gen.atMethodArgsLength(args) != 1) - throw new CompileError(Javac.proceedName - + "() cannot take more than one parameter " - + "for instanceof"); - - gen.atMethodArgs(args, new int[1], new int[1], new String[1]); - bytecode.addOpcode(Opcode.INSTANCEOF); - bytecode.addIndex(index); - gen.setType(CtClass.booleanType); - } + int index; + + ProceedForInstanceof(int i) { + index = i; + } + + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + throws CompileError + { + if (gen.atMethodArgsLength(args) != 1) + throw new CompileError(Javac.proceedName + + "() cannot take more than one parameter " + + "for instanceof"); + + gen.atMethodArgs(args, new int[1], new int[1], new String[1]); + bytecode.addOpcode(Opcode.INSTANCEOF); + bytecode.addIndex(index); + gen.setType(CtClass.booleanType); + } } } diff --git a/src/main/javassist/expr/MethodCall.java b/src/main/javassist/expr/MethodCall.java index 747380b4..e0801659 100644 --- a/src/main/javassist/expr/MethodCall.java +++ b/src/main/javassist/expr/MethodCall.java @@ -1,28 +1,17 @@ /* - * This file is part of the Javassist toolkit. + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2003 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. You may obtain a copy of the License at - * either http://www.mozilla.org/MPL/. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * 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. - * - * The Original Code is Javassist. - * - * The Initial Developer of the Original Code is Shigeru Chiba. Portions - * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. - * All Rights Reserved. - * - * Contributor(s): - * - * The development of this software is supported in part by the PRESTO - * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. */ - package javassist.expr; import javassist.*; @@ -37,19 +26,19 @@ public class MethodCall extends Expr { * Undocumented constructor. Do not use; internal-use only. */ MethodCall(int pos, CodeIterator i, CtClass declaring, MethodInfo m) { - super(pos, i, declaring, m); + super(pos, i, declaring, m); } private int getNameAndType(ConstPool cp) { - String cname; - int pos = currentPos; - int c = iterator.byteAt(pos); - int index = iterator.u16bitAt(pos + 1); - - if (c == INVOKEINTERFACE) - return cp.getInterfaceMethodrefNameAndType(index); - else - return cp.getMethodrefNameAndType(index); + String cname; + int pos = currentPos; + int c = iterator.byteAt(pos); + int index = iterator.u16bitAt(pos + 1); + + if (c == INVOKEINTERFACE) + return cp.getInterfaceMethodrefNameAndType(index); + else + return cp.getMethodrefNameAndType(index); } /** @@ -62,19 +51,19 @@ public class MethodCall extends Expr { * Returns the line number of the source line containing the * method call. * - * @return -1 if this information is not available. + * @return -1 if this information is not available. */ public int getLineNumber() { - return super.getLineNumber(); + return super.getLineNumber(); } /** * Returns the source file containing the method call. * - * @return null if this information is not available. + * @return null if this information is not available. */ public String getFileName() { - return super.getFileName(); + return super.getFileName(); } /** @@ -82,7 +71,7 @@ public class MethodCall extends Expr { * which the method is called on. */ private CtClass getCtClass() throws NotFoundException { - return thisClass.getClassPool().get(getClassName()); + return thisClass.getClassPool().get(getClassName()); } /** @@ -90,41 +79,41 @@ public class MethodCall extends Expr { * which the method is called on. */ public String getClassName() { - String cname; + String cname; - ConstPool cp = getConstPool(); - int pos = currentPos; - int c = iterator.byteAt(pos); - int index = iterator.u16bitAt(pos + 1); + ConstPool cp = getConstPool(); + int pos = currentPos; + int c = iterator.byteAt(pos); + int index = iterator.u16bitAt(pos + 1); - if (c == INVOKEINTERFACE) - cname = cp.getInterfaceMethodrefClassName(index); - else - cname = cp.getMethodrefClassName(index); + if (c == INVOKEINTERFACE) + cname = cp.getInterfaceMethodrefClassName(index); + else + cname = cp.getMethodrefClassName(index); - return cname; + return cname; } /** * Returns the name of the called method. */ public String getMethodName() { - ConstPool cp = getConstPool(); - int nt = getNameAndType(cp); - return cp.getUtf8Info(cp.getNameAndTypeName(nt)); + ConstPool cp = getConstPool(); + int nt = getNameAndType(cp); + return cp.getUtf8Info(cp.getNameAndTypeName(nt)); } /** * Returns the called method. */ public CtMethod getMethod() throws NotFoundException { - return getCtClass().getMethod(getMethodName(), getMethodDesc()); + return getCtClass().getMethod(getMethodName(), getMethodDesc()); } private String getMethodDesc() { - ConstPool cp = getConstPool(); - int nt = getNameAndType(cp); - return cp.getUtf8Info(cp.getNameAndTypeDescriptor(nt)); + ConstPool cp = getConstPool(); + int nt = getNameAndType(cp); + return cp.getUtf8Info(cp.getNameAndTypeDescriptor(nt)); } /** @@ -134,15 +123,15 @@ public class MethodCall extends Expr { * the throws declaration allows the method to throw. */ public CtClass[] mayThrow() { - return super.mayThrow(); + return super.mayThrow(); } /* * Returns the parameter types of the called method. public CtClass[] getParameterTypes() throws NotFoundException { - return Descriptor.getParameterTypes(getMethodDesc(), - thisClass.getClassPool()); + return Descriptor.getParameterTypes(getMethodDesc(), + thisClass.getClassPool()); } */ @@ -150,8 +139,8 @@ public class MethodCall extends Expr { * Returns the return type of the called method. public CtClass getReturnType() throws NotFoundException { - return Descriptor.getReturnType(getMethodDesc(), - thisClass.getClassPool()); + return Descriptor.getReturnType(getMethodDesc(), + thisClass.getClassPool()); } */ @@ -161,60 +150,60 @@ public class MethodCall extends Expr { * * <p>$0 is available even if the called method is static. * - * @param statement a Java statement. + * @param statement a Java statement. */ public void replace(String statement) throws CannotCompileException { - ConstPool constPool = getConstPool(); - int pos = currentPos; - int index = iterator.u16bitAt(pos + 1); - - String classname, methodname, signature; - int opcodeSize; - int c = iterator.byteAt(pos); - if (c == INVOKEINTERFACE) { - opcodeSize = 5; - classname = constPool.getInterfaceMethodrefClassName(index); - methodname = constPool.getInterfaceMethodrefName(index); - signature = constPool.getInterfaceMethodrefType(index); - } - else if (c == INVOKESTATIC - || c == INVOKESPECIAL || c == INVOKEVIRTUAL) { - opcodeSize = 3; - classname = constPool.getMethodrefClassName(index); - methodname = constPool.getMethodrefName(index); - signature = constPool.getMethodrefType(index); - } - else - throw new CannotCompileException("not method invocation"); - - Javac jc = new Javac(thisClass); - ClassPool cp = thisClass.getClassPool(); - CodeAttribute ca = iterator.get(); - try { - CtClass[] params = Descriptor.getParameterTypes(signature, cp); - CtClass retType = Descriptor.getReturnType(signature, cp); - int paramVar = ca.getMaxLocals(); - jc.recordParams(classname, params, - true, paramVar, withinStatic()); - int retVar = jc.recordReturnType(retType, true); - jc.recordProceed(Javac.param0Name, methodname); - - /* Is $_ included in the source code? - */ - checkResultValue(retType, statement); - - Bytecode bytecode = jc.getBytecode(); - storeStack(params, c == INVOKESTATIC, paramVar, bytecode); - jc.compileStmnt(statement); - if (retType != CtClass.voidType) - bytecode.addLoad(retVar, retType); - - replace0(pos, bytecode, opcodeSize); - } - catch (CompileError e) { throw new CannotCompileException(e); } - catch (NotFoundException e) { throw new CannotCompileException(e); } - catch (BadBytecode e) { - throw new CannotCompileException("broken method"); - } + ConstPool constPool = getConstPool(); + int pos = currentPos; + int index = iterator.u16bitAt(pos + 1); + + String classname, methodname, signature; + int opcodeSize; + int c = iterator.byteAt(pos); + if (c == INVOKEINTERFACE) { + opcodeSize = 5; + classname = constPool.getInterfaceMethodrefClassName(index); + methodname = constPool.getInterfaceMethodrefName(index); + signature = constPool.getInterfaceMethodrefType(index); + } + else if (c == INVOKESTATIC + || c == INVOKESPECIAL || c == INVOKEVIRTUAL) { + opcodeSize = 3; + classname = constPool.getMethodrefClassName(index); + methodname = constPool.getMethodrefName(index); + signature = constPool.getMethodrefType(index); + } + else + throw new CannotCompileException("not method invocation"); + + Javac jc = new Javac(thisClass); + ClassPool cp = thisClass.getClassPool(); + CodeAttribute ca = iterator.get(); + try { + CtClass[] params = Descriptor.getParameterTypes(signature, cp); + CtClass retType = Descriptor.getReturnType(signature, cp); + int paramVar = ca.getMaxLocals(); + jc.recordParams(classname, params, + true, paramVar, withinStatic()); + int retVar = jc.recordReturnType(retType, true); + jc.recordProceed(Javac.param0Name, methodname); + + /* Is $_ included in the source code? + */ + checkResultValue(retType, statement); + + Bytecode bytecode = jc.getBytecode(); + storeStack(params, c == INVOKESTATIC, paramVar, bytecode); + jc.compileStmnt(statement); + if (retType != CtClass.voidType) + bytecode.addLoad(retVar, retType); + + replace0(pos, bytecode, opcodeSize); + } + catch (CompileError e) { throw new CannotCompileException(e); } + catch (NotFoundException e) { throw new CannotCompileException(e); } + catch (BadBytecode e) { + throw new CannotCompileException("broken method"); + } } } diff --git a/src/main/javassist/expr/NewExpr.java b/src/main/javassist/expr/NewExpr.java index 73546238..b816867a 100644 --- a/src/main/javassist/expr/NewExpr.java +++ b/src/main/javassist/expr/NewExpr.java @@ -1,28 +1,17 @@ /* - * This file is part of the Javassist toolkit. + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2003 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. You may obtain a copy of the License at - * either http://www.mozilla.org/MPL/. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * 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. - * - * The Original Code is Javassist. - * - * The Initial Developer of the Original Code is Shigeru Chiba. Portions - * created by Shigeru Chiba are Copyright (C) 1999-2003 Shigeru Chiba. - * All Rights Reserved. - * - * Contributor(s): - * - * The development of this software is supported in part by the PRESTO - * program (Sakigake Kenkyu 21) of Japan Science and Technology Corporation. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. */ - package javassist.expr; import javassist.*; @@ -42,23 +31,23 @@ public class NewExpr extends Expr { * Undocumented constructor. Do not use; internal-use only. */ NewExpr(int pos, CodeIterator i, CtClass declaring, MethodInfo m, - String type, int np) + String type, int np) { - super(pos, i, declaring, m); - newTypeName = type; - newPos = np; + super(pos, i, declaring, m); + newTypeName = type; + newPos = np; } private int getNameAndType(ConstPool cp) { - String cname; - int pos = currentPos; - int c = iterator.byteAt(pos); - int index = iterator.u16bitAt(pos + 1); - - if (c == INVOKEINTERFACE) - return cp.getInterfaceMethodrefNameAndType(index); - else - return cp.getMethodrefNameAndType(index); + String cname; + int pos = currentPos; + int c = iterator.byteAt(pos); + int index = iterator.u16bitAt(pos + 1); + + if (c == INVOKEINTERFACE) + return cp.getInterfaceMethodrefNameAndType(index); + else + return cp.getMethodrefNameAndType(index); } /** @@ -71,43 +60,43 @@ public class NewExpr extends Expr { * Returns the line number of the source line containing the * <tt>new</tt> expression. * - * @return -1 if this information is not available. + * @return -1 if this information is not available. */ public int getLineNumber() { - return super.getLineNumber(); + return super.getLineNumber(); } /** * Returns the source file containing the <tt>new</tt> expression. * - * @return null if this information is not available. + * @return null if this information is not available. */ public String getFileName() { - return super.getFileName(); + return super.getFileName(); } /** * Returns the class of the created object. */ private CtClass getCtClass() throws NotFoundException { - return thisClass.getClassPool().get(newTypeName); + return thisClass.getClassPool().get(newTypeName); } /** * Returns the class name of the created object. */ public String getClassName() { - return newTypeName; + return newTypeName; } /** * Returns the constructor called for creating the object. */ public CtConstructor getConstructor() throws NotFoundException { - ConstPool cp = getConstPool(); - int index = iterator.u16bitAt(currentPos + 1); - String desc = cp.getMethodrefType(index); - return getCtClass().getConstructor(desc); + ConstPool cp = getConstPool(); + int index = iterator.u16bitAt(currentPos + 1); + String desc = cp.getMethodrefType(index); + return getCtClass().getConstructor(desc); } /** @@ -117,30 +106,30 @@ public class NewExpr extends Expr { * the throws declaration allows the method to throw. */ public CtClass[] mayThrow() { - return super.mayThrow(); + return super.mayThrow(); } /* * Returns the parameter types of the constructor. public CtClass[] getParameterTypes() throws NotFoundException { - ConstPool cp = getConstPool(); - int index = iterator.u16bitAt(currentPos + 1); - String desc = cp.getMethodrefType(index); - return Descriptor.getParameterTypes(desc, thisClass.getClassPool()); + ConstPool cp = getConstPool(); + int index = iterator.u16bitAt(currentPos + 1); + String desc = cp.getMethodrefType(index); + return Descriptor.getParameterTypes(desc, thisClass.getClassPool()); } */ private int canReplace() throws CannotCompileException { - int op = iterator.byteAt(newPos + 3); - if (op == Opcode.DUP) - return 4; - else if (op == Opcode.DUP_X1 - && iterator.byteAt(newPos + 4) == Opcode.SWAP) - return 5; - else - throw new CannotCompileException( - "sorry, cannot edit NEW followed by no DUP"); + int op = iterator.byteAt(newPos + 3); + if (op == Opcode.DUP) + return 4; + else if (op == Opcode.DUP_X1 + && iterator.byteAt(newPos + 4) == Opcode.SWAP) + return 5; + else + throw new CannotCompileException( + "sorry, cannot edit NEW followed by no DUP"); } /** @@ -149,76 +138,76 @@ public class NewExpr extends Expr { * * <p>$0 is available but the value is null. * - * @param statement a Java statement. + * @param statement a Java statement. */ public void replace(String statement) throws CannotCompileException { - final int bytecodeSize = 3; - int pos = newPos; - - int newIndex = iterator.u16bitAt(pos + 1); - - /* delete the preceding NEW and DUP (or DUP_X1, SWAP) instructions. - */ - int end = pos + canReplace(); - for (int i = pos; i < end; ++i) - iterator.writeByte(NOP, i); - - ConstPool constPool = getConstPool(); - pos = currentPos; - int methodIndex = iterator.u16bitAt(pos + 1); // constructor - - String signature = constPool.getMethodrefType(methodIndex); - - Javac jc = new Javac(thisClass); - ClassPool cp = thisClass.getClassPool(); - CodeAttribute ca = iterator.get(); - try { - CtClass[] params = Descriptor.getParameterTypes(signature, cp); - CtClass newType = cp.get(newTypeName); - int paramVar = ca.getMaxLocals(); - jc.recordParams(newTypeName, params, - true, paramVar, withinStatic()); - int retVar = jc.recordReturnType(newType, true); - jc.recordProceed(new ProceedForNew(newType, newIndex, - methodIndex)); - - /* Is $_ included in the source code? - */ - checkResultValue(newType, statement); - - Bytecode bytecode = jc.getBytecode(); - storeStack(params, true, paramVar, bytecode); - jc.compileStmnt(statement); - bytecode.addAload(retVar); - - replace0(pos, bytecode, bytecodeSize); - } - catch (CompileError e) { throw new CannotCompileException(e); } - catch (NotFoundException e) { throw new CannotCompileException(e); } - catch (BadBytecode e) { - throw new CannotCompileException("broken method"); - } + final int bytecodeSize = 3; + int pos = newPos; + + int newIndex = iterator.u16bitAt(pos + 1); + + /* delete the preceding NEW and DUP (or DUP_X1, SWAP) instructions. + */ + int end = pos + canReplace(); + for (int i = pos; i < end; ++i) + iterator.writeByte(NOP, i); + + ConstPool constPool = getConstPool(); + pos = currentPos; + int methodIndex = iterator.u16bitAt(pos + 1); // constructor + + String signature = constPool.getMethodrefType(methodIndex); + + Javac jc = new Javac(thisClass); + ClassPool cp = thisClass.getClassPool(); + CodeAttribute ca = iterator.get(); + try { + CtClass[] params = Descriptor.getParameterTypes(signature, cp); + CtClass newType = cp.get(newTypeName); + int paramVar = ca.getMaxLocals(); + jc.recordParams(newTypeName, params, + true, paramVar, withinStatic()); + int retVar = jc.recordReturnType(newType, true); + jc.recordProceed(new ProceedForNew(newType, newIndex, + methodIndex)); + + /* Is $_ included in the source code? + */ + checkResultValue(newType, statement); + + Bytecode bytecode = jc.getBytecode(); + storeStack(params, true, paramVar, bytecode); + jc.compileStmnt(statement); + bytecode.addAload(retVar); + + replace0(pos, bytecode, bytecodeSize); + } + catch (CompileError e) { throw new CannotCompileException(e); } + catch (NotFoundException e) { throw new CannotCompileException(e); } + catch (BadBytecode e) { + throw new CannotCompileException("broken method"); + } } static class ProceedForNew implements ProceedHandler { - CtClass newType; - int newIndex, methodIndex; - - ProceedForNew(CtClass nt, int ni, int mi) { - newType = nt; - newIndex = ni; - methodIndex = mi; - } - - public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) - throws CompileError - { - bytecode.addOpcode(NEW); - bytecode.addIndex(newIndex); - bytecode.addOpcode(DUP); - gen.atMethodCall2(newType, MethodInfo.nameInit, - args, false, true); - gen.setType(newType); - } + CtClass newType; + int newIndex, methodIndex; + + ProceedForNew(CtClass nt, int ni, int mi) { + newType = nt; + newIndex = ni; + methodIndex = mi; + } + + public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) + throws CompileError + { + bytecode.addOpcode(NEW); + bytecode.addIndex(newIndex); + bytecode.addOpcode(DUP); + gen.atMethodCall2(newType, MethodInfo.nameInit, + args, false, true); + gen.setType(newType); + } } } diff --git a/src/main/javassist/expr/package.html b/src/main/javassist/expr/package.html new file mode 100644 index 00000000..12a2c637 --- /dev/null +++ b/src/main/javassist/expr/package.html @@ -0,0 +1,8 @@ +<html> +<body> + +<p>This package contains the classes for modifying a method body. +See <code>ExprEditor</code> (expression editor) for more details. + +</body> +</html> |