Функция LLVM и C со структурой в качестве аргумента - PullRequest
7 голосов
/ 20 июня 2011

Я работаю над языком сценариев, и как часть этого я пишу код моста между моим языком и C, используя LLVM.Я работал над оболочкой для API-интерфейсов LLVM в target-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 остается пустым.Я совершенно не понимаю, как это происходит и что я могу сделать, чтобы это исправить.Заранее благодарим за любую помощь, которую вы можете оказать мне.

1 Ответ

10 голосов
/ 20 июня 2011

Вам не хватает платформы ABI.Я предполагаю, что вы на x86-64, тогда ваша структура (согласно ABI) должна быть передана в одном регистре в целом.Однако вы передаете {10, 25} как два отдельных 32-битных значения.Учитывая, что 32-битные операции имеют неявное нулевое расширение, ясно, почему у вас есть 0 в качестве второго значения.

Если быть точным: код C ожидает получить 25 в старших 32 битах первого регистра аргумента, новы передаете значение в младшие 32 бита второго регистра аргумента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...