2015-11-11 1 views
2

Comment définir la directive .maxstack avec ILGenerator?Comment définir ".maxstack" avec ILGenerator

Par exemple, une méthode setter typique a une .maxstack de :

.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 

Il est possible de définir des métadonnées avec ILGenerator car il offre en fait DefineLabel et DeclareLocal, alors pourquoi ne pas offre une méthode SetMaxStack(short/int) ou quelque chose de similaire?

Si je ne peux pas définir ces métadonnées, comment Reflecion.Emit détermine-t-il la taille de la pile? Est-ce qu'il le définit à la valeur maximale possible? Ou peut-être que la pile se développe automatiquement à l'exécution?

+1

Il ne vous fait pas confiance pour le faire correctement. DeclareLocal() obtient toujours le droit. –

Répondre

0

Si votre problème est de ne pas définir correctement la pile max, même si votre méthode est très simple, continuez à lire ci-dessous. Ce qui n'est peut-être pas évident à partir des métadonnées, c'est qu'il y a deux formes d'en-têtes de méthodes dans la CLI: les en-têtes Tiny et Fat.

L'en-tête du procédé, selon la norme ECMA-335 (II.25.4.1 Méthode Les valeurs de type d'en-tête) se présente sous deux formes: (. 0x03) CorILMethod_TinyFormat (0x02) et CorILMethod_FatFormat

Le format minuscule pour les méthodes ne fait ne permet pas la spécification de la pile max. Comme il doit toujours être inférieur ou égal à huit (8.)

La raison pour laquelle vous ne pouvez pas le définir est due à ce que thehennyy a mentionné: IL Builder garde la trace des limites de la pile pour vous.

Il y a quelques autres restrictions qui vont au-delà de votre question, mais si vous êtes curieux, vous pouvez jeter un coup d'oeil à la ECMA-335, qu'il précise tout pour vous (en détail très explicite, peut être NSFW :)