Skip to content
Code Generierung
Optimization
- Zwischendarstellung (AST) transformieren für effizienteren Code
- z.B konstante Expressions, leere Statement-Blöcke, etc.
- Wird bei uns noch ausgelassen
- Kann auch später, z.B. im JIT geschehen
- Ziel bei uns: Erzeugung von Code für eine VM
- Zwischendarstellung ist die Schnittstelle zum "Backend", in diesem Fall eine Runtime
- Mehrere Frontends: Multi-Language
- Mehrere Backends: Multi-Platform
Unsere Zielmaschine
- Subset von .NET IL
- Virtueller Stack-Prozessor
- "goto"-machine
- Keine loops, nur "flacher" Code mit Branches
- Metadaten: Was sind unsere Klassen, Variablen, Typen, etc.?
- U.a. für Linking, Querreferenzen von anderen Libraries / Binaries
- Referenzen für GC
Virtual Stack Machine
- Stack in der Prozedur
- Operanden lesen (pop) und Ergebnis schreiben (push)
- Erster Pop ist right-hand-side der Operation
- Jede Instruktion hat gewisse Anzahl Pops und Pushes
- Stack ist vor und nach der Methode "leer"
- Kann auch alles in einem Stack ausgeführt werden
- Lokale Variablen / Parameter werden durchnummeriert
- Beispiel Auswertung:
x = x * (7 + 11)
- Im Unterschied zu Java / .NET haben wir konkrete Boolean-Werte
- Sonst wären es 0/1 integers
and
und or
-Operators müssen mit Branches nachgebaut werden (äquivalent zu if-else)
- Beispiel Boolean:
b = !a
Kontrollfluss
- Branch to Label Instruktionen
- Conditional Instruktionen (z.B.
brfalse
), um zu anderen Branches zu springen
IL-Generierung
- Builder Pattern
- Serialisierung in XML (bei uns, für Komfort)
- Zuerst Metadaten mit Symboltabelle erstellen
- AST Traversieren mit Visitor und Instruktionen erzeugen
- Labels werden zuerst erstellt (
CreateLabel()
) und erst später an den IL-Code "attached" (SetLabel()
)
- Labels werden am Schluss übersetzt in relative Sprungstellen (in Anzahl Instruktionen)
Code-Templates
- Mit Pattern-Matching Muster im AST erkennen
- z.B. wenn
+
kommt, generieren wir add
- Post-Order-Traversierung und jeweils Pattern erkennen
- Kleine Optimierungen möglich
- Pattern-Erkennung schwieriger, z.B. um
if
und if-else
zu unterscheiden
- Binäre Operatoren mit Booleans als
if-else
behandeln