2011-06-20 71 views
6

我正在研究一種腳本語言,並且我正在使用LLVM在我的語言和C之間編寫橋代碼。我一直在爲Objective-C中的LLVM API進行包裝工作,直到目前爲止它一直在努力工作。以結構作爲參數的LLVM和C函數

typedef struct _test_struct { 
    int x; 
    int y; 
} test_struct; 

id testLLVMStructFuncCall(test_struct x) { 
    NSLog(@"%d %d",x.x,x.y); 
    return N(x.x + x.y); 
} 

-(void) testLLVMStructFuncCall { 
    CGKModule* myMod = [CGKModule moduleWithName:@"llvm_structfunccall_test"]; 
    CGKType* testStructType = [CGKType structTypeWithElementTypes:[NSArray arrayWithObjects:[CGKType intTypeWith32Bits],[CGKType intTypeWith32Bits],nil]]; 
    CGKFunction* lfunc = [CGKFunction functionWithName:@"testLLVMStructFuncCall" types:[NSArray arrayWithObjects:[CGKType idType],testStructType,nil] intoModule:myMod]; 
    CGKFunction* rfunc = [CGKBuilder createStandaloneCallForFunction:lfunc withArguments:[NSArray 
                          arrayWithObjects: 
                         [CGKConstant getStructOfType:testStructType 
                             withValues:[NSArray arrayWithObjects:[CGKConstant getIntConstant:N(10) bits:32], 
                                [CGKConstant getIntConstant:N(25) bits:32],nil]],nil] 
                 inModule:myMod]; 
    [myMod dump]; 
    id var = [[CGKRunner runnerForModule:myMod] runCGKFunction:rfunc]; 
    assertThat(var,is(equalTo(N(35)))); 
} 

我已經在從所述測試輸出下面看到的問題:

Test Case '-[SVFunctionTests testLLVMStructFuncCall]' started. 
; ModuleID = 'llvm_structfunccall_test' 

%0 = type { i32, i32 } 

declare i64* @testLLVMStructFuncCall(%0) 

define i64* @0() { 
entry: 
    %0 = call i64* @testLLVMStructFuncCall(%0 { i32 10, i32 25 }) 
    ret i64* %0 
} 
2011-06-20 21:25:54.821 otest-x86_64[3369:707] 10 0 
/Users/mtindal/Projects/Silver/Tests/SVFunctionTests.m:576: error: -[SVFunctionTests testLLVMStructFuncCall] : Expected <35>, but was <10> 
Test Case '-[SVFunctionTests testLLVMStructFuncCall]' failed (0.016 seconds). 

模塊轉儲表明如預期的那樣結構參數被傳遞,但是,C函數僅接收在x字段設置爲10,並且y字段留空。我完全無知這是怎麼發生的,以及我能做些什麼來解決它。預先感謝您提供的任何幫助。

+0

<35>和<10>指的是以前定義的類型,它應該存在於你的模塊中,嘗試轉儲模塊內容並將其粘貼到你的問題中 – lurscher

回答

9

您錯過了平臺ABI。我假設你在x86-64上,那麼你的結構(根據ABI)應該作爲一個整體在一個寄存器中傳遞。但是,您將{10,25}作爲兩個單獨的32位值傳遞。鑑於32位操作做隱式零擴展,很明顯你爲什麼有0作爲第二個值。

準確而言:C代碼希望在第一個參數寄存器的前32位中接收25,但是您將該值傳遞給第二個參數寄存器的低32位。

+1

@Michael:將你的C代碼編譯爲llvm asm。你會看到函數參數中的'test_struct'如何被更改爲i64以及它如何被調用。你需要這樣做。 –

+0

非常感謝你,那是我需要的信息。 –