Prep work for C ABI compatibility
This commit is contained in:
parent
27bd136487
commit
774551e795
17
build.zig
17
build.zig
@ -308,19 +308,34 @@ pub fn build(b: *std.Build) !void {
|
||||
system_llvm = b.option(bool, "system_llvm", "Link against system LLVM libraries") orelse true;
|
||||
const path = env.get("PATH") orelse unreachable;
|
||||
|
||||
const c_abi = b.addObject(.{
|
||||
.name = "c_abi",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
c_abi.addCSourceFiles(.{
|
||||
.files = &.{"src/c_abi.c"},
|
||||
.flags = &.{"-g"},
|
||||
});
|
||||
|
||||
const exe_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
const configuration = b.addOptions();
|
||||
configuration.addOptionPath("c_abi_object_path", c_abi.getEmittedBin());
|
||||
exe_mod.addOptions("configuration", configuration);
|
||||
|
||||
const llvm = try LLVM.setup(b, path);
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "bloat-buster",
|
||||
.root_module = exe_mod,
|
||||
.link_libc = true,
|
||||
});
|
||||
exe.linkLibC();
|
||||
|
||||
llvm.link(exe);
|
||||
|
||||
|
5485
src/c_abi.c
Normal file
5485
src/c_abi.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -777,11 +777,11 @@ pub const BuildMode = enum {
|
||||
const ConvertOptions = struct {
|
||||
content: []const u8,
|
||||
path: [:0]const u8,
|
||||
object: [:0]const u8,
|
||||
executable: [:0]const u8,
|
||||
build_mode: BuildMode,
|
||||
name: []const u8,
|
||||
has_debug_info: bool,
|
||||
objects: []const [:0]const u8,
|
||||
};
|
||||
|
||||
pub noinline fn convert(options: ConvertOptions) void {
|
||||
@ -1093,14 +1093,14 @@ pub noinline fn convert(options: ConvertOptions) void {
|
||||
.optimize_when_possible = @intFromBool(@intFromEnum(options.build_mode) > @intFromEnum(BuildMode.soft_optimize)),
|
||||
.debug_info = options.has_debug_info,
|
||||
.optimization_level = if (options.build_mode != .debug_none) options.build_mode.to_llvm_ir() else null,
|
||||
.path = options.object,
|
||||
.path = options.objects[0],
|
||||
});
|
||||
|
||||
switch (object_generate_result) {
|
||||
.success => {
|
||||
const result = llvm.link(lib.global.arena, .{
|
||||
.output_path = options.executable,
|
||||
.objects = &.{options.object},
|
||||
.objects = options.objects,
|
||||
});
|
||||
|
||||
switch (result.success) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
const lib = @import("lib.zig");
|
||||
const assert = lib.assert;
|
||||
const std = @import("std");
|
||||
const configuration = @import("configuration");
|
||||
|
||||
const converter = @import("converter.zig");
|
||||
const BuildMode = converter.BuildMode;
|
||||
@ -12,6 +13,7 @@ fn invoke(name: []const u8) !void {
|
||||
|
||||
comptime assert(lib.is_test);
|
||||
const allocator = std.testing.allocator;
|
||||
const c_abi_object_path = lib.global.arena.duplicate_string(configuration.c_abi_object_path);
|
||||
|
||||
inline for (@typeInfo(BuildMode).@"enum".fields) |f| {
|
||||
const build_mode = @field(BuildMode, f.name);
|
||||
@ -21,8 +23,9 @@ fn invoke(name: []const u8) !void {
|
||||
const base_path = lib.global.arena.join_string(&.{ ".zig-cache/tmp/", &tmp_dir.sub_path, "/", name });
|
||||
const executable_path = base_path;
|
||||
const directory_path = lib.global.arena.join_string(&.{ ".zig-cache/tmp/", &tmp_dir.sub_path });
|
||||
const object_path = lib.global.arena.join_string(&.{ base_path, ".o" });
|
||||
try unit_test(allocator, .{
|
||||
.object_path = lib.global.arena.join_string(&.{ base_path, ".o" }),
|
||||
.object_paths = if (lib.string.equal(name, "c_abi")) &.{ object_path, c_abi_object_path } else &.{object_path},
|
||||
.executable_path = executable_path,
|
||||
.file_path = lib.global.arena.join_string(&.{ "tests/", name, ".bbb" }),
|
||||
.name = name,
|
||||
@ -36,7 +39,7 @@ fn invoke(name: []const u8) !void {
|
||||
|
||||
const InvokeWrapper = struct {
|
||||
executable_path: [:0]const u8,
|
||||
object_path: [:0]const u8,
|
||||
object_paths: []const [:0]const u8,
|
||||
file_path: [:0]const u8,
|
||||
name: []const u8,
|
||||
build_mode: BuildMode,
|
||||
@ -50,7 +53,7 @@ fn unit_test(allocator: std.mem.Allocator, options: InvokeWrapper) !void {
|
||||
converter.convert(.{
|
||||
.path = options.file_path,
|
||||
.content = file_content,
|
||||
.object = options.object_path,
|
||||
.objects = options.object_paths,
|
||||
.executable = options.executable_path,
|
||||
.build_mode = options.build_mode,
|
||||
.name = options.name,
|
||||
|
@ -1,4 +1,5 @@
|
||||
const lib = @import("lib.zig");
|
||||
const configuration = @import("configuration");
|
||||
const os = lib.os;
|
||||
const llvm = @import("LLVM.zig");
|
||||
const converter = @import("converter.zig");
|
||||
@ -170,7 +171,7 @@ pub fn main(argc: c_int, argv: [*:null]const ?[*:0]const u8) callconv(.C) c_int
|
||||
const file_path = os.absolute_path(arena, relative_file_path);
|
||||
converter.convert(.{
|
||||
.executable = output_executable_path,
|
||||
.object = output_object_path,
|
||||
.objects = &.{output_object_path},
|
||||
.name = base_name,
|
||||
.build_mode = .debug_none,
|
||||
.content = file_content,
|
||||
|
531
tests/c_abi.bbb
Normal file
531
tests/c_abi.bbb
Normal file
@ -0,0 +1,531 @@
|
||||
Struct_u64_u64 = struct
|
||||
{
|
||||
a: u64,
|
||||
b: u64,
|
||||
}
|
||||
|
||||
BigStruct = struct
|
||||
{
|
||||
a: u64,
|
||||
b: u64,
|
||||
c: u64,
|
||||
d: u64,
|
||||
e: u8,
|
||||
}
|
||||
|
||||
SmallPackedStruct = bitfield(u8)
|
||||
{
|
||||
a: u2,
|
||||
b: u2,
|
||||
c: u2,
|
||||
d: u2,
|
||||
}
|
||||
|
||||
SmallStructInts = struct
|
||||
{
|
||||
a: u8,
|
||||
b: u8,
|
||||
c: u8,
|
||||
d: u8,
|
||||
}
|
||||
|
||||
SplitStructInt = struct
|
||||
{
|
||||
a: u64,
|
||||
b: u8,
|
||||
c: u32,
|
||||
}
|
||||
|
||||
MedStructInts = struct
|
||||
{
|
||||
x: s32,
|
||||
y: s32,
|
||||
z: s32,
|
||||
}
|
||||
|
||||
Rect = struct
|
||||
{
|
||||
left: u32,
|
||||
right: u32,
|
||||
top: u32,
|
||||
bottom: u32,
|
||||
}
|
||||
|
||||
StructWithArray = struct
|
||||
{
|
||||
a: s32,
|
||||
padding: [4]u8,
|
||||
b: s64,
|
||||
}
|
||||
|
||||
ByRef = struct
|
||||
{
|
||||
val: s32,
|
||||
arr: [15]s32,
|
||||
}
|
||||
|
||||
ByValOrigin = struct
|
||||
{
|
||||
x: u64,
|
||||
y: u64,
|
||||
z: u64,
|
||||
}
|
||||
|
||||
ByValSize = struct
|
||||
{
|
||||
width: u64,
|
||||
height: u64,
|
||||
depth: u64,
|
||||
}
|
||||
|
||||
ByVal = struct
|
||||
{
|
||||
origin: ByValOrigin,
|
||||
size: ByValSize,
|
||||
}
|
||||
|
||||
[extern] run_c_tests = fn [cc(c)] () void;
|
||||
|
||||
[extern] c_u8 = fn [cc(.c)] (x: u8) void;
|
||||
[extern] c_u16 = fn [cc(.c)] (x: u16) void;
|
||||
[extern] c_u32 = fn [cc(.c)] (x: u32) void;
|
||||
[extern] c_u64 = fn [cc(.c)] (x: u64) void;
|
||||
|
||||
[extern] c_s8 = fn [cc(.c)] (x: s8) void;
|
||||
[extern] c_s16 = fn [cc(.c)] (x: s16) void;
|
||||
[extern] c_s32 = fn [cc(.c)] (x: s32) void;
|
||||
[extern] c_s64 = fn [cc(.c)] (x: s64) void;
|
||||
|
||||
[extern] c_bool = fn [cc(.c)] (x: u8) void;
|
||||
|
||||
[extern] c_five_integers = fn [cc(.c)] (a: s32, b: s32, c: s32, d: s32, e: s32) void;
|
||||
[extern] c_ret_struct_u64_u64 = fn [cc(.c)] () Struct_u64_u64;
|
||||
|
||||
[extern] c_struct_u64_u64_0 = fn [cc(c)] (a: Struct_u64_u64) void;
|
||||
[extern] c_struct_u64_u64_1 = fn [cc(c)] (a: u64, b: Struct_u64_u64) void;
|
||||
[extern] c_struct_u64_u64_2 = fn [cc(c)] (a: u64, b: u64, c: Struct_u64_u64) void;
|
||||
[extern] c_struct_u64_u64_3 = fn [cc(c)] (a: u64, b: u64, c: u64, d: Struct_u64_u64) void;
|
||||
[extern] c_struct_u64_u64_4 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: Struct_u64_u64) void;
|
||||
[extern] c_struct_u64_u64_5 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: Struct_u64_u64) void;
|
||||
[extern] c_struct_u64_u64_6 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: Struct_u64_u64) void;
|
||||
[extern] c_struct_u64_u64_7 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, h: Struct_u64_u64) void;
|
||||
[extern] c_struct_u64_u64_8 = fn [cc(c)] (a: u64, b: u64, c: u64, d: u64, e: u64, f: u64, g: u64, h: u64, i: Struct_u64_u64) void;
|
||||
|
||||
[extern] c_big_struct = fn [cc(.c)] (x: BigStruct) void;
|
||||
[extern] c_small_struct_ints = fn [cc(.c)] (x: SmallStructInts) void;
|
||||
[extern] c_ret_small_struct_ints = fn [cc(.c)] () SmallStructInts;
|
||||
[extern] c_med_struct_ints = fn [cc(.c)] (x: MedStructInts) void;
|
||||
[extern] c_ret_med_struct_ints = fn [cc(.c)] () MedStructInts;
|
||||
[extern] c_small_packed_struct = fn [cc(.c)] (x: SmallPackedStruct) void;
|
||||
[extern] c_ret_small_packed_struct = fn [cc(.c)] () SmallPackedStruct;
|
||||
[extern] c_split_struct_ints = fn [cc(.c)] (x: SplitStructInt) void;
|
||||
[extern] c_big_struct_both = fn [cc(.c)] (x: BigStruct) BigStruct;
|
||||
[extern] c_multiple_struct_ints = fn [cc(.c)] (a: Rect, b: Rect) void;
|
||||
|
||||
[extern] c_ret_bool = fn [cc(.c)] () u8;
|
||||
|
||||
[extern] c_ret_u8 = fn [cc(.c)] () u8;
|
||||
[extern] c_ret_u16 = fn [cc(.c)] () u16;
|
||||
[extern] c_ret_u32 = fn [cc(.c)] () u32;
|
||||
[extern] c_ret_u64 = fn [cc(.c)] () u64;
|
||||
|
||||
[extern] c_ret_s8 = fn [cc(.c)] () s8;
|
||||
[extern] c_ret_s16 = fn [cc(.c)] () s16;
|
||||
[extern] c_ret_s32 = fn [cc(.c)] () s32;
|
||||
[extern] c_ret_s64 = fn [cc(.c)] () s64;
|
||||
|
||||
[extern] c_struct_with_array = fn [cc(.c)] (x: StructWithArray) void;
|
||||
[extern] c_ret_struct_with_array = fn [cc(.c)] () StructWithArray;
|
||||
|
||||
[extern] c_modify_by_ref_param = fn [cc(.c)] (x: ByRef) ByRef;
|
||||
[extern] c_func_ptr_byval fn [cc(c)] (a: u64, b: u64, c: ByVal, d: u64, e: u64, f: u64) void;
|
||||
|
||||
[export] main = fn [cc(c)] () s32
|
||||
{
|
||||
run_c_tests();
|
||||
c_u8(0xff);
|
||||
c_u16(0xfffe);
|
||||
c_u32(0xfffffffd);
|
||||
c_u64(0xfffffffffffffffc);
|
||||
|
||||
//if (has_i128) {
|
||||
// c_struct_u128({ .value = 0xfffffffffffffffc, });
|
||||
//}
|
||||
|
||||
c_s8(-1);
|
||||
c_s16(-2);
|
||||
c_s32(-3);
|
||||
c_s64(-4);
|
||||
|
||||
//if (has_i128) {
|
||||
// c_struct_i128({ .value = -6, });
|
||||
//}
|
||||
|
||||
c_bool(1);
|
||||
|
||||
c_five_integers(12, 34, 56, 78, 90);
|
||||
|
||||
>s = c_ret_struct_u64_u64();
|
||||
#require(s.a == 21);
|
||||
#require(s.b == 22);
|
||||
c_struct_u64_u64_0({ .a = 23, .b = 24, });
|
||||
c_struct_u64_u64_1(0, { .a = 25, .b = 26, });
|
||||
c_struct_u64_u64_2(0, 1, { .a = 27, .b = 28, });
|
||||
c_struct_u64_u64_3(0, 1, 2, { .a = 29, .b = 30, });
|
||||
c_struct_u64_u64_4(0, 1, 2, 3, { .a = 31, .b = 32, });
|
||||
c_struct_u64_u64_5(0, 1, 2, 3, 4, { .a = 33, .b = 34, });
|
||||
c_struct_u64_u64_6(0, 1, 2, 3, 4, 5, { .a = 35, .b = 36, });
|
||||
c_struct_u64_u64_7(0, 1, 2, 3, 4, 5, 6, { .a = 37, .b = 38, });
|
||||
c_struct_u64_u64_8(0, 1, 2, 3, 4, 5, 6, 7, { .a = 39, .b = 40, });
|
||||
|
||||
>big_struct: BigStruct = {
|
||||
.a = 1,
|
||||
.b = 2,
|
||||
.c = 3,
|
||||
.d = 4,
|
||||
.e = 5,
|
||||
};
|
||||
c_big_struct(big_struct);
|
||||
|
||||
>small: SmallStructInts = {
|
||||
.a = 1,
|
||||
.b = 2,
|
||||
.c = 3,
|
||||
.d = 4,
|
||||
};
|
||||
c_small_struct_ints(small);
|
||||
>small2 = c_ret_small_struct_ints();
|
||||
#require(small2.a == 1);
|
||||
#require(small2.b == 2);
|
||||
#require(small2.c == 3);
|
||||
#require(small2.d == 4);
|
||||
|
||||
>med: MedStructInts = {
|
||||
.x = 1,
|
||||
.y = 2,
|
||||
.z = 3,
|
||||
};
|
||||
c_med_struct_ints(med);
|
||||
>med2 = c_ret_med_struct_ints();
|
||||
#require(med2.x == 1);
|
||||
#require(med2.y == 2);
|
||||
#require(med2.z == 3);
|
||||
|
||||
>p: SmallPackedStruct = { .a = 0, .b = 1, .c = 2, .d = 3, };
|
||||
c_small_packed_struct(p);
|
||||
>p2 = c_ret_small_packed_struct();
|
||||
#require(p2.a == 0);
|
||||
#require(p2.b == 1);
|
||||
#require(p2.c == 2);
|
||||
#require(p2.d == 3);
|
||||
|
||||
>split: SplitStructInt = {
|
||||
.a = 1234,
|
||||
.b = 100,
|
||||
.c = 1337,
|
||||
};
|
||||
c_split_struct_ints(split);
|
||||
|
||||
> big: BigStruct = {
|
||||
.a = 1,
|
||||
.b = 2,
|
||||
.c = 3,
|
||||
.d = 4,
|
||||
.e = 5,
|
||||
};
|
||||
>big2 = c_big_struct_both(big);
|
||||
#require(big2.a == 10);
|
||||
#require(big2.b == 11);
|
||||
#require(big2.c == 12);
|
||||
#require(big2.d == 13);
|
||||
#require(big2.e == 14);
|
||||
|
||||
>r1: Rect = {
|
||||
.left = 1,
|
||||
.right = 21,
|
||||
.top = 16,
|
||||
.bottom = 4,
|
||||
};
|
||||
>r2: Rect = {
|
||||
.left = 178,
|
||||
.right = 189,
|
||||
.top = 21,
|
||||
.bottom = 15,
|
||||
};
|
||||
c_multiple_struct_ints(r1, r2);
|
||||
|
||||
#require(c_ret_bool() == 1);
|
||||
|
||||
#require(c_ret_u8() == 0xff);
|
||||
#require(c_ret_u16() == 0xffff);
|
||||
#require(c_ret_u32() == 0xffffffff);
|
||||
#require(c_ret_u64() == 0xffffffffffffffff);
|
||||
|
||||
#require(c_ret_s8() == -1);
|
||||
#require(c_ret_s16() == -1);
|
||||
#require(c_ret_s32() == -1);
|
||||
#require(c_ret_s64() == -1);
|
||||
|
||||
c_struct_with_array({ .a = 1, .padding = undefined, .b = 2, });
|
||||
|
||||
>x = c_ret_struct_with_array();
|
||||
#require(x.a == 4);
|
||||
#require(x.b == 155);
|
||||
|
||||
>res = c_modify_by_ref_param({ .val = 1, .arr = undefined, });
|
||||
#require(res.val == 42);
|
||||
|
||||
>function_pointer = c_func_ptr_byval&;
|
||||
function_pointer(1, 2, { .origin = { .x = 9, .y = 10, .z = 11, }, .size = { .width = 12, .height = 13, .depth = 14, }, }, 3, 4, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
[export] bb_u8 = fn [cc(c)] (x: u8) void
|
||||
{
|
||||
#require(x == 0xff);
|
||||
}
|
||||
|
||||
[export] bb_u16 = fn [cc(c)] (x: u16) void
|
||||
{
|
||||
#require(x == 0xfffe);
|
||||
}
|
||||
|
||||
[export] bb_u32 = fn [cc(c)] (x: u32) void
|
||||
{
|
||||
#require(x == 0xfffffffd);
|
||||
}
|
||||
|
||||
[export] bb_u64 = fn [cc(c)] (x: u64) void
|
||||
{
|
||||
#require(x == 0xfffffffffffffffc);
|
||||
}
|
||||
|
||||
[export] bb_s8 = fn [cc(c)] (x: s8) void
|
||||
{
|
||||
#require(x == -1);
|
||||
}
|
||||
|
||||
[export] bb_s16 = fn [cc(c)] (x: s16) void
|
||||
{
|
||||
#require(x == -2);
|
||||
}
|
||||
|
||||
[export] bb_s32 = fn [cc(c)] (x: s32) void
|
||||
{
|
||||
#require(x == -3);
|
||||
}
|
||||
|
||||
[export] bb_s64 = fn [cc(c)] (x: s64) void
|
||||
{
|
||||
#require(x == -4);
|
||||
}
|
||||
|
||||
[export] bb_ptr = fn [cc(c)] (x: *u8) void
|
||||
{
|
||||
#require(#int_from_pointer(x) == 0xdeadbeef);
|
||||
}
|
||||
|
||||
[export] bb_five_integers = fn [cc(c)] (a: s32, b: s32, c: s32, d: s32, e: s32) void
|
||||
{
|
||||
#require(a == 12);
|
||||
#require(b == 34);
|
||||
#require(c == 56);
|
||||
#require(d == 78);
|
||||
#require(e == 90);
|
||||
}
|
||||
|
||||
[export] bb_bool = fn [cc(c)] (x: u8) void
|
||||
{
|
||||
#require(x);
|
||||
}
|
||||
|
||||
[export] bb_ret_struct_u64_u64 = fn [cc(c)] () Struct_u64_u64
|
||||
{
|
||||
return { .a = 1, .b = 2, };
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_0 = fn [cc(c)] (s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 3);
|
||||
#require(s.b == 4);
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_1 = fn [cc(c)] (_: u64, s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 5);
|
||||
#require(s.b == 6);
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_2 = fn [cc(c)] (_: u64, _: u64, s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 7);
|
||||
#require(s.b == 8);
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_3 = fn [cc(c)] (_: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 9);
|
||||
#require(s.b == 10);
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_4 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 11);
|
||||
#require(s.b == 12);
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_5 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 13);
|
||||
#require(s.b == 14);
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_6 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 15);
|
||||
#require(s.b == 16);
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_7 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 17);
|
||||
#require(s.b == 18);
|
||||
}
|
||||
|
||||
[export] bb_struct_u64_u64_8 = fn [cc(c)] (_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64, s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 19);
|
||||
#require(s.b == 20);
|
||||
}
|
||||
|
||||
[export] bb_big_struct = fn [cc(c)] (x: BigStruct) void
|
||||
{
|
||||
#require(x.a == 1);
|
||||
#require(x.b == 2);
|
||||
#require(x.c == 3);
|
||||
#require(x.d == 4);
|
||||
#require(x.e == 5);
|
||||
}
|
||||
|
||||
[export] bb_small_packed_struct = fn [cc(c)] (x: SmallPackedStruct) void
|
||||
{
|
||||
#require(x.a == 0);
|
||||
#require(x.b == 1);
|
||||
#require(x.c == 2);
|
||||
#require(x.d == 3);
|
||||
}
|
||||
|
||||
[export] bb_split_struct_ints = fn [cc(c)] (x: SplitStructInt) void
|
||||
{
|
||||
#require(x.a == 1234);
|
||||
#require(x.b == 100);
|
||||
#require(x.c == 1337);
|
||||
}
|
||||
|
||||
[export] bb_big_struct_both = fn [cc(c)] (x: BigStruct) BigStruct
|
||||
{
|
||||
#require(x.a == 30);
|
||||
#require(x.b == 31);
|
||||
#require(x.c == 32);
|
||||
#require(x.d == 33);
|
||||
#require(x.e == 34);
|
||||
>s: BigStruct = {
|
||||
.a = 20,
|
||||
.b = 21,
|
||||
.c = 22,
|
||||
.d = 23,
|
||||
.e = 24,
|
||||
};
|
||||
return s;
|
||||
}
|
||||
|
||||
[export] bb_ret_bool = fn [cc(c)] () u8
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
[export] bb_ret_u8 = fn [cc(c)] () u8
|
||||
{
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
[export] bb_ret_u16 = fn [cc(c)] () u16
|
||||
{
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
[export] bb_ret_u32 = fn [cc(c)] () u32
|
||||
{
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
[export] bb_ret_u64 = fn [cc(c)] () u64
|
||||
{
|
||||
return 0xffffffffffffffff;
|
||||
}
|
||||
|
||||
[export] bb_ret_s8 = fn [cc(c)] () s8
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
[export] bb_ret_s16 = fn [cc(c)] () s16
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
[export] bb_ret_s32 = fn [cc(c)] () s32
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
[export] bb_ret_s64 = fn [cc(c)] () s64
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
[export] bb_ret_small_struct_ints = fn [cc(c)] () SmallStructInts
|
||||
{
|
||||
return {
|
||||
.a = 1,
|
||||
.b = 2,
|
||||
.c = 3,
|
||||
.d = 4,
|
||||
};
|
||||
}
|
||||
|
||||
[export] bb_ret_med_struct_ints = fn [cc(c)] () MedStructInts
|
||||
{
|
||||
return {
|
||||
.x = 1,
|
||||
.y = 2,
|
||||
.z = 3,
|
||||
};
|
||||
}
|
||||
|
||||
[export] bb_multiple_struct_ints = fn [cc(c)] (x: Rect, y: Rect) void
|
||||
{
|
||||
#require(x.left == 1);
|
||||
#require(x.right == 21);
|
||||
#require(x.top == 16);
|
||||
#require(x.bottom == 4);
|
||||
#require(y.left == 178);
|
||||
#require(y.right == 189);
|
||||
#require(y.top == 21);
|
||||
#require(y.bottom == 15);
|
||||
}
|
||||
|
||||
[export] bb_small_struct_ints = fn [cc(c)] (x: SmallStructInts) void
|
||||
{
|
||||
#require(x.a == 1);
|
||||
#require(x.b == 2);
|
||||
#require(x.c == 3);
|
||||
#require(x.d == 4);
|
||||
}
|
||||
|
||||
[export] bb_med_struct_ints = fn [cc(c)] (s: MedStructInts) void
|
||||
{
|
||||
#require(s.x == 1);
|
||||
#require(s.y == 2);
|
||||
#require(s.z == 3);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user