| author | |
| committer | |
| log | e165b8b223bfaaeb5953dec9a1f03b8e0ce4ddab |
| tree | 67af3c2ea71a7b50d283009ed92f0d08223e221d |
| parent | f3a1b5c481646ee35813cbe8bb2b0a3979df3ab8 |
Small iteration oopsie
We could really use some more comprehensive C ABI tests.3 files changed, 133 insertions(+), 8 deletions(-)
src/codegen/llvm.zig+10-8| ... | ... | @@ -1035,10 +1035,11 @@ pub const Object = struct { |
| 1035 | 1035 | } |
| 1036 | 1036 | const ints_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); |
| 1037 | 1037 | const casted_ptr = builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), ""); |
| 1038 | for (llvm_ints) |_, i_usize| { | |
| 1039 | const i = @intCast(c_uint, i_usize); | |
| 1040 | const param = llvm_func.getParam(i); | |
| 1041 | const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, ""); | |
| 1038 | for (llvm_ints) |_, field_i_usize| { | |
| 1039 | const field_i = @intCast(c_uint, field_i_usize); | |
| 1040 | const param = llvm_func.getParam(llvm_arg_i); | |
| 1041 | llvm_arg_i += 1; | |
| 1042 | const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, field_i, ""); | |
| 1042 | 1043 | const store_inst = builder.buildStore(param, field_ptr); |
| 1043 | 1044 | store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 1044 | 1045 | } |
| ... | ... | @@ -1070,10 +1071,11 @@ pub const Object = struct { |
| 1070 | 1071 | } |
| 1071 | 1072 | const floats_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False); |
| 1072 | 1073 | const casted_ptr = builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), ""); |
| 1073 | for (llvm_floats) |_, i_usize| { | |
| 1074 | const i = @intCast(c_uint, i_usize); | |
| 1075 | const param = llvm_func.getParam(i); | |
| 1076 | const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, i, ""); | |
| 1074 | for (llvm_floats) |_, field_i_usize| { | |
| 1075 | const field_i = @intCast(c_uint, field_i_usize); | |
| 1076 | const param = llvm_func.getParam(llvm_arg_i); | |
| 1077 | llvm_arg_i += 1; | |
| 1078 | const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, field_i, ""); | |
| 1077 | 1079 | const store_inst = builder.buildStore(param, field_ptr); |
| 1078 | 1080 | store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8); |
| 1079 | 1081 | } |
test/c_abi/cfuncs.c+52| ... | ... | @@ -120,6 +120,24 @@ typedef struct Vector5 { |
| 120 | 120 | float q; |
| 121 | 121 | } Vector5; |
| 122 | 122 | |
| 123 | typedef struct Rect { | |
| 124 | uint32_t left; | |
| 125 | uint32_t right; | |
| 126 | uint32_t top; | |
| 127 | uint32_t bottom; | |
| 128 | } Rect; | |
| 129 | ||
| 130 | void zig_multiple_struct_ints(struct Rect, struct Rect); | |
| 131 | ||
| 132 | typedef struct FloatRect { | |
| 133 | float left; | |
| 134 | float right; | |
| 135 | float top; | |
| 136 | float bottom; | |
| 137 | } FloatRect; | |
| 138 | ||
| 139 | void zig_multiple_struct_floats(struct FloatRect, struct FloatRect); | |
| 140 | ||
| 123 | 141 | void run_c_tests(void) { |
| 124 | 142 | zig_u8(0xff); |
| 125 | 143 | zig_u16(0xfffe); |
| ... | ... | @@ -200,6 +218,18 @@ void run_c_tests(void) { |
| 200 | 218 | assert_or_panic(res.e == 24); |
| 201 | 219 | } |
| 202 | 220 | |
| 221 | { | |
| 222 | struct Rect r1 = {1, 21, 16, 4}; | |
| 223 | struct Rect r2 = {178, 189, 21, 15}; | |
| 224 | zig_multiple_struct_ints(r1, r2); | |
| 225 | } | |
| 226 | ||
| 227 | { | |
| 228 | struct FloatRect r1 = {1, 21, 16, 4}; | |
| 229 | struct FloatRect r2 = {178, 189, 21, 15}; | |
| 230 | zig_multiple_struct_floats(r1, r2); | |
| 231 | } | |
| 232 | ||
| 203 | 233 | { |
| 204 | 234 | assert_or_panic(zig_ret_bool() == 1); |
| 205 | 235 | |
| ... | ... | @@ -436,6 +466,28 @@ void c_big_struct_floats(Vector5 vec) { |
| 436 | 466 | assert_or_panic(vec.q == 55); |
| 437 | 467 | } |
| 438 | 468 | |
| 469 | void c_multiple_struct_ints(Rect x, Rect y) { | |
| 470 | assert_or_panic(x.left == 1); | |
| 471 | assert_or_panic(x.right == 21); | |
| 472 | assert_or_panic(x.top == 16); | |
| 473 | assert_or_panic(x.bottom == 4); | |
| 474 | assert_or_panic(y.left == 178); | |
| 475 | assert_or_panic(y.right == 189); | |
| 476 | assert_or_panic(y.top == 21); | |
| 477 | assert_or_panic(y.bottom == 15); | |
| 478 | } | |
| 479 | ||
| 480 | void c_multiple_struct_floats(FloatRect x, FloatRect y) { | |
| 481 | assert_or_panic(x.left == 1); | |
| 482 | assert_or_panic(x.right == 21); | |
| 483 | assert_or_panic(x.top == 16); | |
| 484 | assert_or_panic(x.bottom == 4); | |
| 485 | assert_or_panic(y.left == 178); | |
| 486 | assert_or_panic(y.right == 189); | |
| 487 | assert_or_panic(y.top == 21); | |
| 488 | assert_or_panic(y.bottom == 15); | |
| 489 | } | |
| 490 | ||
| 439 | 491 | bool c_ret_bool() { |
| 440 | 492 | return 1; |
| 441 | 493 | } |
test/c_abi/main.zig+71| ... | ... | @@ -355,6 +355,9 @@ export fn zig_split_struct_mixed(x: SplitStructMixed) void { |
| 355 | 355 | |
| 356 | 356 | extern fn c_big_struct_both(BigStruct) BigStruct; |
| 357 | 357 | |
| 358 | extern fn c_multiple_struct_ints(Rect, Rect) void; | |
| 359 | extern fn c_multiple_struct_floats(FloatRect, FloatRect) void; | |
| 360 | ||
| 358 | 361 | test "C ABI sret and byval together" { |
| 359 | 362 | var s = BigStruct{ |
| 360 | 363 | .a = 1, |
| ... | ... | @@ -423,6 +426,74 @@ test "C ABI structs of floats as parameter" { |
| 423 | 426 | c_big_struct_floats(v5); |
| 424 | 427 | } |
| 425 | 428 | |
| 429 | const Rect = extern struct { | |
| 430 | left: u32, | |
| 431 | right: u32, | |
| 432 | top: u32, | |
| 433 | bottom: u32, | |
| 434 | }; | |
| 435 | ||
| 436 | export fn zig_multiple_struct_ints(x: Rect, y: Rect) void { | |
| 437 | expect(x.left == 1) catch @panic("test failure"); | |
| 438 | expect(x.right == 21) catch @panic("test failure"); | |
| 439 | expect(x.top == 16) catch @panic("test failure"); | |
| 440 | expect(x.bottom == 4) catch @panic("test failure"); | |
| 441 | expect(y.left == 178) catch @panic("test failure"); | |
| 442 | expect(y.right == 189) catch @panic("test failure"); | |
| 443 | expect(y.top == 21) catch @panic("test failure"); | |
| 444 | expect(y.bottom == 15) catch @panic("test failure"); | |
| 445 | } | |
| 446 | ||
| 447 | test "C ABI structs of ints as multiple parameters" { | |
| 448 | var r1 = Rect{ | |
| 449 | .left = 1, | |
| 450 | .right = 21, | |
| 451 | .top = 16, | |
| 452 | .bottom = 4, | |
| 453 | }; | |
| 454 | var r2 = Rect{ | |
| 455 | .left = 178, | |
| 456 | .right = 189, | |
| 457 | .top = 21, | |
| 458 | .bottom = 15, | |
| 459 | }; | |
| 460 | c_multiple_struct_ints(r1, r2); | |
| 461 | } | |
| 462 | ||
| 463 | const FloatRect = extern struct { | |
| 464 | left: f32, | |
| 465 | right: f32, | |
| 466 | top: f32, | |
| 467 | bottom: f32, | |
| 468 | }; | |
| 469 | ||
| 470 | export fn zig_multiple_struct_floats(x: FloatRect, y: FloatRect) void { | |
| 471 | expect(x.left == 1) catch @panic("test failure"); | |
| 472 | expect(x.right == 21) catch @panic("test failure"); | |
| 473 | expect(x.top == 16) catch @panic("test failure"); | |
| 474 | expect(x.bottom == 4) catch @panic("test failure"); | |
| 475 | expect(y.left == 178) catch @panic("test failure"); | |
| 476 | expect(y.right == 189) catch @panic("test failure"); | |
| 477 | expect(y.top == 21) catch @panic("test failure"); | |
| 478 | expect(y.bottom == 15) catch @panic("test failure"); | |
| 479 | } | |
| 480 | ||
| 481 | test "C ABI structs of floats as multiple parameters" { | |
| 482 | var r1 = FloatRect{ | |
| 483 | .left = 1, | |
| 484 | .right = 21, | |
| 485 | .top = 16, | |
| 486 | .bottom = 4, | |
| 487 | }; | |
| 488 | var r2 = FloatRect{ | |
| 489 | .left = 178, | |
| 490 | .right = 189, | |
| 491 | .top = 21, | |
| 492 | .bottom = 15, | |
| 493 | }; | |
| 494 | c_multiple_struct_floats(r1, r2); | |
| 495 | } | |
| 496 | ||
| 426 | 497 | export fn zig_ret_bool() bool { |
| 427 | 498 | return true; |
| 428 | 499 | } |