| ... | @@ -198,10 +198,11 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c | ... | @@ -198,10 +198,11 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c |
| 198 | result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; | 198 | result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; |
| 199 | break; | 199 | break; |
| 200 | } | 200 | } |
| 201 | case ConstPtrSpecialBaseStruct: | 201 | case ConstPtrSpecialBaseStruct: { |
| 202 | result = &const_val->data.x_ptr.data.base_struct.struct_val->data.x_struct.fields[ | 202 | ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; |
| 203 | const_val->data.x_ptr.data.base_struct.field_index]; | 203 | result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; |
| 204 | break; | 204 | break; |
| | 205 | } |
| 205 | case ConstPtrSpecialBaseErrorUnionCode: | 206 | case ConstPtrSpecialBaseErrorUnionCode: |
| 206 | result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; | 207 | result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; |
| 207 | break; | 208 | break; |
| ... | @@ -230,20 +231,55 @@ static bool is_opt_err_set(ZigType *ty) { | ... | @@ -230,20 +231,55 @@ static bool is_opt_err_set(ZigType *ty) { |
| 230 | (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet); | 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 | static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { | 236 | static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { |
| 234 | if (a == b) | 237 | if (a == b) |
| 235 | return true; | 238 | return true; |
| 236 | | 239 | |
| 237 | if (a->id == b->id) | | |
| 238 | return true; | | |
| 239 | | | |
| 240 | if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) | 240 | if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) |
| 241 | return true; | 241 | return true; |
| 242 | | 242 | |
| 243 | if (is_opt_err_set(a) && is_opt_err_set(b)) | 243 | if (is_opt_err_set(a) && is_opt_err_set(b)) |
| 244 | return true; | 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 | static bool ir_should_inline(IrExecutable *exec, Scope *scope) { | 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,12 +14457,11 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 14421 | if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) | 14457 | if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) |
| 14422 | return ErrorSemanticAnalyzeFail; | 14458 | return ErrorSemanticAnalyzeFail; |
| 14423 | | 14459 | |
| 14424 | // We don't need to read the padding bytes, so we look at type_size_store bytes | 14460 | size_t src_size = type_size(codegen, pointee->type); |
| 14425 | size_t src_size = type_size_store(codegen, pointee->type); | 14461 | size_t dst_size = type_size(codegen, out_val->type); |
| 14426 | size_t dst_size = type_size_store(codegen, out_val->type); | | |
| 14427 | | 14462 | |
| 14428 | if (dst_size <= src_size) { | 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 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); | 14465 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 14431 | return ErrorNone; | 14466 | return ErrorNone; |
| 14432 | } | 14467 | } |
| ... | @@ -20885,7 +20920,68 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -20885,7 +20920,68 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 20885 | case ZigTypeIdVector: | 20920 | case ZigTypeIdVector: |
| 20886 | return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); | 20921 | return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); |
| 20887 | case ZigTypeIdStruct: | 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 | case ZigTypeIdOptional: | 20985 | case ZigTypeIdOptional: |
| 20890 | zig_panic("TODO buf_write_value_bytes maybe type"); | 20986 | zig_panic("TODO buf_write_value_bytes maybe type"); |
| 20891 | case ZigTypeIdErrorUnion: | 20987 | case ZigTypeIdErrorUnion: |
| ... | @@ -21012,8 +21108,62 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou | ... | @@ -21012,8 +21108,62 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 21012 | } | 21108 | } |
| 21013 | return ErrorNone; | 21109 | return ErrorNone; |
| 21014 | } | 21110 | } |
| 21015 | case ContainerLayoutPacked: | 21111 | case ContainerLayoutPacked: { |
| 21016 | zig_panic("TODO buf_read_value_bytes packed struct"); | 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 | zig_unreachable(); | 21168 | zig_unreachable(); |
| 21019 | case ZigTypeIdOptional: | 21169 | case ZigTypeIdOptional: |