2016-05-21 18 views
1

Ich versuche im Moment einen Compiler für meine Sprache zu erstellen. In meiner Sprache möchte ich eine implizite Zeigerverwendung für Objekte/Strukturen wie in Java haben. Im folgenden Programm teste ich diese Funktion aus. Das Programm läuft jedoch nicht wie erwartet. Ich erwarte nicht, dass ihr meinen gesamten Compiler-Code durchliest, denn das wäre Zeitverschwendung. Stattdessen hatte ich gehofft, ich könnte erklären, was ich für das Programm tun wollte, und ihr wisst, was schief gelaufen ist. Auf diese Weise kann ich den Compiler anpassen, um eine ordnungsgemäße llvm ir zu generieren. LLVM IR - Kann jemand dieses Verhalten erklären?


Fluss:
[Funktion] Main - [Return: Int] {
-> Ordnet Raum für Struktur eines i32
-> Anrufe CREATEOBJ Funktion und speichert die Rückkehr Wert innerhalb vorherigen zugewiesenen Speicherplatz
-> Returns die i32 der Struktur
}

[Funktion] CREATEOBJ - [Return: struct {i32}] {
-> Ordnet Raum für Struktur eines i32
-> Anrufe Objektfunktion auf diesem Raum (Zeiger wirklich)
-> Gibt diesen Raum (Zeiger wirklich)
}

[Funktion] Object - [Return: void] {
-> Speichert den i32 Wert von 5 im Inneren der Struktur Zeigerargument


Das Programm ist, dass Main eine zufällige Zahl anstelle von 5 zurückgibt. Eine solche Nummer ist 159383856. Ich vermute, dass dies die Dezimaldarstellung einer Zeigeradresse ist, aber ich bin mir nicht sicher, warum es druckt aus der Zeigeradresse.


; ModuleID = 'main' 

%Object = type { i32 } 

define i32 @main() { 
entry: 
    %0 = call %Object* @createObj() 
    %o = alloca %Object* 
    store %Object* %0, %Object** %o 
    %1 = load %Object** %o 
    %2 = getelementptr inbounds %Object* %1, i32 0, i32 0 
    %3 = load i32* %2 
    ret i32 %3 
} 

define %Object* @createObj() { 
entry: 
    %0 = alloca %Object 
    call void @-Object(%Object* %0) 
    %o = alloca %Object* 
    store %Object* %0, %Object** %o 
    %1 = load %Object** %o 
    ret %Object* %1 
} 

define void @-Object(%Object* %this) { 
entry: 
    %0 = getelementptr inbounds %Object* %this, i32 0, i32 0 
    store i32 5, i32* %0 
    ret void 
} 

Diese llvm ir wird aus dieser Syntax erzeugt.

Antwort

4

Es scheint, als ob Sie in createObj einen Zeiger auf eine Stapelvariable zurückgeben, die nach der Rückgabe der Funktion nicht mehr gültig ist.

Wenn Sie implizite Objektzeiger wie Java machen, benötigen Sie einen Aufruf für eine Heap-Zuweisung wie malloc, von dem ich nicht glaube, dass Sie ihn haben.

+0

Ah das macht viel Sinn! Vielen Dank. Ich werde es ausprobieren und melden. – k3v