Local Variables

Local Variables

Local variables are the typed data items that are declared within the method scope and exist from the moment the method is called until it returns. ILAsm allows us to assign names to local variables and reference them by name, but IL instructions address the local variables by their zero-based ordinals.

When the source code is compiled in debug mode, the local variable names are stored in the program database (PDB) file accompanying the module, and in this case the local variable names might survive round-tripping. In general, however, these names are not preserved because they, unlike the names of fields and method parameters, are not part of the metadata.

All the local variables, no matter when they are declared within the method scope, form a single signature, kept in the StandAloneSig metadata table (token type 0x11000000).The token referencing the respective signature is part of the method header.

Local variables are declared in ILAsm as follows:

.method public void Foo(int32 ii, int32 jj) {    .locals init (float32 ff, float64 dd, object oo, string ss)     }

Figure 9-4 The structures of tiny and fat method headers.

The init keyword sets the flag 0x4 in the method header, indicating that the JIT compiler must initialize all local variables before commencing the method execution. Initialization means that for all variables of value types the corresponding default constructors are called, and all variables of object reference types are set to null. Code that contains methods without a local variable initialization flag set is deemed unverifiable and can be run from a local drive only with verification disabled.

ILAsm does not require that all local variables be declared in one place; the following is perfectly legal:

.method public void Foo(int32 ii, int32 jj) {    .locals init (float32 ff, float64 dd, object oo, string ss)        {       .locals (int32 kk, bool bb)           }        {       .locals (int32 mm, float32 f)           }     }

In this case, the summary local variables signature will contain the types float32, float64, object, string, int32, bool, int32, and float32. Repeating init in subsequent local variable declarations of the same method is not necessary because any one of the .locals init directives sets the local variable initialization flag.

It’s obvious enough that we have a redundant local variable slot in the composite signature: by the time we need mm, we don’t need kk any more, so we could reuse the slot and reduce the composite signature. In ILAsm, we can do that by explicitly specifying the 0-based slot numbers for local variables:

.method public void Foo(int32 ii, int32 jj) {    .locals init ([0]float32 ff, [1]float64 dd,                   [2]object oo, [3]string ss)        {       .locals ([4]int32 kk, [5]bool bb)           }        {       .locals ([4]int32 mm, [6]float32 f)           }     }

Could we also reuse slot 5 for variable f? No, because the type of slot 5 is bool, and we need a slot of type float32 for f. Only the slots holding local variables of the same type and used within nonoverlapping scopes can be reused.

important

The number of local variables declared in a method is completely unrelated to the .maxstack value, which depends only on how many items you might have to load simultaneously for computational purposes. For example, if you declare 20 local variables, you don’t need to declare .maxstack 20; but if your method is calling another method that takes 20 arguments, you need to ensure that the stack has sufficient depth.



Inside Microsoft. NET IL Assembler
Inside Microsoft .NET IL Assembler
ISBN: 0735615470
EAN: 2147483647
Year: 2005
Pages: 147
Authors: SERGE LIDIN

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net