Unterschied Interpreter - virtuelle Maschine



  • 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