Unterschied Interpreter - virtuelle Maschine



  • Hallo,

    wo liegt der Unterschied zwischen Interpreter und virtueller Maschine?
    Z.B. wird bei C# immer von virtueller Maschine und JIT Compilierung gesprochen, hingegen spricht man bei Python von einem Interpreter.
    Beide jedoch wandeln den Quelltext zuerst in einen Zwischencode um - wo ist der Unterschied?

    Ist ein Interpreter ein Programm, welches den Quelltext in einen Syntaxbaum umwandelt und dieser Baum dann direkt ausgeführt wird, eine virtuelle Maschine hingegen, wenn aus dem Syntaxbaum auch noch Zwischencode generiert wird der dann ausgeführt wird?
    Doch auch bei Zwischencode handelt es sich doch um interpretierten Code - da ist halt dann (einfach gesagt) eine while Schleife die Byte für Byte interpretiert und je nach Opcode irgendwelche Aktionen auslöst - eine direkte Ausführung des Codes auf der CPU findet ja trotzdem nicht statt.

    Vielleicht kann mir da ja jemand helfen den Unterschied zu erkennen.
    Danke!



  • cooooooooooompiler schrieb:

    Ist ein Interpreter ein Programm, welches den Quelltext in einen Syntaxbaum umwandelt und dieser Baum dann direkt ausgeführt wird, eine virtuelle Maschine hingegen, wenn aus dem Syntaxbaum auch noch Zwischencode generiert wird der dann ausgeführt wird?

    Der Interpreter wandelt das Programm nicht in einen Syntaxbaum, das macht schon der Parser. Ein Interpreter würde den AST dann direkt ausführen. Ansonsten würde ich den Unterschied schon so definieren, wenn es unbedingt sein muss. Aber im Endeffekt ist ein Interpreter einfach ein etwas allgemeinerer Begriff. Einen AST Walker würde ich jetzt nicht als Virtuelle Maschine betrachten. Einen Bytecode Interpreter aber schon - und da ist auch wieder "Interpreter" im Namen mit dabei.



  • Kann man überhaupt einen Interpreter mit einer VM vergleichen. Eine VM ist eine Schicht die man zwischen dem Programm und dem OS schaltet. Ein Interpreter nimmt einen Befehl aus einem Programm und führt ihr direkt aus, dann nimmt er den nächsten usw.



  • Ob üblicherweise von einer VM gesprochen wird ist denke ich auch abhängig davon ob der Sprachstandard diesen Begriff verwendet.

    Bzw. ein Unterschied ist für mich auch ob eine Sprache wie Java oder C# erstmal vollständig compiliert wird, wobei dann ein Zwischencode entsteht der mit dem ursprünglichen Programm nicht unbedingt viel zu tun hat.

    Oder ob ein Programm erstmal nur geparsed wird, wobei ein AST rauskommt, den man quasi 1:1 wieder zurück in Sourcecode übersetzen könnte.

    Auf Python (zumindest auf frühe Python Versionen) triffst das zweite zu, deswegen spricht man da eher von einer interpretierten Sprache.



  • DerAndroide schrieb:

    Kann man überhaupt einen Interpreter mit einer VM vergleichen. Eine VM ist eine Schicht die man zwischen dem Programm und dem OS schaltet. Ein Interpreter nimmt einen Befehl aus einem Programm und führt ihr direkt aus, dann nimmt er den nächsten usw.

    Eine VM kann man genau so umsetzen wie einen Interpreter. Also einen Zwischencode-Befehl nach dem anderen holen und direkt ausführen.

    Die Frage ist nur was der Interpreter interpretiert.

    Wird 1:1 das Programm was der Programmierer hingeschrieben hat (bzw. eine vom Parser generierte binäre Abbildung davon) interpretiert?
    Oder wird vom Compiler generierter Zwischencode interpretiert?



  • Der Bytecode entsteht durch Kompilierung des Quellcodes wird dann aber interpretiert. Ob der Bytecode nun auf einer VM oder direkt auf der echten CPU interpretiert wird, spielt keine Rolle für die Erklärung des Begriffes. Bei Java unter Windows ist halt noch die VM dazwischen, das muss aber nicht so sein.



  • das sind eigentlich unterschiedliche dinge die nicht vergleichbar sind.
    ein interpreter ist nur dafuer da code auszufuehren, fuer z.B. Java gab es eine lange zeit keinen JIT, alles lief interpretiert. eine VM hat darueber hinaus alles was eine 'machine' braucht um komplett autonom mit den resourcen zu leben die ihr zur verfuegung gestellt wurden.

    wenn du eine analogie willst, waere ein interpreter ein motor, eine VM ein fahrzeug.

    Wenn du zwei VMs startest, sollten das (wenn man bugs/exploits ausschliesst) zwei komplett getrennte welten sein. startest du zwei interpreter kann es sein dass das nichtmal moeglich ist, weil die idee ist dass du eher ein "context" innerhalb des interpreters startest. in dem laufen dann eigentlich zwei unabhaengige welten die intern aber viel teilen (z.B. speicherverwaltung). ein interpreter verlaesst sich darunter auf die vom system zur verfuegung gestellten mittel, z.b. wird speicher allokiert und freigegeben wie es passt. file handling wird vom system verwendet, manchmal hast du auch die endianess vom system darunter (java VM hat z.B. immer big endian).



  • Wobei jeder gute Interpreter sowieso mit einer VM gleichzusetzen ist. Python oder PHP machen es ja genau gleich: der Code wird kompiliert in einen Bytecode und dieser Bytecode wird dann ausgeführt. Das ist technisch nicht wirklich etwas anderes als eine VM.
    Wobei natürlich die Java VM weit mehr entwickelt ist.



  • Definiere mal "guten Interpreter" im Gegensatz zum allgemeinen Interpreter, nach dem hier gefragt wurde.



  • Python hat auch eine VM. Nur tritt sie da nicht in den Vordergrund.

    Von aussen gesehen wird in Python der Programmcode interpretiert (da reiner Text). Dröselt man den Prozess auf, wird Python erst geparsed, zu Bytecode compiliert dann schliessliche der Bytecode in der VM ausgeführt. Die hinteren Schritte sind aber versteckt.

    In Java ist die VM hingegen im Vordergrund. Das macht es möglich, Java mit anderen Sprachen zu mischen. Ginge in Python theoretisch auch, ist aber nicht vorgesehen.

    Die VM ist genau genommen auch nur ein Interpreter (Bytecode-Interpreter), aber halt mit gewissen Hardware-Abstraktions-Garantien.

    Mit statischer/dynamischer Typisierung hat das nichts zu tun (wie hustbaer impliziert hat).



  • DerAndroide schrieb:

    Definiere mal "guten Interpreter" im Gegensatz zum allgemeinen Interpreter, nach dem hier gefragt wurde.

    Ein "dummer" Interpreter wäre zB die bash. Zeile für Zeile das Script auswerten und ausführen.

    Ein guter Interpreter wäre zB PHP. Zuerst wird alles in einen Bytecode kompiliert und optimiert und dann wird der Bytecode in einer VM ausgeführt.

    Natürlich ist Java hier zB ein paar Dimensionen technisch komplizierter und weiterentwicklet - aber "dumme" Interpreter wie zB bash gibt es heutzutage eher nicht. PHP, Python, JavaScript, Lua,... sie alle haben eine VM intern.



  • wimmer schrieb:

    Mit statischer/dynamischer Typisierung hat das nichts zu tun (wie hustbaer impliziert hat).

    Nein, das habe ich nicht impliziert.
    Weiss nicht wie du darauf kommst.
    Lies meinen Beitrag nochmal.



  • Ich finde es komisch etwas als VM zu bezeichnen, wenn es keine formale Definition dieser VM gibt.
    Bei Java oder C# gibt es diese.
    Bei Python nicht.
    Wieso sollte ich dann sagen dass Python oder PHP mit Hilfe einer VM ausgeführt wird? Nur weil irgend eine Form von Zwischencode und evtl. sogar ein JIT Compiler verwendet werden?

    Oder ist per Definition alles was irgendwelchen Code "umsetzt", aber kein klassischer AST-Walker mehr ist, gleich automatisch eine VM? Wäre eine für mich komische Definition des Begriffs...



  • hustbaer schrieb:

    wimmer schrieb:

    Mit statischer/dynamischer Typisierung hat das nichts zu tun (wie hustbaer impliziert hat).

    Nein, das habe ich nicht impliziert.
    Weiss nicht wie du darauf kommst.
    Lies meinen Beitrag nochmal.

    Also ich habe das gemeint:

    hustbaer schrieb:

    Oder ob ein Programm erstmal nur geparsed wird, wobei ein AST rauskommt, den man quasi 1:1 wieder zurück in Sourcecode übersetzen könnte.

    Auf Python (zumindest auf frühe Python Versionen) triffst das zweite zu, deswegen spricht man da eher von einer interpretierten Sprache.

    Der Python Bytecode ist ziemlich High-Level, da durch das Duck-Typing keine Typinformationen bekannt sein können. Vom Python AST zum Python Bytecode ist sprachbedingt ziemlich einfach (Optimierungen, wie z.B. inlinen oder Operationen umtauschen ist gar nicht erlaubt)

    Deshalb habe ich daraus geschlossen, dass Python (und Duck Typing) nach deiner Auffassung prinzipiell keine VM zulässt.

    hustbaer schrieb:

    Ich finde es komisch etwas als VM zu bezeichnen, wenn es keine formale Definition dieser VM gibt.
    Bei Java oder C# gibt es diese.
    Bei Python nicht.

    Das Ding heisst Python Virtual Machine, obs dir passt oder nicht. Nur dass die VM nicht von der Sprache diktiert wird, sondern von einer Implementierung festgelegt wird.



  • wimmer schrieb:

    hustbaer schrieb:

    Oder ob ein Programm erstmal nur geparsed wird, wobei ein AST rauskommt, den man quasi 1:1 wieder zurück in Sourcecode übersetzen könnte.

    Auf Python (zumindest auf frühe Python Versionen) triffst das zweite zu, deswegen spricht man da eher von einer interpretierten Sprache.

    Der Python Bytecode ist ziemlich High-Level, da durch das Duck-Typing keine Typinformationen bekannt sein können. Vom Python AST zum Python Bytecode ist sprachbedingt ziemlich einfach (Optimierungen, wie z.B. inlinen oder Operationen umtauschen ist gar nicht erlaubt)

    Deshalb habe ich daraus geschlossen, dass Python (und Duck Typing) nach deiner Auffassung prinzipiell keine VM zulässt.

    Ich meinte es ist ein Unterschied ob eine Sprache standardisiert ist, und dieser Standard eine VM beschreibt. Wie eben z.B. bei Java. Dadurch ist die Java-VM etwas explizites, greifbares. Man kann sogar andere Sprachen bauen die in der JVM laufen.

    Bei Python ist das nicht so. Für die ersten Python Versionen gab es nichtmal irgend einen echten Standard, Python war einfach "implementation defined". Mit ein bisschen informeller Beschreibung was man inetwa zu erwarten hat (<- ja, leicht untertrieben, aber prinzipiell ist/war es so).
    Wie das aktuell aussieht weiss ich nicht, vielleicht wurde da bereits nachgebessert.

    Und damit verliert der Begriff VM für mich hier etwas an Realität. Ist doch im Endeffekt einfach nur eine Sammlung von Strukturen und Techniken die die aktuelle Implementierung des Interpreters verwendet um Python auszuführen. Der könnte es aber auch genau so gut anders machen.

    hustbaer schrieb:

    Ich finde es komisch etwas als VM zu bezeichnen, wenn es keine formale Definition dieser VM gibt.
    Bei Java oder C# gibt es diese.
    Bei Python nicht.

    Das Ding heisst Python Virtual Machine, obs dir passt oder nicht. Nur dass die VM nicht von der Sprache diktiert wird, sondern von einer Implementierung festgelegt wird.

    Ich muss mit der Verwendung des Begriffs VM deswegen aber noch lange nicht einverstanden sein, ob es dir nun passt oder nicht 😉
    Nicht alles was irgendwo als Name/Bezeichnung/Beschreibung für etwas verwendet wird ist korrekt, nur weil der Urheber der benannten/beschriebenen Sache den Namen/die Beschreibung selbst gewählt hat.
    Wenn die Python-Katamaran dazu sagen würden wäre es deswegen immer noch kein solcher.

    Bzw. vielleicht wird anhand eines Beispiel besser klar was ich meine: Ich kann auch hergehen und eine Beschreibung für einen "bytecode" basteln der als einzige Opcodes "\r" und "\n" kennt, und damit dann eine Beschreibung für eine "VM" basteln, die 1:1 DOS Batch-Files ausführt.
    Und dann behaupten dass cmd.exe eine VM verwendet.

    Nur dass der "Befehlssatz" dieser "VM" so weit von einem realen oder gedachten Computersystem entfernt wäre, dass der Begriff mMn. nicht mehr viel Sinn macht.

    Also erlaube ich mir "VM" nur für Dinge zu verwenden, deren Befehlssatz inetwa dem entspricht was man von normalen CPUs gewohnt ist. Auf Java oder C# trifft das zu. Auf Python nicht.

    Also: welche Kriterien betrachtest du um zu entscheiden ob etwas eine VM ist, oder doch "nur" ein Interpreter? Wo ziehst du die Grenze?



  • danke für die Antworten.

    Ich fasse also den Grundtenor hier zusammen:
    1. VM nur, wenn eine vernünftige Definition (Standardisierung) dieser existiert und der Befehlssatz halbwegs dem entspricht, was man von echten Befehlssätzen (z.B. x86) her kennt
    2. ob nun AST oder Bytecode ausgeführt wird, spielt keine Rolle für die Bezeichnung als VM
    3. praktisch alle "modernen" Skriptsprachen führen nicht direkt den AST aus, sondern erzeugen Bytecode, welcher dann interpretiert wird. Ob es nun ein Bytecodeinterpreter oder eine VM ist siehe 1.

    Grund der Frage: Hatte letztens eine Diskussion mit einem Kollegen. Er meinte, bei Python handle es sich nicht um einen Interpreter, sondern um eine VM so wie bei Java.
    Ich kann nun also dagegenhalten: ja, Python erzeugt zwar Bytecode, aber als VM kann man das noch nicht bezeichnen da nicht standardisiert und zu wenig Ähnlichkeit mit "echtem" Befehlssatz.



  • Das deckt sich inetwa mit meiner Meinung zu dem Thema.
    Wie du siehst haben andere hier allerdings eine ganz andere Meinung 🙂

    Mit 1-2 leichten Modifikationen hast du aber ein Statement das nicht so leicht "angreifbar" ist, bzw. nicht mehr so stark davon abhängig was man nun als VM durchgehen lässt und was nicht:

    "Ja, Python erzeugt zwar Bytecode, aber als VM wie bei Java kann man das nicht bezeichnen, da bei Python kaum Ähnlichkeit zum Befehlssatz einer realen oder theoretischen CPU besteht, bei Java aber sehr wohl."

    Denn der Teil ist schonmal ziemlich klar, dass - selbst wenn man das was der Python Interpreter verwendet als VM bezeichnen möchte - grosse Unterschiede zwischen der JVM und der "Python VM" bestehen.

    ps: Nö, deckt sich doch nicht ganz mit meiner Meinung zu dem Thema. Etwas was auf einem AST rumrödelt würde ich grundsätzlich nicht als VM bezeichnen, da hier ebenfalls kein Code im Spiel ist der in irgendeiner Form dem einer realen oder gedachten CPU ähnlich wäre. Also doch nicht ganz unabhängig davon.



  • hustbaer schrieb:

    Wieso sollte ich dann sagen dass Python oder PHP mit Hilfe einer VM ausgeführt wird? Nur weil irgend eine Form von Zwischencode und evtl. sogar ein JIT Compiler verwendet werden?

    Also ist PHP auf hiphop(hhvm) eine VM und PHP auf dem php.net Interpreter keine VM - obwohl beide technisch einander sehr aehnlich sind. hhvm ist aber technisch etwas weiter entwickelt und formal definiert, waehrend ja PHP ansich keinen definierten standard hat.

    Willst du technische Gegebenheiten wirklich an der Existenz der Dokumentation festlegen? Die PHP VM ist gut genug definiert dass man optimizer dafuer schreiben kann die dann als extension laufen.



  • @Shade Of Mine
    OK, ich verstehe deinen Standpunkt.
    Aber beantworte du mir bitte die Fragen

    welche Kriterien betrachtest du um zu entscheiden ob etwas eine VM ist, oder doch "nur" ein Interpreter? Wo ziehst du die Grenze?

    ps: Vielleicht ist der interessantere Punkt wirklich ob der Befehlssatz und allgemeine Aufbau dem eines realen Computers ähnlich ist. Also einfache Opcodes mit einfachen Operanden, keine super-komplexen Operationen wie Lookups in String-Dictionaries um die aufzurufende Funktion zu finden.
    Nur, wenn etwas in einem offiziellen Standard beschrieben und als VM bezeichnet wird, trotz dem es dieses Kriterium nicht erfüllt, dann muss man wohl oder übel damit leben dass es von allen so bezeichnet wird.

    Wenn aber beides nicht gegeben ist, dann nehme ich mir die Freiheit Bullshit zu rufen.



  • hustbaer schrieb:

    Das deckt sich inetwa mit meiner Meinung zu dem Thema.
    Wie du siehst haben andere hier allerdings eine ganz andere Meinung 🙂

    Mit 1-2 leichten Modifikationen hast du aber ein Statement das nicht so leicht "angreifbar" ist, bzw. nicht mehr so stark davon abhängig was man nun als VM durchgehen lässt und was nicht:

    "Ja, Python erzeugt zwar Bytecode, aber als VM wie bei Java kann man das nicht bezeichnen, da bei Python kaum Ähnlichkeit zum Befehlssatz einer realen oder theoretischen CPU besteht, bei Java aber sehr wohl."

    Denn der Teil ist schonmal ziemlich klar, dass - selbst wenn man das was der Python Interpreter verwendet als VM bezeichnen möchte - grosse Unterschiede zwischen der JVM und der "Python VM" bestehen.

    Ist es denn technisch unmöglich einen Rechner zu bauen, der Python Bytecode direkt ausführt? Denke nicht, nur ziemlich aufwendig. 😉



  • @Ethon
    Nein, natürlich ist es nicht unmöglich.
    Es ist aber technisch auch nicht unmöglich einen Rechner zu bauen der direkt Batch-Files ausführt.
    Oder diverse BASIC-Dialekte.

    Nennen wir deswegen jetzt alles was BASIC oder Batch-Files ausführt VM?


Anmelden zum Antworten