Seite 9 von 10

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 21.10.2013 20:26
von puretom
Sie müssen nicht zwingend NICHT nullterminiert sein, das ist in Windeseile geändert.

Genau genommen waren sie noch vor ca. 30 Minuten nullterminiert!

Spiele gerade verschiedene Designstudien parallel durch.

LG Thomas

Edit:

Das Einzige, was ich vermeiden möchte, ist, dass die VM zur LAUFZEIT die Länge des Strings für *PC+LÄNGE DES STRINGS berechnen muss, --> Speed.
Deshalb habe ich das mit dem Voranstellen der Stringlänge so gemacht.

Andere Möglichkeit wäre dann ein String-Konstanten-Pool, dann bleibt hier *PC+4 konstant für einen Long-Zahlen-Paramenter (=String Index). Aber den muss ich beim Laden trennen, das ist zusätzlicher Aufwand für einen Lader.

Man sieht, es gibt Pros und Kons für verschiedenste Varianten.
Wie löst ihr das?

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 21.10.2013 21:05
von ts-soft
So, hier ein Beispiel, wie man den String ohne Peeks aus dem Speicher liest.
Wenn Du das verstehst, wird alles schön :wink:

Code: Alles auswählen

str.s = "Hallo"
*str = @str
*mem.String = @*str
Debug *mem\s
Gruß
Thomas

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 21.10.2013 21:35
von puretom
Ganz lieben Dank ts-soft!

Das habe ich daraus gemacht (ohne Debug-Sachen):

Code: Alles auswählen

     
              *PC+4                     ; PC auf String-Länge       
              sLen=*PC\l                ;      - holen
              *PC+4                     ; PC auf String
              *str = *PC                ;      - mit einem Pointer
              *sPara.String = @*str     ;      - kompliziert holen ;-))  
              sPush(*sPara\s)           ; String auf Operanden-Stack
              *PC+sLen-3                ; PC auf nächsten Opcode (nur -3 wg. 0-Byte)

Wir haben hier einen 0-terminierten String, der aber davor trotzdem noch die Länge gespeichert hat.

Warum? Weil ich in der letzten Zeile die sLen (String Lenght) zum *PC rechnen muss und zur RUNTIME NICHT LEN(*sPara\s) machen will.

Das wäre zu meiner Version also bloß 1 Byte mehr, bei - glaube ich zumindest - mehr Performace der VM.
  • Ist die Pointerversion als solches wirklich so viel schneller als PeekS() und PeekL() usw. ?

LG Puretom

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 21.10.2013 21:53
von ts-soft
puretom hat geschrieben:[*]Ist die Pointerversion als solches wirklich so viel schneller als PeekS() und PeekL() usw. ?
Das solltest Du Dir eigentlich beantworten können :wink:
Peek und Poke sind Funktionen, mit Werten auf Stack, Stack bereinigen usw., bei den Pointern wird direkt der Wert
gelesen oder geschrieben. Nicht die länge des Codes ist entscheidend, Poke und Peek scheinen nur kürzer!
Nur der String bedarf einer Extrawurscht, da die Adresse der Variable lediglich die Adresse zum String enthält und nicht
den String.

Gruß
Thomas

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 25.10.2013 17:33
von ts-soft
Fällt mir gerade auf, Du verwendest feste IDs für Dateien usw., das ist ungünstig, weil im Code, der vor dem "Compilieren" ausgeführt wird,
könnte ja bereits eine z.B. Datei mit der ID geöffnet worden sein und nicht geschlossen.

Ich würde in Modulen, genauso wie in Includes, UserLibraries usw. nur mit #PB_Any arbeiten.

Gruß
Thomas

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 25.10.2013 18:06
von puretom
Danke für den Tipp!

Machst du das konsequent immer so?

Und auf einen Pointer?

also:

*SourceFile = CreateFile(#PB_Any, Dateiname$ )

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 25.10.2013 18:21
von ts-soft
puretom hat geschrieben:Machst du das konsequent immer so?
Ich mach das in allen Proceduren, die wiederverwendbar sein sollen, in Modulen, Includes und UserLibraries-Sources sowieso.
puretom hat geschrieben: Und auf einen Pointer?

also:

*SourceFile = CreateFile(#PB_Any, Dateiname$ )
Das kannst Du halten wie ein Dachdecker. Ob Integer oder Pointer hat keine Auswirkungen, dabei geht es mehr um die Ethik.

Gruß
Thomas

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 25.10.2013 18:34
von puretom
Das werde ich mal glatt bei Gelegenheit ändern!

Ich arbeite nämlich gerade im Schweiße meines Angesichts :wink: an meiner Virtual Machine!

Falls ich vergesse, bitte erinnere mich nochmal :oops: !

LG Thomas

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 25.10.2013 21:54
von puretom
Hi Leute!

Ich würde gerne in ein Array, das mein Return-Stack wird, nur Pointer speichern.
Nach einem Gosub speichert die VM da drin den alten Program Counter (*PC), der eben selber schon ein Pointer in eine Memory-Zelle ist.

Wird das so (siehe Code) was?
Global Dim *RetStack(10000)
Der Compiler akzeptiert es problemlos, doch ich frage mich:
  • Ist das jetzt ein Array of Integers, das als Namensbestandteil ein * vorne hat?
  • Oder ist das jetzt ein Array of Pointers?
Was ist der Unterschied für mich bzw. warum grüble ich darüber nach?

Ich GLAUBE gelesen zu haben irgendwo, dass man sich beim Typ Pointer darauf verlassen könne, dass er vom Typ (also 4 Byte, 8 Byte usw.) immer dem entsprechenden Adressierungsraum meines verwendeten Betriebssystems (32 Bit, 64 Bit, ... bzw. der dazu passenden Pure Basic Compilerversion) entsprechen würden. Das trifft zwar für Integer auch zu, aber irgendwo /:-> habe ich mal eine Diskussion gelesen, denke ich, wo da ein Unterschied gemacht wurde!

Danke für eure Hilfe!

Re: [Tutorial] Compiler und Virtual Machine

Verfasst: 25.10.2013 22:07
von ts-soft
Naja, pointer als Arraytyp ist nicht offiziell dokumentiert. Es funktioniert zwar und das Array wird auch reserviert, ich
würde aber in diesem Fall eher Integer nehmen, weil das könnte mit der nächsten Version von PB evtl. verboten werden.

Ansonsten, Pointer und Integer passen sich der nativen Registerbreite des Compilers an, also entweder 32 oder 64 Bit.

Pointer in ein IntegerArray sollte kein Problem sein.

Gruß
Thomas

// edit
PS: Du solltest EnableExplicit in den Modulen nutzen, z.B. bei der Umstellung auf #PB_Any hast Du File als Variable
eingeführt. Ohne Deklaration wird es schwer zu erkennen, ist das Global oder Lokal in der Procedure.
Also ein Protected File am beginn der Procedure gibt einem gleich den notwendigen Hinweis, ausserdem vermeidet
EnableExplicit auch weitere Fehler.