-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
struct passing bug(?) #2149
Comments
recording this for my reference: %struct.CXCursor = type { i32, i32, [3 x i8*] }
%struct.CXCursor = type { i32, i32, i8*,i8*,i8* }
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
declare i32 @clang_hashCursor(%struct.CXCursor* byval align 8)
define void @test_cu2(%struct.CXCursor* byval align 8 %cu) uwtable {
%1 = alloca %struct.CXCursor, align 8
call void @llvm.dbg.declare(metadata !{%struct.CXCursor* %cu}, metadata !2262), !dbg !2263
%2 = bitcast %struct.CXCursor* %1 to i8*, !dbg !2264
%3 = bitcast %struct.CXCursor* %cu to i8*, !dbg !2264
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %3, i64 32, i32 8, i1 false), !dbg !2264
%4 = call i32 @clang_hashCursor(%struct.CXCursor* byval align 8 %1), !dbg !2264
%5 = getelementptr inbounds %struct.CXCursor* %cu, i32 0, i32 0, !dbg !2264
%6 = load i32* %5, align 4, !dbg !2264
%7 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([25 x i8]* @.str3, i32 0, i32 0), i3
2 %4, i32 %6), !dbg !2264
ret void, !dbg !2266
} |
75f8321 fixes it. julia> using cindex; tu = tu_init("Index.h")
Ptr{Void} @0x00000000032a1560
julia> cu = ccall( (:test_cu1, "../lib/libwrapcindex"), CXCursor, (Ptr{Void},), tu)
hash out: ef5bd483 kind out: 300
CXCursor(300,0,Ptr3(0x00000000032a1560000000000000000100000000032a01d0))
julia> ccall( (:test_cu2, "../lib/libwrapcindex"), Void, (CXCursor,), cu)
hash in: ef5bd483 kind in: 300
julia> cindex.hashCursor(cu)
0xef5bd483
julia> cindex.hashCursor(cu)
0xef5bd483 |
… struct return (disabled). unfortunately this breaks ComplexPair{Int} (ComplexPair{Float64} seems OK)"" This reverts commit 4fa9364.
ComplexPair{Int32} and similar small, integer structs are broken for ccall pass-by-value (not a new problem)
sigh. apparently passing structs to functions is not actually supported by the LLVM StructType. Clang has about 20k lines of code apparently just for this purpose. I can try to put something simple together that works for 90% of cases, but I won't be sure if I've got everything, and it will only be for x86 and x86_64. In the long term, we may need to leverage more from clang (it has over 1.5k lines of code just for x86_64 calling convention rules themselves), but that will be really annoying too, since we'll have to rebuild all of the llvm integer and floating points types in clang's type system. oddly, clang also distinguishes between complex float and struct { float re; float im; } when generating LLVM op-codes (although the x86 asm is the same) |
Probably not useful for Julia, but the LuaJIT ffi implementation is really impressive (as is LuaJIT in general): (a few other notes about struct ffi approaches: https://github.com/ihnorton/notes/wiki/Notes-on-struct-passing ) |
those are some great references. it's worth noting that a struct of 2 floats != complex float on x86_64 this is probably the most possible to port: http://repo.or.cz/w/luajit-2.0.git/blob/master:/src/lj_ccall.c for v0.1, I would like to ensure that passing complex numbers, structs larger than 2 pointers, and possibly structs of only integer types works on x86 and x86_64 linux. the remaining options should be an error (for now). then we can go from there. |
3 years and counting waiting for support for this: http://llvm.org/bugs/show_bug.cgi?id=4246 |
… struct return (disabled). unfortunately this breaks ComplexPair{Int} (ComplexPair{Float64} seems OK)"" This reverts commit 4fa9364.
well, the clang approach seems to have died in the waters. however, hope is not to be forsaken (not yet anyways) The D language looks like it has this awesome llvm implementation which supports everything (of course it has to). What's better, its only a few thousands lines of C++ code -- unlike the attempt from clang -- and it looks reasonably intelligible (although there's a comment in the code claiming this part is a bit of a mess :). if anyone can point me to the Doxygen files or wants to try asking them to split that part off into a library (saving me the work of doing just that), it would be much appreciated! The license for the relevant files is "Artistic license or the GPL version 2 or later." which seems OK, although perhaps not great? Definitely seems like an argument for making this a standalone library. |
Kind of ugly. Artistic is complicated and really only supposed to show up in conjunction with Perl. |
The comments in the files themselves refer mostly to the "BSD-style LDC license", which is fine. |
Oops, Jeff is right, I was tired and looking at the wrong file's license. It is in fact "three-clause BSD" LDC license.
|
will be addressed by #3466 |
"oddly, clang also distinguishes between complex float and struct { float re; float im; } when generating LLVM op-codes (although the x86 asm is the same)" @vtjnash These are probably the same on 64-bit x86; they differ on 32-bit x86. This also means that C's complex number (which use a built-in type) return complex numbers different from C++ (which defines them essentially as struct). One simple way to handle this in Julia, which uses the C++ approach and defines complex numbers in a library instead of requiring them as a built-in type, would be to wrap any external routines that return complex numbers in C++ code with |
@vtjnash knows what I am talking about from IRC. Struct return seems to be working, but struct passing is problematic.
debugging lines:
https://github.com/ihnorton/CIndex.jl/blob/purejl/lib/wrapcindex.cpp#L79-L89
debugging output:
https://gist.github.com/4653523#file-gist1-L4-L12
all of the hashes should match.
the branch with attempt to use pure julia structs is here:
https://github.com/ihnorton/CIndex.jl/tree/purejl
The text was updated successfully, but these errors were encountered: