Matias Cicero
Matias Cicero

Reputation: 26301

How to set ".maxstack" with ILGenerator

How to set the .maxstack directive with ILGenerator?

For instance, a typical setter method has a .maxstack of 2:

.maxstack 2         // The evaluation stack has a max size of 2

IL_0000: ldarg.0                  // the current instance (this)
IL_0001: ldarg.1                  // new value
IL_0002: stfld Int32 _someField   // stores the new value on _someField
IL_0007: ret                      // Return to caller

It's possible to set metadata with ILGenerator because it actually offers DefineLabel and DeclareLocal, so why doesn't it offer a SetMaxStack(short/int) method or something similar?

If I can't set this metadata, how does Reflecion.Emit determines the size of the stack? Does it set it to the max possible value? Or maybe the stack automatically expands at runtime?

Upvotes: 2

Views: 672

Answers (2)

If your concern is it isn't setting the max-stack correctly even though your method is very simple, continue reading below.

What might not be obvious from the Metadata at first is, there are two forms of method headers within the CLI: Tiny and Fat headers.

The method header, according to the ECMA-335 (II.25.4.1 Method header type values) comes in two forms: CorILMethod_TinyFormat (0x02) and CorILMethod_FatFormat (0x03.)

The tiny format for methods does not allow the specification of max stack. As it always must be at or below eight (8.)

The reason you can't set it is due to what thehennyy mentioned: the IL Builder keeps track of the stack limits for you.

There's a few other restrictions that go beyond your question, but if you're curious you can take a peek at the ECMA-335, which spells it all out for you (in very explicit detail, may be NSFW :)

Upvotes: 0

thehennyy
thehennyy

Reputation: 4218

The ILGenerator Class will keep track of the stacksize. Have a look at the reference source. For example the UpdateStackSize function is involved.

Upvotes: 2

Related Questions