> The method has a max stack size parameter somewhere. I
> forget the name.
> It doesn't verify if the max size is exceeded. You
can
> update the size.
Hi Erik,
If i call MethodGen#getMaxStack() before and after
instrumenting the
method both values are the same.
If i call MethodGen#setMaxStack() i get following Exception:
java.lang.NullPointerException
at
org.apache.bcel.generic.FieldOrMethod.getSignature(FieldOrMe
thod.java:54
)
at
org.apache.bcel.generic.InvokeInstruction.getReturnType(Invo
keInstructio
n.java:109)
at
org.apache.bcel.generic.InvokeInstruction.produceStack(Invok
eInstruction
.java:88)
at
org.apache.bcel.generic.MethodGen.getMaxStack(MethodGen.java
:928)
at
org.apache.bcel.generic.MethodGen.setMaxStack(MethodGen.java
:814)
at test.BCELRewriter.main(BCELRewriter.java:34)
I post my two test classes - Sample.class is insrumented by
class
BCELRewriter:
package test;
public class Sample
{
protected int protectedField;
Sample()
{
protectedField++;
}
}
package test;
import org.apache.bcel.*;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.*;
public class BCELRewriter
{
public static void main( String[] args )
throws Exception
{
JavaClass clazz = Repository.lookupClass(
"test.Sample" );
ConstantPoolGen cp = new ConstantPoolGen(
clazz.getConstantPool() );
ClassGen cg = new ClassGen( clazz );
InstructionFactory instrFactory = new
InstructionFactory( cg );
Method[] methods = clazz.getMethods();
for( int i=0; i < methods.length; i++ )
{
MethodGen mg = new MethodGen(methods[i],
cg.getClassName(),
cp);
InstructionList instrList =
mg.getInstructionList();
Instruction preReturnInstr =
instrList.getEnd().getPrev().getInstruction();
System.out.println( "MaxStackSize before:
" +
mg.getMaxStack() );
System.out.println( mg.getInstructionList() );
instrList.append(preReturnInstr,
buildStaticInvoke(instrFactory) );
System.out.println( "MaxStackSize after:
" +
mg.getMaxStack() );
System.out.println( mg.getInstructionList() );
mg.setMaxStack();
methods[i] = mg.getMethod();
}
cg.setMethods( methods );
cg.getJavaClass().dump(
"C:\\test\\Sample.class" );
}
private static InstructionList
buildStaticInvoke(InstructionFactory
instrFactory)
{
InstructionList il = new InstructionList();
InvokeInstruction invokeLog =
instrFactory.createInvoke(
"test.Logger",
"log",
Type.VOID,
new Type[] { Type.STRING,
Type.STRING,
Type.STRING, Type.STRING },
Constants.INVOKESTATIC);
ConstantPoolGen constPoolGen =
instrFactory.getConstantPool();
il.append(new PUSH(constPoolGen,
"arg1"));
il.append(new PUSH(constPoolGen,
"arg2"));
il.append(new PUSH(constPoolGen,
"arg3"));
il.append(new PUSH(constPoolGen,
"arg4"));
il.append( invokeLog );
return il;
}
}
When running "java test.Sample" i get following
error:
java.lang.VerifyError: (class: test/Sample, method:
<init> signature:
()V) Stack size too large
Exception in thread "main"
If you only use three arguments everything works fine...?!
Kind Regards,
Patrick
------------------------------------------------------------
---------
To unsubscribe, e-mail: bcel-user-unsubscribe jakarta.apache.org
For additional commands, e-mail: bcel-user-help jakarta.apache.org
|