2009-03-06 12 views
1

J'écris mon propre langage de script en C#, avec quelques fonctionnalités que j'aime, et j'ai choisi d'utiliser MSIL comme bytecode de sortie (Reflection.Emit est très utile, et je ne dois pas penser à un autre bytecode). Cela fonctionne, émet un exécutable, qui peut être exécuté (même décompilé avec Reflector :)) et est assez rapide. Mais - Je veux exécuter plusieurs 'processus' en un seul processus et un seul thread, et contrôler manuellement leur temps processeur assigné (également implémenter un IPC beaucoup plus robuste qui est offert par le framework .NET) Y at-il un moyen de désactiver complètement JIT et créer propre VM, pas à pas instruction-après-instruction en utilisant. NET framework (et contrôler l'utilisation de la mémoire, etc.), sans besoin d'écrire quelque chose par moi-même, ou pour y parvenir, je dois écrire MSIL interpréter?Désactivation de JIT et contrôle du flux de code dans MSIL (propre VM)

EDIT 1): Je sais que l'interprétation de l'IL n'est pas la chose la plus rapide dans l'univers :)

EDIT 2): Pour clarifier - Je veux que ma machine virtuelle pour être une sorte de « système d'exploitation » - il obtient un peu de temps CPU et le divise entre les processus, contrôle l'allocation de mémoire pour eux, et ainsi de suite. Il ne doit pas être rapide, ni efficace, mais juste une preuve de concept pour certaines de mes expériences. Je n'ai pas besoin de l'implémenter au niveau du traitement de toutes les instructions - si cela doit être fait par .NET, je ne vais pas m'inquiéter, je veux juste dire: première étape, et attendez que je vous dise de passer à la suivante.

EDIT 3): J'ai réalisé, que ICorDebug peut peut-être accomplir mes besoins, maintenant en regardant l'implémentation de l'exécution de Mono.

Répondre

5

Vous pouvez utiliser Mono - Je crois que cela permet une option pour interpréter le IL au lieu de le JITting. Le fait que ce soit open source signifie (sous réserve de licence) que vous devriez être capable de le modifier en fonction de vos besoins, aussi.

Mono ne possède pas toutes les fonctionnalités de .NET, certes - mais il peut faire tout ce dont vous avez besoin.

1

Attention, MSIL a été conçu pour être analysé par un compilateur JIT. Ce n'est pas très approprié pour un interprète. Un bon exemple est peut-être l'instruction ADD. Il est utilisé pour ajouter une grande variété de valeurs de type de valeur: byte, short, int32, int64, ushort, uint32, uint64. Votre compilateur sait quel type d'ajout est requis, mais vous perdrez cette information de type lors de la génération du MSIL.

Vous devez maintenant le retrouver au moment de l'exécution et cela nécessite de vérifier les types de valeurs de la pile d'évaluation. Très lent.

Une interprété facilement IL a consacré des instructions ADD comme ADD8, ADD16, etc.

1

Microsofts mise en œuvre du Common Language Runtime ne dispose que d'un seul système d'exécution, le JIT. Mono, d'un autre côté vient avec les deux, un JIT et un interprète.

I, cependant, ne pas bien comprendre exactement ce que vous voulez vous faire et ce que vous voulez laisser à la mise en œuvre Microsofts:

Est-il possible de désactiver totalement JIT et créer votre propre machine virtuelle ?

et

... sans avoir besoin d'écrire quoi que ce soit moi-même, ou pour y parvenir, je dois écrire toute MSIL interpréter?

est en quelque sorte contradictoire.

Si vous pensez, vous pouvez écrire un meilleur système d'exécution que JIT microsoft, vous devrez l'écrire à partir de zéro. Gardez à l'esprit, cependant, que les microsoft et monos JIT sont des compilateurs hautement optimisés. (Programming language shootout)

La possibilité de programmer le temps CPU pour les processus du système d'exploitation n'est pas possible en mode utilisateur. C'est la tâche des systèmes d'exploitation.

Une implémentation de threads verts pourrait être une idée, mais c'est certainement un sujet pour le code non géré. Si c'est ce que vous voulez, jetez un oeil à l'API d'hébergement CLR.

Je suggérerais, vous essayez d'implémenter votre langage dans CIL. Après tout, il est compilé jusqu'à x86 brut. Si vous ne vous souciez pas de la vérifiabilité, vous pouvez utiliser des pointeurs si nécessaire.

1

Une chose que vous pourriez envisager est de générer du code dans un style de machine d'état. Laissez-moi vous expliquer ce que je veux dire par là.

Lorsque vous écrivez des méthodes de générateur en C# avec retour de rendement, la méthode est compilée dans une classe interne IEnumerator qui implémente une machine d'état. Le code de la méthode est compilé en blocs logiques qui se terminent par un retour de rendement ou une déclaration de rupture de rendement, et chaque bloc correspond à un état numéroté. Comme chaque retour de rendement doit fournir une valeur, chaque bloc se termine en stockant une valeur dans un champ local. L'objet énumérateur, afin de générer sa prochaine valeur, appelle une méthode qui consiste en une instruction switch géante sur le numéro d'état courant afin d'exécuter le bloc courant, puis avance l'état et renvoie la valeur du champ local. Votre langage de script peut générer ses méthodes dans un style similaire, où une méthode correspond à un objet machine d'état, et la VM alloue du temps en faisant avancer la machine d'état pendant le temps alloué. Quelques parties délicates de cette méthode: implémenter des choses comme des appels de méthodes et des blocs try/finally est plus difficile que de générer MSIL directement.