jakarta-bcel-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Volker Leidl <le...@nt.imp.univie.ac.at>
Subject Re: Instrumenting a constructor
Date Wed, 23 Oct 2002 14:54:27 GMT
Hi Peter (Schneider)!

Unfortunately I cannot disagree with what you stated. Obviously I missed 
some details of the JVM spec (Admittedly I did not read it from 
beginning to end ;-) ). Thanks alot for these valuable explanations.

Although none of the mentioned cases ever occured until now in my 
environment, it is not guaranteed that this cannot not happen at some 
future point of time.

Nevertheless I'm still wondering about the full consequences of the 
sections you cited. Particualrly, wouldn't the first citation mean, that 
I can never wrap an exception handler around code that has not been 
compiled with a surrounding exception handler, i. e. I could solely nest 
new exception handlers in existing (since compilaiton) ones? Otherwise 
it would be in general impossible to modify the code in a way that 
guarantees that there are no uninitialized class instances in local 
variables without risking to break the intended logic.

If this is really true, I'm in trouble, since I cannot think of any 
other way to create something like try-finally on the bytecode level.

Cheers,
Volker.

Peter Schneider wrote:

>>Hi,
>>
>>I'm forwarding a mail regarding bytecode
>>instrumentation, more specifically "encapsulating a
>>method body in a try-finally block" through dynamic
>>instrumentation. I'm forwarding it to the archiving
>>list for two reasons: first, it will help others who
>>wants to know about it & second, for experts who can
>>correct us in case there is some thing wrong in it.
>>    
>>
>
>Hi
>I have read the proposed modification, but i have to remark that this
>won't work that easily.
>
>The critical point is, that bytecode has to fullfill strict constraints.
>Or the verifier will reject it.
>
>[...]
>  
>
>>As you correctly stated there are two ways to exit a method on the 
>>bytcode level: by explicitly returning
>>or by throwing an exception. In BCEL you can cope with the second one 
>>easily by adding a new exception handler that encloses the critical
>>    
>>
>code 
>  
>
>>section. You can do so by calling MethodGen.addExceptionHandler(...). 
>>The last parameter to this method takes the type of exception
>>to be caught by this handler. To accept any type, simply use null. At 
>>the target of the exception handler you
>>have to jump to your finally block.
>>    
>>
>Simply try catch the whole method body isn't possible in general,
>if the method stores unitialized objects in local variables this
>strategy will fail.
>
>(JVMSPEC)# There must never be an uninitialized class instance on the
>operand stack or in a local variable when any backwards branch is taken.
>There must never be an uninitialized class instance in a local variable
>in code protected by an exception handler. However, an uninitialized
>class instance may be on the operand stack in code protected by an
>exception handler. When an exception is thrown, the contents of the
>operand stack are discarded.
>
>  
>
>>Secondly you have to insert code before each return instruction in the 
>>method code, which is slightly more complicated. I did so by utilizing 
>>the Visitor facility of  BCEL. A convenient way is to sublcass 
>>org.apache.bcel.generic.EmptyVisitor and overwrite all visit* methods 
>>that handle return instructions, e.g. visitRETURN, visitARETURN, etc.
>>
>>For example in my code the visitDRETURN (for double values) looks like 
>>the following:
>>
>>       //double has a word size of 2
>>       public void visitDRETURN(DRETURN obj) {
>>           if (max - offset < 2) max += (2 - max + offset);
>>
>>           //store away return value on the stack
>>           code.insert(handle, new DSTORE(offset + 1));
>>           code.insert(handle, new JSR(finallyClause));
>>           code.insert(handle, new DLOAD(offset + 1));
>>       }
>>    
>>
>Again it's not that simple, If you use a nice compiler this will work,
>but there is no guarantee that the stack will contain a single item when
>returning.
>If some stack items are discarded through return, then this simple jump
>will lead to a constraint violation. 
>This only happens with compilers that optimize, and the sun compiler
>even produces dead code, so you don't have to fear it will ever produce
>something like that.
>
>(JVMSPEC)# If an instruction can be executed along several different
>execution paths, the operand stack must have the same depth (ยง3.6.2)
>prior to the execution of the instruction, regardless of the path taken.
>
>
>
>
>--
>To unsubscribe, e-mail:   <mailto:bcel-user-unsubscribe@jakarta.apache.org>
>For additional commands, e-mail: <mailto:bcel-user-help@jakarta.apache.org>
>
>
>  
>


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


Mime
View raw message