| author | |
| committer | |
| log | e2d4709779d23c83edf26db2d92f4a326b790825 |
| tree | 85370c966f64aae0a71e240ccfe6fddae3dff76a |
| parent | f50c98a75a7d263cf74ade18f1ad76292d37598a |
9 files changed, 1030 insertions(+), 1030 deletions(-)
test/c_abi/build.zig created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | const Builder = @import("std").build.Builder; | |
| 2 | ||
| 3 | pub 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 @@ |
| 1 | const std = @import("std"); | |
| 2 | const Builder = std.build.Builder; | |
| 3 | ||
| 4 | pub 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 | ||
| 6 | void zig_panic(); | |
| 7 | ||
| 8 | static void assert_or_panic(bool ok) { | |
| 9 | if (!ok) { | |
| 10 | zig_panic(); | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | struct i128 { | |
| 15 | __int128 value; | |
| 16 | }; | |
| 17 | ||
| 18 | struct u128 { | |
| 19 | unsigned __int128 value; | |
| 20 | }; | |
| 21 | ||
| 22 | void zig_u8(uint8_t); | |
| 23 | void zig_u16(uint16_t); | |
| 24 | void zig_u32(uint32_t); | |
| 25 | void zig_u64(uint64_t); | |
| 26 | void zig_struct_u128(struct u128); | |
| 27 | void zig_i8(int8_t); | |
| 28 | void zig_i16(int16_t); | |
| 29 | void zig_i32(int32_t); | |
| 30 | void zig_i64(int64_t); | |
| 31 | void zig_struct_i128(struct i128); | |
| 32 | void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); | |
| 33 | ||
| 34 | void zig_f32(float); | |
| 35 | void zig_f64(double); | |
| 36 | void zig_five_floats(float, float, float, float, float); | |
| 37 | ||
| 38 | bool zig_ret_bool(); | |
| 39 | uint8_t zig_ret_u8(); | |
| 40 | uint16_t zig_ret_u16(); | |
| 41 | uint32_t zig_ret_u32(); | |
| 42 | uint64_t zig_ret_u64(); | |
| 43 | int8_t zig_ret_i8(); | |
| 44 | int16_t zig_ret_i16(); | |
| 45 | int32_t zig_ret_i32(); | |
| 46 | int64_t zig_ret_i64(); | |
| 47 | ||
| 48 | void zig_ptr(void *); | |
| 49 | ||
| 50 | void zig_bool(bool); | |
| 51 | ||
| 52 | struct BigStruct { | |
| 53 | uint64_t a; | |
| 54 | uint64_t b; | |
| 55 | uint64_t c; | |
| 56 | uint64_t d; | |
| 57 | uint8_t e; | |
| 58 | }; | |
| 59 | ||
| 60 | void zig_big_struct(struct BigStruct); | |
| 61 | ||
| 62 | union BigUnion { | |
| 63 | struct BigStruct a; | |
| 64 | }; | |
| 65 | ||
| 66 | void zig_big_union(union BigUnion); | |
| 67 | ||
| 68 | struct SmallStructInts { | |
| 69 | uint8_t a; | |
| 70 | uint8_t b; | |
| 71 | uint8_t c; | |
| 72 | uint8_t d; | |
| 73 | }; | |
| 74 | ||
| 75 | void zig_small_struct_ints(struct SmallStructInts); | |
| 76 | struct SmallStructInts zig_ret_small_struct_ints(); | |
| 77 | ||
| 78 | struct MedStructMixed { | |
| 79 | uint32_t a; | |
| 80 | float b; | |
| 81 | float c; | |
| 82 | uint32_t d; | |
| 83 | }; | |
| 84 | ||
| 85 | void zig_med_struct_mixed(struct MedStructMixed); | |
| 86 | struct MedStructMixed zig_ret_med_struct_mixed(); | |
| 87 | ||
| 88 | struct 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 | ||
| 96 | struct 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 | |
| 105 | void zig_big_packed_struct(struct BigPackedStruct); | |
| 106 | ||
| 107 | struct SplitStructInts { | |
| 108 | uint64_t a; | |
| 109 | uint8_t b; | |
| 110 | uint32_t c; | |
| 111 | }; | |
| 112 | void zig_split_struct_ints(struct SplitStructInts); | |
| 113 | ||
| 114 | struct SplitStructMixed { | |
| 115 | uint64_t a; | |
| 116 | uint8_t b; | |
| 117 | float c; | |
| 118 | }; | |
| 119 | void zig_split_struct_mixed(struct SplitStructMixed); | |
| 120 | struct SplitStructMixed zig_ret_split_struct_mixed(); | |
| 121 | ||
| 122 | struct BigStruct zig_big_struct_both(struct BigStruct); | |
| 123 | ||
| 124 | typedef struct Vector3 { | |
| 125 | float x; | |
| 126 | float y; | |
| 127 | float z; | |
| 128 | } Vector3; | |
| 129 | ||
| 130 | typedef struct Vector5 { | |
| 131 | float x; | |
| 132 | float y; | |
| 133 | float z; | |
| 134 | float w; | |
| 135 | float q; | |
| 136 | } Vector5; | |
| 137 | ||
| 138 | void 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 | ||
| 226 | void c_u8(uint8_t x) { | |
| 227 | assert_or_panic(x == 0xff); | |
| 228 | } | |
| 229 | ||
| 230 | void c_u16(uint16_t x) { | |
| 231 | assert_or_panic(x == 0xfffe); | |
| 232 | } | |
| 233 | ||
| 234 | void c_u32(uint32_t x) { | |
| 235 | assert_or_panic(x == 0xfffffffd); | |
| 236 | } | |
| 237 | ||
| 238 | void c_u64(uint64_t x) { | |
| 239 | assert_or_panic(x == 0xfffffffffffffffcULL); | |
| 240 | } | |
| 241 | ||
| 242 | void c_struct_u128(struct u128 x) { | |
| 243 | assert_or_panic(x.value == 0xfffffffffffffffcULL); | |
| 244 | } | |
| 245 | ||
| 246 | void c_i8(int8_t x) { | |
| 247 | assert_or_panic(x == -1); | |
| 248 | } | |
| 249 | ||
| 250 | void c_i16(int16_t x) { | |
| 251 | assert_or_panic(x == -2); | |
| 252 | } | |
| 253 | ||
| 254 | void c_i32(int32_t x) { | |
| 255 | assert_or_panic(x == -3); | |
| 256 | } | |
| 257 | ||
| 258 | void c_i64(int64_t x) { | |
| 259 | assert_or_panic(x == -4); | |
| 260 | } | |
| 261 | ||
| 262 | void c_struct_i128(struct i128 x) { | |
| 263 | assert_or_panic(x.value == -6); | |
| 264 | } | |
| 265 | ||
| 266 | void c_f32(float x) { | |
| 267 | assert_or_panic(x == 12.34f); | |
| 268 | } | |
| 269 | ||
| 270 | void c_f64(double x) { | |
| 271 | assert_or_panic(x == 56.78); | |
| 272 | } | |
| 273 | ||
| 274 | void c_ptr(void *x) { | |
| 275 | assert_or_panic(x == (void*)0xdeadbeefL); | |
| 276 | } | |
| 277 | ||
| 278 | void c_bool(bool x) { | |
| 279 | assert_or_panic(x); | |
| 280 | } | |
| 281 | ||
| 282 | void 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 | ||
| 290 | void 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 | ||
| 298 | void 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 | ||
| 306 | void 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 | ||
| 313 | void 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 | ||
| 327 | struct 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 | ||
| 337 | void 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 | ||
| 349 | struct 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 | ||
| 358 | void 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 | ||
| 364 | void 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 | ||
| 375 | struct 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 | ||
| 386 | void 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 | ||
| 394 | struct 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 | ||
| 405 | void 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 | ||
| 413 | struct 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 | ||
| 422 | struct 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 | ||
| 432 | void 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 | ||
| 438 | void 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 | ||
| 445 | void 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 | ||
| 453 | bool c_ret_bool() { | |
| 454 | return 1; | |
| 455 | } | |
| 456 | uint8_t c_ret_u8() { | |
| 457 | return 0xff; | |
| 458 | } | |
| 459 | uint16_t c_ret_u16() { | |
| 460 | return 0xffff; | |
| 461 | } | |
| 462 | uint32_t c_ret_u32() { | |
| 463 | return 0xffffffff; | |
| 464 | } | |
| 465 | uint64_t c_ret_u64() { | |
| 466 | return 0xffffffffffffffff; | |
| 467 | } | |
| 468 | int8_t c_ret_i8() { | |
| 469 | return -1; | |
| 470 | } | |
| 471 | int16_t c_ret_i16() { | |
| 472 | return -1; | |
| 473 | } | |
| 474 | int32_t c_ret_i32() { | |
| 475 | return -1; | |
| 476 | } | |
| 477 | int64_t c_ret_i64() { | |
| 478 | return -1; | |
| 479 | } |
test/c_abi/main.zig created+503| ... | ... | @@ -0,0 +1,503 @@ |
| 1 | const std = @import("std"); | |
| 2 | const print = std.debug.print; | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | extern fn run_c_tests() void; | |
| 6 | ||
| 7 | export fn zig_panic() noreturn { | |
| 8 | @panic("zig_panic called from C"); | |
| 9 | } | |
| 10 | ||
| 11 | test "C importing Zig ABI Tests" { | |
| 12 | run_c_tests(); | |
| 13 | } | |
| 14 | ||
| 15 | extern fn c_u8(u8) void; | |
| 16 | extern fn c_u16(u16) void; | |
| 17 | extern fn c_u32(u32) void; | |
| 18 | extern fn c_u64(u64) void; | |
| 19 | extern fn c_struct_u128(U128) void; | |
| 20 | extern fn c_i8(i8) void; | |
| 21 | extern fn c_i16(i16) void; | |
| 22 | extern fn c_i32(i32) void; | |
| 23 | extern fn c_i64(i64) void; | |
| 24 | extern fn c_struct_i128(I128) void; | |
| 25 | ||
| 26 | // On windows x64, the first 4 are passed via registers, others on the stack. | |
| 27 | extern fn c_five_integers(i32, i32, i32, i32, i32) void; | |
| 28 | ||
| 29 | export 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 | ||
| 37 | test "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 | ||
| 52 | export fn zig_u8(x: u8) void { | |
| 53 | expect(x == 0xff) catch @panic("test failure: zig_u8"); | |
| 54 | } | |
| 55 | export fn zig_u16(x: u16) void { | |
| 56 | expect(x == 0xfffe) catch @panic("test failure: zig_u16"); | |
| 57 | } | |
| 58 | export fn zig_u32(x: u32) void { | |
| 59 | expect(x == 0xfffffffd) catch @panic("test failure: zig_u32"); | |
| 60 | } | |
| 61 | export fn zig_u64(x: u64) void { | |
| 62 | expect(x == 0xfffffffffffffffc) catch @panic("test failure: zig_u64"); | |
| 63 | } | |
| 64 | export fn zig_i8(x: i8) void { | |
| 65 | expect(x == -1) catch @panic("test failure: zig_i8"); | |
| 66 | } | |
| 67 | export fn zig_i16(x: i16) void { | |
| 68 | expect(x == -2) catch @panic("test failure: zig_i16"); | |
| 69 | } | |
| 70 | export fn zig_i32(x: i32) void { | |
| 71 | expect(x == -3) catch @panic("test failure: zig_i32"); | |
| 72 | } | |
| 73 | export fn zig_i64(x: i64) void { | |
| 74 | expect(x == -4) catch @panic("test failure: zig_i64"); | |
| 75 | } | |
| 76 | ||
| 77 | const I128 = extern struct { | |
| 78 | value: i128, | |
| 79 | }; | |
| 80 | const U128 = extern struct { | |
| 81 | value: u128, | |
| 82 | }; | |
| 83 | export fn zig_struct_i128(a: I128) void { | |
| 84 | expect(a.value == -6) catch @panic("test failure: zig_struct_i128"); | |
| 85 | } | |
| 86 | export fn zig_struct_u128(a: U128) void { | |
| 87 | expect(a.value == 0xfffffffffffffffc) catch @panic("test failure: zig_struct_u128"); | |
| 88 | } | |
| 89 | ||
| 90 | extern fn c_f32(f32) void; | |
| 91 | extern fn c_f64(f64) void; | |
| 92 | ||
| 93 | // On windows x64, the first 4 are passed via registers, others on the stack. | |
| 94 | extern fn c_five_floats(f32, f32, f32, f32, f32) void; | |
| 95 | ||
| 96 | export 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 | ||
| 104 | test "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 | ||
| 110 | export fn zig_f32(x: f32) void { | |
| 111 | expect(x == 12.34) catch @panic("test failure: zig_f32"); | |
| 112 | } | |
| 113 | export fn zig_f64(x: f64) void { | |
| 114 | expect(x == 56.78) catch @panic("test failure: zig_f64"); | |
| 115 | } | |
| 116 | ||
| 117 | extern fn c_ptr(*anyopaque) void; | |
| 118 | ||
| 119 | test "C ABI pointer" { | |
| 120 | c_ptr(@intToPtr(*anyopaque, 0xdeadbeef)); | |
| 121 | } | |
| 122 | ||
| 123 | export fn zig_ptr(x: *anyopaque) void { | |
| 124 | expect(@ptrToInt(x) == 0xdeadbeef) catch @panic("test failure: zig_ptr"); | |
| 125 | } | |
| 126 | ||
| 127 | extern fn c_bool(bool) void; | |
| 128 | ||
| 129 | test "C ABI bool" { | |
| 130 | c_bool(true); | |
| 131 | } | |
| 132 | ||
| 133 | export fn zig_bool(x: bool) void { | |
| 134 | expect(x) catch @panic("test failure: zig_bool"); | |
| 135 | } | |
| 136 | ||
| 137 | const BigStruct = extern struct { | |
| 138 | a: u64, | |
| 139 | b: u64, | |
| 140 | c: u64, | |
| 141 | d: u64, | |
| 142 | e: u8, | |
| 143 | }; | |
| 144 | extern fn c_big_struct(BigStruct) void; | |
| 145 | ||
| 146 | test "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 | ||
| 157 | export 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 | ||
| 165 | const BigUnion = extern union { | |
| 166 | a: BigStruct, | |
| 167 | }; | |
| 168 | extern fn c_big_union(BigUnion) void; | |
| 169 | ||
| 170 | test "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 | ||
| 183 | export 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 | ||
| 191 | const MedStructMixed = extern struct { | |
| 192 | a: u32, | |
| 193 | b: f32, | |
| 194 | c: f32, | |
| 195 | d: u32 = 0, | |
| 196 | }; | |
| 197 | extern fn c_med_struct_mixed(MedStructMixed) void; | |
| 198 | extern fn c_ret_med_struct_mixed() MedStructMixed; | |
| 199 | ||
| 200 | test "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 | ||
| 213 | export 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 | ||
| 219 | const SmallStructInts = extern struct { | |
| 220 | a: u8, | |
| 221 | b: u8, | |
| 222 | c: u8, | |
| 223 | d: u8, | |
| 224 | }; | |
| 225 | extern fn c_small_struct_ints(SmallStructInts) void; | |
| 226 | extern fn c_ret_small_struct_ints() SmallStructInts; | |
| 227 | ||
| 228 | test "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 | ||
| 243 | export 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 | ||
| 250 | const SmallPackedStruct = packed struct { | |
| 251 | a: u2, | |
| 252 | b: u2, | |
| 253 | c: u2, | |
| 254 | d: u2, | |
| 255 | e: bool, | |
| 256 | }; | |
| 257 | const c_small_packed_struct: fn (SmallPackedStruct) callconv(.C) void = @compileError("TODO: #1481"); | |
| 258 | extern 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 | ||
| 269 | test "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 | ||
| 280 | const BigPackedStruct = packed struct { | |
| 281 | a: u64, | |
| 282 | b: u64, | |
| 283 | c: u64, | |
| 284 | d: u64, | |
| 285 | e: u8, | |
| 286 | }; | |
| 287 | extern fn c_big_packed_struct(BigPackedStruct) void; | |
| 288 | extern fn c_ret_big_packed_struct() BigPackedStruct; | |
| 289 | ||
| 290 | export 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 | ||
| 298 | test "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 | ||
| 309 | const SplitStructInt = extern struct { | |
| 310 | a: u64, | |
| 311 | b: u8, | |
| 312 | c: u32, | |
| 313 | }; | |
| 314 | extern fn c_split_struct_ints(SplitStructInt) void; | |
| 315 | ||
| 316 | test "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 | ||
| 325 | export 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 | ||
| 331 | const SplitStructMixed = extern struct { | |
| 332 | a: u64, | |
| 333 | b: u8, | |
| 334 | c: f32, | |
| 335 | }; | |
| 336 | extern fn c_split_struct_mixed(SplitStructMixed) void; | |
| 337 | extern fn c_ret_split_struct_mixed() SplitStructMixed; | |
| 338 | ||
| 339 | test "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 | ||
| 352 | export 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 | ||
| 358 | extern fn c_big_struct_both(BigStruct) BigStruct; | |
| 359 | ||
| 360 | test "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 | ||
| 376 | export 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 | ||
| 392 | const Vector3 = extern struct { | |
| 393 | x: f32, | |
| 394 | y: f32, | |
| 395 | z: f32, | |
| 396 | }; | |
| 397 | extern fn c_small_struct_floats(Vector3) void; | |
| 398 | extern fn c_small_struct_floats_extra(Vector3, ?[*]const u8) void; | |
| 399 | ||
| 400 | const Vector5 = extern struct { | |
| 401 | x: f32, | |
| 402 | y: f32, | |
| 403 | z: f32, | |
| 404 | w: f32, | |
| 405 | q: f32, | |
| 406 | }; | |
| 407 | extern fn c_big_struct_floats(Vector5) void; | |
| 408 | ||
| 409 | test "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 | ||
| 428 | export fn zig_ret_bool() bool { | |
| 429 | return true; | |
| 430 | } | |
| 431 | export fn zig_ret_u8() u8 { | |
| 432 | return 0xff; | |
| 433 | } | |
| 434 | export fn zig_ret_u16() u16 { | |
| 435 | return 0xffff; | |
| 436 | } | |
| 437 | export fn zig_ret_u32() u32 { | |
| 438 | return 0xffffffff; | |
| 439 | } | |
| 440 | export fn zig_ret_u64() u64 { | |
| 441 | return 0xffffffffffffffff; | |
| 442 | } | |
| 443 | export fn zig_ret_i8() i8 { | |
| 444 | return -1; | |
| 445 | } | |
| 446 | export fn zig_ret_i16() i16 { | |
| 447 | return -1; | |
| 448 | } | |
| 449 | export fn zig_ret_i32() i32 { | |
| 450 | return -1; | |
| 451 | } | |
| 452 | export fn zig_ret_i64() i64 { | |
| 453 | return -1; | |
| 454 | } | |
| 455 | ||
| 456 | export fn zig_ret_small_struct_ints() SmallStructInts { | |
| 457 | return .{ | |
| 458 | .a = 1, | |
| 459 | .b = 2, | |
| 460 | .c = 3, | |
| 461 | .d = 4, | |
| 462 | }; | |
| 463 | } | |
| 464 | ||
| 465 | export fn zig_ret_med_struct_mixed() MedStructMixed { | |
| 466 | return .{ | |
| 467 | .a = 1234, | |
| 468 | .b = 100.0, | |
| 469 | .c = 1337.0, | |
| 470 | }; | |
| 471 | } | |
| 472 | ||
| 473 | export fn zig_ret_split_struct_mixed() SplitStructMixed { | |
| 474 | return .{ | |
| 475 | .a = 1234, | |
| 476 | .b = 100, | |
| 477 | .c = 1337.0, | |
| 478 | }; | |
| 479 | } | |
| 480 | ||
| 481 | extern fn c_ret_bool() bool; | |
| 482 | extern fn c_ret_u8() u8; | |
| 483 | extern fn c_ret_u16() u16; | |
| 484 | extern fn c_ret_u32() u32; | |
| 485 | extern fn c_ret_u64() u64; | |
| 486 | extern fn c_ret_i8() i8; | |
| 487 | extern fn c_ret_i16() i16; | |
| 488 | extern fn c_ret_i32() i32; | |
| 489 | extern fn c_ret_i64() i64; | |
| 490 | ||
| 491 | test "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 @@ |
| 1 | const Builder = @import("std").build.Builder; | |
| 2 | ||
| 3 | pub 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 @@ |
| 1 | const std = @import("std"); | |
| 2 | const Builder = std.build.Builder; | |
| 3 | ||
| 4 | pub 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 | ||
| 6 | void zig_panic(); | |
| 7 | ||
| 8 | static void assert_or_panic(bool ok) { | |
| 9 | if (!ok) { | |
| 10 | zig_panic(); | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | struct i128 { | |
| 15 | __int128 value; | |
| 16 | }; | |
| 17 | ||
| 18 | struct u128 { | |
| 19 | unsigned __int128 value; | |
| 20 | }; | |
| 21 | ||
| 22 | void zig_u8(uint8_t); | |
| 23 | void zig_u16(uint16_t); | |
| 24 | void zig_u32(uint32_t); | |
| 25 | void zig_u64(uint64_t); | |
| 26 | void zig_struct_u128(struct u128); | |
| 27 | void zig_i8(int8_t); | |
| 28 | void zig_i16(int16_t); | |
| 29 | void zig_i32(int32_t); | |
| 30 | void zig_i64(int64_t); | |
| 31 | void zig_struct_i128(struct i128); | |
| 32 | void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); | |
| 33 | ||
| 34 | void zig_f32(float); | |
| 35 | void zig_f64(double); | |
| 36 | void zig_five_floats(float, float, float, float, float); | |
| 37 | ||
| 38 | bool zig_ret_bool(); | |
| 39 | uint8_t zig_ret_u8(); | |
| 40 | uint16_t zig_ret_u16(); | |
| 41 | uint32_t zig_ret_u32(); | |
| 42 | uint64_t zig_ret_u64(); | |
| 43 | int8_t zig_ret_i8(); | |
| 44 | int16_t zig_ret_i16(); | |
| 45 | int32_t zig_ret_i32(); | |
| 46 | int64_t zig_ret_i64(); | |
| 47 | ||
| 48 | void zig_ptr(void *); | |
| 49 | ||
| 50 | void zig_bool(bool); | |
| 51 | ||
| 52 | struct BigStruct { | |
| 53 | uint64_t a; | |
| 54 | uint64_t b; | |
| 55 | uint64_t c; | |
| 56 | uint64_t d; | |
| 57 | uint8_t e; | |
| 58 | }; | |
| 59 | ||
| 60 | void zig_big_struct(struct BigStruct); | |
| 61 | ||
| 62 | union BigUnion { | |
| 63 | struct BigStruct a; | |
| 64 | }; | |
| 65 | ||
| 66 | void zig_big_union(union BigUnion); | |
| 67 | ||
| 68 | struct SmallStructInts { | |
| 69 | uint8_t a; | |
| 70 | uint8_t b; | |
| 71 | uint8_t c; | |
| 72 | uint8_t d; | |
| 73 | }; | |
| 74 | ||
| 75 | void zig_small_struct_ints(struct SmallStructInts); | |
| 76 | struct SmallStructInts zig_ret_small_struct_ints(); | |
| 77 | ||
| 78 | struct MedStructMixed { | |
| 79 | uint32_t a; | |
| 80 | float b; | |
| 81 | float c; | |
| 82 | uint32_t d; | |
| 83 | }; | |
| 84 | ||
| 85 | void zig_med_struct_mixed(struct MedStructMixed); | |
| 86 | struct MedStructMixed zig_ret_med_struct_mixed(); | |
| 87 | ||
| 88 | struct 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 | ||
| 96 | struct 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 | |
| 105 | void zig_big_packed_struct(struct BigPackedStruct); | |
| 106 | ||
| 107 | struct SplitStructInts { | |
| 108 | uint64_t a; | |
| 109 | uint8_t b; | |
| 110 | uint32_t c; | |
| 111 | }; | |
| 112 | void zig_split_struct_ints(struct SplitStructInts); | |
| 113 | ||
| 114 | struct SplitStructMixed { | |
| 115 | uint64_t a; | |
| 116 | uint8_t b; | |
| 117 | float c; | |
| 118 | }; | |
| 119 | void zig_split_struct_mixed(struct SplitStructMixed); | |
| 120 | struct SplitStructMixed zig_ret_split_struct_mixed(); | |
| 121 | ||
| 122 | struct BigStruct zig_big_struct_both(struct BigStruct); | |
| 123 | ||
| 124 | typedef struct Vector3 { | |
| 125 | float x; | |
| 126 | float y; | |
| 127 | float z; | |
| 128 | } Vector3; | |
| 129 | ||
| 130 | typedef struct Vector5 { | |
| 131 | float x; | |
| 132 | float y; | |
| 133 | float z; | |
| 134 | float w; | |
| 135 | float q; | |
| 136 | } Vector5; | |
| 137 | ||
| 138 | void 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 | ||
| 226 | void c_u8(uint8_t x) { | |
| 227 | assert_or_panic(x == 0xff); | |
| 228 | } | |
| 229 | ||
| 230 | void c_u16(uint16_t x) { | |
| 231 | assert_or_panic(x == 0xfffe); | |
| 232 | } | |
| 233 | ||
| 234 | void c_u32(uint32_t x) { | |
| 235 | assert_or_panic(x == 0xfffffffd); | |
| 236 | } | |
| 237 | ||
| 238 | void c_u64(uint64_t x) { | |
| 239 | assert_or_panic(x == 0xfffffffffffffffcULL); | |
| 240 | } | |
| 241 | ||
| 242 | void c_struct_u128(struct u128 x) { | |
| 243 | assert_or_panic(x.value == 0xfffffffffffffffcULL); | |
| 244 | } | |
| 245 | ||
| 246 | void c_i8(int8_t x) { | |
| 247 | assert_or_panic(x == -1); | |
| 248 | } | |
| 249 | ||
| 250 | void c_i16(int16_t x) { | |
| 251 | assert_or_panic(x == -2); | |
| 252 | } | |
| 253 | ||
| 254 | void c_i32(int32_t x) { | |
| 255 | assert_or_panic(x == -3); | |
| 256 | } | |
| 257 | ||
| 258 | void c_i64(int64_t x) { | |
| 259 | assert_or_panic(x == -4); | |
| 260 | } | |
| 261 | ||
| 262 | void c_struct_i128(struct i128 x) { | |
| 263 | assert_or_panic(x.value == -6); | |
| 264 | } | |
| 265 | ||
| 266 | void c_f32(float x) { | |
| 267 | assert_or_panic(x == 12.34f); | |
| 268 | } | |
| 269 | ||
| 270 | void c_f64(double x) { | |
| 271 | assert_or_panic(x == 56.78); | |
| 272 | } | |
| 273 | ||
| 274 | void c_ptr(void *x) { | |
| 275 | assert_or_panic(x == (void*)0xdeadbeefL); | |
| 276 | } | |
| 277 | ||
| 278 | void c_bool(bool x) { | |
| 279 | assert_or_panic(x); | |
| 280 | } | |
| 281 | ||
| 282 | void 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 | ||
| 290 | void 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 | ||
| 298 | void 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 | ||
| 306 | void 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 | ||
| 313 | void 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 | ||
| 327 | struct 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 | ||
| 337 | void 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 | ||
| 349 | struct 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 | ||
| 358 | void 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 | ||
| 364 | void 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 | ||
| 375 | struct 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 | ||
| 386 | void 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 | ||
| 394 | struct 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 | ||
| 405 | void 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 | ||
| 413 | struct 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 | ||
| 422 | struct 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 | ||
| 432 | void 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 | ||
| 438 | void 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 | ||
| 445 | void 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 | ||
| 453 | bool c_ret_bool() { | |
| 454 | return 1; | |
| 455 | } | |
| 456 | uint8_t c_ret_u8() { | |
| 457 | return 0xff; | |
| 458 | } | |
| 459 | uint16_t c_ret_u16() { | |
| 460 | return 0xffff; | |
| 461 | } | |
| 462 | uint32_t c_ret_u32() { | |
| 463 | return 0xffffffff; | |
| 464 | } | |
| 465 | uint64_t c_ret_u64() { | |
| 466 | return 0xffffffffffffffff; | |
| 467 | } | |
| 468 | int8_t c_ret_i8() { | |
| 469 | return -1; | |
| 470 | } | |
| 471 | int16_t c_ret_i16() { | |
| 472 | return -1; | |
| 473 | } | |
| 474 | int32_t c_ret_i32() { | |
| 475 | return -1; | |
| 476 | } | |
| 477 | int64_t c_ret_i64() { | |
| 478 | return -1; | |
| 479 | } |
test/stage1/c_abi/main.zig deleted-503| ... | ... | @@ -1,503 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const print = std.debug.print; | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | extern fn run_c_tests() void; | |
| 6 | ||
| 7 | export fn zig_panic() noreturn { | |
| 8 | @panic("zig_panic called from C"); | |
| 9 | } | |
| 10 | ||
| 11 | test "C importing Zig ABI Tests" { | |
| 12 | run_c_tests(); | |
| 13 | } | |
| 14 | ||
| 15 | extern fn c_u8(u8) void; | |
| 16 | extern fn c_u16(u16) void; | |
| 17 | extern fn c_u32(u32) void; | |
| 18 | extern fn c_u64(u64) void; | |
| 19 | extern fn c_struct_u128(U128) void; | |
| 20 | extern fn c_i8(i8) void; | |
| 21 | extern fn c_i16(i16) void; | |
| 22 | extern fn c_i32(i32) void; | |
| 23 | extern fn c_i64(i64) void; | |
| 24 | extern fn c_struct_i128(I128) void; | |
| 25 | ||
| 26 | // On windows x64, the first 4 are passed via registers, others on the stack. | |
| 27 | extern fn c_five_integers(i32, i32, i32, i32, i32) void; | |
| 28 | ||
| 29 | export 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 | ||
| 37 | test "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 | ||
| 52 | export fn zig_u8(x: u8) void { | |
| 53 | expect(x == 0xff) catch @panic("test failure: zig_u8"); | |
| 54 | } | |
| 55 | export fn zig_u16(x: u16) void { | |
| 56 | expect(x == 0xfffe) catch @panic("test failure: zig_u16"); | |
| 57 | } | |
| 58 | export fn zig_u32(x: u32) void { | |
| 59 | expect(x == 0xfffffffd) catch @panic("test failure: zig_u32"); | |
| 60 | } | |
| 61 | export fn zig_u64(x: u64) void { | |
| 62 | expect(x == 0xfffffffffffffffc) catch @panic("test failure: zig_u64"); | |
| 63 | } | |
| 64 | export fn zig_i8(x: i8) void { | |
| 65 | expect(x == -1) catch @panic("test failure: zig_i8"); | |
| 66 | } | |
| 67 | export fn zig_i16(x: i16) void { | |
| 68 | expect(x == -2) catch @panic("test failure: zig_i16"); | |
| 69 | } | |
| 70 | export fn zig_i32(x: i32) void { | |
| 71 | expect(x == -3) catch @panic("test failure: zig_i32"); | |
| 72 | } | |
| 73 | export fn zig_i64(x: i64) void { | |
| 74 | expect(x == -4) catch @panic("test failure: zig_i64"); | |
| 75 | } | |
| 76 | ||
| 77 | const I128 = extern struct { | |
| 78 | value: i128, | |
| 79 | }; | |
| 80 | const U128 = extern struct { | |
| 81 | value: u128, | |
| 82 | }; | |
| 83 | export fn zig_struct_i128(a: I128) void { | |
| 84 | expect(a.value == -6) catch @panic("test failure: zig_struct_i128"); | |
| 85 | } | |
| 86 | export fn zig_struct_u128(a: U128) void { | |
| 87 | expect(a.value == 0xfffffffffffffffc) catch @panic("test failure: zig_struct_u128"); | |
| 88 | } | |
| 89 | ||
| 90 | extern fn c_f32(f32) void; | |
| 91 | extern fn c_f64(f64) void; | |
| 92 | ||
| 93 | // On windows x64, the first 4 are passed via registers, others on the stack. | |
| 94 | extern fn c_five_floats(f32, f32, f32, f32, f32) void; | |
| 95 | ||
| 96 | export 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 | ||
| 104 | test "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 | ||
| 110 | export fn zig_f32(x: f32) void { | |
| 111 | expect(x == 12.34) catch @panic("test failure: zig_f32"); | |
| 112 | } | |
| 113 | export fn zig_f64(x: f64) void { | |
| 114 | expect(x == 56.78) catch @panic("test failure: zig_f64"); | |
| 115 | } | |
| 116 | ||
| 117 | extern fn c_ptr(*anyopaque) void; | |
| 118 | ||
| 119 | test "C ABI pointer" { | |
| 120 | c_ptr(@intToPtr(*anyopaque, 0xdeadbeef)); | |
| 121 | } | |
| 122 | ||
| 123 | export fn zig_ptr(x: *anyopaque) void { | |
| 124 | expect(@ptrToInt(x) == 0xdeadbeef) catch @panic("test failure: zig_ptr"); | |
| 125 | } | |
| 126 | ||
| 127 | extern fn c_bool(bool) void; | |
| 128 | ||
| 129 | test "C ABI bool" { | |
| 130 | c_bool(true); | |
| 131 | } | |
| 132 | ||
| 133 | export fn zig_bool(x: bool) void { | |
| 134 | expect(x) catch @panic("test failure: zig_bool"); | |
| 135 | } | |
| 136 | ||
| 137 | const BigStruct = extern struct { | |
| 138 | a: u64, | |
| 139 | b: u64, | |
| 140 | c: u64, | |
| 141 | d: u64, | |
| 142 | e: u8, | |
| 143 | }; | |
| 144 | extern fn c_big_struct(BigStruct) void; | |
| 145 | ||
| 146 | test "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 | ||
| 157 | export 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 | ||
| 165 | const BigUnion = extern union { | |
| 166 | a: BigStruct, | |
| 167 | }; | |
| 168 | extern fn c_big_union(BigUnion) void; | |
| 169 | ||
| 170 | test "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 | ||
| 183 | export 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 | ||
| 191 | const MedStructMixed = extern struct { | |
| 192 | a: u32, | |
| 193 | b: f32, | |
| 194 | c: f32, | |
| 195 | d: u32 = 0, | |
| 196 | }; | |
| 197 | extern fn c_med_struct_mixed(MedStructMixed) void; | |
| 198 | extern fn c_ret_med_struct_mixed() MedStructMixed; | |
| 199 | ||
| 200 | test "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 | ||
| 213 | export 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 | ||
| 219 | const SmallStructInts = extern struct { | |
| 220 | a: u8, | |
| 221 | b: u8, | |
| 222 | c: u8, | |
| 223 | d: u8, | |
| 224 | }; | |
| 225 | extern fn c_small_struct_ints(SmallStructInts) void; | |
| 226 | extern fn c_ret_small_struct_ints() SmallStructInts; | |
| 227 | ||
| 228 | test "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 | ||
| 243 | export 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 | ||
| 250 | const SmallPackedStruct = packed struct { | |
| 251 | a: u2, | |
| 252 | b: u2, | |
| 253 | c: u2, | |
| 254 | d: u2, | |
| 255 | e: bool, | |
| 256 | }; | |
| 257 | const c_small_packed_struct: fn (SmallPackedStruct) callconv(.C) void = @compileError("TODO: #1481"); | |
| 258 | extern 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 | ||
| 269 | test "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 | ||
| 280 | const BigPackedStruct = packed struct { | |
| 281 | a: u64, | |
| 282 | b: u64, | |
| 283 | c: u64, | |
| 284 | d: u64, | |
| 285 | e: u8, | |
| 286 | }; | |
| 287 | extern fn c_big_packed_struct(BigPackedStruct) void; | |
| 288 | extern fn c_ret_big_packed_struct() BigPackedStruct; | |
| 289 | ||
| 290 | export 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 | ||
| 298 | test "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 | ||
| 309 | const SplitStructInt = extern struct { | |
| 310 | a: u64, | |
| 311 | b: u8, | |
| 312 | c: u32, | |
| 313 | }; | |
| 314 | extern fn c_split_struct_ints(SplitStructInt) void; | |
| 315 | ||
| 316 | test "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 | ||
| 325 | export 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 | ||
| 331 | const SplitStructMixed = extern struct { | |
| 332 | a: u64, | |
| 333 | b: u8, | |
| 334 | c: f32, | |
| 335 | }; | |
| 336 | extern fn c_split_struct_mixed(SplitStructMixed) void; | |
| 337 | extern fn c_ret_split_struct_mixed() SplitStructMixed; | |
| 338 | ||
| 339 | test "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 | ||
| 352 | export 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 | ||
| 358 | extern fn c_big_struct_both(BigStruct) BigStruct; | |
| 359 | ||
| 360 | test "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 | ||
| 376 | export 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 | ||
| 392 | const Vector3 = extern struct { | |
| 393 | x: f32, | |
| 394 | y: f32, | |
| 395 | z: f32, | |
| 396 | }; | |
| 397 | extern fn c_small_struct_floats(Vector3) void; | |
| 398 | extern fn c_small_struct_floats_extra(Vector3, ?[*]const u8) void; | |
| 399 | ||
| 400 | const Vector5 = extern struct { | |
| 401 | x: f32, | |
| 402 | y: f32, | |
| 403 | z: f32, | |
| 404 | w: f32, | |
| 405 | q: f32, | |
| 406 | }; | |
| 407 | extern fn c_big_struct_floats(Vector5) void; | |
| 408 | ||
| 409 | test "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 | ||
| 428 | export fn zig_ret_bool() bool { | |
| 429 | return true; | |
| 430 | } | |
| 431 | export fn zig_ret_u8() u8 { | |
| 432 | return 0xff; | |
| 433 | } | |
| 434 | export fn zig_ret_u16() u16 { | |
| 435 | return 0xffff; | |
| 436 | } | |
| 437 | export fn zig_ret_u32() u32 { | |
| 438 | return 0xffffffff; | |
| 439 | } | |
| 440 | export fn zig_ret_u64() u64 { | |
| 441 | return 0xffffffffffffffff; | |
| 442 | } | |
| 443 | export fn zig_ret_i8() i8 { | |
| 444 | return -1; | |
| 445 | } | |
| 446 | export fn zig_ret_i16() i16 { | |
| 447 | return -1; | |
| 448 | } | |
| 449 | export fn zig_ret_i32() i32 { | |
| 450 | return -1; | |
| 451 | } | |
| 452 | export fn zig_ret_i64() i64 { | |
| 453 | return -1; | |
| 454 | } | |
| 455 | ||
| 456 | export fn zig_ret_small_struct_ints() SmallStructInts { | |
| 457 | return .{ | |
| 458 | .a = 1, | |
| 459 | .b = 2, | |
| 460 | .c = 3, | |
| 461 | .d = 4, | |
| 462 | }; | |
| 463 | } | |
| 464 | ||
| 465 | export fn zig_ret_med_struct_mixed() MedStructMixed { | |
| 466 | return .{ | |
| 467 | .a = 1234, | |
| 468 | .b = 100.0, | |
| 469 | .c = 1337.0, | |
| 470 | }; | |
| 471 | } | |
| 472 | ||
| 473 | export fn zig_ret_split_struct_mixed() SplitStructMixed { | |
| 474 | return .{ | |
| 475 | .a = 1234, | |
| 476 | .b = 100, | |
| 477 | .c = 1337.0, | |
| 478 | }; | |
| 479 | } | |
| 480 | ||
| 481 | extern fn c_ret_bool() bool; | |
| 482 | extern fn c_ret_u8() u8; | |
| 483 | extern fn c_ret_u16() u16; | |
| 484 | extern fn c_ret_u32() u32; | |
| 485 | extern fn c_ret_u64() u64; | |
| 486 | extern fn c_ret_i8() i8; | |
| 487 | extern fn c_ret_i16() i16; | |
| 488 | extern fn c_ret_i32() i32; | |
| 489 | extern fn c_ret_i64() i64; | |
| 490 | ||
| 491 | test "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 | 41 | // C ABI compatibility issue: https://github.com/ziglang/zig/issues/1481 |
| 42 | 42 | if (builtin.cpu.arch == .x86_64) { |
| 43 | 43 | 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 | 47 | // 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 | 49 | .requires_stage2 = true, |
| 50 | 50 | .use_emulation = true, |
| 51 | 51 | }); |