2009-04-04 6 views
9

Existe-t-il un moyen .NET, utilisant Reflection.Emit, pour accéder à l'élément le plus haut de la pile? Donc, si A est le plus haut, et B ensuite - je veux traiter B puis A. Il serait bien de dupliquer B dessus de A (puisque je peux simplement "pop" le deuxième B quand j'y arriverai).Reflection.Emit - accès à l'élément le plus en amont de la pile

Actuellement, je déclare local:

LocalBuilder loc = il.DeclareLocal(typeof(Foo)); 
    il.Emit(OpCodes.Stloc, loc); // store and pop topmost stack item 
    // work with (pop) previous stack item 
    il.Emit(OpCodes.Ldloc, loc); // push old topmost stack item 

est-il une route qui n'a pas besoin local explicite?

Répondre

7

Je ne pense pas. Dans IL il n'y a pas d'instructions comme swap qui vous permettrait de faire ce que vous voulez. Pourquoi voyez-vous l'utilisation d'un local comme répréhensible? Si le compilateur JIT est suffisamment bon, cela n'entraînera pas de code machine plus lent que l'utilisation d'une opération de swap hypothétique dans IL.

+1

Pour le "pourquoi" - ceci est dans le code généré qui devrait introduire plus de locaux que je veux. Si je pouvais utiliser le haut de la pile à la place, je pourrais sauvegarder des quantités non-triviales d'espace de pile (les sections locales sont réservées indépendamment de l'utilisation, AFAIK). –

1
+0

L'auteur de codeproject a des pensées similaires à moi, alors. SWAP ou OVER ferait l'affaire ;-p je vais devoir vérifier ma VM 4.0, mais je ne suis pas optimiste que ce soit différent ... –

1

ligne avec ce que KVB dit, vous pouvez essayer une petite fonction pour faire réorganisant. Je ne sais pas si ce serait plus rapide.

+0

Bonne idée, mais certainement pas; même si le JUT l'a souligné. –

1

J'ai rencontré ce même problème. Je voulais générer une méthode plutôt grande et je voulais souvent «échanger» afin de stocker une valeur calculée. J'étais mécontent du grand nombre de locaux qui se présentaient dans les ildasm et j'ai remarqué que BeginScope/EndScope n'était d'aucune aide. J'ai fini par créer un «swap» local pour le contexte de ma méthode et le réutiliser pour chaque opération d'échange. Cela rend le produit IL plus propre; pas sûr si cela a un impact significatif sur la performance.