| ... | ... | @@ -198,10 +198,11 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c |
| 198 | 198 | result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; |
| 199 | 199 | break; |
| 200 | 200 | } |
| 201 | | case ConstPtrSpecialBaseStruct: |
| 202 | | result = &const_val->data.x_ptr.data.base_struct.struct_val->data.x_struct.fields[ |
| 203 | | const_val->data.x_ptr.data.base_struct.field_index]; |
| 201 | case ConstPtrSpecialBaseStruct: { |
| 202 | ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; |
| 203 | result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; |
| 204 | 204 | break; |
| 205 | } |
| 205 | 206 | case ConstPtrSpecialBaseErrorUnionCode: |
| 206 | 207 | result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; |
| 207 | 208 | break; |
| ... | ... | @@ -230,20 +231,55 @@ static bool is_opt_err_set(ZigType *ty) { |
| 230 | 231 | (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet); |
| 231 | 232 | } |
| 232 | 233 | |
| 234 | // This function returns true when you can change the type of a ConstExprValue and the |
| 235 | // value remains meaningful. |
| 233 | 236 | static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { |
| 234 | 237 | if (a == b) |
| 235 | 238 | return true; |
| 236 | 239 | |
| 237 | | if (a->id == b->id) |
| 238 | | return true; |
| 239 | | |
| 240 | 240 | if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) |
| 241 | 241 | return true; |
| 242 | 242 | |
| 243 | 243 | if (is_opt_err_set(a) && is_opt_err_set(b)) |
| 244 | 244 | return true; |
| 245 | 245 | |
| 246 | | return false; |
| 246 | if (a->id != b->id) |
| 247 | return false; |
| 248 | |
| 249 | switch (a->id) { |
| 250 | case ZigTypeIdInvalid: |
| 251 | case ZigTypeIdUnreachable: |
| 252 | zig_unreachable(); |
| 253 | case ZigTypeIdMetaType: |
| 254 | case ZigTypeIdVoid: |
| 255 | case ZigTypeIdBool: |
| 256 | case ZigTypeIdComptimeFloat: |
| 257 | case ZigTypeIdComptimeInt: |
| 258 | case ZigTypeIdPointer: |
| 259 | case ZigTypeIdUndefined: |
| 260 | case ZigTypeIdNull: |
| 261 | case ZigTypeIdNamespace: |
| 262 | case ZigTypeIdBoundFn: |
| 263 | case ZigTypeIdErrorSet: |
| 264 | case ZigTypeIdOpaque: |
| 265 | return true; |
| 266 | case ZigTypeIdFloat: |
| 267 | return a->data.floating.bit_count == b->data.floating.bit_count; |
| 268 | case ZigTypeIdInt: |
| 269 | return a->data.integral.is_signed == b->data.integral.is_signed; |
| 270 | case ZigTypeIdArray: |
| 271 | case ZigTypeIdStruct: |
| 272 | case ZigTypeIdOptional: |
| 273 | case ZigTypeIdErrorUnion: |
| 274 | case ZigTypeIdEnum: |
| 275 | case ZigTypeIdUnion: |
| 276 | case ZigTypeIdFn: |
| 277 | case ZigTypeIdArgTuple: |
| 278 | case ZigTypeIdPromise: |
| 279 | case ZigTypeIdVector: |
| 280 | return false; |
| 281 | } |
| 282 | zig_unreachable(); |
| 247 | 283 | } |
| 248 | 284 | |
| 249 | 285 | static bool ir_should_inline(IrExecutable *exec, Scope *scope) { |
| ... | ... | @@ -14421,12 +14457,11 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 14421 | 14457 | if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) |
| 14422 | 14458 | return ErrorSemanticAnalyzeFail; |
| 14423 | 14459 | |
| 14424 | | // We don't need to read the padding bytes, so we look at type_size_store bytes |
| 14425 | | size_t src_size = type_size_store(codegen, pointee->type); |
| 14426 | | size_t dst_size = type_size_store(codegen, out_val->type); |
| 14460 | size_t src_size = type_size(codegen, pointee->type); |
| 14461 | size_t dst_size = type_size(codegen, out_val->type); |
| 14427 | 14462 | |
| 14428 | 14463 | if (dst_size <= src_size) { |
| 14429 | | if (types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { |
| 14464 | if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { |
| 14430 | 14465 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 14431 | 14466 | return ErrorNone; |
| 14432 | 14467 | } |
| ... | ... | @@ -20885,7 +20920,68 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 20885 | 20920 | case ZigTypeIdVector: |
| 20886 | 20921 | return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); |
| 20887 | 20922 | case ZigTypeIdStruct: |
| 20888 | | zig_panic("TODO buf_write_value_bytes struct type"); |
| 20923 | switch (val->type->data.structure.layout) { |
| 20924 | case ContainerLayoutAuto: |
| 20925 | zig_unreachable(); |
| 20926 | case ContainerLayoutExtern: |
| 20927 | zig_panic("TODO buf_write_value_bytes extern struct"); |
| 20928 | case ContainerLayoutPacked: { |
| 20929 | size_t src_field_count = val->type->data.structure.src_field_count; |
| 20930 | size_t gen_field_count = val->type->data.structure.gen_field_count; |
| 20931 | size_t gen_i = 0; |
| 20932 | size_t src_i = 0; |
| 20933 | size_t offset = 0; |
| 20934 | bool is_big_endian = codegen->is_big_endian; |
| 20935 | uint8_t child_buf_prealloc[16]; |
| 20936 | size_t child_buf_len = 16; |
| 20937 | uint8_t *child_buf = child_buf_prealloc; |
| 20938 | while (gen_i < gen_field_count) { |
| 20939 | LLVMTypeRef gen_llvm_int_type = LLVMStructGetTypeAtIndex(val->type->type_ref, |
| 20940 | (unsigned)gen_i); |
| 20941 | size_t big_int_bit_count = LLVMGetIntTypeWidth(gen_llvm_int_type); |
| 20942 | size_t big_int_byte_count = big_int_bit_count / 8; |
| 20943 | if (big_int_byte_count > child_buf_len) { |
| 20944 | child_buf = allocate_nonzero<uint8_t>(big_int_byte_count); |
| 20945 | child_buf_len = big_int_byte_count; |
| 20946 | } |
| 20947 | BigInt big_int; |
| 20948 | bigint_init_unsigned(&big_int, 0); |
| 20949 | size_t used_bits = 0; |
| 20950 | while (src_i < src_field_count) { |
| 20951 | TypeStructField *field = &val->type->data.structure.fields[src_i]; |
| 20952 | assert(field->gen_index != SIZE_MAX); |
| 20953 | if (field->gen_index != gen_i) |
| 20954 | break; |
| 20955 | uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); |
| 20956 | buf_write_value_bytes(codegen, child_buf, &val->data.x_struct.fields[src_i]); |
| 20957 | BigInt child_val; |
| 20958 | bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian, |
| 20959 | false); |
| 20960 | if (is_big_endian) { |
| 20961 | BigInt shift_amt; |
| 20962 | bigint_init_unsigned(&shift_amt, packed_bits_size); |
| 20963 | BigInt shifted; |
| 20964 | bigint_shl(&shifted, &big_int, &shift_amt); |
| 20965 | bigint_or(&big_int, &shifted, &child_val); |
| 20966 | } else { |
| 20967 | BigInt shift_amt; |
| 20968 | bigint_init_unsigned(&shift_amt, used_bits); |
| 20969 | BigInt child_val_shifted; |
| 20970 | bigint_shl(&child_val_shifted, &child_val, &shift_amt); |
| 20971 | BigInt tmp; |
| 20972 | bigint_or(&tmp, &big_int, &child_val_shifted); |
| 20973 | big_int = tmp; |
| 20974 | used_bits += packed_bits_size; |
| 20975 | } |
| 20976 | src_i += 1; |
| 20977 | } |
| 20978 | bigint_write_twos_complement(&big_int, buf + offset, big_int_bit_count, is_big_endian); |
| 20979 | offset += big_int_byte_count; |
| 20980 | gen_i += 1; |
| 20981 | } |
| 20982 | } |
| 20983 | } |
| 20984 | return; |
| 20889 | 20985 | case ZigTypeIdOptional: |
| 20890 | 20986 | zig_panic("TODO buf_write_value_bytes maybe type"); |
| 20891 | 20987 | case ZigTypeIdErrorUnion: |
| ... | ... | @@ -21012,8 +21108,62 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 21012 | 21108 | } |
| 21013 | 21109 | return ErrorNone; |
| 21014 | 21110 | } |
| 21015 | | case ContainerLayoutPacked: |
| 21016 | | zig_panic("TODO buf_read_value_bytes packed struct"); |
| 21111 | case ContainerLayoutPacked: { |
| 21112 | size_t src_field_count = val->type->data.structure.src_field_count; |
| 21113 | val->data.x_struct.fields = create_const_vals(src_field_count); |
| 21114 | size_t gen_field_count = val->type->data.structure.gen_field_count; |
| 21115 | size_t gen_i = 0; |
| 21116 | size_t src_i = 0; |
| 21117 | size_t offset = 0; |
| 21118 | bool is_big_endian = codegen->is_big_endian; |
| 21119 | uint8_t child_buf_prealloc[16]; |
| 21120 | size_t child_buf_len = 16; |
| 21121 | uint8_t *child_buf = child_buf_prealloc; |
| 21122 | while (gen_i < gen_field_count) { |
| 21123 | LLVMTypeRef gen_llvm_int_type = LLVMStructGetTypeAtIndex(val->type->type_ref, |
| 21124 | (unsigned)gen_i); |
| 21125 | size_t big_int_bit_count = LLVMGetIntTypeWidth(gen_llvm_int_type); |
| 21126 | size_t big_int_byte_count = big_int_bit_count / 8; |
| 21127 | if (big_int_byte_count > child_buf_len) { |
| 21128 | child_buf = allocate_nonzero<uint8_t>(big_int_byte_count); |
| 21129 | child_buf_len = big_int_byte_count; |
| 21130 | } |
| 21131 | BigInt big_int; |
| 21132 | bigint_read_twos_complement(&big_int, buf + offset, big_int_bit_count, is_big_endian, false); |
| 21133 | while (src_i < src_field_count) { |
| 21134 | TypeStructField *field = &val->type->data.structure.fields[src_i]; |
| 21135 | assert(field->gen_index != SIZE_MAX); |
| 21136 | if (field->gen_index != gen_i) |
| 21137 | break; |
| 21138 | ConstExprValue *field_val = &val->data.x_struct.fields[src_i]; |
| 21139 | field_val->special = ConstValSpecialStatic; |
| 21140 | field_val->type = field->type_entry; |
| 21141 | uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); |
| 21142 | |
| 21143 | BigInt child_val; |
| 21144 | if (is_big_endian) { |
| 21145 | zig_panic("TODO buf_read_value_bytes packed struct big endian"); |
| 21146 | } else { |
| 21147 | BigInt packed_bits_size_bi; |
| 21148 | bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size); |
| 21149 | bigint_truncate(&child_val, &big_int, packed_bits_size, false); |
| 21150 | BigInt tmp; |
| 21151 | bigint_shr(&tmp, &big_int, &packed_bits_size_bi); |
| 21152 | big_int = tmp; |
| 21153 | } |
| 21154 | |
| 21155 | bigint_write_twos_complement(&child_val, child_buf, big_int_bit_count, is_big_endian); |
| 21156 | if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { |
| 21157 | return err; |
| 21158 | } |
| 21159 | |
| 21160 | src_i += 1; |
| 21161 | } |
| 21162 | offset += big_int_byte_count; |
| 21163 | gen_i += 1; |
| 21164 | } |
| 21165 | return ErrorNone; |
| 21166 | } |
| 21017 | 21167 | } |
| 21018 | 21168 | zig_unreachable(); |
| 21019 | 21169 | case ZigTypeIdOptional: |