> 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(FieldOrMethod.java:54
)
        at
org.apache.bcel.generic.InvokeInstruction.getReturnType(InvokeInstructio
n.java:109)
        at
org.apache.bcel.generic.InvokeInstruction.produceStack(InvokeInstruction
.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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to