External functions and array type refinements
This commit is contained in:
parent
e290f61890
commit
6135ade3a7
@ -23,6 +23,28 @@ const right_brace = '}';
|
||||
const left_parenthesis = '(';
|
||||
const right_parenthesis = ')';
|
||||
|
||||
fn array_type_name(element_count: u64, noalias array: *ArrayType) [:0]const u8 {
|
||||
var buffer: [256]u8 = undefined;
|
||||
var i: usize = 0;
|
||||
buffer[i] = left_bracket;
|
||||
i += 1;
|
||||
i += lib.string_format.integer_decimal(buffer[i..], element_count);
|
||||
buffer[i] = right_bracket;
|
||||
i += 1;
|
||||
const element_name = array.element_type.name.?;
|
||||
@memcpy(buffer[i..][0..element_name.len], element_name);
|
||||
i += element_name.len;
|
||||
return lib.global.arena.duplicate_string(buffer[0..i]);
|
||||
}
|
||||
|
||||
fn array_type_llvm(noalias module: *Module, noalias array: *ArrayType) Type.LLVM {
|
||||
const element_count = array.element_count.?;
|
||||
return .{
|
||||
.handle = array.element_type.llvm.handle.get_array_type(element_count).to_type(),
|
||||
.debug = if (module.llvm.di_builder) |di_builder| di_builder.create_array_type(element_count, @intCast(array.element_type.get_bit_alignment()), array.element_type.llvm.debug, &.{}).to_type() else undefined,
|
||||
};
|
||||
}
|
||||
|
||||
fn is_identifier_start_ch(ch: u8) bool {
|
||||
return (ch >= 'a' and ch <= 'z') or (ch >= 'A' and ch <= 'Z') or ch == '_';
|
||||
}
|
||||
@ -249,6 +271,11 @@ pub const Function = struct {
|
||||
calling_convention: CallingConvention,
|
||||
};
|
||||
|
||||
pub const ConstantInteger = struct {
|
||||
value: u64,
|
||||
signed: bool,
|
||||
};
|
||||
|
||||
pub const Value = struct {
|
||||
bb: union(enum) {
|
||||
function: Function,
|
||||
@ -259,8 +286,9 @@ pub const Value = struct {
|
||||
struct_initialization,
|
||||
bits_initialization,
|
||||
infer_or_ignore,
|
||||
constant_integer,
|
||||
constant_integer: ConstantInteger,
|
||||
constant_array,
|
||||
external_function,
|
||||
},
|
||||
type: *Type,
|
||||
llvm: *llvm.Value,
|
||||
@ -503,7 +531,7 @@ const Converter = struct {
|
||||
|
||||
converter.skip_space();
|
||||
|
||||
const length_expression = converter.parse_value(module, null);
|
||||
const length_expression = converter.parse_value(module, module.integer_type(64, false));
|
||||
converter.skip_space();
|
||||
converter.expect_character(right_bracket);
|
||||
|
||||
@ -522,7 +550,17 @@ const Converter = struct {
|
||||
});
|
||||
return ty;
|
||||
} else {
|
||||
@trap();
|
||||
const ty = module.types.add(.{
|
||||
.name = undefined,
|
||||
.llvm = undefined,
|
||||
.bb = .{
|
||||
.array = .{
|
||||
.element_count = length_expression.bb.constant_integer.value,
|
||||
.element_type = element_type,
|
||||
},
|
||||
},
|
||||
});
|
||||
return ty;
|
||||
}
|
||||
},
|
||||
else => @trap(),
|
||||
@ -592,7 +630,7 @@ const Converter = struct {
|
||||
assert(!is_space(integer_start_ch));
|
||||
assert(is_decimal_ch(integer_start_ch));
|
||||
|
||||
const value: u64 = switch (integer_start_ch) {
|
||||
const absolute_value: u64 = switch (integer_start_ch) {
|
||||
'0' => blk: {
|
||||
converter.offset += 1;
|
||||
|
||||
@ -619,25 +657,32 @@ const Converter = struct {
|
||||
},
|
||||
true => switch (next_ch) {
|
||||
'x', 'o', 'b', '0' => converter.report_error(),
|
||||
'1'...'9' => @bitCast(-@as(i64, @intCast(converter.parse_decimal()))),
|
||||
'1'...'9' => converter.parse_decimal(),
|
||||
else => unreachable,
|
||||
},
|
||||
};
|
||||
},
|
||||
'1'...'9' => switch (sign) {
|
||||
true => @bitCast(-@as(i64, @intCast(converter.parse_decimal()))),
|
||||
false => converter.parse_decimal(),
|
||||
},
|
||||
'1'...'9' => converter.parse_decimal(),
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
const value: u64 = switch (sign) {
|
||||
true => @bitCast(-@as(i64, @intCast(absolute_value))),
|
||||
false => absolute_value,
|
||||
};
|
||||
|
||||
const integer_type = expected_type.llvm.handle.to_integer();
|
||||
const llvm_integer_value = integer_type.get_constant(value, @intFromBool(expected_type.bb.integer.signed));
|
||||
const integer_value = module.values.add();
|
||||
integer_value.* = .{
|
||||
.llvm = llvm_integer_value.to_value(),
|
||||
.type = expected_type,
|
||||
.bb = .constant_integer,
|
||||
.bb = .{
|
||||
.constant_integer = .{
|
||||
.value = absolute_value,
|
||||
.signed = sign,
|
||||
},
|
||||
},
|
||||
};
|
||||
return integer_value;
|
||||
}
|
||||
@ -1251,22 +1296,8 @@ const Converter = struct {
|
||||
@trap();
|
||||
} else {
|
||||
array.element_count = element_count;
|
||||
ty.llvm = .{
|
||||
.handle = array.element_type.llvm.handle.get_array_type(element_count).to_type(),
|
||||
.debug = if (module.llvm.di_builder) |di_builder| di_builder.create_array_type(element_count, @intCast(array.element_type.get_bit_alignment()), array.element_type.llvm.debug, &.{}).to_type() else undefined,
|
||||
};
|
||||
|
||||
var buffer: [256]u8 = undefined;
|
||||
var i: usize = 0;
|
||||
buffer[i] = left_bracket;
|
||||
i += 1;
|
||||
i += lib.string_format.integer_decimal(buffer[i..], element_count);
|
||||
buffer[i] = right_bracket;
|
||||
i += 1;
|
||||
const element_name = array.element_type.name.?;
|
||||
@memcpy(buffer[i..][0..element_name.len], element_name);
|
||||
i += element_name.len;
|
||||
ty.name = lib.global.arena.duplicate_string(buffer[0..i]);
|
||||
ty.llvm = array_type_llvm(module, array);
|
||||
ty.name = array_type_name(element_count, array);
|
||||
}
|
||||
|
||||
const array_elements = element_buffer[0..element_count];
|
||||
@ -1511,6 +1542,7 @@ pub noinline fn convert(options: ConvertOptions) void {
|
||||
}
|
||||
|
||||
var is_export = false;
|
||||
var is_extern = false;
|
||||
|
||||
const global_line = converter.get_line();
|
||||
const global_column = converter.get_column();
|
||||
@ -1525,7 +1557,7 @@ pub noinline fn convert(options: ConvertOptions) void {
|
||||
const global_keyword = string_to_enum(GlobalKeyword, global_keyword_string) orelse converter.report_error();
|
||||
switch (global_keyword) {
|
||||
.@"export" => is_export = true,
|
||||
else => converter.report_error(),
|
||||
.@"extern" => is_extern = true,
|
||||
}
|
||||
|
||||
switch (converter.content[converter.offset]) {
|
||||
@ -1667,9 +1699,6 @@ pub noinline fn convert(options: ConvertOptions) void {
|
||||
for (arguments, argument_types, debug_argument_types[1..]) |*argument, *argument_type, *debug_argument_type| {
|
||||
argument_type.* = argument.type.llvm.handle;
|
||||
debug_argument_type.* = argument.type.llvm.debug;
|
||||
if (module.llvm.di_builder) |_| {
|
||||
assert(@intFromPtr(argument.type.llvm.debug) != 0xaaaa_aaaa_aaaa_aaaa);
|
||||
}
|
||||
}
|
||||
},
|
||||
// TODO: C calling convention
|
||||
@ -1680,7 +1709,7 @@ pub noinline fn convert(options: ConvertOptions) void {
|
||||
const llvm_function_type = llvm.Type.Function.get(return_type.llvm.handle, argument_types, false);
|
||||
const llvm_handle = module.llvm.handle.create_function(.{
|
||||
.name = global_name,
|
||||
.linkage = switch (is_export) {
|
||||
.linkage = switch (is_export or is_extern) {
|
||||
true => .ExternalLinkage,
|
||||
false => .InternalLinkage,
|
||||
},
|
||||
@ -1688,19 +1717,15 @@ pub noinline fn convert(options: ConvertOptions) void {
|
||||
});
|
||||
llvm_handle.set_calling_convention(calling_convention.to_llvm());
|
||||
|
||||
const entry_block = module.llvm.context.create_basic_block("entry", llvm_handle);
|
||||
module.llvm.builder.position_at_end(entry_block);
|
||||
|
||||
const global = module.globals.add();
|
||||
|
||||
var subroutine_type: *llvm.DI.Type.Subroutine = undefined;
|
||||
const current_scope: *llvm.DI.Scope = if (module.llvm.di_builder) |di_builder| blk: {
|
||||
const subroutine_type_flags = llvm.DI.Flags{};
|
||||
subroutine_type = di_builder.create_subroutine_type(module.llvm.file, debug_argument_types, subroutine_type_flags);
|
||||
const scope_line: u32 = @intCast(converter.line_offset + 1);
|
||||
const local_to_unit = !is_export;
|
||||
const local_to_unit = !is_export and !is_extern;
|
||||
const flags = llvm.DI.Flags{};
|
||||
const is_definition = true;
|
||||
const is_definition = !is_extern;
|
||||
const subprogram = di_builder.create_function(module.llvm.global_scope, global_name, linkage_name, module.llvm.file, global_line, subroutine_type, local_to_unit, is_definition, scope_line, flags, options.build_mode.is_optimized());
|
||||
llvm_handle.set_subprogram(subprogram);
|
||||
|
||||
@ -1729,76 +1754,98 @@ pub noinline fn convert(options: ConvertOptions) void {
|
||||
},
|
||||
});
|
||||
|
||||
const value = module.values.add();
|
||||
value.* = .{
|
||||
.llvm = llvm_handle.to_value(),
|
||||
.type = function_type,
|
||||
.bb = .{
|
||||
.function = .{
|
||||
.current_basic_block = entry_block,
|
||||
.calling_convention = calling_convention,
|
||||
.current_scope = current_scope,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
global.* = .{
|
||||
.value = value,
|
||||
.name = global_name,
|
||||
};
|
||||
|
||||
module.current_function = global;
|
||||
defer module.current_function = null;
|
||||
|
||||
const argument_variables = global.value.bb.function.arguments.add_many(argument_count);
|
||||
|
||||
for (argument_variables, arguments) |*argument_variable, *argument| {
|
||||
const argument_alloca = module.llvm.builder.create_alloca(argument.type.llvm.handle, argument.name);
|
||||
const argument_value = module.values.add();
|
||||
argument_value.* = .{
|
||||
.llvm = argument_alloca,
|
||||
.type = argument.type,
|
||||
.bb = .argument,
|
||||
if (converter.consume_character_if_match(';')) {
|
||||
const value = module.values.add();
|
||||
value.* = .{
|
||||
.llvm = llvm_handle.to_value(),
|
||||
.type = function_type,
|
||||
.bb = .external_function,
|
||||
};
|
||||
argument_variable.* = .{
|
||||
.value = argument_value,
|
||||
.name = argument.name,
|
||||
|
||||
global.* = .{
|
||||
.value = value,
|
||||
.name = global_name,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const entry_block = module.llvm.context.create_basic_block("entry", llvm_handle);
|
||||
module.llvm.builder.position_at_end(entry_block);
|
||||
|
||||
var llvm_argument_buffer: [argument_buffer.len]*llvm.Argument = undefined;
|
||||
llvm_handle.get_arguments(&llvm_argument_buffer);
|
||||
const llvm_arguments = llvm_argument_buffer[0..argument_count];
|
||||
|
||||
if (argument_count > 0) {
|
||||
switch (calling_convention) {
|
||||
.unknown => {
|
||||
for (argument_variables, llvm_arguments) |*argument_variable, llvm_argument| {
|
||||
_ = module.llvm.builder.create_store(llvm_argument.to_value(), argument_variable.value.llvm);
|
||||
}
|
||||
const value = module.values.add();
|
||||
value.* = .{
|
||||
.llvm = llvm_handle.to_value(),
|
||||
.type = function_type,
|
||||
.bb = .{
|
||||
.function = .{
|
||||
.current_basic_block = entry_block,
|
||||
.calling_convention = calling_convention,
|
||||
.current_scope = current_scope,
|
||||
},
|
||||
},
|
||||
.c => @trap(),
|
||||
};
|
||||
|
||||
global.* = .{
|
||||
.value = value,
|
||||
.name = global_name,
|
||||
};
|
||||
|
||||
module.current_function = global;
|
||||
defer module.current_function = null;
|
||||
|
||||
const argument_variables = global.value.bb.function.arguments.add_many(argument_count);
|
||||
|
||||
for (argument_variables, arguments) |*argument_variable, *argument| {
|
||||
const argument_alloca = module.llvm.builder.create_alloca(argument.type.llvm.handle, argument.name);
|
||||
const argument_value = module.values.add();
|
||||
argument_value.* = .{
|
||||
.llvm = argument_alloca,
|
||||
.type = argument.type,
|
||||
.bb = .argument,
|
||||
};
|
||||
argument_variable.* = .{
|
||||
.value = argument_value,
|
||||
.name = argument.name,
|
||||
};
|
||||
}
|
||||
|
||||
if (module.llvm.di_builder) |di_builder| {
|
||||
for (argument_variables, arguments, 0..) |argument_variable, argument, argument_number| {
|
||||
const always_preserve = true;
|
||||
const flags = llvm.DI.Flags{};
|
||||
const parameter_variable = di_builder.create_parameter_variable(global.value.bb.function.current_scope, argument_variable.name, @intCast(argument_number + 1), module.llvm.file, argument.line, argument.type.llvm.debug, always_preserve, flags);
|
||||
const inlined_at: ?*llvm.DI.Metadata = null; // TODO
|
||||
const debug_location = llvm.DI.create_debug_location(module.llvm.context, argument.line, argument.column, global.value.bb.function.current_scope, inlined_at);
|
||||
_ = di_builder.insert_declare_record_at_end(argument_variable.value.llvm, parameter_variable, di_builder.null_expression(), debug_location, global.value.bb.function.current_basic_block);
|
||||
var llvm_argument_buffer: [argument_buffer.len]*llvm.Argument = undefined;
|
||||
llvm_handle.get_arguments(&llvm_argument_buffer);
|
||||
const llvm_arguments = llvm_argument_buffer[0..argument_count];
|
||||
|
||||
if (argument_count > 0) {
|
||||
switch (calling_convention) {
|
||||
.unknown => {
|
||||
for (argument_variables, llvm_arguments) |*argument_variable, llvm_argument| {
|
||||
_ = module.llvm.builder.create_store(llvm_argument.to_value(), argument_variable.value.llvm);
|
||||
}
|
||||
},
|
||||
.c => @trap(),
|
||||
}
|
||||
|
||||
if (module.llvm.di_builder) |di_builder| {
|
||||
for (argument_variables, arguments, 0..) |argument_variable, argument, argument_number| {
|
||||
const always_preserve = true;
|
||||
const flags = llvm.DI.Flags{};
|
||||
const parameter_variable = di_builder.create_parameter_variable(global.value.bb.function.current_scope, argument_variable.name, @intCast(argument_number + 1), module.llvm.file, argument.line, argument.type.llvm.debug, always_preserve, flags);
|
||||
const inlined_at: ?*llvm.DI.Metadata = null; // TODO
|
||||
const debug_location = llvm.DI.create_debug_location(module.llvm.context, argument.line, argument.column, global.value.bb.function.current_scope, inlined_at);
|
||||
_ = di_builder.insert_declare_record_at_end(argument_variable.value.llvm, parameter_variable, di_builder.null_expression(), debug_location, global.value.bb.function.current_basic_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
converter.parse_block(module);
|
||||
|
||||
if (lib.optimization_mode == .Debug and module.llvm.di_builder == null) {
|
||||
const verify_result = llvm_handle.verify();
|
||||
if (!verify_result.success) {
|
||||
os.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
converter.parse_block(module);
|
||||
|
||||
if (module.llvm.di_builder) |di_builder| {
|
||||
di_builder.finalize_subprogram(llvm_handle.get_subprogram());
|
||||
}
|
||||
|
||||
if (lib.optimization_mode == .Debug and module.llvm.di_builder == null) {
|
||||
} else if (lib.optimization_mode == .Debug and global.value.bb == .function) {
|
||||
const verify_result = llvm_handle.verify();
|
||||
if (!verify_result.success) {
|
||||
os.abort();
|
||||
|
256
tests/c_abi.bbb
256
tests/c_abi.bbb
@ -86,20 +86,20 @@ ByVal = struct
|
||||
|
||||
[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_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_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_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_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;
|
||||
@ -111,33 +111,33 @@ ByVal = struct
|
||||
[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_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_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_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_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_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_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] require = fn [cc(c)] (ok: u8)
|
||||
@ -174,8 +174,8 @@ ByVal = struct
|
||||
c_five_integers(12, 34, 56, 78, 90);
|
||||
|
||||
>s = c_ret_struct_u64_u64();
|
||||
#require(s.a == 21);
|
||||
#require(s.b == 22);
|
||||
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, });
|
||||
@ -203,10 +203,10 @@ ByVal = struct
|
||||
};
|
||||
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);
|
||||
require(small2.a == 1);
|
||||
require(small2.b == 2);
|
||||
require(small2.c == 3);
|
||||
require(small2.d == 4);
|
||||
|
||||
>med: MedStructInts = {
|
||||
.x = 1,
|
||||
@ -215,17 +215,17 @@ ByVal = struct
|
||||
};
|
||||
c_med_struct_ints(med);
|
||||
>med2 = c_ret_med_struct_ints();
|
||||
#require(med2.x == 1);
|
||||
#require(med2.y == 2);
|
||||
#require(med2.z == 3);
|
||||
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);
|
||||
require(p2.a == 0);
|
||||
require(p2.b == 1);
|
||||
require(p2.c == 2);
|
||||
require(p2.d == 3);
|
||||
|
||||
>split: SplitStructInt = {
|
||||
.a = 1234,
|
||||
@ -242,11 +242,11 @@ ByVal = struct
|
||||
.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);
|
||||
require(big2.a == 10);
|
||||
require(big2.b == 11);
|
||||
require(big2.c == 12);
|
||||
require(big2.d == 13);
|
||||
require(big2.e == 14);
|
||||
|
||||
>r1: Rect = {
|
||||
.left = 1,
|
||||
@ -262,26 +262,26 @@ ByVal = struct
|
||||
};
|
||||
c_multiple_struct_ints(r1, r2);
|
||||
|
||||
#require(c_ret_bool() == 1);
|
||||
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_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);
|
||||
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);
|
||||
require(x.a == 4);
|
||||
require(x.b == 155);
|
||||
|
||||
>res = c_modify_by_ref_param({ .val = 1, .arr = undefined, });
|
||||
#require(res.val == 42);
|
||||
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);
|
||||
@ -290,61 +290,61 @@ ByVal = struct
|
||||
|
||||
[export] bb_u8 = fn [cc(c)] (x: u8) void
|
||||
{
|
||||
#require(x == 0xff);
|
||||
require(x == 0xff);
|
||||
}
|
||||
|
||||
[export] bb_u16 = fn [cc(c)] (x: u16) void
|
||||
{
|
||||
#require(x == 0xfffe);
|
||||
require(x == 0xfffe);
|
||||
}
|
||||
|
||||
[export] bb_u32 = fn [cc(c)] (x: u32) void
|
||||
{
|
||||
#require(x == 0xfffffffd);
|
||||
require(x == 0xfffffffd);
|
||||
}
|
||||
|
||||
[export] bb_u64 = fn [cc(c)] (x: u64) void
|
||||
{
|
||||
#require(x == 0xfffffffffffffffc);
|
||||
require(x == 0xfffffffffffffffc);
|
||||
}
|
||||
|
||||
[export] bb_s8 = fn [cc(c)] (x: s8) void
|
||||
{
|
||||
#require(x == -1);
|
||||
require(x == -1);
|
||||
}
|
||||
|
||||
[export] bb_s16 = fn [cc(c)] (x: s16) void
|
||||
{
|
||||
#require(x == -2);
|
||||
require(x == -2);
|
||||
}
|
||||
|
||||
[export] bb_s32 = fn [cc(c)] (x: s32) void
|
||||
{
|
||||
#require(x == -3);
|
||||
require(x == -3);
|
||||
}
|
||||
|
||||
[export] bb_s64 = fn [cc(c)] (x: s64) void
|
||||
{
|
||||
#require(x == -4);
|
||||
require(x == -4);
|
||||
}
|
||||
|
||||
[export] bb_ptr = fn [cc(c)] (x: *u8) void
|
||||
{
|
||||
#require(#int_from_pointer(x) == 0xdeadbeef);
|
||||
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);
|
||||
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);
|
||||
require(x);
|
||||
}
|
||||
|
||||
[export] bb_ret_struct_u64_u64 = fn [cc(c)] () Struct_u64_u64
|
||||
@ -354,89 +354,89 @@ ByVal = struct
|
||||
|
||||
[export] bb_struct_u64_u64_0 = fn [cc(c)] (s: Struct_u64_u64) void
|
||||
{
|
||||
#require(s.a == 3);
|
||||
#require(s.b == 4);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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,
|
||||
@ -513,27 +513,27 @@ ByVal = struct
|
||||
|
||||
[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);
|
||||
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);
|
||||
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);
|
||||
require(s.x == 1);
|
||||
require(s.y == 2);
|
||||
require(s.z == 3);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user