Question

Je suis sortie pour générer un exécutable .Net de ma propre langue ... l'opcode (appelé « aléatoire ») qui est en cours de traduction de ma langue est censé créer un nombre aléatoire dans une plage spécifique.

Le but de mon code est de produire le nombre aléatoire en utilisant la classe System.Reflection.Emit.ILGenerator ... pour comprendre comment le code CIL apparence que j'ai créé un code de vb.net:

Sub Main()
    Dim A As Random

    A = New Random

    Console.WriteLine(A.Next(100))
End Sub

Ce qui ILDASM rapporte que:

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       23 (0x17)
  .maxstack  2
  .locals init ([0] class [mscorlib]System.Random A)
  IL_0000:  nop
  IL_0001:  newobj     instance void [mscorlib]System.Random::.ctor()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.s   100
  IL_000a:  callvirt   instance int32 [mscorlib]System.Random::Next(int32)
  IL_000f:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_0014:  nop
  IL_0015:  nop
  IL_0016:  ret
} // end of method Main::Main

Je peux tout reproduire en utilisant la méthode ILGenerator.Emit; excepter la ligne IL_0001 ( "vide instance newobj [mscorlib] System.Random ::. cteur ()") ...

Si tout va bien, je ne l'ai pas dépassé tout le monde avec trop d'informations. Mais je dis qu'il vaut mieux être bavard pour décrire un problème qui me semble complexe.

Enfin, j'ai le code que j'ai produit jusqu'à présent:

 Sub EmitRandom()
    Dim NewRandom As New Random
    Dim stringtype As Type = GetType(System.Random)

    Dim paramtypes() As Type = {GetType(Integer)}, blankparams() As Type = {}
    'Dim RandomMethod = stringtype.GetMethod("New", paramtypes)

    m_ILGen.Emit(OpCodes.Newobj, New Random().GetType)

    EmitStoreInLocal(tempVariableRnd)
    EmitLoadLocal(tempVariableRnd)

    m_ILGen.Emit(OpCodes.Callvirt, stringtype.GetMethod("Next", paramtypes))
End Sub

Ce qui émet le code suivant:

.
.
.
IL_0073:  newobj     [mscorlib]System.Random
IL_0078:  stloc.2
IL_0079:  ldloc.2
IL_007a:  callvirt   instance int32 [mscorlib]System.Random::Next(int32)
.
.
.

Les choses que j'ai déjà essayé :

  • Venir avec un moyen de pointer IL_Gen.Emit (OpCodes.NewObj, ... cteur ()) ... ne peut pas comprendre comment.

  • Venir avec un moyen de pointez sur Nouveau () - puisque cela semble être ce que .ctor () est ... Nouveau ne peut pas être utilisé comme tout sauf un initialiseur

  • Il suffit de désactiver la fonction aléatoire jusqu'à ce que je peux trouver une meilleure façon d'émettre.

Le problème semble difficile pour moi, mais je sais qu'il ya quelqu'un là-bas qui comprend la génération de code et MSIL plus facilement que moi et qui est prêt à signaler une réponse.

Merci pour votre temps,

Dominick

Était-ce utile?

La solution

Vous devez utiliser le ConstructorInfo:

 m_ILGen.Emit(OpCodes.Newobj, GetType(Random).GetConstructor(Type.EmptyTypes))

Aussi - le stockage et le chargement du local ne sont pas nécessaires. Vous voulez vraiment que l'équivalent de new Random (). Ensuite (100), à droite? ... dans ce cas, le stockage et le chargement d'une jamais locale passe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top