LLVM IR - 有人可以解释这种行为吗?

LLVM IR - Can someone explain this behavior?

我目前正在尝试为我的语言构建一个编译器。在我的语言中,我想对 objects/structs 使用隐式指针,就像在 Java 中一样。在下面的程序中,我正在测试此功能。但是,该程序并没有像我预期的那样运行。我不希望你们通读我的整个编译器代码,因为那样会浪费时间。相反,我希望我能解释我打算让程序做什么,你们可以在 llvm ir 中发现哪里出了问题。这样,我可以调整编译器以生成正确的 llvm ir。


流量:
[功能] 主要 - [Return: Int] {
-> 为一个 i32
的结构分配 space -> 调用 createObj 函数并将返回值存储在先前分配的 space
中 -> Returns 结构的 i32
}

[函数] createObj - [Return: struct { i32 }] {
-> 为一个 i32
的结构分配 space -> 在此 space 上调用对象函数(实际上是指针)
-> Returns this space(真正的指针)
}

[函数] 对象 - [Return: void] {
-> 将 5 的 i32 值存储在结构指针参数
中 }


该程序是 main 不断返回一些随机数而不是 5。一个这样的数字是 159383856。我猜这是指针地址的十进制表示,但我不确定它为什么打印出指针地址。


; 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
}

这个 llvm ir 是从这个语法生成的。

func () > main > (int) {
    Object o = createObj();

    return o.id;
}

// Create an object and returns it
func () > createObj > (Object) { 
    Object o = make Object < ();

    return o;
}

// Object decl
tmpl Object {
    int id; // Property

    // This is run every time an object is created.
    constructor < () {
        this.id = 5;
    }
}

似乎在 createObj 中,您正在 return 指向堆栈变量的指针,该变量在函数 return.

之后将不再有效

如果您至少要使用 Java 这样的隐式对象指针,您将需要调用像 malloc 这样的堆分配,我认为您没有。