From 45fab3dd290f325fb66e6b3a7a621a7c2d35688d Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Fri, 13 Jun 2025 13:41:51 -0600 Subject: [PATCH] Pass 'small_struct_ints' --- src/compiler.bbb | 47 +++++++++++++++++++++++++++++++++++++++++------ src/emitter.cpp | 10 ++++------ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/compiler.bbb b/src/compiler.bbb index 2da677e..fa807d1 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -7172,7 +7172,26 @@ contains_no_user_data = fn (type: &Type, start: u64, end: u64) u1 .struct => { result = 1; - #trap(); + + >fields = type.content.struct.fields; + + for (&field: fields) + { + >field_offset = field.offset; + + if (field_offset >= end) + { + break; + } + + >field_start = #select(field_offset < start, start - field_offset, 0); + + if (!contains_no_user_data(field.type, field_start, end - field_offset)) + { + result = 0; + break; + } + } }, .array, .enum_array => { @@ -12945,15 +12964,30 @@ emit = fn (module: &Module) void else { return_value = create_load(module, { - .type = semantic_return_type, - .pointer = return_alloca, - zero, - }); + .type = semantic_return_type, + .pointer = return_alloca, + zero, + }); } } else { - #trap(); + >source: &LLVMValue = zero; + if (function_type.abi.return_abi.attributes.direct.offset == 0) + { + source = return_alloca; + } + else + { + #trap(); + } + + assert(source != zero); + + >source_type = function_type.abi.return_abi.semantic_type; + >destination_type = coerce_to_type; + >result = create_coerced_load(module, source, source_type, destination_type); + return_value = result; } }, .indirect => @@ -13329,6 +13363,7 @@ names: [_][]u8 = "return_u64_u64", "select", "slice", + "small_struct_ints", ]; [export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32 diff --git a/src/emitter.cpp b/src/emitter.cpp index 6ec6266..b5601c6 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -609,21 +609,19 @@ fn bool contains_no_user_data(Type* type, u64 start, u64 end) { case TypeId::structure: { - u64 offset = 0; - for (auto& field: type->structure.fields) { - if (offset >= end) + auto field_offset = field.offset; + if (field_offset >= end) { break; } - auto field_start = offset < start ? start - offset : 0; - if (!contains_no_user_data(field.type, field_start, end - offset)) + auto field_start = field_offset < start ? start - field_offset : 0; + if (!contains_no_user_data(field.type, field_start, end - field_offset)) { return false; } - offset += get_byte_size(field.type); } return true;