| 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,11 +41,11 @@ pub fn addCases(cases: *tests.StandaloneContext) void { |
| 41 | // C ABI compatibility issue: https://github.com/ziglang/zig/issues/1481 | 41 | // 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/12222 | 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 | // C ABI tests only pass for the Wasm target when using stage2 | 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 | .requires_stage2 = true, | 49 | .requires_stage2 = true, |
| 50 | .use_emulation = true, | 50 | .use_emulation = true, |
| 51 | }); | 51 | }); |