vorteile einer virtual machine?



  • Optimizer schrieb:

    Vergiss auch nicht, dass du durch das hinzuladen neuer Klassen, vorhandenen, eigentlich statischen Code ändern musst.

    C/C++ Code:
    class Fraction
    {
    // Implementiert nicht op<< aber ein op(double)
    };

    int main()
    {
    Type type;
    ... // Klasse Fraction laden

    Type* a new Type(5, 2);
    cout << *a; // Gibt ein double aus.
    }
    C/C++ Code:
    class Fraction
    {
    // Implementiert nicht op<< aber ein op(double)
    };

    int main()
    {
    Type type;
    ... // Klasse Fraction laden

    Type* a new Type(5, 2);
    cout << *a; // Gibt ein double aus.
    }
    C/C++ Code:
    class Fraction
    {
    // Implementiert nicht op<< aber ein op(double)
    };

    int main()
    {
    Type type;
    ... // Klasse Fraction laden

    Type* a new Type(5, 2);
    cout << *a; // Gibt ein double aus.
    }

    Ich darf aber statt Fraction auch was anderes laden, oder?
    Jetzt laden wir die Klasse Fraction2 hinzu, die den op<< aber implementiert.
    Jetzt muss statt dem op(double) der op<< aufgerufen werden, der nicht mal Element der Klasse selber ist, sondern global.
    Was wir jetzt haben ist keine dynamische Bindung, auch keine "extended super complicated dynamische Bindung", sondern völlig anderes Verhalten. Und das machst du mir ohne Compiler.

    Ne, ich bin ja eigentlich schon fast geneigt zu sagen, dass die Sprache C++ schon an sich fast zu kompliziert für solche Späße ist. Aber dann ohne JIT-Compiler noch... kann ich mir nicht vorstellen.

    wenn ich eine DLL lade, brauch ich keine VM dafür und ich brauche auch nicht den statischen code zu ändern!

    Es könnte doch in C++ genauso wie in Java realisiert werden:

    //Diese Klasse ist in einer "CDLL (Class DLL)"
    //in einer Class DLL sind alle reflection infos im gleichen format wie in einer .class datei von java, nur im native code
    class MeineDynamischeKlasse {
    
    int x;
    public:
    
        MeineDynamischeKlasse(int a): x(a) {}
    
        int f(int b) {
           cout << "hallo " << x << b;
        }
    
    }
    
    public static void main() {
    
        //lade MeineDynamischeKlasse dynamisch nach
        // alle reflection infos mit den dazugehörigen adressen werden jetzt aus der CDLL geladen und in "dynamischeKlasse" gepackt.
        Class* dynamischeKlasse = Class::forName("MeineDynamischeKlasse");
    
        //hole konstruktor mit dem parameter "int"
        Constructor* standardKonstruktor = dynamischeKlasse->getConstructor(Class::forName("int")):
    
        //hole die Methode "f"
        Method* fMethode = dynamischeKlasse->getMethod("f", Class::forName("int"));
    
        //erzeuge jetzt ein objekt vom typ MeineDynamischeKlasse und übergebe konstruktor die 10
        Object* obj = standardKonstruktor->newInstance(10);
    
        //rufe die methode "f" auf. auf der konsole sollte jetzt "hallo 10 20" ausgegeben werden
        fMethode->invoke(obj, 20);
    }
    

    das ist doch "Laufzeit-Reflection", oder? Wo muss man hier den bestehenden statischen Code ändern? Hier werden überall nur Zeiger bzw. Referenzen verwendet!

    was du dort gepostet hast, mit dem << operator. sowas ist mit java reflection auch nicht möglich!



  • Wo muss man hier den bestehenden statischen Code ändern? Hier werden überall nur Zeiger bzw. Referenzen verwendet!

    Ja, was ist hier? Dein Code jetzt? Super! 😃 👍
    Und was ist mit meinem, legalen, standardkonformen C++ Code?

    was du dort gepostet hast, mit dem << operator. sowas ist mit java reflection auch nicht möglich!

    Doch. Ich kann auch statische Funktionen (wie der operator<< eine wäre) mit Reflection getten und aufrufen.



  • Komisch, ich verstehe das Problem gar nicht. Ich sag ja nicht mal, dass man sowas unbedingt braucht. Ich sag auch nicht, dass es toll ist (auch wenn ich es trotztdem toll finden darf). Die Frage war doch nur "wofür braucht man ne VM", worauf ich sage, für JIT-Compilierung, außer ich bau nen Compiler in meine .exe ein, was natürlich Unsinn ist.
    Das kann man doch akzeptieren, oder?



  • Optimizer schrieb:

    Wo muss man hier den bestehenden statischen Code ändern? Hier werden überall nur Zeiger bzw. Referenzen verwendet!

    Ja, was ist hier? Dein Code jetzt? Super! 😃 👍
    Und was ist mit meinem, legalen, standardkonformen C++ Code?

    Dein Code sieht schön und einfach aus. Ich kann nachvollziehen, dass man dafür einen JIT braucht.
    Allerdings ist dort die ganze Typprüfung futsch! Nicht mal in Java funktioniet das so einfach, und unsicher! Dort musst du dir alles schön selber über die Class besorgen! (siehe Beitrag oben)

    was du dort gepostet hast, mit dem << operator. sowas ist mit java reflection auch nicht möglich!

    Doch. Ich kann auch statische Funktionen (wie der operator<< eine wäre) mit Reflection getten und aufrufen.[/quote]

    globale Funktionen gibt es bei Java nicht.

    BTW: es geht mir nicht darum, dass wir uns hier jetzt für C++ eine Reflection-API ausdenken. Mag seien, dass man für C++-reflection einen JIT benötigen würde. Will mir da auch echt kein Kopf drüber machen...
    Meiner Meinung nach ist für Java-Reflection keine VM oder auch JIT notwendig.



  • Optimizer schrieb:

    Komisch, ich verstehe das Problem gar nicht. Ich sag ja nicht mal, dass man sowas unbedingt braucht. Ich sag auch nicht, dass es toll ist (auch wenn ich es trotztdem toll finden darf). Die Frage war doch nur "wofür braucht man ne VM", worauf ich sage, für JIT-Compilierung, außer ich bau nen Compiler in meine .exe ein, was natürlich Unsinn ist.
    Das kann man doch akzeptieren, oder?

    Wofür braucht man JIT Compilierung, bei Java?
    Ich denke, für Reflection nicht....

    Evtl. fürs dynamische Optmieren? Wenn ja, bringt das wirklich so viel?



  • mathik schrieb:

    Optimizer schrieb:

    Wo muss man hier den bestehenden statischen Code ändern? Hier werden überall nur Zeiger bzw. Referenzen verwendet!

    Ja, was ist hier? Dein Code jetzt? Super! 😃 👍
    Und was ist mit meinem, legalen, standardkonformen C++ Code?

    Dein Code sieht schön und einfach aus. Ich kann nachvollziehen, dass man dafür einen JIT braucht.

    Allerdings ist dort die ganze Typprüfung futsch! Nicht mal in Java funktioniet das so einfach, und unsicher! Dort musst du dir alles schön selber über die Class besorgen! (siehe Beitrag oben)

    Klar. Das dynamische hinzuladen von Klassen hat Nachteile und Einschränkungen, das stand ja nie in Frage.

    was du dort gepostet hast, mit dem << operator. sowas ist mit java reflection auch nicht möglich!

    Doch. Ich kann auch statische Funktionen (wie der operator<< eine wäre) mit Reflection getten und aufrufen.

    globale Funktionen gibt es bei Java nicht.

    Man, jetzt bitte. 😞
    "(wie der operator<< eine wäre)". Nimm halt dann C#. Da kannst Operatoren schreiben. Der muss nicht außerhalb einer Klasse stehen. Er ist nicht Member und wird nicht dynamisch gebunden, das ist der Punkt. Und nicht, ob's global oder statisch ist. Sowas langweilt doch.

    BTW: es geht mir nicht darum, dass wir uns hier jetzt für C++ eine Reflection-API ausdenken. Mag seien, dass man für C++-reflection einen JIT benötigen würde. Will mir da auch echt kein Kopf drüber machen...
    Meiner Meinung nach ist für Java-Reflection keine VM oder auch JIT notwendig.

    Diese Meinung kann ich nicht nachvollziehen. In Java kriegst du die selben Probleme in Grün. Du hast halt keinen globalen Operator aber dafür ne statische Funktion.



  • Optimizer schrieb:

    mathik schrieb:

    Optimizer schrieb:

    Wo muss man hier den bestehenden statischen Code ändern? Hier werden überall nur Zeiger bzw. Referenzen verwendet!

    Ja, was ist hier? Dein Code jetzt? Super! 😃 👍
    Und was ist mit meinem, legalen, standardkonformen C++ Code?

    Dein Code sieht schön und einfach aus. Ich kann nachvollziehen, dass man dafür einen JIT braucht.

    Allerdings ist dort die ganze Typprüfung futsch! Nicht mal in Java funktioniet das so einfach, und unsicher! Dort musst du dir alles schön selber über die Class besorgen! (siehe Beitrag oben)

    Klar. Das dynamische hinzuladen von Klassen hat Nachteile und Einschränkungen, das stand ja nie in Frage.

    was du dort gepostet hast, mit dem << operator. sowas ist mit java reflection auch nicht möglich!

    Doch. Ich kann auch statische Funktionen (wie der operator<< eine wäre) mit Reflection getten und aufrufen.

    globale Funktionen gibt es bei Java nicht.

    Man, jetzt bitte. 😞
    "(wie der operator<< eine wäre)". Nimm halt dann C#. Da kannst Operatoren schreiben. Der muss nicht außerhalb einer Klasse stehen. Er ist nicht Member und wird nicht dynamisch gebunden, das ist der Punkt. Und nicht, ob's global oder statisch ist. Sowas langweilt doch.

    BTW: es geht mir nicht darum, dass wir uns hier jetzt für C++ eine Reflection-API ausdenken. Mag seien, dass man für C++-reflection einen JIT benötigen würde. Will mir da auch echt kein Kopf drüber machen...
    Meiner Meinung nach ist für Java-Reflection keine VM oder auch JIT notwendig.

    Diese Meinung kann ich nicht nachvollziehen. In Java kriegst du die selben Probleme in Grün. Du hast halt keinen globalen Operator aber dafür ne statische Funktion.

    hierfür braucht man kein JIT:

    Methode* statischeOp = dynamischeKlasse->getStaticMethod("operator<<", Class::forName("ostream"), Class::forName("DynamischeKlasse"))
    
       statischeOp->invoke(cout, dynamischeKlasse);
    

    selbst in java musst du das so ähnlich machen!!

    hierfür braucht man JIT:

    cout<<dynamischeKlasse
    

    das ist dann aber auch echt wie eine Skriptsprache...
    sowas funktioniert nicht mal bei Java! dort musst du dir die statische Methode ersmal holen (siehe oben)



  • @optimizer
    vielleicht könntest du ein Reflection-Beispiel in Java bringen, wo man einen JIT bräuchte.



  • Du brauchst allein schon nur nen Compiler, um sicherzustellen, dass der hinzugeladene Code im hineinzuladenden Kontext gültig ist.

    class FooBlubberBar extends BlubberBar
    {
        @Override
        void foo()        {...}
    }
    

    Das ist eine perfekt gültige Klassendefinition.

    Wenn du es aber in diesen Kontext hineinlädst:
    [java]
    final class BlubberBar extends java.lang.Object
    {
    void bar() {...}
    }
    [/java]
    Dann passieren böse Dinge. Das @Override ist illegal und ableiten von BlubberBar auch. Mit ein paar trivialen Checks ist es IMHO nicht getan. Ehrlich gesagt möchte ich mir jetzt nicht noch weitere Beispiele ausdenken, aber ich zweifle nicht daran, dass es noch komplizierter geht. Die einzige saubere Lösung ist und bliebt compilieren.

    Dann hätten wir noch den bekannten Fall, dass vorhandener Code geändert werden muss:

    MyType x = new MyType();
    x.statischeMethode();
    

    Wenn MyType eine statische Methode Namens statischeMethode() definiert, wird diese aufgerufen. Wenn es das nicht tut, muss eine statische Methode der Basisklasse mit dem Namen statischeMethode() aufgerufen werden. In Java ist nämlich der Aufruf einer statischen Methode über den statischen Typ einer Instanz erlaubt. Das ist vergleichbar mit dem Operator-Gefrickel in C++.

    EDIT: Dazu passt natürlich, was bei der Dokumentation zu Class<T> steht, welche ja die ganzen Reflection-Informationen enthält.

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html schrieb:

    Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.



  • Optimizer schrieb:

    Du brauchst allein schon nur nen Compiler, um sicherzustellen, dass der hinzugeladene Code im hineinzuladenden Kontext gültig ist.

    class FooBlubberBar extends BlubberBar
    {
        @Override
        void foo()        {...}
    }
    

    Das ist eine perfekt gültige Klassendefinition.

    Wenn du es aber in diesen Kontext hineinlädst:
    [java]
    final class BlubberBar extends java.lang.Object
    {
    void bar() {...}
    }
    [/java]
    Dann passieren böse Dinge. Das @Override ist illegal und ableiten von BlubberBar auch. Mit ein paar trivialen Checks ist es IMHO nicht getan. Ehrlich gesagt möchte ich mir jetzt nicht noch weitere Beispiele ausdenken, aber ich zweifle nicht daran, dass es noch komplizierter geht. Die einzige saubere Lösung ist und bliebt compilieren.

    ich denke schon, dass die Checks vom ClassLoader durchgeführt werden können. Von mir aus, soll der ClassLoader einen ganzen Compiler haben, um die Checks durchzuführen. Vorhandener Code muss hierfür nicht geändert werden.

    Optimizer schrieb:

    Dann hätten wir noch den bekannten Fall, dass vorhandener Code geändert werden muss:

    MyType x = new MyType();
    x.statischeMethode();
    

    Wenn MyType eine statische Methode Namens statischeMethode() definiert, wird diese aufgerufen. Wenn es das nicht tut, muss eine statische Methode der Basisklasse mit dem Namen statischeMethode() aufgerufen werden. In Java ist nämlich der Aufruf einer statischen Methode über den statischen Typ einer Instanz erlaubt. Das ist vergleichbar mit dem Operator-Gefrickel in C++.

    hmmh...
    man könnte auch statische Methoden in die vtable oder ähnliches packen.
    Ich denke sogar, dass das auch bei java so gemacht wird...

    Optimizer schrieb:

    EDIT: Dazu passt natürlich, was bei der Dokumentation zu Class<T> steht, welche ja die ganzen Reflection-Informationen enthält.

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html schrieb:

    Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.

    Die Class-Objekte können auch dynamisch vom ClassLoader kontruiert werden (Class Class::forName(String)).

    BTW: kennt jemand vielleicht ein Dokument von Sun oder Microsoft, wo steht, warum die sich für eine VM entschieden haben?



  • ich denke schon, dass die Checks vom ClassLoader durchgeführt werden können. Von mir aus, soll der ClassLoader einen ganzen Compiler haben, um die Checks durchzuführen. Vorhandener Code muss hierfür nicht geändert werden.

    Ich habe auch nicht gesagt, dass hierfür Code geändert werden muss. 🙄

    man könnte auch statische Methoden in die vtable oder ähnliches packen.
    Ich denke sogar, dass das auch bei java so gemacht wird...

    So ein Unsinn. Statische Methoden stehen nicht in einer VTable und das wird auch nicht bei Java so gemacht. Aus welchen Grund sollte man das tun? Nur damit du angeblich auf einen JIT-Compiler verzichten kannst? Was für ein Quatsch.
    Ich hab auch extra unterstrichen, dass der Methodenaufruf anhand des statischen Typs erfolgt, also nix dynamische Bindung. Es wäre ein Fehler, die statische Methode dynamisch zu binden (Fehler == es entspricht nicht der Spezifikation).

    Wie auch immer, ich klink mich jetzt aus.



  • Sovok schrieb:

    n gewisser zeitaufwand wenn du updates für 20 plattformen erstellen musst

    *rofl*?
    wer stellt denn seine programme bitte für 20 programme bereit? 99% der programme laufen auf 32-bit windows und damit basta.

    anscheinend leiden vm-leute unter größenwahn: sie denken, dass sie plötzlich für alle systeme porten zu müssen, weil sie es vorher nicht schafften standard-nah zu
    hacken und neuerdings denken sie auch noch, dass sie wie phönix aus der asche steigen und von den "profis" akzeptiert werden, so wie bill gates mit windows. AHAHAHAHA! 😃

    mfg



  • btw: es heißt hier anscheinend öfters, dass plugins über vererbung zu stande kommen müssen. wozu? macht es doch wie in half-life (iirc):
    eine struct mit functionspointer, die von den plugins (= mods) aufgerufen wird. die engine hat es dann schon gerichtet, und anscheinend funktioniert das prima, da cs und konsorten ansonsten wahrscheinlich im beta-stadium stecken geblieben wären... 😮

    mfg



  • terraner schrieb:

    btw: es heißt hier anscheinend öfters, dass plugins über vererbung zu stande kommen müssen. wozu? macht es doch wie in half-life (iirc):
    eine struct mit functionspointer, die von den plugins (= mods) aufgerufen wird. die engine hat es dann schon gerichtet, und anscheinend funktioniert das prima, da cs und konsorten ansonsten wahrscheinlich im beta-stadium stecken geblieben wären... 😮

    öh, ah achja



  • kingruedi schrieb:

    öh, ah achja

    plugins müssen nicht mit hilfe von vererbung implementiert werden, aber es wurde hier mehrmals angesprochen, wenn du das meinst.

    mfg



  • terraner schrieb:

    plugins müssen nicht mit hilfe von vererbung implementiert werden, aber es wurde hier mehrmals angesprochen, wenn du das meinst.

    Nein, das bezog sich auf deinen Kommentar mit der "struct mit functionspointer".



  • kingruedi schrieb:

    Nein, das bezog sich auf deinen Kommentar mit der "struct mit functionspointer".

    vererbung wird auch mit zeigern implementiert iirc, aber bei der struct bräuchte ich keine zur compilezeit erstellte vtable.

    mfg



  • terraner schrieb:

    kingruedi schrieb:

    Nein, das bezog sich auf deinen Kommentar mit der "struct mit functionspointer".

    vererbung wird auch mit zeigern implementiert iirc, aber bei der struct bräuchte ich keine zur compilezeit erstellte vtable.

    Das vtable entspricht dieser Struktur. Nur wäre das über die Vererbung sauberer und robuster gelöst worden.

    Das kommt davon, wenn man auf veraltete oder falsche Aussagen vertraut, wie "Objekt Orientierung ist langsam" etc.


Anmelden zum Antworten