要正确使用OCaml GC,您需要使用CAMLparam0
和CAMLlocal
等宏。如何从LLVM生成此文件?添加GC" ocaml" llvalue函数似乎不会改变生成的IR。
用于连接某些字符串的示例C代码:
int main(void) {
CAMLparam0();
subsetphp_gc_init();
CAMLlocal1(val1);
CAMLlocal1(val2);
val1 = subsetphp_string_init("asd", 3, 1);
val2 = subsetphp_string_init("qwe", 3, 1);
for (int i = 0; i < 100000; i++) {
val1 = subsetphp_concat_function(val1, val2);
}
CAMLreturn(0);
}
这是我生成的LLVM IR,它将使用下面的valgrind消息进行sigfault:
; ModuleID = 'llvm_test.bc'
%caml_value = type opaque
@asd = private unnamed_addr constant [4 x i8] c"asd\00"
@qwe = private unnamed_addr constant [4 x i8] c"qwe\00"
declare %caml_value* @subsetphp_string_init(i8*, i32, i32)
declare %caml_value* @subsetphp_concat_function(%caml_value*, %caml_value*)
declare void @subsetphp_gc_init()
define i32 @main() gc "ocaml" {
entry:
%"$i1" = alloca double
%"$i" = alloca double
%"$b" = alloca %caml_value*
call void @subsetphp_gc_init()
%str = call %caml_value* @subsetphp_string_init(i8* getelementptr inbounds ([4 x i8]* @asd, i32 0, i32 0), i32 3, i32 1)
store %caml_value* %str, %caml_value** %"$b"
store double 0.000000e+00, double* %"$i1"
store double 0.000000e+00, double* %"$i1"
store double 0.000000e+00, double* %"$i"
br label %loop
loop: ; preds = %loop, %entry
%str2 = call %caml_value* @subsetphp_string_init(i8* getelementptr inbounds ([4 x i8]* @qwe, i32 0, i32 0), i32 3, i32 1)
%"$b3" = load %caml_value** %"$b"
%concat = call %caml_value* @subsetphp_concat_function(%caml_value* %str2, %caml_value* %"$b3")
store %caml_value* %concat, %caml_value** %"$b"
%"$i4" = load double* %"$i"
%addtmp = fadd double %"$i4", 1.000000e+00
store double %addtmp, double* %"$i"
%"$i5" = load double* %"$i"
%EQeqeq = fcmp olt double %"$i5", 1.000000e+05
%booltmp = uitofp i1 %EQeqeq to double
store double %addtmp, double* %"$i"
%loopcond = fcmp one double %booltmp, 0.000000e+00
br i1 %loopcond, label %loop, label %afterloop
afterloop: ; preds = %loop
ret i32 0
}
Valgrind的:
==5938== Invalid read of size 1
==5938== at 0x4C2F950: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5938== by 0x4D7FDF: subsetphp_concat_function (bindings.c:203)
==5938== by 0x4D8430: main (llvm_test.s:46)
==5938== Address 0x6a84558 is 24 bytes inside a block of size 8,224 free'd
==5938== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5938== by 0x4D83BA: subsetphp_finalize_string (bindings.c:38)
==5938== by 0x4D2C70: caml_empty_minor_heap (in /home/olle/kod/subsetphp/test)
==5938== by 0x4D2DC8: caml_minor_collection (in /home/olle/kod/subsetphp/test)
==5938== by 0x4BFB36: caml_alloc_small (in /home/olle/kod/subsetphp/test)
==5938== by 0x4C328B: caml_alloc_custom (in /home/olle/kod/subsetphp/test)
==5938== by 0x4D7CB0: subsetphp_string_alloc (bindings.c:114)
==5938== by 0x4D7DFE: subsetphp_string_init (bindings.c:161)
==5938== by 0x4D8423: main (llvm_test.s:42)
对不起大量的代码。任何帮助表示赞赏。
编辑:最后找到一些关于IR如何看起来像here的例子。