diff options
-rw-r--r-- | Readme.html | 2 | ||||
-rw-r--r-- | src/main/javassist/CtBehavior.java | 11 | ||||
-rw-r--r-- | src/main/javassist/CtClass.java | 2 | ||||
-rw-r--r-- | src/main/javassist/compiler/Javac.java | 72 | ||||
-rw-r--r-- | src/main/javassist/compiler/JvstCodeGen.java | 22 | ||||
-rw-r--r-- | src/main/javassist/expr/Cast.java | 1 | ||||
-rw-r--r-- | src/main/javassist/expr/FieldAccess.java | 1 | ||||
-rw-r--r-- | src/main/javassist/expr/Instanceof.java | 1 | ||||
-rw-r--r-- | src/main/javassist/expr/MethodCall.java | 1 | ||||
-rw-r--r-- | src/main/javassist/expr/NewExpr.java | 1 | ||||
-rw-r--r-- | tutorial/tutorial.html | 2 | ||||
-rw-r--r-- | tutorial/tutorial2.html | 35 |
12 files changed, 119 insertions, 32 deletions
diff --git a/Readme.html b/Readme.html index 7fad5788..3d688faa 100644 --- a/Readme.html +++ b/Readme.html @@ -253,6 +253,8 @@ see javassist.Dump. <p>- version 2.7 <ul> + <li>Now local variables were made available in the source text passed to + CtBehavior.insertBefore(), MethodCall.replace(), etc. <li>CtClass.main(), which prints the version number, has been added. <li>ClassPool.SimpleLoader has been public. <li>javassist.bytecode.DeprecatedAttribute has been added. diff --git a/src/main/javassist/CtBehavior.java b/src/main/javassist/CtBehavior.java index 52a13095..ea256482 100644 --- a/src/main/javassist/CtBehavior.java +++ b/src/main/javassist/CtBehavior.java @@ -352,8 +352,9 @@ public abstract class CtBehavior extends CtMember { CodeIterator iterator = ca.iterator(); Javac jv = new Javac(declaringClass); try { - jv.recordParams(getParameterTypes(), - Modifier.isStatic(getModifiers())); + int nvars = jv.recordParams(getParameterTypes(), + Modifier.isStatic(getModifiers())); + jv.recordParamNames(ca, nvars); jv.compileStmnt(src); Bytecode b = jv.getBytecode(); int stack = b.getMaxStack(); @@ -418,8 +419,9 @@ public abstract class CtBehavior extends CtMember { b.setStackDepth(ca.getMaxStack() + 1); Javac jv = new Javac(b, declaringClass); try { - jv.recordParams(getParameterTypes(), - Modifier.isStatic(getModifiers())); + int nvars = jv.recordParams(getParameterTypes(), + Modifier.isStatic(getModifiers())); + jv.recordParamNames(ca, nvars); CtClass rtype = getReturnType0(); int varNo = jv.recordReturnType(rtype, true); @@ -750,6 +752,7 @@ public abstract class CtBehavior extends CtMember { CodeIterator iterator = ca.iterator(); Javac jv = new Javac(declaringClass); try { + jv.recordLocalVariables(ca, index); jv.recordParams(getParameterTypes(), Modifier.isStatic(getModifiers())); jv.compileStmnt(src); diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index bded5c90..268c40f1 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -36,7 +36,7 @@ public abstract class CtClass { /** * The version number of this release. */ - public static final String version = "2.7 alpha 7"; + public static final String version = "2.7 alpha 8"; /** * Prints the version number and the copyright notice. diff --git a/src/main/javassist/compiler/Javac.java b/src/main/javassist/compiler/Javac.java index 4f83bda8..5e20e7e8 100644 --- a/src/main/javassist/compiler/Javac.java +++ b/src/main/javassist/compiler/Javac.java @@ -25,6 +25,8 @@ import javassist.CtConstructor; import javassist.CannotCompileException; import javassist.Modifier; import javassist.bytecode.Bytecode; +import javassist.bytecode.CodeAttribute; +import javassist.bytecode.LocalVariableAttribute; import javassist.bytecode.Opcode; import javassist.NotFoundException; @@ -242,6 +244,66 @@ public class Javac { } /** + * Records local variables available at the specified program counter. + * If the LocalVariableAttribute is not available, this method does not + * record any local variable. It only returns false. + * + * @param pc program counter (>= 0) + * @return false if the CodeAttribute does not include a + * LocalVariableAttribute. + */ + public boolean recordLocalVariables(CodeAttribute ca, int pc) + throws CompileError + { + LocalVariableAttribute va + = (LocalVariableAttribute) + ca.getAttribute(LocalVariableAttribute.tag); + if (va == null) + return false; + + int n = va.tableLength(); + for (int i = 0; i < n; ++i) { + int start = va.startPc(i); + int len = va.codeLength(i); + if (start <= pc && pc < start + len) + gen.recordVariable(va.descriptor(i), va.variableName(i), + va.index(i), stable); + } + + return true; + } + + /** + * Records parameter names if the LocalVariableAttribute is available. + * It returns false unless the LocalVariableAttribute is available. + * + * @param numOfLocalVars the number of local variables used + * for storing the parameters. + * @return false if the CodeAttribute does not include a + * LocalVariableAttribute. + */ + public boolean recordParamNames(CodeAttribute ca, int numOfLocalVars) + throws CompileError + { + LocalVariableAttribute va + = (LocalVariableAttribute) + ca.getAttribute(LocalVariableAttribute.tag); + if (va == null) + return false; + + int n = va.tableLength(); + for (int i = 0; i < n; ++i) { + int index = va.index(i); + if (index < numOfLocalVars) + gen.recordVariable(va.descriptor(i), va.variableName(i), + index, stable); + } + + return true; + } + + + /** * Makes variables $0 (this), $1, $2, ..., and $args represent method * parameters. $args represents an array of all the parameters. * It also makes $$ available as a parameter list of method call. @@ -250,10 +312,10 @@ public class Javac { * <code>compileExpr()</code>. The correct value of * <code>isStatic</code> must be recorded before compilation. */ - public void recordParams(CtClass[] params, boolean isStatic) + public int recordParams(CtClass[] params, boolean isStatic) throws CompileError { - gen.recordParams(params, isStatic, "$", "$args", "$$", stable); + return gen.recordParams(params, isStatic, "$", "$args", "$$", stable); } /** @@ -273,12 +335,12 @@ public class Javac { * @param isStatic true if the method in which the compiled bytecode * is embedded is static. */ - public void recordParams(String target, CtClass[] params, + public int recordParams(String target, CtClass[] params, boolean use0, int varNo, boolean isStatic) throws CompileError { - gen.recordParams(params, isStatic, "$", "$args", "$$", - use0, varNo, target, stable); + return gen.recordParams(params, isStatic, "$", "$args", "$$", + use0, varNo, target, stable); } /** diff --git a/src/main/javassist/compiler/JvstCodeGen.java b/src/main/javassist/compiler/JvstCodeGen.java index 07e7521b..6c78f477 100644 --- a/src/main/javassist/compiler/JvstCodeGen.java +++ b/src/main/javassist/compiler/JvstCodeGen.java @@ -462,13 +462,13 @@ public class JvstCodeGen extends MemberCodeGen { * $0 is equivalent to THIS if the method is not static. Otherwise, * if the method is static, then $0 is not available. */ - public void recordParams(CtClass[] params, boolean isStatic, + public int recordParams(CtClass[] params, boolean isStatic, String prefix, String paramVarName, String paramsName, SymbolTable tbl) throws CompileError { - recordParams(params, isStatic, prefix, paramVarName, - paramsName, !isStatic, 0, getThisName(), tbl); + return recordParams(params, isStatic, prefix, paramVarName, + paramsName, !isStatic, 0, getThisName(), tbl); } /** @@ -484,11 +484,11 @@ public class JvstCodeGen extends MemberCodeGen { * @param isStatic true if the method in which the compiled bytecode * is embedded is static. */ - public void recordParams(CtClass[] params, boolean isStatic, - String prefix, String paramVarName, - String paramsName, boolean use0, - int paramBase, String target, - SymbolTable tbl) + public int recordParams(CtClass[] params, boolean isStatic, + String prefix, String paramVarName, + String paramsName, boolean use0, + int paramBase, String target, + SymbolTable tbl) throws CompileError { int varNo; @@ -516,6 +516,8 @@ public class JvstCodeGen extends MemberCodeGen { if (getMaxLocals() < varNo) setMaxLocals(varNo); + + return varNo; } /** @@ -574,9 +576,9 @@ public class JvstCodeGen extends MemberCodeGen { String cname = null; if (type == CLASS) { if (dim == 0) - cname = typeDesc; + cname = typeDesc.substring(1, typeDesc.length() - 1); else - cname = typeDesc.substring(dim); + cname = typeDesc.substring(dim + 1, typeDesc.length() - 1); } Declarator decl diff --git a/src/main/javassist/expr/Cast.java b/src/main/javassist/expr/Cast.java index 33324ce4..80ad4012 100644 --- a/src/main/javassist/expr/Cast.java +++ b/src/main/javassist/expr/Cast.java @@ -112,6 +112,7 @@ public class Cast extends Expr { Bytecode bytecode = jc.getBytecode(); storeStack(params, true, paramVar, bytecode); + jc.recordLocalVariables(ca, pos); jc.compileStmnt(statement); bytecode.addLoad(retVar, retType); diff --git a/src/main/javassist/expr/FieldAccess.java b/src/main/javassist/expr/FieldAccess.java index cc1f06f5..8598f456 100644 --- a/src/main/javassist/expr/FieldAccess.java +++ b/src/main/javassist/expr/FieldAccess.java @@ -188,6 +188,7 @@ public class FieldAccess extends Expr { Bytecode bytecode = jc.getBytecode(); storeStack(params, isStatic(), paramVar, bytecode); + jc.recordLocalVariables(ca, pos); jc.compileStmnt(statement); if (read) bytecode.addLoad(retVar, retType); diff --git a/src/main/javassist/expr/Instanceof.java b/src/main/javassist/expr/Instanceof.java index 1421faee..a0982583 100644 --- a/src/main/javassist/expr/Instanceof.java +++ b/src/main/javassist/expr/Instanceof.java @@ -117,6 +117,7 @@ public class Instanceof extends Expr { Bytecode bytecode = jc.getBytecode(); storeStack(params, true, paramVar, bytecode); + jc.recordLocalVariables(ca, pos); jc.compileStmnt(statement); bytecode.addLoad(retVar, retType); diff --git a/src/main/javassist/expr/MethodCall.java b/src/main/javassist/expr/MethodCall.java index 60ec45da..28ed8d2d 100644 --- a/src/main/javassist/expr/MethodCall.java +++ b/src/main/javassist/expr/MethodCall.java @@ -210,6 +210,7 @@ public class MethodCall extends Expr { Bytecode bytecode = jc.getBytecode(); storeStack(params, c == INVOKESTATIC, paramVar, bytecode); + jc.recordLocalVariables(ca, pos); jc.compileStmnt(statement); if (retType != CtClass.voidType) bytecode.addLoad(retVar, retType); diff --git a/src/main/javassist/expr/NewExpr.java b/src/main/javassist/expr/NewExpr.java index 9d4f20e1..1fa7d4e9 100644 --- a/src/main/javassist/expr/NewExpr.java +++ b/src/main/javassist/expr/NewExpr.java @@ -177,6 +177,7 @@ public class NewExpr extends Expr { Bytecode bytecode = jc.getBytecode(); storeStack(params, true, paramVar, bytecode); + jc.recordLocalVariables(ca, pos); jc.compileStmnt(statement); bytecode.addAload(retVar); diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html index 77c3dc97..c68eb814 100644 --- a/tutorial/tutorial.html +++ b/tutorial/tutorial.html @@ -690,6 +690,6 @@ binary code license.</i> <hr> Java(TM) is a trademark of Sun Microsystems, Inc.<br> -Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved. +Copyright (C) 2000-2004 by Shigeru Chiba, All rights reserved. </body> </html> diff --git a/tutorial/tutorial2.html b/tutorial/tutorial2.html index 0e7530bf..b78c1ae1 100644 --- a/tutorial/tutorial2.html +++ b/tutorial/tutorial2.html @@ -149,12 +149,20 @@ if (i < 0) { i = -i; } </pre></ul> <p>The statement and the block can refer to fields and methods. -However, they <em>cannot refer to local variables</em> declared in the -method that they are inserted into. -They can refer to the parameters -to the method although they must use different names -<code>$0</code>, <code>$1</code>, <code>$2</code>, ... described -below. Declaring a local variable in the block is allowed. +They can also refer to the parameters +to the method that they are inserted into +if that method was compiled with the -g option +(to include a local variable attribute in the class file). +Otherwise, they must access the method parameters through the special +variables <code>$0</code>, <code>$1</code>, <code>$2</code>, ... described +below. +<em>Accessing local variables declared in the method is not allowed</em> +although declaring a new local variable in the block is allowed. +However, <code>insertAt()</code> allows the statement and the block +to access local variables +if these variables are available at the specified line number +and the target method was compiled with the -g option. + <!-- <p><center><table border=8 cellspacing=0 bordercolor="#cfcfcf"> @@ -166,8 +174,8 @@ below. Declaring a local variable in the block is allowed. --> <p>The <code>String</code> object passed to the methods -<code>insertBefore()</code>, <code>insertAfter()</code>, and -<code>addCatch()</code> are compiled by +<code>insertBefore()</code>, <code>insertAfter()</code>, +<code>addCatch()</code>, and <code>insertAt()</code> are compiled by the compiler included in Javassist. Since the compiler supports language extensions, several identifiers starting with <code>$</code> @@ -239,8 +247,7 @@ the class currently edited.</td> <h4>$0, $1, $2, ...</h4> -<p>The parameters passed to the methods <code>insertBefore()</code>, -<code>insertAfter()</code>, and <code>addCatch()</code> +<p>The parameters passed to the target method are accessible with <code>$0</code>, <code>$1</code>, <code>$2</code>, ... instead of the original parameter names. @@ -685,6 +692,12 @@ object creation, or others. The second statement could be: <p>if the expression is write access. +<p>Local variables available in the target expression is +also available in the source text passed to <code>replace()</code> +if the method searched by <code>instrument()</code> was compiled +with the -g option (the class file includes a local variable +attribute). + <h4>javassist.expr.MethodCall</h4> <p>A <code>MethodCall</code> object represents a method call. @@ -1318,6 +1331,6 @@ write: <hr> Java(TM) is a trademark of Sun Microsystems, Inc.<br> -Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved. +Copyright (C) 2000-2004 by Shigeru Chiba, All rights reserved. </body> </html> |