You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-user@jakarta.apache.org by Al <no...@eircom.net> on 2004/01/14 21:33:48 UTC

Help inserting instructions - simple question

Will somone please take a quick look at the example below. I am trying to modify each method in a class s.t. the first thing it does is allocate a new byte[] (for the moment Im happy to just create it and let it go, ... I mean I dont need to bind it to anything). I dont understand what more I am supposed to do to insert instructions in a method. This code will result in an error like -

Exception in thread "main" java.lang.VerifyError: (class: tests/test1/Test, method: main signature: ([Ljava/lang/String;)V) Unable to pop operand off an empty stack

Thanks,

Alan.

-----

public static void doit(final String sourcePath, final String className) throws Exception
{ // Setup
 org.apache.bcel.Repository.setRepository(org.apache.bcel.util.SyntheticRepository.getInstance(new org.apache.bcel.util.ClassPath(sourcePath)));
 final org.apache.bcel.classfile.JavaClass jc = org.apache.bcel.Repository.lookupClass(className);
 final org.apache.bcel.generic.ClassGen cg = new org.apache.bcel.generic.ClassGen(jc);
 final org.apache.bcel.generic.ConstantPoolGen cpg = new org.apache.bcel.generic.ConstantPoolGen(jc.getConstantPool());
 cg.setConstantPool(cpg);

 // For all the methods in the class, some new instructions
 final org.apache.bcel.classfile.Method[] m = jc.getMethods();
 for(int i = 0; i < m.length; i++)
 { org.apache.bcel.generic.MethodGen mg = new org.apache.bcel.generic.MethodGen(m[i], className, cpg);
  mg.setConstantPool(cpg);
  org.apache.bcel.generic.InstructionList origIL = mg.getInstructionList();
  org.apache.bcel.generic.InstructionHandle[] ih = origIL.getInstructionHandles();
 
  org.apache.bcel.generic.InstructionFactory f = new org.apache.bcel.generic.InstructionFactory(cg);
  org.apache.bcel.generic.InstructionList newIL = new org.apache.bcel.generic.InstructionList();
  
  // Create a byte array
  newIL.append(f.createNewArray(new org.apache.bcel.generic.ArrayType(org.apache.bcel.generic.Type.BYTE, 1), (short)1));

  if(m[index].getName().equals("<init>"))
  { // First let the super or other constructor be called
   for(int j = 1; j < ih.length; j++)
   { if(ih[j].getInstruction() instanceof org.apache.bcel.generic.INVOKESPECIAL)
    { origIL.append(ih[j], newIL);
     break;
    }
   }
  }
  else origIL.insert(ih[0], newIL);

  mg.setMaxLocals();
  mg.setMaxStack();
  m[i] = mg.getMethod();
  origIL.dispose(); // Reuse instruction handles
 }
 
 // Dump the modified class
 jc.setMethods(m);
 jc.setConstantPool(cpg.getFinalConstantPool());
 jc.dump(System.out);
}

Re: Help inserting instructions - simple question

Posted by Toby Reyelts <to...@reyelts.com>.
I think BCEL assumes you have a very good understanding of the VM spec. 
If you don't, you probably shouldn't be writing bytecode (or using 
BCEL). Working with that assumption, the documentation is mostly "ok", 
though there are places that could use clarification.

God bless,
-Toby

Al wrote:

>Just thought I should give this some closure. Following Eriks instructions
>and looking up the jvm spec I realised that
>InstructionsFactory.createNewArray doesnt do the whole job. It expects the
>length of the array to be on the stack. Simple really. Seriously though lads
>... BCEL is desperately in need of some proper documentation if its ever
>going to achieve its potential. Am I alone in feeling that this should be
>one of, if not the, priority for its maintainers/developers (easy to say I
>know when youre not one of them!)?
>
>Best of luck,
>
>Alan
>
>----- Original Message ----- 
>From: "Erik Corry" <er...@arbat.com>
>To: "BCEL Users List" <bc...@jakarta.apache.org>
>Sent: Wednesday, January 14, 2004 9:00 PM
>Subject: Re: Help inserting instructions - simple question
>
>
>  
>
>>On Wed, Jan 14, 2004 at 08:33:48PM -0000, Al wrote:
>>    
>>
>>>Will somone please take a quick look at the example below. I am trying
>>>      
>>>
>to modify each method in a class s.t. the first thing it does is allocate a
>new byte[] (for the moment Im happy to just create it and let it go, ... I
>mean I dont need to bind it to anything). I dont understand what more I am
>supposed to do to insert instructions in a method. This code will result in
>an error like -
>  
>
>>>Exception in thread "main" java.lang.VerifyError: (class:
>>>      
>>>
>tests/test1/Test, method: main signature: ([Ljava/lang/String;)V) Unable to
>pop operand off an empty stack
>  
>
>>Probably the best thing is to run either
>>
>>java org.apache.bcel.util.Class2HTML mymodifiedclassfile.class
>>
>>or
>>
>>java org.apache.bcel.verifier.Verifier mymodifiedclassfile.class
>>
>>and look at the output until you can see where you are getting a stack
>>underflow.
>>
>>-- 
>>Erik Corry         I'd be a Libertarian, if they weren't all a
>>erik@arbat.com     bunch of tax-dodging professional whiners.   - B.
>>    
>>
>Breathed.
>  
>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
>>For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>>
>>
>>
>>    
>>
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>
>
>  
>


---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org


Re: Help inserting instructions - simple question

Posted by Al <no...@eircom.net>.
Just thought I should give this some closure. Following Eriks instructions
and looking up the jvm spec I realised that
InstructionsFactory.createNewArray doesnt do the whole job. It expects the
length of the array to be on the stack. Simple really. Seriously though lads
... BCEL is desperately in need of some proper documentation if its ever
going to achieve its potential. Am I alone in feeling that this should be
one of, if not the, priority for its maintainers/developers (easy to say I
know when youre not one of them!)?

Best of luck,

Alan

----- Original Message ----- 
From: "Erik Corry" <er...@arbat.com>
To: "BCEL Users List" <bc...@jakarta.apache.org>
Sent: Wednesday, January 14, 2004 9:00 PM
Subject: Re: Help inserting instructions - simple question


> On Wed, Jan 14, 2004 at 08:33:48PM -0000, Al wrote:
> > Will somone please take a quick look at the example below. I am trying
to modify each method in a class s.t. the first thing it does is allocate a
new byte[] (for the moment Im happy to just create it and let it go, ... I
mean I dont need to bind it to anything). I dont understand what more I am
supposed to do to insert instructions in a method. This code will result in
an error like -
> >
> > Exception in thread "main" java.lang.VerifyError: (class:
tests/test1/Test, method: main signature: ([Ljava/lang/String;)V) Unable to
pop operand off an empty stack
>
> Probably the best thing is to run either
>
> java org.apache.bcel.util.Class2HTML mymodifiedclassfile.class
>
> or
>
> java org.apache.bcel.verifier.Verifier mymodifiedclassfile.class
>
> and look at the output until you can see where you are getting a stack
> underflow.
>
> -- 
> Erik Corry         I'd be a Libertarian, if they weren't all a
> erik@arbat.com     bunch of tax-dodging professional whiners.   - B.
Breathed.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org


Re: Help inserting instructions - simple question

Posted by Erik Corry <er...@arbat.com>.
On Wed, Jan 14, 2004 at 08:33:48PM -0000, Al wrote:
> Will somone please take a quick look at the example below. I am trying to modify each method in a class s.t. the first thing it does is allocate a new byte[] (for the moment Im happy to just create it and let it go, ... I mean I dont need to bind it to anything). I dont understand what more I am supposed to do to insert instructions in a method. This code will result in an error like -
> 
> Exception in thread "main" java.lang.VerifyError: (class: tests/test1/Test, method: main signature: ([Ljava/lang/String;)V) Unable to pop operand off an empty stack

Probably the best thing is to run either

java org.apache.bcel.util.Class2HTML mymodifiedclassfile.class

or

java org.apache.bcel.verifier.Verifier mymodifiedclassfile.class

and look at the output until you can see where you are getting a stack
underflow.

-- 
Erik Corry         I'd be a Libertarian, if they weren't all a
erik@arbat.com     bunch of tax-dodging professional whiners.   - B. Breathed.

---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org