Naja, ich würde erstmal die Sprache selbst festlegen, bevor ich das Ausgabeformat festlege.
Ach, und bei x86 Prozessoeren hat man auch erst die Sprachen festgelgt und dann die CPU entwickelt?
Nein kommt nicht in Frage, zuerst ein solides Ausgabeformat nach dem sich dann die Sprachen zu richten haben!
Die VM würde ich auf einer virtuellen Maschine mit beliebig vielen Registern aufbauen und nicht auf einem Stack wie in Java oder .NET. Das hat den Vorteil, das man einige Optimierungen besser vornehmen kann, wie z.B. Typchecks zur Compilierzeit. Die Register kann man dann teilweise 1:1 auf die realen Register übertragen und muss nicht den Umweg über Stackzugriffe nehmen.
Ich denke mehr an eine System das ohne beides auskommt.
Ob du Little oder Big Endian benutzt ist nicht wirklich wichtig, der JIT muss dann zwar eventuell beim Laden der Anwendung etwas rumshiften, aber das solle keinen bemerkbaren Performanceunterschied geben.
Hmm ok, dass dürfte eigentlich nicht soviel Zeit benötigen.
@Osbios: Für den 2. Fall hast du wahrscheinlich die optimale Möglichkeit (ohne das man irgendwelche Verteilungen vom Eintreten der Bedingungen kennt) schon hingeschrieben!
Nein habe ich nicht, aber sie währe (meine Meinung nach):
if Bedingung1 then
{
X = sin(y)/pi+pi*360
A = X
if Bedingung2 then B = X
}
else
if Bedingung2 then B = sin(y)/pi+pi*360
Du hast aber einen grundlegenden Unterschied schon mal zum Java Bytecode drin der schon mal ein potenzieller Grund für ein neues Format darstellt: Du willst alles für maximales Tempo drin. Der Java Bytecode sollte in erster Linie kompakt sein, damit die Programme schnell übers Internet übertragen werden können.
Allerdings ist deine Forderung nach einem halbwegs universellem, sicherem Bytecode ähnlich der Anforderungen des Bytecodes von .NET.
Nunja, ich will damit auch Treiber Schreiben und die im Ring 0 laufen lassen. Da muss schon etwas Geschwindigkeit und Sicherhheit vorhanden sein.
Nun ja, vieles kann man zur Ladezeit machen. Programme die Daten über das Internet verschicken wollen werden aber sich aber darauf verlassen müssen das die Daten die sie zur Laufzeit erzeugen die richtige Reihenfolge haben.
Dafür gibt es in standard Netzerk Libs, Systemunabhängige Funktionen, die dafür sorgen, dass für bestimmte dinge nur eine Bytereihenfolge im Netzwerk benutzt wird.
Ich denke optimales Tempo kann man wahrscheinlich erreichen indem man Instruktionen die möglichst nahe an klassichen CPUs liegen anbietet, jedoch ohne die Sicherheit zu gefährden, sonst kann man sich ne VM auch praktisch sparen!
Das mit der Sicherheit dürfte uns allen klar sein, aber ich bin nicht der Meinung, dass man führ eine hohe Geschwindigkeit, CPU nahe Instruktionen nutzen sollte.
@PorkChicken:
X = sin(y)/pi+pi*360
if Bedingung1 then A = X
print(X)
X = sin(y)/pi+pi*360
if X < 100 then A = X
Bei diesen beiden Varianten wird X explizit von einer folgenden Berechnung benötigt, daher spielt es keine Rolle ob sie woanders eventuell benötigt oder nicht benötigt wird.
und woher weisst du dass sin(y) nicht vielleicht mehr macht, als nur einen wert zurückzugeben? vielleicht schreibt es was auf den monitor oder so.
Ich weiß es weil ich
alles, bis auf die Kernelfunktionen, in Module unterbringen werde. Man kann daher relativ einfach ein neues Modul den den schon vorhandenen Modulen verschmelzen.
Als Beispiel: mal angenommen man hätte 2 Module, wobei das eine auf die angebotenen Funkionen des anderen zugreift.
X = 8663
Funktion XY
{
return X
}
A = 1337
B = A + XY
Hierbei kann man erkennen das XY nur eine Konstante zurück gibt und man dann zwei Konstandten addieren kann:
B = 10000
Das ist natürlich ein sehr einfaches Beispiel, es soll auch nur zeigen, dass man sehr wohl wissen kann was die einzelnen Funktionen aufrufen wenn man ein ganzes System darauf aufbaut.
und was machst du hiermit:
X = 1/sin(y)
if Bedingung1 then A = X
unter bestimmten bedingungen wird sin(y) gleich 0 und es gibt eine divide-by-zero-exceptionen. was, wenn das programm in diesem fall auch genau eine exception braucht?
if Bedingung1 then A = 1/sin(y)
dieser code kann nur dann eine divide-by-zero-exception auslösen, wenn auch Bedingung1 erfüllt ist. die beiden code abschnitte sind also nicht gleichwertig.
Ein Programm das eine exception brauch? Ich würde vorschreiben das man Teiler auf <> 0 Testen müsste um unvorhergesehene "Porgrammeigenschaften" zu vermeiden. Nein, ehrlich gesagt weiß ich noch nicht wie man X/0 handhaben sollte.
if Bedingung1 or Bedingung2 then
X = sin(y)/pi+pi*360
if Bedingung1 then A = X
if Bedingung2 then B = X
end if
Ich würde die doppelten if then vermeiden. Hab ich zwar schon weiter oben hingeschrieben, aber hier nochmal:
if Bedingung1 then
{
X = sin(y)/pi+pi*360
A = X
if Bedingung2 then B = X
}
else
if Bedingung2 then B = sin(y)/pi+pi*360
Ich hoffe das mit dem Modlen, als System und Optimierungsbasis, ist rübergekommen.
Nochmal in Kurzform:
Es gibt nur ganz wenige Funktionen die direkt vom JIT bzw. Kernel zur Verfügung gestellt werden. Alle anderen Funktionen werden von Modulen bereitgestellt.
Der JIT kann auf die Module übergreifende Optimierungen vornehmen.
Wieder ein kleines Beispiel anhand eines Treibermodules und eines Programmmodules (das keine I/O Rechte besitzt).
Wenn das Programm auf eine Funktion des Treibermodules zugreift, die auf einen Port schreibt, kann es sein, dass der JIT zur Optimierung den CALL-Aufruf umgeht indem er einfach den entsprächenden Code des Treibers im Laufzeitcode des Programms einfügt.
Dann ist im Laufzeitcode des Programms ein I/O Zugrif obwohl das Programm garkeine I/O berechtigung hat.