Unterschied Interpreter - virtuelle Maschine



  • 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?



  • hustbaer schrieb:

    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.

    Ich finde auch, dass der Befehlssatz aus "einfachen" Operationen bestehen soll. Also mit Instruktionpointer und Jump, kein AST-Walker.

    Aber was sich dahinter verbirgt kann durchaus komplexer sein. Bei Java ist der GC Teil der VM und das ist durchaus nichts triviales. Ein bisschen String-Lookup ist da mMn voll ok.

    hustbaer schrieb:

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

    Meine Definition:
    Bytecodeinterpreter: Code besteht nur aus einfachen Instruktionen, der Programmfluss ist vorhersehbar. Kümmert sich nur um die Ausführung, nicht um Memory-Management, oder die Datentypen.
    VM: Besteht aus Bytecodeinterpreter plus Maschinenabstraktion, d.h. Definition des Int-Datentyps, Speicherverwaltung (GC) etc. Alles ist unabhängig von der darunterliegenden Architektur, auch der Bytecodeinterpreter.

    VM nur, wenn eine vernünftige Definition (Standardisierung) dieser existiert

    Wenn es eine VM ohne Definition gibt und dann kommt eine Doku hinzu, ist die VM erst dann eine VM? Standardisiert oder nicht macht mMn gar keinen Unterschied. Eine Programmiersprache braucht auch keine formale Definition (siehe z.B. D).



  • Also die Speicherverwaltung ist mMn. nicht notwendigerweise ein Teil einer VM. Ich kenne z.B. auch keine reale Maschine die eine solche eingebaut hat.
    Und die Datentypen muss der Bytecode-Interpreter schon festlegen. Bzw. sind sie Teil der Definition des Bytecodes.

    Was bleibt jetzt also noch übrig was zum Bytecode-Interpreter dazukommen muss, damit wir es VM nennen können?



  • hustbaer schrieb:

    @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?

    Ich finde solche Trennungen einfach falsch. Du wirst nie eine perfekte Definition dafuer finden. Denn ein weiter entwickelter Interpreter ist immer eine unterentwickelte VM.

    Desto weiter er sich entwickelt desto VM aehlicher wird er und desto simpler eine VM ist, desto interpreteraehnlich ist sie.



  • Basic auf dem C64, Amiga usw ist ein reiner Interpreter. Die Technik hinter VMWare, QEmu sind VMs. Bei Java würde ich gar nicht von einer VM reden, eher einfach nur von einer Runtime Umgebung, diese ist bei Oracle Java dynamisch oder auch bei Androids ART statisch.

    Ist aber wirklich schwer zu definieren, Wikipedia sagt auf der einen Seite auch dass eine VM nur einen Abbildung eine kompletten Rechners in Software ist. Auf der anderen Seite wird bei Javas Unterbau zwar nicht direkt VM genannt, sondern JVM, aber das passt alles vorn und hinten nicht.

    VM und Laufzeitumgebung ist noch schwieriger zu trennen, aber eher vergleichbar als ein Interpreter der zusammen mit einer VM/Laufzeitumgebung arbeitet.

    Der Interpreter ist für mich die Schicht über der Laufzeitumgebung. So komme ich am besten damit klar.



  • @Shade Of Mine
    Und ich würde dann halt sagen: ein weiter entwickelter Interpreter verwendet vielleicht eine VM, aber warum sollte man sagen er ist eine VM? Speziell wenn es nur ein Implementierungsdetail ist dass etwas VM-artiges verwendet wird. Also Bytecode-Interpreter bzw. JIT-compiler.

    Gerade weil der Begriff so schwammig bzw. schlecht abgrenzbar ist. Er ist auf jeden Fall mal ein Interpreter, ganz wurst ob gebytecoded und gejitet wird, deswegen würde ich eher den Begriff verwenden und VM halt wirklich nur sagen wenn ich unterstreichen will dass hier irgendwas besonders "VM-ig" gemacht wird.



  • Shade Of Mine schrieb:

    Wobei jeder gute Interpreter sowieso mit einer VM gleichzusetzen ist.

    ich implizierte darueber genau das gegenteil, die dinge sind nicht gleich zu stellen sondern verschiedene dinge.

    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.

    ein bytecode kann interpretiert werden. ein bytecode kann mit JIT auf eine CPU compiliert werden. Das macht aber keinen unterschied darueber, ob es in einer VM laeuft oder nicht.

    VM gegenueber steht eher der eigentlich prozess, also keine virtual machine, sondern die echte umgebung auf der auch der eigentliche prozess laeuft. viele hand geschriebene parser/interpreten laufen in die prozess umgebung gebunden und sind dort schwer zu seperieren z.b. unrealscript oder das scripting in the Doom3 engine.

    der unterschied zu einer VM ist dann, dass du in c++ auf denselben daten arbeitest wie die scriptsprache, dabei ist es egal, ob die scriptsprache interpretiert laeuft oder JIT kompiliert wird.

    das hast du bei z.B. java nicht, wenn du jni nutzt, hast du immer eine schnittstelle aus der du java aufrufst oder aus der java dein prozess aufruft und dort kannst du funktionen bereitstellen mit denen in deiner welt etwas passiert.
    im gegensatz dazu ist z.B. in der doom3 engine jedes objekt dem scripting und dem c++ code bekannt. wenn du objekte instanzierst, dann rufst du dieselbe factory auf wie es das scripting macht. auf der anderen seite kannst du in keine umgebung der scriptsprache ein 'query' nach einem objekt oder desgleichen machen, da es keine solche seperate umgebung gibt.

    ich weiss nicht wie python laeuft, ob es eine VM hat oder direkt in den prozess gebunden ist, aber ich koennte mir vorstellen, dass es anfangs als reiner interpret implementiert war und jetzt mit all den jahren an entwicklung eine VM bekommen hat.



  • rapso schrieb:

    VM gegenueber steht eher der eigentlich prozess, also keine virtual machine, sondern die echte umgebung auf der auch der eigentliche prozess laeuft. viele hand geschriebene parser/interpreten laufen in die prozess umgebung gebunden und sind dort schwer zu seperieren z.b. unrealscript oder das scripting in the Doom3 engine.

    Dann ist PHP per CGI eine VM und PHP per SAPI keine.

    der unterschied zu einer VM ist dann, dass du in c++ auf denselben daten arbeitest wie die scriptsprache, dabei ist es egal, ob die scriptsprache interpretiert laeuft oder JIT kompiliert wird.

    das hast du bei z.B. java nicht, wenn du jni nutzt, hast du immer eine schnittstelle aus der du java aufrufst oder aus der java dein prozess aufruft und dort kannst du funktionen bereitstellen mit denen in deiner welt etwas passiert.

    Das verstehe ich nicht. JNI ist doch nur ein Interface um sich an die VM zu binden. Statt JNI zu verwenden kann ich ja auch einfach direkt Java Bytecode generieren aus dem C++ Code. Das ist doch nur eine Frage was ich machen will und welche Optionen die Plattform mir bietet.

    Definiert jetzt das Interface für dich ob etwas eine VM ist? Denk dabei zB an die Anfänge von Java wo die VM nicht offen war für andere Sprachen, wo es uU auch noch kein JNI gab - keine öffentliche Definition der VM, etc. War Java damals keine VM?



  • Shade Of Mine schrieb:

    rapso schrieb:

    VM gegenueber steht eher der eigentlich prozess, also keine virtual machine, sondern die echte umgebung auf der auch der eigentliche prozess laeuft. viele hand geschriebene parser/interpreten laufen in die prozess umgebung gebunden und sind dort schwer zu seperieren z.b. unrealscript oder das scripting in the Doom3 engine.

    Dann ist PHP per CGI eine VM und PHP per SAPI keine.

    CGI ist kein virtueller raum bzw VM, es ist innerhalb des prozesses ein global sichtbarer raum. virtuell wird es erst, wenn es kuentslich auferzwungen ist innerhalb einer "machine" also prozesses.

    der unterschied zu einer VM ist dann, dass du in c++ auf denselben daten arbeitest wie die scriptsprache, dabei ist es egal, ob die scriptsprache interpretiert laeuft oder JIT kompiliert wird.

    das hast du bei z.B. java nicht, wenn du jni nutzt, hast du immer eine schnittstelle aus der du java aufrufst oder aus der java dein prozess aufruft und dort kannst du funktionen bereitstellen mit denen in deiner welt etwas passiert.

    Das verstehe ich nicht. JNI ist doch nur ein Interface um sich an die VM zu binden. Statt JNI zu verwenden kann ich ja auch einfach direkt Java Bytecode generieren aus dem C++ Code. Das ist doch nur eine Frage was ich machen will und welche Optionen die Plattform mir bietet.

    nochmal, es geht bei einer VM nicht um den code, sondern um die verwaltung drumherum. deswegen sage ich dass die zwei dinge nicht miteinander vergleichbar sind. eine VM bietet quasi einen autonomen raum. du kannst interner komplett aendern, sofern das interface gleich bleibt. genau so andersrum kannst du die VM migrieren auf eine andere platform, sofern das interface erhalten bleibt.

    hast du keine VM, ist also script umgebung an die umgebung des prozesses gebunden, ist es unerheblich ob das script interpretiert oder per JIT an den prozess gebunden wurde, du kannst weder migrieren noch irgendwie die daten abtrennen, da beides auf denselben daten/datentypen/objekten arbeitet.

    Definiert jetzt das Interface für dich ob etwas eine VM ist? Denk dabei zB an die Anfänge von Java wo die VM nicht offen war für andere Sprachen, wo es uU auch noch kein JNI gab - keine öffentliche Definition der VM, etc. War Java damals keine VM?

    du konntest aus java auf objekten von deinem prozess nie arbeiten. -> war schon immer eine VM, obwohl es damals immer interpretiert wurde.

    vielleicht vermittle ich es hier schlecht. ich will die ganze zeit aussagen dass eine VM und ein interpreter zwei komplett andere dinge sind.

    VM vs inner-prozess -> verwaltung von daten, objekten, etc.

    interpreter vs JIT/Native code -> ausfuehrung von code, unabhaengig davon ob VM oder inner preozess.



  • rapso schrieb:

    CGI ist kein virtueller raum bzw VM, es ist innerhalb des prozesses ein global sichtbarer raum. virtuell wird es erst, wenn es kuentslich auferzwungen ist innerhalb einer "machine" also prozesses.

    Ich habe gesagt PHP als CGI. CGI ist eine Schnittstelle.
    Wenn PHP als CGI läuft, dann wird pro Anfrage ein komplett eigener PHP Prozess gestartet - also genau das was du bei einer VM verlangst: komplettes trennen der einzelnen "Instanzen".

    Bei SAPI ist das nicht der Fall, hier werden die Instanzen nicht hart getrennt und man kann auf eine andere laufende Anfrage zugreifen.

    nochmal, es geht bei einer VM nicht um den code, sondern um die verwaltung drumherum. deswegen sage ich dass die zwei dinge nicht miteinander vergleichbar sind. eine VM bietet quasi einen autonomen raum. du kannst interner komplett aendern, sofern das interface gleich bleibt. genau so andersrum kannst du die VM migrieren auf eine andere platform, sofern das interface erhalten bleibt.

    Und ich sage das ist "wischi waschi". Weil das gleiche kann ich bei einem Interpreter easy machen. Beispiel HHVM ist ein neuer PHP "Interpreter" der komplett anders ist als die PHP.net Variante - aber das Interface auf die VM (sprich die Sprache PHP) ist ident.

    Oder ist das zu abstrakt? Dann nehme man als Beispiel den Umstieg von Zend1 auf Zend2 bei PHP. Da wurde der komplette Kern ausgetauscht und dennoch blieben die Interfaces weitgehenst stabil.

    du konntest aus java auf objekten von deinem prozess nie arbeiten. -> war schon immer eine VM, obwohl es damals immer interpretiert wurde.

    Erkläre das bitte, weil das macht gerade keinen Sinn. Wir reden nämlich gerade davon dass man auf die Java Objekt von Auswärts zugreifen kann. Oder geht es dir um die Überhabe in die VM hinein? Weil dann wäre dein Beispiel noch schlechter - da ich aus PHP heraus auch nicht auf C++ Objekte zugreifen kann (wohl aber anders herum).

    VM vs inner-prozess -> verwaltung von daten, objekten, etc.

    interpreter vs JIT/Native code -> ausfuehrung von code, unabhaengig davon ob VM oder inner preozess.

    Also ist der "Interpreter" ein Teil der VM, nämlich der der sich um die Ausführung kümmert während die VM die Verwaltung macht.



  • @rapso
    Ich versteh' ehrlich gesagt auch nicht was du für einen Unterschied meinst.
    Von aussen (also vom Host aus) in eine VM kann man immer reingreifen. Das geht bei Java, geht bei PHP, bei Windows-Prozessen, bei VMware - überall. Muss auch, ist irgendwie logisch.

    Die VM kann bloss nicht so ohne weiteres auf den Host oder eine andere, im selben Host laufende VM zugreifen.

    Sogesehen wäre dann aber so-gut-wie alles wo eine Sprache interpretiert wird eine VM, weil es die wenigsten Sprachen erlauben/ermöglichen einfach so in den Host reinzugreifen.


Anmelden zum Antworten