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 这样的堆分配,我认为您没有。
我目前正在尝试为我的语言构建一个编译器。在我的语言中,我想对 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 这样的堆分配,我认为您没有。