diff --git a/src/compiler.bbb b/src/compiler.bbb index 2da677e..9d1a43c 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 => { @@ -13329,6 +13348,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;