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 sp...@uark.edu on 2004/07/11 02:45:49 UTC

accessing local variables

Hi ,

Is there a way to access local variables declared in a function in another function during run time.



Say for example I have the following program



public class abc{



public static void f()

{

 int x=10;

 .....



}



public static int g()

{

 int y=4;

  return x+y;

}



public static void main(String args[])

{

  System.out.println("The result of g() is " + g());

}



}



Is there any possibilities of g() accessing variable x declared in f().



Im simplifying the issue. Actually I want to do this at runtime.



Help would be greatly useful



-Sri



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


Relying on local variable slot 0

Posted by Dick Eimers <dw...@cs.uu.nl>.
This problem was brought to our attention by Toby Reyelts in October
2002, but was not really examined as much as I'd like :)

Many rewriting of existing methods rely on the *this* reference to be
in slot 0. When a method is invoked a new stack frame is created by
the virtual machine where the object reference to the object on which
the method is invoked, i.e. in Java programming language is referred to
as *this*, is placed in the first local variable slot indexed by 0. 

The object initialization method (<init>) is special, because slot 0
contains the uninitialized *this*, as explained in the VM Section
4.9.4 on how code is verified:

"When doing dataflow analysis on instance methods, the verifier
initializes local variable 0 to contain an object of the current
class, or, for instance initialization methods, local variable 0
contains a special type indicating an uninitialized object. After an
appropriate instance initialization method is invoked (from the
current class or the current superclass) on this object, all
occurrences of this special type on the verifier's model of the
operand stack and in the local variable array are replaced by the
current class type. The verifier rejects code that uses the new object
before it has been initialized or that initializes the object more
than once. In addition, it ensures that every normal return of the
method has invoked an instance initialization method either in the
class of this method or in the direct superclass."

Reyelts said he'd seen bytecode which overwrites slot 0, so the "this"
reference that's placed there when the method begins execution is
lost, and thus cannot be relied on!  He proposed a solutions where the
*this* is stored in the first free local variable slot, which seems
valid, BUT.. 

I created the following method that implements his proposal: 

public Initializer(); // javap lies, this is actually called "<init>"
Signature: ()V
0: aload_0            ; load unitialized object from locvar slot 0
1: dup                ; duplicate
2: astore N           ; store the unitialized object in locvar slot 1
3: aconst_null
4: astore_0           ; store special null value in locvar slot 0	
5: invokespecial #x; //Method java/lang/Object."<init>":()V
8: return

which does nothing but load the slot, duplicate it, store it in the
next free slot N and override the 0th slot with null. The object is
eventually initialized, so local var slot N refers a initialized
object that can be relied on to do whatever with.

Now the problem, different verifiers yield different results, that is,
the native verifier by sun accepts this class and sun's vm executes it
perfectly, but JustIce returns this: 

*********************************************************************
Pass 3b, method number 0 ['public void <init>()']:
VERIFIED_REJECTED

Constraint violated in method 'public void <init>()':
Instruction ASTORE constraint violated: Working on an uninitialized
object '<UNINITIALIZED OBJECT OF TYPE 'Initializer'>'.
InstructionHandle:    2: astore_1[76](1)
 
Execution Frame:
Local Variables:
0: <UNINITIALIZED OBJECT OF TYPE 'Initializer'>
1: <unknown object>
2: <unknown object>
OperandStack:
Slots used: 2 MaxStack: 2.
<UNINITIALIZED OBJECT OF TYPE 'Initializer'> (Size: 1)
<UNINITIALIZED OBJECT OF TYPE 'Initializer'> (Size: 1)
Execution flow:
   0: aload_0   [InstructionContext]
   1: dup       [InstructionContext]
   2: astore_1  [InstructionContext]
*********************************************************************

I think the source of the problem is the definition of _use_ as in "The
verifier rejects code that uses the new object before it has been
initialized or that initializes the object more than once." 

Anyone who can shed some light on this case?? What is correct? Is this a
bug in JustIce or is Sun not obeying their own spec?


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


Re: accessing local variables

Posted by Andrew Huntwork <as...@huntwork.net>.
Not only not allowed by the spec, but it doesn't necessarily even make 
any sense as stated.  If a function has never been invoked, what do you 
want the values of its variables to be?  Some languages have nested 
functions and i think usually nested functions a) can only be called 
from their outer function; and b) have access to the most recent 
invocation of the enclosing function.  Something like this:

function a() {
   function b() {
     return c;
   }
   if(bar())
     a();
   int c = foo();
   int d = b();
}

a recurses, but you usually expect that b will access c in the most 
recent invocation.

I think it would be somewhat painful but definitely possible to 
implement nested functions using bcel to copy local variable values into 
global vars before invoking the nested function.  or something like 
that.  but that's certainly not the exact question asked.

Dick Eimers wrote:
>> Is there a way to access local variables declared in a function in
>> another function during run time.
> 
> 
> No this is not allowed by spec.
> 
> -Dick
> 
> 
> ---------------------------------------------------------------------
>  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: accessing local variables

Posted by Dick Eimers <dw...@cs.uu.nl>.
> Is there a way to access local variables declared in a function in another function during run time.

No this is not allowed by spec.

-Dick


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