authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-26 14:51:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-26 14:51:45-07:00
loge2d4709779d23c83edf26db2d92f4a326b790825
tree85370c966f64aae0a71e240ccfe6fddae3dff76a
parentf50c98a75a7d263cf74ade18f1ad76292d37598a

C ABI tests no longer apply to only stage1


9 files changed, 1030 insertions(+), 1030 deletions(-)

test/c_abi/build.zig created+22
...@@ -0,0 +1,22 @@
1const Builder = @import("std").build.Builder;
2
3pub fn build(b: *Builder) void {
4 const rel_opts = b.standardReleaseOptions();
5 const target = b.standardTargetOptions(.{});
6
7 const c_obj = b.addObject("cfuncs", null);
8 c_obj.addCSourceFile("cfuncs.c", &[_][]const u8{"-std=c99"});
9 c_obj.setBuildMode(rel_opts);
10 c_obj.linkSystemLibrary("c");
11 c_obj.target = target;
12
13 const main = b.addTest("main.zig");
14 main.setBuildMode(rel_opts);
15 main.addObject(c_obj);
16 main.target = target;
17
18 const test_step = b.step("test", "Test the program");
19 test_step.dependOn(&main.step);
20
21 b.default_step.dependOn(test_step);
22}
test/c_abi/build_wasm.zig created+24
...@@ -0,0 +1,24 @@
1const std = @import("std");
2const Builder = std.build.Builder;
3
4pub fn build(b: *Builder) void {
5 const rel_opts = b.standardReleaseOptions();
6 const target: std.zig.CrossTarget = .{ .cpu_arch = .wasm32, .os_tag = .wasi };
7 b.use_stage1 = false;
8
9 const c_obj = b.addObject("cfuncs", null);
10 c_obj.addCSourceFile("cfuncs.c", &[_][]const u8{"-std=c99"});
11 c_obj.setBuildMode(rel_opts);
12 c_obj.linkSystemLibrary("c");
13 c_obj.setTarget(target);
14
15 const main = b.addTest("main.zig");
16 main.setBuildMode(rel_opts);
17 main.addObject(c_obj);
18 main.setTarget(target);
19
20 const test_step = b.step("test", "Test the program");
21 test_step.dependOn(&main.step);
22
23 b.default_step.dependOn(test_step);
24}
test/c_abi/cfuncs.c created+479
...@@ -0,0 +1,479 @@
1#include <inttypes.h>
2#include <stdlib.h>
3#include <stdbool.h>
4#include <string.h>
5
6void zig_panic();
7
8static void assert_or_panic(bool ok) {
9 if (!ok) {
10 zig_panic();
11 }
12}
13
14struct i128 {
15 __int128 value;
16};
17
18struct u128 {
19 unsigned __int128 value;
20};
21
22void zig_u8(uint8_t);
23void zig_u16(uint16_t);
24void zig_u32(uint32_t);
25void zig_u64(uint64_t);
26void zig_struct_u128(struct u128);
27void zig_i8(int8_t);
28void zig_i16(int16_t);
29void zig_i32(int32_t);
30void zig_i64(int64_t);
31void zig_struct_i128(struct i128);
32void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t);
33
34void zig_f32(float);
35void zig_f64(double);
36void zig_five_floats(float, float, float, float, float);
37
38bool zig_ret_bool();
39uint8_t zig_ret_u8();
40uint16_t zig_ret_u16();
41uint32_t zig_ret_u32();
42uint64_t zig_ret_u64();
43int8_t zig_ret_i8();
44int16_t zig_ret_i16();
45int32_t zig_ret_i32();
46int64_t zig_ret_i64();
47
48void zig_ptr(void *);
49
50void zig_bool(bool);
51
52struct BigStruct {
53 uint64_t a;
54 uint64_t b;
55 uint64_t c;
56 uint64_t d;
57 uint8_t e;
58};
59
60void zig_big_struct(struct BigStruct);
61
62union BigUnion {
63 struct BigStruct a;
64};
65
66void zig_big_union(union BigUnion);
67
68struct SmallStructInts {
69 uint8_t a;
70 uint8_t b;
71 uint8_t c;
72 uint8_t d;
73};
74
75void zig_small_struct_ints(struct SmallStructInts);
76struct SmallStructInts zig_ret_small_struct_ints();
77
78struct MedStructMixed {
79 uint32_t a;
80 float b;
81 float c;
82 uint32_t d;
83};
84
85void zig_med_struct_mixed(struct MedStructMixed);
86struct MedStructMixed zig_ret_med_struct_mixed();
87
88struct SmallPackedStruct {
89 uint8_t a: 2;
90 uint8_t b: 2;
91 uint8_t c: 2;
92 uint8_t d: 2;
93 uint8_t e: 1;
94};
95
96struct BigPackedStruct {
97 uint64_t a: 64;
98 uint64_t b: 64;
99 uint64_t c: 64;
100 uint64_t d: 64;
101 uint8_t e: 8;
102};
103
104//void zig_small_packed_struct(struct SmallPackedStruct); // #1481
105void zig_big_packed_struct(struct BigPackedStruct);
106
107struct SplitStructInts {
108 uint64_t a;
109 uint8_t b;
110 uint32_t c;
111};
112void zig_split_struct_ints(struct SplitStructInts);
113
114struct SplitStructMixed {
115 uint64_t a;
116 uint8_t b;
117 float c;
118};
119void zig_split_struct_mixed(struct SplitStructMixed);
120struct SplitStructMixed zig_ret_split_struct_mixed();
121
122struct BigStruct zig_big_struct_both(struct BigStruct);
123
124typedef struct Vector3 {
125 float x;
126 float y;
127 float z;
128} Vector3;
129
130typedef struct Vector5 {
131 float x;
132 float y;
133 float z;
134 float w;
135 float q;
136} Vector5;
137
138void run_c_tests(void) {
139 zig_u8(0xff);
140 zig_u16(0xfffe);
141 zig_u32(0xfffffffd);
142 zig_u64(0xfffffffffffffffc);
143 {
144 struct u128 s = {0xfffffffffffffffc};
145 zig_struct_u128(s);
146 }
147
148 zig_i8(-1);
149 zig_i16(-2);
150 zig_i32(-3);
151 zig_i64(-4);
152 {
153 struct i128 s = {-6};
154 zig_struct_i128(s);
155 }
156 zig_five_integers(12, 34, 56, 78, 90);
157
158 zig_f32(12.34f);
159 zig_f64(56.78);
160 zig_five_floats(1.0f, 2.0f, 3.0f, 4.0f, 5.0f);
161
162 zig_ptr((void*)0xdeadbeefL);
163
164 zig_bool(true);
165
166 {
167 struct BigStruct s = {1, 2, 3, 4, 5};
168 zig_big_struct(s);
169 }
170
171 {
172 struct SmallStructInts s = {1, 2, 3, 4};
173 zig_small_struct_ints(s);
174 }
175
176 {
177 struct BigPackedStruct s = {1, 2, 3, 4, 5};
178 zig_big_packed_struct(s);
179 }
180
181 {
182 struct SmallPackedStruct s = {0, 1, 2, 3, 1};
183 //zig_small_packed_struct(s);
184 }
185
186 {
187 struct SplitStructInts s = {1234, 100, 1337};
188 zig_split_struct_ints(s);
189 }
190
191 {
192 struct MedStructMixed s = {1234, 100.0f, 1337.0f};
193 zig_med_struct_mixed(s);
194 }
195
196 {
197 struct SplitStructMixed s = {1234, 100, 1337.0f};
198 zig_split_struct_mixed(s);
199 }
200
201 {
202 struct BigStruct s = {30, 31, 32, 33, 34};
203 struct BigStruct res = zig_big_struct_both(s);
204 assert_or_panic(res.a == 20);
205 assert_or_panic(res.b == 21);
206 assert_or_panic(res.c == 22);
207 assert_or_panic(res.d == 23);
208 assert_or_panic(res.e == 24);
209 }
210
211 {
212 assert_or_panic(zig_ret_bool() == 1);
213
214 assert_or_panic(zig_ret_u8() == 0xff);
215 assert_or_panic(zig_ret_u16() == 0xffff);
216 assert_or_panic(zig_ret_u32() == 0xffffffff);
217 assert_or_panic(zig_ret_u64() == 0xffffffffffffffff);
218
219 assert_or_panic(zig_ret_i8() == -1);
220 assert_or_panic(zig_ret_i16() == -1);
221 assert_or_panic(zig_ret_i32() == -1);
222 assert_or_panic(zig_ret_i64() == -1);
223 }
224}
225
226void c_u8(uint8_t x) {
227 assert_or_panic(x == 0xff);
228}
229
230void c_u16(uint16_t x) {
231 assert_or_panic(x == 0xfffe);
232}
233
234void c_u32(uint32_t x) {
235 assert_or_panic(x == 0xfffffffd);
236}
237
238void c_u64(uint64_t x) {
239 assert_or_panic(x == 0xfffffffffffffffcULL);
240}
241
242void c_struct_u128(struct u128 x) {
243 assert_or_panic(x.value == 0xfffffffffffffffcULL);
244}
245
246void c_i8(int8_t x) {
247 assert_or_panic(x == -1);
248}
249
250void c_i16(int16_t x) {
251 assert_or_panic(x == -2);
252}
253
254void c_i32(int32_t x) {
255 assert_or_panic(x == -3);
256}
257
258void c_i64(int64_t x) {
259 assert_or_panic(x == -4);
260}
261
262void c_struct_i128(struct i128 x) {
263 assert_or_panic(x.value == -6);
264}
265
266void c_f32(float x) {
267 assert_or_panic(x == 12.34f);
268}
269
270void c_f64(double x) {
271 assert_or_panic(x == 56.78);
272}
273
274void c_ptr(void *x) {
275 assert_or_panic(x == (void*)0xdeadbeefL);
276}
277
278void c_bool(bool x) {
279 assert_or_panic(x);
280}
281
282void c_five_integers(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e) {
283 assert_or_panic(a == 12);
284 assert_or_panic(b == 34);
285 assert_or_panic(c == 56);
286 assert_or_panic(d == 78);
287 assert_or_panic(e == 90);
288}
289
290void c_five_floats(float a, float b, float c, float d, float e) {
291 assert_or_panic(a == 1.0);
292 assert_or_panic(b == 2.0);
293 assert_or_panic(c == 3.0);
294 assert_or_panic(d == 4.0);
295 assert_or_panic(e == 5.0);
296}
297
298void c_big_struct(struct BigStruct x) {
299 assert_or_panic(x.a == 1);
300 assert_or_panic(x.b == 2);
301 assert_or_panic(x.c == 3);
302 assert_or_panic(x.d == 4);
303 assert_or_panic(x.e == 5);
304}
305
306void c_big_union(union BigUnion x) {
307 assert_or_panic(x.a.a == 1);
308 assert_or_panic(x.a.b == 2);
309 assert_or_panic(x.a.c == 3);
310 assert_or_panic(x.a.d == 4);
311}
312
313void c_small_struct_ints(struct SmallStructInts x) {
314 assert_or_panic(x.a == 1);
315 assert_or_panic(x.b == 2);
316 assert_or_panic(x.c == 3);
317 assert_or_panic(x.d == 4);
318
319 struct SmallStructInts y = zig_ret_small_struct_ints();
320
321 assert_or_panic(y.a == 1);
322 assert_or_panic(y.b == 2);
323 assert_or_panic(y.c == 3);
324 assert_or_panic(y.d == 4);
325}
326
327struct SmallStructInts c_ret_small_struct_ints() {
328 struct SmallStructInts s = {
329 .a = 1,
330 .b = 2,
331 .c = 3,
332 .d = 4,
333 };
334 return s;
335}
336
337void c_med_struct_mixed(struct MedStructMixed x) {
338 assert_or_panic(x.a == 1234);
339 assert_or_panic(x.b == 100.0f);
340 assert_or_panic(x.c == 1337.0f);
341
342 struct MedStructMixed y = zig_ret_med_struct_mixed();
343
344 assert_or_panic(y.a == 1234);
345 assert_or_panic(y.b == 100.0f);
346 assert_or_panic(y.c == 1337.0f);
347}
348
349struct MedStructMixed c_ret_med_struct_mixed() {
350 struct MedStructMixed s = {
351 .a = 1234,
352 .b = 100.0,
353 .c = 1337.0,
354 };
355 return s;
356}
357
358void c_split_struct_ints(struct SplitStructInts x) {
359 assert_or_panic(x.a == 1234);
360 assert_or_panic(x.b == 100);
361 assert_or_panic(x.c == 1337);
362}
363
364void c_split_struct_mixed(struct SplitStructMixed x) {
365 assert_or_panic(x.a == 1234);
366 assert_or_panic(x.b == 100);
367 assert_or_panic(x.c == 1337.0f);
368 struct SplitStructMixed y = zig_ret_split_struct_mixed();
369
370 assert_or_panic(y.a == 1234);
371 assert_or_panic(y.b == 100);
372 assert_or_panic(y.c == 1337.0f);
373}
374
375struct SmallPackedStruct c_ret_small_packed_struct() {
376 struct SmallPackedStruct s = {
377 .a = 0,
378 .b = 1,
379 .c = 2,
380 .d = 3,
381 .e = 1,
382 };
383 return s;
384}
385
386void c_small_packed_struct(struct SmallPackedStruct x) {
387 assert_or_panic(x.a == 0);
388 assert_or_panic(x.a == 1);
389 assert_or_panic(x.a == 2);
390 assert_or_panic(x.a == 3);
391 assert_or_panic(x.e == 1);
392}
393
394struct BigPackedStruct c_ret_big_packed_struct() {
395 struct BigPackedStruct s = {
396 .a = 1,
397 .b = 2,
398 .c = 3,
399 .d = 4,
400 .e = 5,
401 };
402 return s;
403}
404
405void c_big_packed_struct(struct BigPackedStruct x) {
406 assert_or_panic(x.a == 1);
407 assert_or_panic(x.b == 2);
408 assert_or_panic(x.c == 3);
409 assert_or_panic(x.d == 4);
410 assert_or_panic(x.e == 5);
411}
412
413struct SplitStructMixed c_ret_split_struct_mixed() {
414 struct SplitStructMixed s = {
415 .a = 1234,
416 .b = 100,
417 .c = 1337.0f,
418 };
419 return s;
420}
421
422struct BigStruct c_big_struct_both(struct BigStruct x) {
423 assert_or_panic(x.a == 1);
424 assert_or_panic(x.b == 2);
425 assert_or_panic(x.c == 3);
426 assert_or_panic(x.d == 4);
427 assert_or_panic(x.e == 5);
428 struct BigStruct y = {10, 11, 12, 13, 14};
429 return y;
430}
431
432void c_small_struct_floats(Vector3 vec) {
433 assert_or_panic(vec.x == 3.0);
434 assert_or_panic(vec.y == 6.0);
435 assert_or_panic(vec.z == 12.0);
436}
437
438void c_small_struct_floats_extra(Vector3 vec, const char *str) {
439 assert_or_panic(vec.x == 3.0);
440 assert_or_panic(vec.y == 6.0);
441 assert_or_panic(vec.z == 12.0);
442 assert_or_panic(!strcmp(str, "hello"));
443}
444
445void c_big_struct_floats(Vector5 vec) {
446 assert_or_panic(vec.x == 76.0);
447 assert_or_panic(vec.y == -1.0);
448 assert_or_panic(vec.z == -12.0);
449 assert_or_panic(vec.w == 69);
450 assert_or_panic(vec.q == 55);
451}
452
453bool c_ret_bool() {
454 return 1;
455}
456uint8_t c_ret_u8() {
457 return 0xff;
458}
459uint16_t c_ret_u16() {
460 return 0xffff;
461}
462uint32_t c_ret_u32() {
463 return 0xffffffff;
464}
465uint64_t c_ret_u64() {
466 return 0xffffffffffffffff;
467}
468int8_t c_ret_i8() {
469 return -1;
470}
471int16_t c_ret_i16() {
472 return -1;
473}
474int32_t c_ret_i32() {
475 return -1;
476}
477int64_t c_ret_i64() {
478 return -1;
479}
test/c_abi/main.zig created+503
...@@ -0,0 +1,503 @@
1const std = @import("std");
2const print = std.debug.print;
3const expect = std.testing.expect;
4
5extern fn run_c_tests() void;
6
7export fn zig_panic() noreturn {
8 @panic("zig_panic called from C");
9}
10
11test "C importing Zig ABI Tests" {
12 run_c_tests();
13}
14
15extern fn c_u8(u8) void;
16extern fn c_u16(u16) void;
17extern fn c_u32(u32) void;
18extern fn c_u64(u64) void;
19extern fn c_struct_u128(U128) void;
20extern fn c_i8(i8) void;
21extern fn c_i16(i16) void;
22extern fn c_i32(i32) void;
23extern fn c_i64(i64) void;
24extern fn c_struct_i128(I128) void;
25
26// On windows x64, the first 4 are passed via registers, others on the stack.
27extern fn c_five_integers(i32, i32, i32, i32, i32) void;
28
29export fn zig_five_integers(a: i32, b: i32, c: i32, d: i32, e: i32) void {
30 expect(a == 12) catch @panic("test failure: zig_five_integers 12");
31 expect(b == 34) catch @panic("test failure: zig_five_integers 34");
32 expect(c == 56) catch @panic("test failure: zig_five_integers 56");
33 expect(d == 78) catch @panic("test failure: zig_five_integers 78");
34 expect(e == 90) catch @panic("test failure: zig_five_integers 90");
35}
36
37test "C ABI integers" {
38 c_u8(0xff);
39 c_u16(0xfffe);
40 c_u32(0xfffffffd);
41 c_u64(0xfffffffffffffffc);
42 c_struct_u128(.{ .value = 0xfffffffffffffffc });
43
44 c_i8(-1);
45 c_i16(-2);
46 c_i32(-3);
47 c_i64(-4);
48 c_struct_i128(.{ .value = -6 });
49 c_five_integers(12, 34, 56, 78, 90);
50}
51
52export fn zig_u8(x: u8) void {
53 expect(x == 0xff) catch @panic("test failure: zig_u8");
54}
55export fn zig_u16(x: u16) void {
56 expect(x == 0xfffe) catch @panic("test failure: zig_u16");
57}
58export fn zig_u32(x: u32) void {
59 expect(x == 0xfffffffd) catch @panic("test failure: zig_u32");
60}
61export fn zig_u64(x: u64) void {
62 expect(x == 0xfffffffffffffffc) catch @panic("test failure: zig_u64");
63}
64export fn zig_i8(x: i8) void {
65 expect(x == -1) catch @panic("test failure: zig_i8");
66}
67export fn zig_i16(x: i16) void {
68 expect(x == -2) catch @panic("test failure: zig_i16");
69}
70export fn zig_i32(x: i32) void {
71 expect(x == -3) catch @panic("test failure: zig_i32");
72}
73export fn zig_i64(x: i64) void {
74 expect(x == -4) catch @panic("test failure: zig_i64");
75}
76
77const I128 = extern struct {
78 value: i128,
79};
80const U128 = extern struct {
81 value: u128,
82};
83export fn zig_struct_i128(a: I128) void {
84 expect(a.value == -6) catch @panic("test failure: zig_struct_i128");
85}
86export fn zig_struct_u128(a: U128) void {
87 expect(a.value == 0xfffffffffffffffc) catch @panic("test failure: zig_struct_u128");
88}
89
90extern fn c_f32(f32) void;
91extern fn c_f64(f64) void;
92
93// On windows x64, the first 4 are passed via registers, others on the stack.
94extern fn c_five_floats(f32, f32, f32, f32, f32) void;
95
96export fn zig_five_floats(a: f32, b: f32, c: f32, d: f32, e: f32) void {
97 expect(a == 1.0) catch @panic("test failure: zig_five_floats 1.0");
98 expect(b == 2.0) catch @panic("test failure: zig_five_floats 2.0");
99 expect(c == 3.0) catch @panic("test failure: zig_five_floats 3.0");
100 expect(d == 4.0) catch @panic("test failure: zig_five_floats 4.0");
101 expect(e == 5.0) catch @panic("test failure: zig_five_floats 5.0");
102}
103
104test "C ABI floats" {
105 c_f32(12.34);
106 c_f64(56.78);
107 c_five_floats(1.0, 2.0, 3.0, 4.0, 5.0);
108}
109
110export fn zig_f32(x: f32) void {
111 expect(x == 12.34) catch @panic("test failure: zig_f32");
112}
113export fn zig_f64(x: f64) void {
114 expect(x == 56.78) catch @panic("test failure: zig_f64");
115}
116
117extern fn c_ptr(*anyopaque) void;
118
119test "C ABI pointer" {
120 c_ptr(@intToPtr(*anyopaque, 0xdeadbeef));
121}
122
123export fn zig_ptr(x: *anyopaque) void {
124 expect(@ptrToInt(x) == 0xdeadbeef) catch @panic("test failure: zig_ptr");
125}
126
127extern fn c_bool(bool) void;
128
129test "C ABI bool" {
130 c_bool(true);
131}
132
133export fn zig_bool(x: bool) void {
134 expect(x) catch @panic("test failure: zig_bool");
135}
136
137const BigStruct = extern struct {
138 a: u64,
139 b: u64,
140 c: u64,
141 d: u64,
142 e: u8,
143};
144extern fn c_big_struct(BigStruct) void;
145
146test "C ABI big struct" {
147 var s = BigStruct{
148 .a = 1,
149 .b = 2,
150 .c = 3,
151 .d = 4,
152 .e = 5,
153 };
154 c_big_struct(s);
155}
156
157export fn zig_big_struct(x: BigStruct) void {
158 expect(x.a == 1) catch @panic("test failure: zig_big_struct 1");
159 expect(x.b == 2) catch @panic("test failure: zig_big_struct 2");
160 expect(x.c == 3) catch @panic("test failure: zig_big_struct 3");
161 expect(x.d == 4) catch @panic("test failure: zig_big_struct 4");
162 expect(x.e == 5) catch @panic("test failure: zig_big_struct 5");
163}
164
165const BigUnion = extern union {
166 a: BigStruct,
167};
168extern fn c_big_union(BigUnion) void;
169
170test "C ABI big union" {
171 var x = BigUnion{
172 .a = BigStruct{
173 .a = 1,
174 .b = 2,
175 .c = 3,
176 .d = 4,
177 .e = 5,
178 },
179 };
180 c_big_union(x);
181}
182
183export fn zig_big_union(x: BigUnion) void {
184 expect(x.a.a == 1) catch @panic("test failure: zig_big_union a");
185 expect(x.a.b == 2) catch @panic("test failure: zig_big_union b");
186 expect(x.a.c == 3) catch @panic("test failure: zig_big_union c");
187 expect(x.a.d == 4) catch @panic("test failure: zig_big_union d");
188 expect(x.a.e == 5) catch @panic("test failure: zig_big_union e");
189}
190
191const MedStructMixed = extern struct {
192 a: u32,
193 b: f32,
194 c: f32,
195 d: u32 = 0,
196};
197extern fn c_med_struct_mixed(MedStructMixed) void;
198extern fn c_ret_med_struct_mixed() MedStructMixed;
199
200test "C ABI medium struct of ints and floats" {
201 var s = MedStructMixed{
202 .a = 1234,
203 .b = 100.0,
204 .c = 1337.0,
205 };
206 c_med_struct_mixed(s);
207 var s2 = c_ret_med_struct_mixed();
208 expect(s2.a == 1234) catch @panic("test failure");
209 expect(s2.b == 100.0) catch @panic("test failure");
210 expect(s2.c == 1337.0) catch @panic("test failure");
211}
212
213export fn zig_med_struct_mixed(x: MedStructMixed) void {
214 expect(x.a == 1234) catch @panic("test failure");
215 expect(x.b == 100.0) catch @panic("test failure");
216 expect(x.c == 1337.0) catch @panic("test failure");
217}
218
219const SmallStructInts = extern struct {
220 a: u8,
221 b: u8,
222 c: u8,
223 d: u8,
224};
225extern fn c_small_struct_ints(SmallStructInts) void;
226extern fn c_ret_small_struct_ints() SmallStructInts;
227
228test "C ABI small struct of ints" {
229 var s = SmallStructInts{
230 .a = 1,
231 .b = 2,
232 .c = 3,
233 .d = 4,
234 };
235 c_small_struct_ints(s);
236 var s2 = c_ret_small_struct_ints();
237 expect(s2.a == 1) catch @panic("test failure");
238 expect(s2.b == 2) catch @panic("test failure");
239 expect(s2.c == 3) catch @panic("test failure");
240 expect(s2.d == 4) catch @panic("test failure");
241}
242
243export fn zig_small_struct_ints(x: SmallStructInts) void {
244 expect(x.a == 1) catch @panic("test failure");
245 expect(x.b == 2) catch @panic("test failure");
246 expect(x.c == 3) catch @panic("test failure");
247 expect(x.d == 4) catch @panic("test failure");
248}
249
250const SmallPackedStruct = packed struct {
251 a: u2,
252 b: u2,
253 c: u2,
254 d: u2,
255 e: bool,
256};
257const c_small_packed_struct: fn (SmallPackedStruct) callconv(.C) void = @compileError("TODO: #1481");
258extern fn c_ret_small_packed_struct() SmallPackedStruct;
259
260// waiting on #1481
261//export fn zig_small_packed_struct(x: SmallPackedStruct) void {
262// expect(x.a == 0) catch @panic("test failure");
263// expect(x.b == 1) catch @panic("test failure");
264// expect(x.c == 2) catch @panic("test failure");
265// expect(x.d == 3) catch @panic("test failure");
266// expect(x.e) catch @panic("test failure");
267//}
268
269test "C ABI small packed struct" {
270 var s = SmallPackedStruct{ .a = 0, .b = 1, .c = 2, .d = 3, .e = true };
271 _ = s; //c_small_packed_struct(s); // waiting on #1481
272 var s2 = c_ret_small_packed_struct();
273 try expect(s2.a == 0);
274 try expect(s2.b == 1);
275 try expect(s2.c == 2);
276 try expect(s2.d == 3);
277 try expect(s2.e);
278}
279
280const BigPackedStruct = packed struct {
281 a: u64,
282 b: u64,
283 c: u64,
284 d: u64,
285 e: u8,
286};
287extern fn c_big_packed_struct(BigPackedStruct) void;
288extern fn c_ret_big_packed_struct() BigPackedStruct;
289
290export fn zig_big_packed_struct(x: BigPackedStruct) void {
291 expect(x.a == 1) catch @panic("test failure");
292 expect(x.b == 2) catch @panic("test failure");
293 expect(x.c == 3) catch @panic("test failure");
294 expect(x.d == 4) catch @panic("test failure");
295 expect(x.e == 5) catch @panic("test failure");
296}
297
298test "C ABI big packed struct" {
299 var s = BigPackedStruct{ .a = 1, .b = 2, .c = 3, .d = 4, .e = 5 };
300 c_big_packed_struct(s);
301 var s2 = c_ret_big_packed_struct();
302 try expect(s2.a == 1);
303 try expect(s2.b == 2);
304 try expect(s2.c == 3);
305 try expect(s2.d == 4);
306 try expect(s2.e == 5);
307}
308
309const SplitStructInt = extern struct {
310 a: u64,
311 b: u8,
312 c: u32,
313};
314extern fn c_split_struct_ints(SplitStructInt) void;
315
316test "C ABI split struct of ints" {
317 var s = SplitStructInt{
318 .a = 1234,
319 .b = 100,
320 .c = 1337,
321 };
322 c_split_struct_ints(s);
323}
324
325export fn zig_split_struct_ints(x: SplitStructInt) void {
326 expect(x.a == 1234) catch @panic("test failure");
327 expect(x.b == 100) catch @panic("test failure");
328 expect(x.c == 1337) catch @panic("test failure");
329}
330
331const SplitStructMixed = extern struct {
332 a: u64,
333 b: u8,
334 c: f32,
335};
336extern fn c_split_struct_mixed(SplitStructMixed) void;
337extern fn c_ret_split_struct_mixed() SplitStructMixed;
338
339test "C ABI split struct of ints and floats" {
340 var s = SplitStructMixed{
341 .a = 1234,
342 .b = 100,
343 .c = 1337.0,
344 };
345 c_split_struct_mixed(s);
346 var s2 = c_ret_split_struct_mixed();
347 expect(s2.a == 1234) catch @panic("test failure");
348 expect(s2.b == 100) catch @panic("test failure");
349 expect(s2.c == 1337.0) catch @panic("test failure");
350}
351
352export fn zig_split_struct_mixed(x: SplitStructMixed) void {
353 expect(x.a == 1234) catch @panic("test failure");
354 expect(x.b == 100) catch @panic("test failure");
355 expect(x.c == 1337.0) catch @panic("test failure");
356}
357
358extern fn c_big_struct_both(BigStruct) BigStruct;
359
360test "C ABI sret and byval together" {
361 var s = BigStruct{
362 .a = 1,
363 .b = 2,
364 .c = 3,
365 .d = 4,
366 .e = 5,
367 };
368 var y = c_big_struct_both(s);
369 try expect(y.a == 10);
370 try expect(y.b == 11);
371 try expect(y.c == 12);
372 try expect(y.d == 13);
373 try expect(y.e == 14);
374}
375
376export fn zig_big_struct_both(x: BigStruct) BigStruct {
377 expect(x.a == 30) catch @panic("test failure");
378 expect(x.b == 31) catch @panic("test failure");
379 expect(x.c == 32) catch @panic("test failure");
380 expect(x.d == 33) catch @panic("test failure");
381 expect(x.e == 34) catch @panic("test failure");
382 var s = BigStruct{
383 .a = 20,
384 .b = 21,
385 .c = 22,
386 .d = 23,
387 .e = 24,
388 };
389 return s;
390}
391
392const Vector3 = extern struct {
393 x: f32,
394 y: f32,
395 z: f32,
396};
397extern fn c_small_struct_floats(Vector3) void;
398extern fn c_small_struct_floats_extra(Vector3, ?[*]const u8) void;
399
400const Vector5 = extern struct {
401 x: f32,
402 y: f32,
403 z: f32,
404 w: f32,
405 q: f32,
406};
407extern fn c_big_struct_floats(Vector5) void;
408
409test "C ABI structs of floats as parameter" {
410 var v3 = Vector3{
411 .x = 3.0,
412 .y = 6.0,
413 .z = 12.0,
414 };
415 c_small_struct_floats(v3);
416 c_small_struct_floats_extra(v3, "hello");
417
418 var v5 = Vector5{
419 .x = 76.0,
420 .y = -1.0,
421 .z = -12.0,
422 .w = 69.0,
423 .q = 55,
424 };
425 c_big_struct_floats(v5);
426}
427
428export fn zig_ret_bool() bool {
429 return true;
430}
431export fn zig_ret_u8() u8 {
432 return 0xff;
433}
434export fn zig_ret_u16() u16 {
435 return 0xffff;
436}
437export fn zig_ret_u32() u32 {
438 return 0xffffffff;
439}
440export fn zig_ret_u64() u64 {
441 return 0xffffffffffffffff;
442}
443export fn zig_ret_i8() i8 {
444 return -1;
445}
446export fn zig_ret_i16() i16 {
447 return -1;
448}
449export fn zig_ret_i32() i32 {
450 return -1;
451}
452export fn zig_ret_i64() i64 {
453 return -1;
454}
455
456export fn zig_ret_small_struct_ints() SmallStructInts {
457 return .{
458 .a = 1,
459 .b = 2,
460 .c = 3,
461 .d = 4,
462 };
463}
464
465export fn zig_ret_med_struct_mixed() MedStructMixed {
466 return .{
467 .a = 1234,
468 .b = 100.0,
469 .c = 1337.0,
470 };
471}
472
473export fn zig_ret_split_struct_mixed() SplitStructMixed {
474 return .{
475 .a = 1234,
476 .b = 100,
477 .c = 1337.0,
478 };
479}
480
481extern fn c_ret_bool() bool;
482extern fn c_ret_u8() u8;
483extern fn c_ret_u16() u16;
484extern fn c_ret_u32() u32;
485extern fn c_ret_u64() u64;
486extern fn c_ret_i8() i8;
487extern fn c_ret_i16() i16;
488extern fn c_ret_i32() i32;
489extern fn c_ret_i64() i64;
490
491test "C ABI integer return types" {
492 try expect(c_ret_bool() == true);
493
494 try expect(c_ret_u8() == 0xff);
495 try expect(c_ret_u16() == 0xffff);
496 try expect(c_ret_u32() == 0xffffffff);
497 try expect(c_ret_u64() == 0xffffffffffffffff);
498
499 try expect(c_ret_i8() == -1);
500 try expect(c_ret_i16() == -1);
501 try expect(c_ret_i32() == -1);
502 try expect(c_ret_i64() == -1);
503}
test/stage1/c_abi/build.zig deleted-22
...@@ -1,22 +0,0 @@
1const Builder = @import("std").build.Builder;
2
3pub fn build(b: *Builder) void {
4 const rel_opts = b.standardReleaseOptions();
5 const target = b.standardTargetOptions(.{});
6
7 const c_obj = b.addObject("cfuncs", null);
8 c_obj.addCSourceFile("cfuncs.c", &[_][]const u8{"-std=c99"});
9 c_obj.setBuildMode(rel_opts);
10 c_obj.linkSystemLibrary("c");
11 c_obj.target = target;
12
13 const main = b.addTest("main.zig");
14 main.setBuildMode(rel_opts);
15 main.addObject(c_obj);
16 main.target = target;
17
18 const test_step = b.step("test", "Test the program");
19 test_step.dependOn(&main.step);
20
21 b.default_step.dependOn(test_step);
22}
test/stage1/c_abi/build_wasm.zig deleted-24
...@@ -1,24 +0,0 @@
1const std = @import("std");
2const Builder = std.build.Builder;
3
4pub fn build(b: *Builder) void {
5 const rel_opts = b.standardReleaseOptions();
6 const target: std.zig.CrossTarget = .{ .cpu_arch = .wasm32, .os_tag = .wasi };
7 b.use_stage1 = false;
8
9 const c_obj = b.addObject("cfuncs", null);
10 c_obj.addCSourceFile("cfuncs.c", &[_][]const u8{"-std=c99"});
11 c_obj.setBuildMode(rel_opts);
12 c_obj.linkSystemLibrary("c");
13 c_obj.setTarget(target);
14
15 const main = b.addTest("main.zig");
16 main.setBuildMode(rel_opts);
17 main.addObject(c_obj);
18 main.setTarget(target);
19
20 const test_step = b.step("test", "Test the program");
21 test_step.dependOn(&main.step);
22
23 b.default_step.dependOn(test_step);
24}
test/stage1/c_abi/cfuncs.c deleted-479
...@@ -1,479 +0,0 @@
1#include <inttypes.h>
2#include <stdlib.h>
3#include <stdbool.h>
4#include <string.h>
5
6void zig_panic();
7
8static void assert_or_panic(bool ok) {
9 if (!ok) {
10 zig_panic();
11 }
12}
13
14struct i128 {
15 __int128 value;
16};
17
18struct u128 {
19 unsigned __int128 value;
20};
21
22void zig_u8(uint8_t);
23void zig_u16(uint16_t);
24void zig_u32(uint32_t);
25void zig_u64(uint64_t);
26void zig_struct_u128(struct u128);
27void zig_i8(int8_t);
28void zig_i16(int16_t);
29void zig_i32(int32_t);
30void zig_i64(int64_t);
31void zig_struct_i128(struct i128);
32void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t);
33
34void zig_f32(float);
35void zig_f64(double);
36void zig_five_floats(float, float, float, float, float);
37
38bool zig_ret_bool();
39uint8_t zig_ret_u8();
40uint16_t zig_ret_u16();
41uint32_t zig_ret_u32();
42uint64_t zig_ret_u64();
43int8_t zig_ret_i8();
44int16_t zig_ret_i16();
45int32_t zig_ret_i32();
46int64_t zig_ret_i64();
47
48void zig_ptr(void *);
49
50void zig_bool(bool);
51
52struct BigStruct {
53 uint64_t a;
54 uint64_t b;
55 uint64_t c;
56 uint64_t d;
57 uint8_t e;
58};
59
60void zig_big_struct(struct BigStruct);
61
62union BigUnion {
63 struct BigStruct a;
64};
65
66void zig_big_union(union BigUnion);
67
68struct SmallStructInts {
69 uint8_t a;
70 uint8_t b;
71 uint8_t c;
72 uint8_t d;
73};
74
75void zig_small_struct_ints(struct SmallStructInts);
76struct SmallStructInts zig_ret_small_struct_ints();
77
78struct MedStructMixed {
79 uint32_t a;
80 float b;
81 float c;
82 uint32_t d;
83};
84
85void zig_med_struct_mixed(struct MedStructMixed);
86struct MedStructMixed zig_ret_med_struct_mixed();
87
88struct SmallPackedStruct {
89 uint8_t a: 2;
90 uint8_t b: 2;
91 uint8_t c: 2;
92 uint8_t d: 2;
93 uint8_t e: 1;
94};
95
96struct BigPackedStruct {
97 uint64_t a: 64;
98 uint64_t b: 64;
99 uint64_t c: 64;
100 uint64_t d: 64;
101 uint8_t e: 8;
102};
103
104//void zig_small_packed_struct(struct SmallPackedStruct); // #1481
105void zig_big_packed_struct(struct BigPackedStruct);
106
107struct SplitStructInts {
108 uint64_t a;
109 uint8_t b;
110 uint32_t c;
111};
112void zig_split_struct_ints(struct SplitStructInts);
113
114struct SplitStructMixed {
115 uint64_t a;
116 uint8_t b;
117 float c;
118};
119void zig_split_struct_mixed(struct SplitStructMixed);
120struct SplitStructMixed zig_ret_split_struct_mixed();
121
122struct BigStruct zig_big_struct_both(struct BigStruct);
123
124typedef struct Vector3 {
125 float x;
126 float y;
127 float z;
128} Vector3;
129
130typedef struct Vector5 {
131 float x;
132 float y;
133 float z;
134 float w;
135 float q;
136} Vector5;
137
138void run_c_tests(void) {
139 zig_u8(0xff);
140 zig_u16(0xfffe);
141 zig_u32(0xfffffffd);
142 zig_u64(0xfffffffffffffffc);
143 {
144 struct u128 s = {0xfffffffffffffffc};
145 zig_struct_u128(s);
146 }
147
148 zig_i8(-1);
149 zig_i16(-2);
150 zig_i32(-3);
151 zig_i64(-4);
152 {
153 struct i128 s = {-6};
154 zig_struct_i128(s);
155 }
156 zig_five_integers(12, 34, 56, 78, 90);
157
158 zig_f32(12.34f);
159 zig_f64(56.78);
160 zig_five_floats(1.0f, 2.0f, 3.0f, 4.0f, 5.0f);
161
162 zig_ptr((void*)0xdeadbeefL);
163
164 zig_bool(true);
165
166 {
167 struct BigStruct s = {1, 2, 3, 4, 5};
168 zig_big_struct(s);
169 }
170
171 {
172 struct SmallStructInts s = {1, 2, 3, 4};
173 zig_small_struct_ints(s);
174 }
175
176 {
177 struct BigPackedStruct s = {1, 2, 3, 4, 5};
178 zig_big_packed_struct(s);
179 }
180
181 {
182 struct SmallPackedStruct s = {0, 1, 2, 3, 1};
183 //zig_small_packed_struct(s);
184 }
185
186 {
187 struct SplitStructInts s = {1234, 100, 1337};
188 zig_split_struct_ints(s);
189 }
190
191 {
192 struct MedStructMixed s = {1234, 100.0f, 1337.0f};
193 zig_med_struct_mixed(s);
194 }
195
196 {
197 struct SplitStructMixed s = {1234, 100, 1337.0f};
198 zig_split_struct_mixed(s);
199 }
200
201 {
202 struct BigStruct s = {30, 31, 32, 33, 34};
203 struct BigStruct res = zig_big_struct_both(s);
204 assert_or_panic(res.a == 20);
205 assert_or_panic(res.b == 21);
206 assert_or_panic(res.c == 22);
207 assert_or_panic(res.d == 23);
208 assert_or_panic(res.e == 24);
209 }
210
211 {
212 assert_or_panic(zig_ret_bool() == 1);
213
214 assert_or_panic(zig_ret_u8() == 0xff);
215 assert_or_panic(zig_ret_u16() == 0xffff);
216 assert_or_panic(zig_ret_u32() == 0xffffffff);
217 assert_or_panic(zig_ret_u64() == 0xffffffffffffffff);
218
219 assert_or_panic(zig_ret_i8() == -1);
220 assert_or_panic(zig_ret_i16() == -1);
221 assert_or_panic(zig_ret_i32() == -1);
222 assert_or_panic(zig_ret_i64() == -1);
223 }
224}
225
226void c_u8(uint8_t x) {
227 assert_or_panic(x == 0xff);
228}
229
230void c_u16(uint16_t x) {
231 assert_or_panic(x == 0xfffe);
232}
233
234void c_u32(uint32_t x) {
235 assert_or_panic(x == 0xfffffffd);
236}
237
238void c_u64(uint64_t x) {
239 assert_or_panic(x == 0xfffffffffffffffcULL);
240}
241
242void c_struct_u128(struct u128 x) {
243 assert_or_panic(x.value == 0xfffffffffffffffcULL);
244}
245
246void c_i8(int8_t x) {
247 assert_or_panic(x == -1);
248}
249
250void c_i16(int16_t x) {
251 assert_or_panic(x == -2);
252}
253
254void c_i32(int32_t x) {
255 assert_or_panic(x == -3);
256}
257
258void c_i64(int64_t x) {
259 assert_or_panic(x == -4);
260}
261
262void c_struct_i128(struct i128 x) {
263 assert_or_panic(x.value == -6);
264}
265
266void c_f32(float x) {
267 assert_or_panic(x == 12.34f);
268}
269
270void c_f64(double x) {
271 assert_or_panic(x == 56.78);
272}
273
274void c_ptr(void *x) {
275 assert_or_panic(x == (void*)0xdeadbeefL);
276}
277
278void c_bool(bool x) {
279 assert_or_panic(x);
280}
281
282void c_five_integers(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e) {
283 assert_or_panic(a == 12);
284 assert_or_panic(b == 34);
285 assert_or_panic(c == 56);
286 assert_or_panic(d == 78);
287 assert_or_panic(e == 90);
288}
289
290void c_five_floats(float a, float b, float c, float d, float e) {
291 assert_or_panic(a == 1.0);
292 assert_or_panic(b == 2.0);
293 assert_or_panic(c == 3.0);
294 assert_or_panic(d == 4.0);
295 assert_or_panic(e == 5.0);
296}
297
298void c_big_struct(struct BigStruct x) {
299 assert_or_panic(x.a == 1);
300 assert_or_panic(x.b == 2);
301 assert_or_panic(x.c == 3);
302 assert_or_panic(x.d == 4);
303 assert_or_panic(x.e == 5);
304}
305
306void c_big_union(union BigUnion x) {
307 assert_or_panic(x.a.a == 1);
308 assert_or_panic(x.a.b == 2);
309 assert_or_panic(x.a.c == 3);
310 assert_or_panic(x.a.d == 4);
311}
312
313void c_small_struct_ints(struct SmallStructInts x) {
314 assert_or_panic(x.a == 1);
315 assert_or_panic(x.b == 2);
316 assert_or_panic(x.c == 3);
317 assert_or_panic(x.d == 4);
318
319 struct SmallStructInts y = zig_ret_small_struct_ints();
320
321 assert_or_panic(y.a == 1);
322 assert_or_panic(y.b == 2);
323 assert_or_panic(y.c == 3);
324 assert_or_panic(y.d == 4);
325}
326
327struct SmallStructInts c_ret_small_struct_ints() {
328 struct SmallStructInts s = {
329 .a = 1,
330 .b = 2,
331 .c = 3,
332 .d = 4,
333 };
334 return s;
335}
336
337void c_med_struct_mixed(struct MedStructMixed x) {
338 assert_or_panic(x.a == 1234);
339 assert_or_panic(x.b == 100.0f);
340 assert_or_panic(x.c == 1337.0f);
341
342 struct MedStructMixed y = zig_ret_med_struct_mixed();
343
344 assert_or_panic(y.a == 1234);
345 assert_or_panic(y.b == 100.0f);
346 assert_or_panic(y.c == 1337.0f);
347}
348
349struct MedStructMixed c_ret_med_struct_mixed() {
350 struct MedStructMixed s = {
351 .a = 1234,
352 .b = 100.0,
353 .c = 1337.0,
354 };
355 return s;
356}
357
358void c_split_struct_ints(struct SplitStructInts x) {
359 assert_or_panic(x.a == 1234);
360 assert_or_panic(x.b == 100);
361 assert_or_panic(x.c == 1337);
362}
363
364void c_split_struct_mixed(struct SplitStructMixed x) {
365 assert_or_panic(x.a == 1234);
366 assert_or_panic(x.b == 100);
367 assert_or_panic(x.c == 1337.0f);
368 struct SplitStructMixed y = zig_ret_split_struct_mixed();
369
370 assert_or_panic(y.a == 1234);
371 assert_or_panic(y.b == 100);
372 assert_or_panic(y.c == 1337.0f);
373}
374
375struct SmallPackedStruct c_ret_small_packed_struct() {
376 struct SmallPackedStruct s = {
377 .a = 0,
378 .b = 1,
379 .c = 2,
380 .d = 3,
381 .e = 1,
382 };
383 return s;
384}
385
386void c_small_packed_struct(struct SmallPackedStruct x) {
387 assert_or_panic(x.a == 0);
388 assert_or_panic(x.a == 1);
389 assert_or_panic(x.a == 2);
390 assert_or_panic(x.a == 3);
391 assert_or_panic(x.e == 1);
392}
393
394struct BigPackedStruct c_ret_big_packed_struct() {
395 struct BigPackedStruct s = {
396 .a = 1,
397 .b = 2,
398 .c = 3,
399 .d = 4,
400 .e = 5,
401 };
402 return s;
403}
404
405void c_big_packed_struct(struct BigPackedStruct x) {
406 assert_or_panic(x.a == 1);
407 assert_or_panic(x.b == 2);
408 assert_or_panic(x.c == 3);
409 assert_or_panic(x.d == 4);
410 assert_or_panic(x.e == 5);
411}
412
413struct SplitStructMixed c_ret_split_struct_mixed() {
414 struct SplitStructMixed s = {
415 .a = 1234,
416 .b = 100,
417 .c = 1337.0f,
418 };
419 return s;
420}
421
422struct BigStruct c_big_struct_both(struct BigStruct x) {
423 assert_or_panic(x.a == 1);
424 assert_or_panic(x.b == 2);
425 assert_or_panic(x.c == 3);
426 assert_or_panic(x.d == 4);
427 assert_or_panic(x.e == 5);
428 struct BigStruct y = {10, 11, 12, 13, 14};
429 return y;
430}
431
432void c_small_struct_floats(Vector3 vec) {
433 assert_or_panic(vec.x == 3.0);
434 assert_or_panic(vec.y == 6.0);
435 assert_or_panic(vec.z == 12.0);
436}
437
438void c_small_struct_floats_extra(Vector3 vec, const char *str) {
439 assert_or_panic(vec.x == 3.0);
440 assert_or_panic(vec.y == 6.0);
441 assert_or_panic(vec.z == 12.0);
442 assert_or_panic(!strcmp(str, "hello"));
443}
444
445void c_big_struct_floats(Vector5 vec) {
446 assert_or_panic(vec.x == 76.0);
447 assert_or_panic(vec.y == -1.0);
448 assert_or_panic(vec.z == -12.0);
449 assert_or_panic(vec.w == 69);
450 assert_or_panic(vec.q == 55);
451}
452
453bool c_ret_bool() {
454 return 1;
455}
456uint8_t c_ret_u8() {
457 return 0xff;
458}
459uint16_t c_ret_u16() {
460 return 0xffff;
461}
462uint32_t c_ret_u32() {
463 return 0xffffffff;
464}
465uint64_t c_ret_u64() {
466 return 0xffffffffffffffff;
467}
468int8_t c_ret_i8() {
469 return -1;
470}
471int16_t c_ret_i16() {
472 return -1;
473}
474int32_t c_ret_i32() {
475 return -1;
476}
477int64_t c_ret_i64() {
478 return -1;
479}
test/stage1/c_abi/main.zig deleted-503
...@@ -1,503 +0,0 @@
1const std = @import("std");
2const print = std.debug.print;
3const expect = std.testing.expect;
4
5extern fn run_c_tests() void;
6
7export fn zig_panic() noreturn {
8 @panic("zig_panic called from C");
9}
10
11test "C importing Zig ABI Tests" {
12 run_c_tests();
13}
14
15extern fn c_u8(u8) void;
16extern fn c_u16(u16) void;
17extern fn c_u32(u32) void;
18extern fn c_u64(u64) void;
19extern fn c_struct_u128(U128) void;
20extern fn c_i8(i8) void;
21extern fn c_i16(i16) void;
22extern fn c_i32(i32) void;
23extern fn c_i64(i64) void;
24extern fn c_struct_i128(I128) void;
25
26// On windows x64, the first 4 are passed via registers, others on the stack.
27extern fn c_five_integers(i32, i32, i32, i32, i32) void;
28
29export fn zig_five_integers(a: i32, b: i32, c: i32, d: i32, e: i32) void {
30 expect(a == 12) catch @panic("test failure: zig_five_integers 12");
31 expect(b == 34) catch @panic("test failure: zig_five_integers 34");
32 expect(c == 56) catch @panic("test failure: zig_five_integers 56");
33 expect(d == 78) catch @panic("test failure: zig_five_integers 78");
34 expect(e == 90) catch @panic("test failure: zig_five_integers 90");
35}
36
37test "C ABI integers" {
38 c_u8(0xff);
39 c_u16(0xfffe);
40 c_u32(0xfffffffd);
41 c_u64(0xfffffffffffffffc);
42 c_struct_u128(.{ .value = 0xfffffffffffffffc });
43
44 c_i8(-1);
45 c_i16(-2);
46 c_i32(-3);
47 c_i64(-4);
48 c_struct_i128(.{ .value = -6 });
49 c_five_integers(12, 34, 56, 78, 90);
50}
51
52export fn zig_u8(x: u8) void {
53 expect(x == 0xff) catch @panic("test failure: zig_u8");
54}
55export fn zig_u16(x: u16) void {
56 expect(x == 0xfffe) catch @panic("test failure: zig_u16");
57}
58export fn zig_u32(x: u32) void {
59 expect(x == 0xfffffffd) catch @panic("test failure: zig_u32");
60}
61export fn zig_u64(x: u64) void {
62 expect(x == 0xfffffffffffffffc) catch @panic("test failure: zig_u64");
63}
64export fn zig_i8(x: i8) void {
65 expect(x == -1) catch @panic("test failure: zig_i8");
66}
67export fn zig_i16(x: i16) void {
68 expect(x == -2) catch @panic("test failure: zig_i16");
69}
70export fn zig_i32(x: i32) void {
71 expect(x == -3) catch @panic("test failure: zig_i32");
72}
73export fn zig_i64(x: i64) void {
74 expect(x == -4) catch @panic("test failure: zig_i64");
75}
76
77const I128 = extern struct {
78 value: i128,
79};
80const U128 = extern struct {
81 value: u128,
82};
83export fn zig_struct_i128(a: I128) void {
84 expect(a.value == -6) catch @panic("test failure: zig_struct_i128");
85}
86export fn zig_struct_u128(a: U128) void {
87 expect(a.value == 0xfffffffffffffffc) catch @panic("test failure: zig_struct_u128");
88}
89
90extern fn c_f32(f32) void;
91extern fn c_f64(f64) void;
92
93// On windows x64, the first 4 are passed via registers, others on the stack.
94extern fn c_five_floats(f32, f32, f32, f32, f32) void;
95
96export fn zig_five_floats(a: f32, b: f32, c: f32, d: f32, e: f32) void {
97 expect(a == 1.0) catch @panic("test failure: zig_five_floats 1.0");
98 expect(b == 2.0) catch @panic("test failure: zig_five_floats 2.0");
99 expect(c == 3.0) catch @panic("test failure: zig_five_floats 3.0");
100 expect(d == 4.0) catch @panic("test failure: zig_five_floats 4.0");
101 expect(e == 5.0) catch @panic("test failure: zig_five_floats 5.0");
102}
103
104test "C ABI floats" {
105 c_f32(12.34);
106 c_f64(56.78);
107 c_five_floats(1.0, 2.0, 3.0, 4.0, 5.0);
108}
109
110export fn zig_f32(x: f32) void {
111 expect(x == 12.34) catch @panic("test failure: zig_f32");
112}
113export fn zig_f64(x: f64) void {
114 expect(x == 56.78) catch @panic("test failure: zig_f64");
115}
116
117extern fn c_ptr(*anyopaque) void;
118
119test "C ABI pointer" {
120 c_ptr(@intToPtr(*anyopaque, 0xdeadbeef));
121}
122
123export fn zig_ptr(x: *anyopaque) void {
124 expect(@ptrToInt(x) == 0xdeadbeef) catch @panic("test failure: zig_ptr");
125}
126
127extern fn c_bool(bool) void;
128
129test "C ABI bool" {
130 c_bool(true);
131}
132
133export fn zig_bool(x: bool) void {
134 expect(x) catch @panic("test failure: zig_bool");
135}
136
137const BigStruct = extern struct {
138 a: u64,
139 b: u64,
140 c: u64,
141 d: u64,
142 e: u8,
143};
144extern fn c_big_struct(BigStruct) void;
145
146test "C ABI big struct" {
147 var s = BigStruct{
148 .a = 1,
149 .b = 2,
150 .c = 3,
151 .d = 4,
152 .e = 5,
153 };
154 c_big_struct(s);
155}
156
157export fn zig_big_struct(x: BigStruct) void {
158 expect(x.a == 1) catch @panic("test failure: zig_big_struct 1");
159 expect(x.b == 2) catch @panic("test failure: zig_big_struct 2");
160 expect(x.c == 3) catch @panic("test failure: zig_big_struct 3");
161 expect(x.d == 4) catch @panic("test failure: zig_big_struct 4");
162 expect(x.e == 5) catch @panic("test failure: zig_big_struct 5");
163}
164
165const BigUnion = extern union {
166 a: BigStruct,
167};
168extern fn c_big_union(BigUnion) void;
169
170test "C ABI big union" {
171 var x = BigUnion{
172 .a = BigStruct{
173 .a = 1,
174 .b = 2,
175 .c = 3,
176 .d = 4,
177 .e = 5,
178 },
179 };
180 c_big_union(x);
181}
182
183export fn zig_big_union(x: BigUnion) void {
184 expect(x.a.a == 1) catch @panic("test failure: zig_big_union a");
185 expect(x.a.b == 2) catch @panic("test failure: zig_big_union b");
186 expect(x.a.c == 3) catch @panic("test failure: zig_big_union c");
187 expect(x.a.d == 4) catch @panic("test failure: zig_big_union d");
188 expect(x.a.e == 5) catch @panic("test failure: zig_big_union e");
189}
190
191const MedStructMixed = extern struct {
192 a: u32,
193 b: f32,
194 c: f32,
195 d: u32 = 0,
196};
197extern fn c_med_struct_mixed(MedStructMixed) void;
198extern fn c_ret_med_struct_mixed() MedStructMixed;
199
200test "C ABI medium struct of ints and floats" {
201 var s = MedStructMixed{
202 .a = 1234,
203 .b = 100.0,
204 .c = 1337.0,
205 };
206 c_med_struct_mixed(s);
207 var s2 = c_ret_med_struct_mixed();
208 expect(s2.a == 1234) catch @panic("test failure");
209 expect(s2.b == 100.0) catch @panic("test failure");
210 expect(s2.c == 1337.0) catch @panic("test failure");
211}
212
213export fn zig_med_struct_mixed(x: MedStructMixed) void {
214 expect(x.a == 1234) catch @panic("test failure");
215 expect(x.b == 100.0) catch @panic("test failure");
216 expect(x.c == 1337.0) catch @panic("test failure");
217}
218
219const SmallStructInts = extern struct {
220 a: u8,
221 b: u8,
222 c: u8,
223 d: u8,
224};
225extern fn c_small_struct_ints(SmallStructInts) void;
226extern fn c_ret_small_struct_ints() SmallStructInts;
227
228test "C ABI small struct of ints" {
229 var s = SmallStructInts{
230 .a = 1,
231 .b = 2,
232 .c = 3,
233 .d = 4,
234 };
235 c_small_struct_ints(s);
236 var s2 = c_ret_small_struct_ints();
237 expect(s2.a == 1) catch @panic("test failure");
238 expect(s2.b == 2) catch @panic("test failure");
239 expect(s2.c == 3) catch @panic("test failure");
240 expect(s2.d == 4) catch @panic("test failure");
241}
242
243export fn zig_small_struct_ints(x: SmallStructInts) void {
244 expect(x.a == 1) catch @panic("test failure");
245 expect(x.b == 2) catch @panic("test failure");
246 expect(x.c == 3) catch @panic("test failure");
247 expect(x.d == 4) catch @panic("test failure");
248}
249
250const SmallPackedStruct = packed struct {
251 a: u2,
252 b: u2,
253 c: u2,
254 d: u2,
255 e: bool,
256};
257const c_small_packed_struct: fn (SmallPackedStruct) callconv(.C) void = @compileError("TODO: #1481");
258extern fn c_ret_small_packed_struct() SmallPackedStruct;
259
260// waiting on #1481
261//export fn zig_small_packed_struct(x: SmallPackedStruct) void {
262// expect(x.a == 0) catch @panic("test failure");
263// expect(x.b == 1) catch @panic("test failure");
264// expect(x.c == 2) catch @panic("test failure");
265// expect(x.d == 3) catch @panic("test failure");
266// expect(x.e) catch @panic("test failure");
267//}
268
269test "C ABI small packed struct" {
270 var s = SmallPackedStruct{ .a = 0, .b = 1, .c = 2, .d = 3, .e = true };
271 _ = s; //c_small_packed_struct(s); // waiting on #1481
272 var s2 = c_ret_small_packed_struct();
273 try expect(s2.a == 0);
274 try expect(s2.b == 1);
275 try expect(s2.c == 2);
276 try expect(s2.d == 3);
277 try expect(s2.e);
278}
279
280const BigPackedStruct = packed struct {
281 a: u64,
282 b: u64,
283 c: u64,
284 d: u64,
285 e: u8,
286};
287extern fn c_big_packed_struct(BigPackedStruct) void;
288extern fn c_ret_big_packed_struct() BigPackedStruct;
289
290export fn zig_big_packed_struct(x: BigPackedStruct) void {
291 expect(x.a == 1) catch @panic("test failure");
292 expect(x.b == 2) catch @panic("test failure");
293 expect(x.c == 3) catch @panic("test failure");
294 expect(x.d == 4) catch @panic("test failure");
295 expect(x.e == 5) catch @panic("test failure");
296}
297
298test "C ABI big packed struct" {
299 var s = BigPackedStruct{ .a = 1, .b = 2, .c = 3, .d = 4, .e = 5 };
300 c_big_packed_struct(s);
301 var s2 = c_ret_big_packed_struct();
302 try expect(s2.a == 1);
303 try expect(s2.b == 2);
304 try expect(s2.c == 3);
305 try expect(s2.d == 4);
306 try expect(s2.e == 5);
307}
308
309const SplitStructInt = extern struct {
310 a: u64,
311 b: u8,
312 c: u32,
313};
314extern fn c_split_struct_ints(SplitStructInt) void;
315
316test "C ABI split struct of ints" {
317 var s = SplitStructInt{
318 .a = 1234,
319 .b = 100,
320 .c = 1337,
321 };
322 c_split_struct_ints(s);
323}
324
325export fn zig_split_struct_ints(x: SplitStructInt) void {
326 expect(x.a == 1234) catch @panic("test failure");
327 expect(x.b == 100) catch @panic("test failure");
328 expect(x.c == 1337) catch @panic("test failure");
329}
330
331const SplitStructMixed = extern struct {
332 a: u64,
333 b: u8,
334 c: f32,
335};
336extern fn c_split_struct_mixed(SplitStructMixed) void;
337extern fn c_ret_split_struct_mixed() SplitStructMixed;
338
339test "C ABI split struct of ints and floats" {
340 var s = SplitStructMixed{
341 .a = 1234,
342 .b = 100,
343 .c = 1337.0,
344 };
345 c_split_struct_mixed(s);
346 var s2 = c_ret_split_struct_mixed();
347 expect(s2.a == 1234) catch @panic("test failure");
348 expect(s2.b == 100) catch @panic("test failure");
349 expect(s2.c == 1337.0) catch @panic("test failure");
350}
351
352export fn zig_split_struct_mixed(x: SplitStructMixed) void {
353 expect(x.a == 1234) catch @panic("test failure");
354 expect(x.b == 100) catch @panic("test failure");
355 expect(x.c == 1337.0) catch @panic("test failure");
356}
357
358extern fn c_big_struct_both(BigStruct) BigStruct;
359
360test "C ABI sret and byval together" {
361 var s = BigStruct{
362 .a = 1,
363 .b = 2,
364 .c = 3,
365 .d = 4,
366 .e = 5,
367 };
368 var y = c_big_struct_both(s);
369 try expect(y.a == 10);
370 try expect(y.b == 11);
371 try expect(y.c == 12);
372 try expect(y.d == 13);
373 try expect(y.e == 14);
374}
375
376export fn zig_big_struct_both(x: BigStruct) BigStruct {
377 expect(x.a == 30) catch @panic("test failure");
378 expect(x.b == 31) catch @panic("test failure");
379 expect(x.c == 32) catch @panic("test failure");
380 expect(x.d == 33) catch @panic("test failure");
381 expect(x.e == 34) catch @panic("test failure");
382 var s = BigStruct{
383 .a = 20,
384 .b = 21,
385 .c = 22,
386 .d = 23,
387 .e = 24,
388 };
389 return s;
390}
391
392const Vector3 = extern struct {
393 x: f32,
394 y: f32,
395 z: f32,
396};
397extern fn c_small_struct_floats(Vector3) void;
398extern fn c_small_struct_floats_extra(Vector3, ?[*]const u8) void;
399
400const Vector5 = extern struct {
401 x: f32,
402 y: f32,
403 z: f32,
404 w: f32,
405 q: f32,
406};
407extern fn c_big_struct_floats(Vector5) void;
408
409test "C ABI structs of floats as parameter" {
410 var v3 = Vector3{
411 .x = 3.0,
412 .y = 6.0,
413 .z = 12.0,
414 };
415 c_small_struct_floats(v3);
416 c_small_struct_floats_extra(v3, "hello");
417
418 var v5 = Vector5{
419 .x = 76.0,
420 .y = -1.0,
421 .z = -12.0,
422 .w = 69.0,
423 .q = 55,
424 };
425 c_big_struct_floats(v5);
426}
427
428export fn zig_ret_bool() bool {
429 return true;
430}
431export fn zig_ret_u8() u8 {
432 return 0xff;
433}
434export fn zig_ret_u16() u16 {
435 return 0xffff;
436}
437export fn zig_ret_u32() u32 {
438 return 0xffffffff;
439}
440export fn zig_ret_u64() u64 {
441 return 0xffffffffffffffff;
442}
443export fn zig_ret_i8() i8 {
444 return -1;
445}
446export fn zig_ret_i16() i16 {
447 return -1;
448}
449export fn zig_ret_i32() i32 {
450 return -1;
451}
452export fn zig_ret_i64() i64 {
453 return -1;
454}
455
456export fn zig_ret_small_struct_ints() SmallStructInts {
457 return .{
458 .a = 1,
459 .b = 2,
460 .c = 3,
461 .d = 4,
462 };
463}
464
465export fn zig_ret_med_struct_mixed() MedStructMixed {
466 return .{
467 .a = 1234,
468 .b = 100.0,
469 .c = 1337.0,
470 };
471}
472
473export fn zig_ret_split_struct_mixed() SplitStructMixed {
474 return .{
475 .a = 1234,
476 .b = 100,
477 .c = 1337.0,
478 };
479}
480
481extern fn c_ret_bool() bool;
482extern fn c_ret_u8() u8;
483extern fn c_ret_u16() u16;
484extern fn c_ret_u32() u32;
485extern fn c_ret_u64() u64;
486extern fn c_ret_i8() i8;
487extern fn c_ret_i16() i16;
488extern fn c_ret_i32() i32;
489extern fn c_ret_i64() i64;
490
491test "C ABI integer return types" {
492 try expect(c_ret_bool() == true);
493
494 try expect(c_ret_u8() == 0xff);
495 try expect(c_ret_u16() == 0xffff);
496 try expect(c_ret_u32() == 0xffffffff);
497 try expect(c_ret_u64() == 0xffffffffffffffff);
498
499 try expect(c_ret_i8() == -1);
500 try expect(c_ret_i16() == -1);
501 try expect(c_ret_i32() == -1);
502 try expect(c_ret_i64() == -1);
503}
test/standalone.zig+2-2
...@@ -41,11 +41,11 @@ pub fn addCases(cases: *tests.StandaloneContext) void {...@@ -41,11 +41,11 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
41 // C ABI compatibility issue: https://github.com/ziglang/zig/issues/148141 // C ABI compatibility issue: https://github.com/ziglang/zig/issues/1481
42 if (builtin.cpu.arch == .x86_64) {42 if (builtin.cpu.arch == .x86_64) {
43 if (builtin.zig_backend == .stage1) { // https://github.com/ziglang/zig/issues/1222243 if (builtin.zig_backend == .stage1) { // https://github.com/ziglang/zig/issues/12222
44 cases.addBuildFile("test/stage1/c_abi/build.zig", .{});44 cases.addBuildFile("test/c_abi/build.zig", .{});
45 }45 }
46 }46 }
47 // C ABI tests only pass for the Wasm target when using stage247 // C ABI tests only pass for the Wasm target when using stage2
48 cases.addBuildFile("test/stage1/c_abi/build_wasm.zig", .{48 cases.addBuildFile("test/c_abi/build_wasm.zig", .{
49 .requires_stage2 = true,49 .requires_stage2 = true,
50 .use_emulation = true,50 .use_emulation = true,
51 });51 });