Harbour Handbuch – DE
HTML-Ausgabe

Kapitel 13

Hinweis: Dies ist die vollständige deutsche Übersetzung des Kapitels. Codebeispiele und Diagramme sind sprachunabhängig gültig.

Kapitel 13: Das Herz der Harbour-VM

Im Zentrum von Harbour befindet sich eine leistungsfähige virtuelle Maschine (VM), die – gemeinsam mit dem Compiler – den Sourcecode in portable, effiziente Anwendungen umwandelt. Dieses Kapitel erklärt die Hauptbestandteile dieser Architektur.

Der Kompilierer: vom Sourcecode zum P-Code

Der Harbour-Compiler (harbour.exe) ist ein Preprozessor und Übersetzer, der:

  1. den Sourcecode (.prg) analysiert
  2. in optimierten P-Code (Pseudo-Code) übersetzt
  3. den P-Code in .c-Dateien verpackt
  4. diese mit einem C-Compiler zu einer .exe oder einem Binärprogramm kompilieren lässt

Dieses zweistufige Kompilieren über C macht Harbour extrem portabel.


graph TD;
    subgraph "Schritt 1: Kompilieren mit Harbour"
        A[.prg Sourcecode] --> B{Harbour Compiler};
        B --> C[P-Code → C];
        C --> D[C-Datei (.c)];
    end

    subgraph "Schritt 2: Kompilieren mit C-Compiler"
        D --> E{C-Compiler (GCC, Clang...)};
        F[Harbour-Libs (VM, RTL, RDDs)] --> E;
    end
    
    E --> G[Ausführbare Anwendung (.exe)];

Die virtuelle Maschine (VM): der Executor von Harbour

Die VM von Harbour:


graph TD;
    subgraph "Harbour-VM"
        A[P-Code Executor]
        B[Speicher-Manager
(GC)] C[Stack-Verwaltung] D[Dynamisches Typ-System] end E[Harbour-Programm] --> A; A --> C; A --> B; A --> D; A --> F[Datenschicht (RDD)];

P-Code: die optimierte Zwischensprache

Harbour-Programme werden in eine interne, kompakte Zwischensprache übersetzt: den **P-Code**.

Beispiel:

nErgebnis := (nWert1 + nWert2) * 2

→ Entspricht konzeptionell folgendem P-Code:

Der Compiler führt bereits zur Compile-Zeit Optimierungen durch (z. B. Konstantenberechnung).

Der Stack: Funktionsaufrufe und lokale Variablen

Jeder Funktionsaufruf erzeugt einen Stack-Frame:

  1. Parameter werden auf den Stack gelegt
  2. Rücksprungadresse wird gespeichert
  3. Platz für LOCAL-Variablen wird reserviert
  4. nach RETURN: alles wird wieder entfernt

sequenceDiagram
    participant Aufrufer
    participant Stack
    participant Funktion

    Aufrufer->>Stack: Parameter pushen
    Aufrufer->>Stack: Rücksprungadresse pushen
    Aufrufer->>Funktion: Lokale Variablen aktivieren

    Funktion-->>Stack: Rückgabewert pushen
    Funktion-->>Aufrufer: Rücksprung
    Aufrufer->>Stack: Rückgabewert lesen
    Aufrufer->>Stack: Stack säubern

Dank dieser Technik sind verschachtelte und rekursive Aufrufe sicher und speichereffizient.