2011-06-20 13 views
6

Estoy trabajando en un lenguaje de scripting, y como parte de eso estoy escribiendo código de puente entre mi lenguaje y C usando LLVM. He estado trabajando en un contenedor para API LLVM en Object-C que ha estado funcionando bien hasta este momento.Función LLVM y C con struct como argumento

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)))); 
} 

El problema que tengo es visto en la siguiente salida de la prueba:

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). 

El módulo volcado muestra que el argumento de la estructura se pasa como era de esperar, sin embargo, la función C sólo recibe x campo establecido en 10, y el campo y se deja vacío. No tengo ni idea de cómo sucede esto y qué puedo hacer para solucionarlo. Gracias de antemano por cualquier ayuda que pueda darme.

+0

<35> y <10> se refiere a un tipo definido anteriormente, que debería existir en su módulo, intente volcar el contenido del módulo y péguelo en su pregunta – lurscher

Respuesta

9

Te estás perdiendo la Plataforma ABI. Supongo que está en x86-64, luego su estructura (de acuerdo con el ABI) debe pasarse en un solo registro como un todo. Sin embargo, está pasando {10, 25} como dos valores separados de 32 bits. Dado que las operaciones de 32 bits implican una extensión cero implícita, está claro por qué tiene 0 como el segundo valor.

Para ser precisos: el código C espera recibir 25 en los 32 primeros bits del primer registro de argumento, pero está pasando el valor en los 32 bits bajos del segundo registro de argumento.

+1

@Michael: compile su código C para llvm asm. Verá cómo 'test_struct' en el argumento de función se cambia a i64 y cómo se llama su letra. Necesitas hacer lo mismo. –

+0

Muchas gracias, esa es la información que necesitaba. –

Cuestiones relacionadas